在Python中读取Arduino发送的最新字符
我刚开始学习Arduino和Python,脑子里有个想法,但就是搞不定。简单来说,就是在Arduino上按下一个按钮时,它会通过串口发送一个“4”。我希望在Python中,一旦读取到这个“4”,就能执行某个操作。这是我目前写的代码:
import serial
ser = serial.Serial('/dev/tty.usbserial-A900frF6', 9600)
var = 1
while var == 1:
if ser.inWaiting() > 0:
ser.readline(1)
print "hello"
但是显然,这段代码无论如何都会打印“hello”。我需要的是像这样:
import serial
ser = serial.Serial('/dev/tty.usbserial-A900frF6', 9600)
var = 1
while var == 1:
if ser.inWaiting() > 0:
ser.readline(1)
if last.read == "4":
print "hello"
但是我该怎么定义last.read呢?
2 个回答
我觉得可以通过这些修改来实现:
import serial
ser = serial.Serial('/dev/tty.usbserial-A900frF6', 9600)
var = 1
while var == 1:
if (ser.inWaiting() > 0):
ser.readline(1)
print "hello"
我不知道怎么用 readLine
来同步通信,因为它不是一个阻塞调用。你可以使用 ser.read(numBytes)
,这是一个阻塞调用。不过,你需要知道 Arduino 发送了多少字节,这样才能正确解码字节流。下面是一个简单的例子,它读取 8 个字节,并把它们解包成 2 个无符号短整型和一个长整型(<HHL
部分)在 Python 中。
try:
data = [struct.unpack('<HHL', handle.read(8)) for i in range(PACKETS_PER_TRANSMIT)]
except OSError:
self.emit(SIGNAL("connectionLost()"))
self.connected = False
这里有一个关于 struct.unpack() 的参考资料。
与此相关的 Arduino 代码。它读取两个模拟传感器的值和微秒时间戳,并通过串口发送。
unsigned int SensA, SensB;
byte out_buffer[64];
unsigned int buffer_head = 0;
unsigned int buffer_size = 64;
SensA = analogRead(SENSOR_A);
SensB = analogRead(SENSOR_B);
micr = micros();
out_buffer[buffer_head++] = (SensA & 0xFF);
out_buffer[buffer_head++] = (SensA >> 8) & 0xFF;
out_buffer[buffer_head++] = (SensB & 0xFF);
out_buffer[buffer_head++] = (SensB >> 8) & 0xFF;
out_buffer[buffer_head++] = (micr & 0xFF);
out_buffer[buffer_head++] = (micr >> 8) & 0xFF;
out_buffer[buffer_head++] = (micr >> 16) & 0xFF;
out_buffer[buffer_head++] = (micr >> 24) & 0xFF;
Serial.write(out_buffer, buffer_size);
Arduino 的社区和 Processing 论坛也是寻找这类代码的好地方。
更新 我觉得我可能误导了你,readLine
其实是不会阻塞的。无论如何,上面的代码应该可以工作。我还找到了一条关于同样主题的 其他讨论。
更新 你不一定要使用模拟传感器,这只是我做的项目恰好用到的,你当然可以通过串口发送任何值。所以 Arduino 代码的工作是,它有一个类型为 byte
的缓冲区,用来存储输出,然后再发送。传感器的值和微秒时间戳会被写入这个缓冲区,然后通过串口发送出去。(SensA & 0xFF)
是一个位掩码操作符,它将 SensA
值的位模式与 0xFF
(十进制的 255)进行掩码操作。简单来说,这样可以从 16 位的 SensA
值中取出前 8 位。下一行做的事情类似,但将位向右移动了 8 位,因此取出的是最后 8 位。
你需要理解位模式、位掩码和位移的概念。然后缓冲区会被写入串口。
Python 代码则是每次从串口读取 8 位。看看 struct.unpack 的文档。for comprehension 只是为了允许发送多组值。因为 Arduino 板和 Python 代码的运行是不同步的,我加了这个功能,以便每次传输可以发送多条“行”。你可以直接用 struct.unpack('<HHL',handle.read(8))
替换掉。记住,´handle.read()´ 是以字节为单位读取,而 Arduino 的发送代码是处理位的。