意外的变量打印
Unexpected variable printing
我在 Raspberry Pi 上使用 python 从 Arduino 和 mySQL 数据库发送和接收变量,进行一些计算并将数据发送到适当的目的地。在脚本开始时,我将数据保存在 "oldVariables" 中以查看数据库数据是否已更改。出于某种原因,我在 if
函数中将变量设置为 0
或 1
,如果调用了该函数,它会打印出 6
。我只开始使用 python 对于这个项目,所以请随时批评我的代码,以便我改进它。这是我得到的:
这是 returns 6(我从 Arduino on button 事件发送“6”):
arduino = ser.readline().strip()
while arduino < 8:
if (arduino == 6):
if (oldAlarm == 0):
aStat = 1
armed = True
os.system("python alarmOn.py")
else:
aStat = 0
armed = False
cur.execute("UPDATE elements SET value = %s WHERE element = 'Alarm'",
(aStat))
print aStat
con.commit()
arduino = ser.readline().strip()
由于某些或其他原因,更新数据库的唯一功能是 LDR,其中 if (arduino > 100):
但是其他更新数据库的功能看起来完全一样,但它们不会更新,甚至在我将它们放入之前while arduino < 8
循环。
剩下的就这些了..:[=19=]
import MySQLdb as mdb
import sys
import serial
import os
import time
ser = serial.Serial('/dev/ttyACM1', 9600)
con = mdb.connect('10.0.0.100', 'pi', 'pi', 'Smart_Home')
arduino = 0
oldAlarm = 0
aStat = 0
rStat = 0
lStat = 0
armed = False
with con:
cur = con.cursor()
cur.execute("SELECT value FROM elements WHERE element='Alarm'")
rows = cur.fetchone()
for row in rows:
oldAlarm = int(row)
cur.execute("SELECT value FROM elements WHERE element='Relay'")
rows = cur.fetchone()
for row in rows:
oldRelay = int(row)
cur.execute("SELECT value FROM elements WHERE element='Motion'")
rows = cur.fetchone()
for row in rows:
oldMotion = int(row)
def triggerAlarm():
global oldAlarm
if (oldAlarm != alarm):
ser.write('1')
if (oldAlarm == 0):
oldAlarm = 1
armed = True
else:
oldAlarm = 0
armed = False
def triggerRelay():
global oldRelay
if (oldRelay != relay):
ser.write('2')
if (oldRelay == 0): oldRelay = 1
else: oldRelay = 0
def triggerMotion():
global oldMotion
if (oldMotion != motion & armed == True):
ser.write('3')
while True:
arduino = ser.readline().strip()
if (arduino > 100):
lStat = arduino
print lStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'LDR'",
(lStat))
con.commit()
arduino = ser.readline().strip()
while arduino < 8:
if (arduino == 6):
if (oldAlarm == 0):
aStat = 1
armed = True
os.system("python alarmOn.py")
else:
aStat = 0
armed = False
cur.execute("UPDATE elements SET value = %s WHERE element = 'Alarm'",
(aStat))
print aStat
con.commit()
arduino = ser.readline().strip()
if (arduino == 7):
rStat = 1
print rStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'Relay'",
(rStat))
con.commit()
arduino = ser.readline().strip()
if (arduino == 8):
rStat = 0
print rStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'Relay'",
(rStat))
con.commit()
break;
cur.execute("SELECT value FROM elements WHERE element = 'Alarm'")
rows = cur.fetchone()
for row in rows:
alarm = int(row)
triggerAlarm()
cur.execute("SELECT value FROM elements WHERE element = 'Relay'")
rows = cur.fetchone()
for row in rows:
relay = int(row)
triggerRelay()
cur.execute("SELECT value FROM elements WHERE element = 'Motion'")
rows = cur.fetchone()
for row in rows:
motion = int(row)
triggerMotion()
print 'end'
抱歉代码太长了,但我从 python 中学到的一件事是它对我来说非常不可预测,简单的错误可能在任何地方..
当我在广播时,我的 os.system("python alarmOn.py")
在调用事件时也没有执行.. :/
您的主要问题是您正在将串行输入读取为带有行的字符串
arduino = ser.readline().strip()
并将其与程序主体中的整数进行比较,例如:if (arduino == 6)
或
while arduino < 8
.
虽然 Python 2 不会在数字和字符串之间的 <
或 >
比较中引发错误,但它是一个错误。在 Python 2 中,所有字符串都比任何数字都大。 (例如,您的 while arduino < 8
永远不会被输入)。在 Python3 中,程序将
在这一点上打破 TypeError。 (== 比较并没有错,只是
从来都不是真的)。
所以,请记住,与 SQL 或 ShellScript 不同,Python 是一种强类型语言 -
和数字与字符串根本不同。
如果你实际上是从arduino发送文本数字(ASCII字符与
字节值 48 - 58),你必须在读取它们之后用 int
转换为整数:
arduino = int(ser.readline().strip())
另一方面,如果您要发送“0 - 255”范围内的数字字节“8”或“100”
从 arduino,你可以用 ord
Python built-in 得到这个数字:
arduino = 0
value = ser.readline().strip()
if value:
arduino = ord(value)
您可能会在该代码中遇到其他问题,但解决此问题将使您步入正轨,以便您了解发生了什么。由于您正在打印值以检查发生了什么,因此打印 arduino
变量,以便您知道实际发生了什么。
(您可以使用 print repr(arduino)
来区分字符串值和整数值)
我在 Raspberry Pi 上使用 python 从 Arduino 和 mySQL 数据库发送和接收变量,进行一些计算并将数据发送到适当的目的地。在脚本开始时,我将数据保存在 "oldVariables" 中以查看数据库数据是否已更改。出于某种原因,我在 if
函数中将变量设置为 0
或 1
,如果调用了该函数,它会打印出 6
。我只开始使用 python 对于这个项目,所以请随时批评我的代码,以便我改进它。这是我得到的:
这是 returns 6(我从 Arduino on button 事件发送“6”):
arduino = ser.readline().strip()
while arduino < 8:
if (arduino == 6):
if (oldAlarm == 0):
aStat = 1
armed = True
os.system("python alarmOn.py")
else:
aStat = 0
armed = False
cur.execute("UPDATE elements SET value = %s WHERE element = 'Alarm'",
(aStat))
print aStat
con.commit()
arduino = ser.readline().strip()
由于某些或其他原因,更新数据库的唯一功能是 LDR,其中 if (arduino > 100):
但是其他更新数据库的功能看起来完全一样,但它们不会更新,甚至在我将它们放入之前while arduino < 8
循环。
剩下的就这些了..:[=19=]
import MySQLdb as mdb
import sys
import serial
import os
import time
ser = serial.Serial('/dev/ttyACM1', 9600)
con = mdb.connect('10.0.0.100', 'pi', 'pi', 'Smart_Home')
arduino = 0
oldAlarm = 0
aStat = 0
rStat = 0
lStat = 0
armed = False
with con:
cur = con.cursor()
cur.execute("SELECT value FROM elements WHERE element='Alarm'")
rows = cur.fetchone()
for row in rows:
oldAlarm = int(row)
cur.execute("SELECT value FROM elements WHERE element='Relay'")
rows = cur.fetchone()
for row in rows:
oldRelay = int(row)
cur.execute("SELECT value FROM elements WHERE element='Motion'")
rows = cur.fetchone()
for row in rows:
oldMotion = int(row)
def triggerAlarm():
global oldAlarm
if (oldAlarm != alarm):
ser.write('1')
if (oldAlarm == 0):
oldAlarm = 1
armed = True
else:
oldAlarm = 0
armed = False
def triggerRelay():
global oldRelay
if (oldRelay != relay):
ser.write('2')
if (oldRelay == 0): oldRelay = 1
else: oldRelay = 0
def triggerMotion():
global oldMotion
if (oldMotion != motion & armed == True):
ser.write('3')
while True:
arduino = ser.readline().strip()
if (arduino > 100):
lStat = arduino
print lStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'LDR'",
(lStat))
con.commit()
arduino = ser.readline().strip()
while arduino < 8:
if (arduino == 6):
if (oldAlarm == 0):
aStat = 1
armed = True
os.system("python alarmOn.py")
else:
aStat = 0
armed = False
cur.execute("UPDATE elements SET value = %s WHERE element = 'Alarm'",
(aStat))
print aStat
con.commit()
arduino = ser.readline().strip()
if (arduino == 7):
rStat = 1
print rStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'Relay'",
(rStat))
con.commit()
arduino = ser.readline().strip()
if (arduino == 8):
rStat = 0
print rStat
cur.execute("UPDATE elements SET value = %s WHERE element = 'Relay'",
(rStat))
con.commit()
break;
cur.execute("SELECT value FROM elements WHERE element = 'Alarm'")
rows = cur.fetchone()
for row in rows:
alarm = int(row)
triggerAlarm()
cur.execute("SELECT value FROM elements WHERE element = 'Relay'")
rows = cur.fetchone()
for row in rows:
relay = int(row)
triggerRelay()
cur.execute("SELECT value FROM elements WHERE element = 'Motion'")
rows = cur.fetchone()
for row in rows:
motion = int(row)
triggerMotion()
print 'end'
抱歉代码太长了,但我从 python 中学到的一件事是它对我来说非常不可预测,简单的错误可能在任何地方..
当我在广播时,我的 os.system("python alarmOn.py")
在调用事件时也没有执行.. :/
您的主要问题是您正在将串行输入读取为带有行的字符串
arduino = ser.readline().strip()
并将其与程序主体中的整数进行比较,例如:if (arduino == 6)
或
while arduino < 8
.
虽然 Python 2 不会在数字和字符串之间的 <
或 >
比较中引发错误,但它是一个错误。在 Python 2 中,所有字符串都比任何数字都大。 (例如,您的 while arduino < 8
永远不会被输入)。在 Python3 中,程序将
在这一点上打破 TypeError。 (== 比较并没有错,只是
从来都不是真的)。
所以,请记住,与 SQL 或 ShellScript 不同,Python 是一种强类型语言 - 和数字与字符串根本不同。
如果你实际上是从arduino发送文本数字(ASCII字符与
字节值 48 - 58),你必须在读取它们之后用 int
转换为整数:
arduino = int(ser.readline().strip())
另一方面,如果您要发送“0 - 255”范围内的数字字节“8”或“100”
从 arduino,你可以用 ord
Python built-in 得到这个数字:
arduino = 0
value = ser.readline().strip()
if value:
arduino = ord(value)
您可能会在该代码中遇到其他问题,但解决此问题将使您步入正轨,以便您了解发生了什么。由于您正在打印值以检查发生了什么,因此打印 arduino
变量,以便您知道实际发生了什么。
(您可以使用 print repr(arduino)
来区分字符串值和整数值)