gpt4 book ai didi

python - 从 Arduino 读取字符串

转载 作者:太空宇宙 更新时间:2023-11-04 01:17:29 27 4
gpt4 key购买 nike

我有一个 Arduino 板,它每秒输出一个类似这样的字符串“287、612、109、1134”。我的代码尝试读取此字符串并将其转换为风速和风向。最初它工作正常但最终在其中一个 readines 上它只读取字符串中导致错误的第一个数字。我怎样才能让代码获得完整的字符串而不仅仅是第一个数字?

import serial, time, csv, decimal

#for Mac
port = '/dev/cu.usbserial-A401316V'

ser = serial.Serial(port , baudrate=57600, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=2)

while True:

time.sleep(2)

data = ser.readline( eol="\r\n").strip()

data = data.split(',')

if len(data) > 0:

if data[0] != '2501':

s = float( 1000 / float(data[0]) )

print 'wind speed %.1f' %(round(float((2.5 * s)), 1))
print 'wind direction', round((int(data[1]) - (50)) * .39, 0)
print 'software version', data[2], '\n'
else:
print 'wind speed is zero'
print 'wind direction', round((int(data[1]) - (50)) * .39, 0)
print 'software version', data[2]

ser.close()

最佳答案

没有看到更多来自串行端口的错误数据,我可以说,您在行(甚至空行)上看到单个数字的最常见原因是由于 Arduino 程序发送数据到端口和您的程序试图读取该数据。我敢打赌,如果你在 data=ser.readline() 之后打印 data 并注释掉其余的处​​理过程,你会发现像下面这样的行在输出中:

252, 236, 218, 1136
251, 202, 215
2, 1353
199, 303, 200, 1000
259, 231, 245, 993
28
4, 144, 142, 1112
245, 199, 143, 1403

251, 19
2, 187, 1639
246, 235, 356, 1323

数据跨行甚至空行拆分的原因是程序试图在写入期间或写入之间从串行连接读取数据。发生这种情况时,readline() 获取可用的内容(即使部分/未写入)并在它找到的内容末尾抛出一个 \n

解决这个问题的方法是确保 Arduino 在我们读取之前已经完成发送数据,并且那里有数据供我们读取。处理这个问题的一个好方法是使用一个生成器,它只在主循环完成时生成行(例如,它们以 \r\n 结束,表示对端口的写入结束)。

def get_data():
ibuffer = "" # Buffer for raw data waiting to be processed
while True:
time.sleep(.1) # Best between .1 and 1
data = ser.read(4096) # May need to adjust read size
ibuffer += data # Concat data sets that were possibly split during reading
if '\r\n' in ibuffer: # If complete data set
line, ibuffer = ibuffer.split('\r\n', 1) # Split off first completed set
yield line.strip('\r\n') # Sanitize and Yield data

yield 使此函数成为一个生成器,您可以调用它来获取下一组完整的数据,同时将 read() 拆分的任何内容保存在缓冲区中等待下一个 read() 可以连接数据集的各个部分。将 yield 视为 return,但它不是传递值并离开函数/循环,而是传递值并等待 next() 被调用,它将在下一次通过循环时中断的地方继续执行。使用此函数,您的程序的其余部分将如下所示:

import serial, time, csv, decimal

port = '/dev/cu.usbserial-A401316V'
ser = serial.Serial(port , baudrate=57600, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=2)

def get_data():
"""
The above function here
"""

ser_data = get_data()
while True:
data = ser_data.next().replace(' ','').split(',')

if len(data) > 0:
"""
data processing down here

"""
ser.close()

根据您的设置,您可能希望在 get_data() 中抛出一个条件来中断,例如,如果串行连接丢失,或者 try/except 围绕 data 声明。

值得注意的是,除了上述内容之外,我所做的一件事是将您的 ser.readline(eol) 更改为字节大小的 ser.read(4096)。 PySerial 的 readline() with eol 实际上是 deprecated使用最新版本的 Python。

希望这对您有所帮助;或者,如果您有更多问题,希望它至少能给您一些想法,让您走上正轨。

关于python - 从 Arduino 读取字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23498853/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com