为什么python pyserial在发送字符串时前面加ø?

0 投票
1 回答
1262 浏览
提问于 2025-04-18 02:04

我遇到了一个问题 :o 搜索了很久但没找到答案!

我的树莓派(Rpi)通过串口和pyserial库向我的Moteino网关发送命令。我的Moteino网关会等待这些命令并进行处理。

所以,我可以双向发送和接收数据,但有个问题。

当我从树莓派发送一个字符串到Moteino时,pyserial会在字符串的开头加上一个none或者斜杠零 ø。举个例子:

Python代码

#!/usr/bin/python
# -*- coding: utf-8 -*- 
port =                 serial.Serial(port='/dev/ttyAMA0',baudrate=115200,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=0)

port.flushOutput()
#Ecriture de la pré-commande "LMPCDE"
cde = "LMPCDE\r\n"
cde.encode('ascii','strict')
print cde
port.write(cde )
time.sleep(.1)
data = port.readline()
print data

或者

#!/usr/bin/python
# -*- coding: utf-8 -*- 

port = serial.Serial(port='/dev/ttyAMA0',baudrate=115200,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,timeout=0)

port.flushOutput()
#Ecriture de la pré-commande "LMPCDE"
cde = "LMPCDE\r\n"
print cde
port.write(cde)
time.sleep(.1)
data = port.readline()
print data

Moteino的代码会等待命令字符串,读取它并发送回树莓派。

所以: print cde 提示 LMPCDE 然后 print data 提示 øLMPCDE

我使用的是Python 2.7.3。

为什么python的pyserial在发送的字符串开头加上ø呢? :o

我可以修改Moteino的代码来去掉第一个字符,但即使这是个简单的方法,我也觉得这不是解决问题的好办法,因为我不明白为什么会这样!

我发现了另一个问题!

我通过命令行(Putty)运行python脚本。

如果我打开另一个Putty实例,运行minicom命令“minicom -b 115200 -o -D /dev/ttyAMA0”,然后在第一个控制台运行python脚本,LMPCDE命令前就不会再加ø了。当然,因为串口输入被重定向到minicom,我需要通过minicom发送其他字符串命令。

以下是完整的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
#Importation des librairies
import MySQLdb
import serial
import time
#import string

#Mes Fonctions
def convertstring(mystring):
    if len(mystring) == 3:
        mystring = "0" + mystring
    elif len(mystring) == 2:
        mystring = "00" + mystring
    elif len(mystring) == 1:
        mystring = "000" + mystring
    return mystring

#Connexion à la base de donnees
db = MySQLdb.connect(host="localhost", user="root", passwd="xxxxxxx",                db="logsensorsvalues")  #Password with specials char like (&,@,# ...)
# you must create a Cursor object. It will let,
# you execute all the queries you need
cursor = db.cursor() 
# Use all the SQL you like
cursor.execute("SELECT Far_Red,Red,Red_Orange,Green,Blue,UV_410,UV_395 FROM ledlampvalues Order by ID desc limit 1")
# Values received
rows = cursor.fetchall()
#Fermeture de la base de donnees
cursor.close()
db.close()
#lecture de rows
commandstring=""
for row in rows:
    FarRed = convertstring(str(row[0]*10))  #x10 pour conserver l'architecture du protocole
    Red = convertstring(str(row[1]*10))
    RedOrange = convertstring(str(row[2]*10))
    Green = convertstring(str(row[3]*10))
    Blue = convertstring(str(row[4]*10))
    UV1 = convertstring(str(row[5]*10))
    UV2 = convertstring(str(row[6]*10))
#Formatage de la chaine de caracteres
commandstring = "C" + "F" + FarRed + "R" + Red + "O" + RedOrange + "G" + Green + "B" + Blue + "U" + UV1 + "V" + UV2 + "E" #+ "\r\n"

#Serial Port http://pyserial.sourceforge.net/pyserial_api.html#serial.FileLike.readline
#Possible values for the parameter timeout:
#timeout = None: wait forever
#timeout = 0: non-blocking mode (return immediately on read)
#timeout = x: set timeout to x seconds (float allowed)
serialport = serial.Serial()

serialport.port = "/dev/ttyAMA0"
serialport.baudrate = 115200
serialport.bytesize = serial.EIGHTBITS #number of bits per bytes
serialport.parity = serial.PARITY_NONE #set parity check: no parity
serialport.stopbits = serial.STOPBITS_ONE #number of stop bits
serialport.timeout = 0            #non-blocking mode (return immediately on read)
serialport.xonxoff = False     #disable software flow control
serialport.rtscts = False     #disable hardware (RTS/CTS) flow control
serialport.dsrdtr = False       #disable hardware (DSR/DTR) flow control
serialport.writeTimeout = 0     #timeout for write

try:
    serialport.open()
except Exception , e:
    print "error open serial port: " + str(e)
    exit()

if serialport.isOpen():
    print "Port Open"
    try:
        #Pay attention to the flush order : Output before Input
        serialport.flushOutput() #flush output buffer, aborting current output and discard all that is in buffer
        serialport.flushInput() #flush input buffer, discarding all its contents
        #Ecriture de la pré-commande "LMPCDE"   /// cde.encode('ascii','strict')
        print serialport.write('LMPCDE')
        serialport.flushInput()
        time.sleep(.1)

                #----------------------------DEBUG ZONE----------------------------
        #data = serialport.readline()
        #print data
        while serialport.inWaiting() > 0:
        print serialport.read()
        #-------------------------------END--------------------------------

        while serialport.inWaiting() > 0:
            data = serialport.readline()
            if data.startswith("Expecting"):
                print data
                #Waiting for an acknowledgement from Node
                while serialport.inWaiting() > 0:
                    data = serialport.readline()
                    if data.startswith("ok"):
                        print "Sending Command"
                        serialport.write(commandstring)

        time.sleep(.1)

        #Waiting for an acknowledgement from Node
        while serialport.inWaiting() > 0:
            data = serialport.readline()
            if data.startswith("ok"):
                print data

        serialport.close()          
    except Exception , e1:
        print "error open serial port: " + str(e1)
        exit()
else:
    print "cannot open serial port "

1 个回答

0

你可以尝试以下几种方法来解决这个问题:

  • 在执行完 port.flush.Output() 后,立刻用命令 port.flushInput() 清空串口输入。

  • 使用 port.read() 来逐个字符地读取串口数据。

while 1:

    ch = port.read()
    #Condition for end of line, any other condition may be here
    if ch = '\n'
        #Terminate while loop
        break

撰写回答