我编写了一个最小的双向 python 和串行通信脚本,将整数发送到 arduino。然后,arduino 递增整数并通过串行将其发送回。
comm.py
from time import sleep
from pySerialTransfer import pySerialTransfer as txfer
class struct:
control = 0
class receivestruct:
status = 0
if __name__ == '__main__':
try:
testStruct = struct
rstruct =receivestruct
link = txfer.SerialTransfer('COM7')
link.open()
sleep(2)
counter = 0
while True:
sendSize = 0
testStruct.control = counter
sendSize = link.tx_obj(testStruct.control, start_pos=sendSize)
link.send(sendSize)
print('sent')
#sleep(0.5)
read_correctly = False
while (read_correctly == False):
try:
if not (link.available()):
pass
recSize = 0
# this section returns errors with can't read str as int
rstruct.status = link.rx_obj(obj_type='i', start_pos=recSize)
counter = rstruct.status
recSize += txfer.STRUCT_FORMAT_LENGTHS['i']
print(rstruct.status)
read_correctly = True
except:
pass
except KeyboardInterrupt:
link.close()
arduino.ino
#include "SerialTransfer.h"
SerialTransfer myTransfer;
uint32_t rcontrol;
uint32_t control;
void setup()
{
Serial.begin(115200);
myTransfer.begin(Serial);
}
void loop()
{
if(myTransfer.available())
{
// use this variable to keep track of how many
// bytes we've processed from the receive buffer
uint16_t recSize = 0;
recSize = myTransfer.rxObj(rcontrol, recSize);
control = rcontrol + 1;
uint16_t sendSize = 0;
sendSize = myTransfer.txObj(control, sendSize);
myTransfer.sendData(sendSize);
}
}
现在,我认为这可以正常工作。然而,这里是控制台日志,似乎 python 没有正确读取增量值,并且每 n 次尝试才读取正确的增量值:
115
sent
115
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
116
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
117
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
118
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
119
sent
我在这里尝试了 pySerialTransfer 的两种方式示例,但它似乎使用不再支持的库的过时版本。知道为什么我在双向串行通信中遇到这些问题吗?
问题出在 Python 脚本的接收循环中。你试图在每次循环迭代中读取数据,而无论数据是否可用,这会导致你读取旧数据或根本没有数据。
下面是改进后的 Python 脚本:
from time import sleep
from pySerialTransfer import pySerialTransfer as txfer
class struct:
control = 0
class receivestruct:
status = 0
if __name__ == '__main__':
try:
testStruct = struct
rstruct = receivestruct
link = txfer.SerialTransfer('COM7')
link.open()
sleep(2)
counter = 0
while True:
sendSize = 0
testStruct.control = counter
sendSize = link.tx_obj(testStruct.control, start_pos=sendSize)
link.send(sendSize)
print(f'Sent: {counter}')
# 等待数据可用
while not link.available():
pass
recSize = 0
# 读取数据
rstruct.status = link.rx_obj(obj_type='i', start_pos=recSize)
counter = rstruct.status
recSize += txfer.STRUCT_FORMAT_LENGTHS['i']
print(f'Received: {rstruct.status}')
except KeyboardInterrupt:
link.close()
改进说明:
-
等待数据可用: 在尝试读取数据之前,添加了一个
while not link.available(): pass
循环。这将确保只有在串行端口上有可用数据时才进行读取,从而避免读取到旧数据。 -
移除不必要的 try-except 块: 在接收循环中,你使用了一个 try-except 块来处理可能出现的错误。但是,
link.rx_obj()
本身已经包含了错误处理机制,所以外部的 try-except 块是不必要的。 -
更清晰的打印语句: 将
print('sent')
和print(rstruct.status)
改为更具描述性的print(f'Sent: {counter}')
和print(f'Received: {rstruct.status}')
,以便更清晰地了解发送和接收的数据。
通过这些修改,你的 Python 脚本应该能够正确地接收 Arduino 发送的增量值,而不会出现重复或遗漏。
标签:python,arduino,serial-port,serial-communication From: 78747462