Python 3.x 如何通过串行代码将python转换为arduino,通过串行代码将python3转换为arduino?

Python 3.x 如何通过串行代码将python转换为arduino,通过串行代码将python3转换为arduino?,python-3.x,serial-port,pyserial,Python 3.x,Serial Port,Pyserial,下面的代码用于在spyder中与arduino进行串行通信。在spyder的控制台窗口中,我会看到打印出来的数据行: 78.7,77.9100,80 78.7,77.9100,80 78.7,77.9100,80 78.7,77.9100,80 数据来自两个温度探头、一个流量计和恒温器设定温度 我将Kubuntu 18.04系统升级为all things python3。现在,代码运行,但spyder3控制台窗口不显示可见字符,而是滚动空行。用于解析和绘制此数据的python代码的其余部分不起作

下面的代码用于在spyder中与arduino进行串行通信。在spyder的控制台窗口中,我会看到打印出来的数据行:

78.7,77.9100,80

78.7,77.9100,80

78.7,77.9100,80

78.7,77.9100,80

数据来自两个温度探头、一个流量计和恒温器设定温度

我将Kubuntu 18.04系统升级为all things python3。现在,代码运行,但spyder3控制台窗口不显示可见字符,而是滚动空行。用于解析和绘制此数据的python代码的其余部分不起作用

我花了一整天的时间试图解决这个问题,但运气不好。我猜这对比我更有经验的人来说是个简单的解决办法

旧的工作代码和下面的代码之间的唯一区别是,print语句添加了括号以消除语法错误

python

""" This code was originally copied from:
Listen to serial, return most recent numeric values
Lots of help from here:
http://stackoverflow.com/questions/1093598/pyserial-how-to-read-last-line-sent-from-serial-device
"""

from threading import Thread

import time
import serial

last_received = ''
def receiving(ser):
    global last_received
    buffer = ''
    while True:
        buffer = buffer + ser.read(ser.inWaiting())
        if '\n' in buffer:
            lines = buffer.split('\n') # Guaranteed to have at least 2 entries
            last_received = lines[-2]
            #If the Arduino sends lots of empty lines, you'll lose the
            #last filled line, so you could make the above statement conditional
            #like so: if lines[-2]: last_received = lines[-2]
            buffer = lines[-1]


class SerialData(object):
    def __init__(self, init=50):
        try:
            self.ser = serial.Serial(
                port='/dev/ttyACM0',
                baudrate=9600,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                timeout=0.1,
                xonxoff=0,
                rtscts=0,
                interCharTimeout=None
            )
        except serial.serialutil.SerialException:
            #no serial connection
            self.ser = None
        else:
            Thread(target=receiving, args=(self.ser,)).start()

    def next(self):
        if not self.ser:
            return '81.3,78.1,10.0,60.0,0' #100 #return anything so we can test when Arduino isn't connected
        #return a float value or try a few times until we get one
        for i in range(40):
            raw_line = last_received
            try:
               # return float(raw_line.strip())
                return str(raw_line.strip())
            except ValueError:
                print('bogus data',raw_line)
                time.sleep(.005)
        return 0.
    def __del__(self):
        if self.ser:
            self.ser.close()
    def write(self,val):
        self.ser.write(val)

if __name__=='__main__':
    s = SerialData()
    for i in range(500):
        time.sleep(.015)
        print( s.next())


Python2.x和3.x之间最显著的区别之一是文本字符串的编码方式。对于Python 3.x,与2.x的ASCII相比,所有内容都是Unicode,因此您只需解码从串行端口读取的原始字节:

buffer = buffer + ser.read(ser.inWaiting()).decode('utf-8')
编辑:现在您似乎遇到了另一个涉及异常的问题。您的端口似乎已打开,以确保在实例化端口时可以更改处理异常的方式:

except serial.serialutil.SerialException as e: 
    print(e)
    self.ser = None

一旦你知道错误,你应该能够处理它。很可能您的端口在以前的会话中未正确关闭。

答对了!最后一个建议修复了程序,我为其编写的python GUI界面正在处理这些更正

python

from threading import Thread
import time
import serial

last_received = ''
def receiving(ser):
    global last_received
    buffer = ''
    while True:
        buffer = buffer + ser.read(ser.inWaiting()).decode('utf-8')
        if '\n' in buffer:
            lines = buffer.split('\n') # Guaranteed to have at least 2 entries
            last_received = lines[-2]
            #If the Arduino sends lots of empty lines, you'll lose the
            #last filled line, so you could make the above statement conditional
            #like so: if lines[-2]: last_received = lines[-2]
            buffer = lines[-1]


class SerialData(object):
    def __init__(self, init=50):
        try:
            self.ser = serial.Serial(
                port='/dev/ttyACM1',
                baudrate=9600,
                bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE,
                stopbits=serial.STOPBITS_ONE,
                timeout=0.1,
                xonxoff=0,
                rtscts=0,
                interCharTimeout=None
            )
        except serial.serialutil.SerialException as e: 
            print(e)
            #no serial connection
            self.ser = None
        else:
            Thread(target=receiving, args=(self.ser,)).start()

    def next(self):
       # if not self.ser:
       #     return '81.3,78.1,10.0,60.0,0' #100 #return anything so we can test when Arduino isn't connected
        #return a float value or try a few times until we get one
        for i in range(40):
            raw_line = last_received
            try:
               # return float(raw_line.strip())
                return str(raw_line.strip())
            except ValueError:
                print('bogus data',raw_line)
                time.sleep(.005)
        return 0.
    def __del__(self):
        if self.ser:
            self.ser.close()
    def write(self,val):
        self.ser.write(val)

if __name__=='__main__':
    s = SerialData()
    for i in range(500):
        time.sleep(.015)
        print (s.next())

谢谢你的提示。我不断的研究使我发现了ascii和unicode之间的区别。现在进行.decode更改会导致:感谢您的建议-我的持续努力指出了ascii和unicode之间的差异。替换.decode语句可以改善某些情况。现在,“def next(self)”声明中的“if not self.ser”语句始终为true,错误默认值“81.3,78.1,10.0,60.0,0”通过“print(s.next())”继续打印。请参阅更新以打印异常并继续调试。