意外的变量打印

Unexpected variable printing

我在 Raspberry Pi 上使用 python 从 Arduino 和 mySQL 数据库发送和接收变量,进行一些计算并将数据发送到适当的目的地。在脚本开始时,我将数据保存在 "oldVariables" 中以查看数据库数据是否已更改。出于某种原因,我在 if 函数中将变量设置为 01,如果调用了该函数,它会打印出 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) 来区分字符串值和整数值)