Python 串行读取线是不是会中断 Arduino 循环?

Posted

技术标签:

【中文标题】Python 串行读取线是不是会中断 Arduino 循环?【英文标题】:Does Python serial readline interupt Arduino loop?Python 串行读取线是否会中断 Arduino 循环? 【发布时间】:2012-09-10 14:40:50 【问题描述】:

我正在尝试从与 Arduino 接口的传感器发布 Twitter 更新。 Adruino 回路在读取传感器电压之间有 1 秒的延迟。 Python 代码在 Twitter 更新之间有 1 小时的延迟。

似乎 Python 脚本实际上中断 Arduino 循环,直到它在串行端口上读取一个新行。它是否正确?

例如,尽管 Arduino 程序循环运行 1 小时,但它只会显示 millis() 计数器值 1001,2 小时后它将显示 2002。没有运行 Python 脚本并仅观察串行监视器,Arduino 代码按预期计算毫秒数。

这通常不是问题,但如果您想同时运行一个数据记录器和millis() 以高采集率连续运行,这将是一个问题。很难知道发生了什么,因为串行监视器不能与 Python 程序共享同一个端口。

这是 Arduino 代码示例

void loop() 
    unsigned long ms=millis();
    // read the input on analog pin 1:
    int sensorValue = analogRead(A1);
    float Temp = sensorValue * Vref * (100.0/1023.0); 
    // print out the value you read:
    Serial.print(Temp); 
    Serial.print(" degC");
    Serial.print(" , ");
    Serial.print(ms);
    Serial.println(" milliseconds");
    delay(1000);        // delay in miliseconds between reads for stability

下面是有问题的 Python 代码部分:

arduino = serial.Serial('COM6', 9600)

while 1:  ##Infinite Loop
    status = arduino.readline() ##Wait for new line to come across Serial
    api.PostUpdate(status) ##Post message to Twitter
    time.sleep(3600) ##Wait 3600 seconds

【问题讨论】:

没关系。也许这与您如何在操作系统中设置串行端口有关?你在使用 Windows 吗? Linux?操作系统? 视窗。因此,我如何将串行端口定义为“COM6”。我认为基于 Linux 的系统应该是“/dev/ttlusb0” 【参考方案1】:

Serial.write(以及任何依赖它的函数,如Serial.print)如果输出缓冲区已满,将阻塞。仅当另一端(即您的 Python 脚本或串行监视器)从端口读取时,输出缓冲区才能被耗尽。

串行监视器不断读取串行端口输出,因此缓冲区不会填满。但是,由于您的 Python 脚本每小时只读取一行输出,因此缓冲区一直是满的。因为串行端口是缓冲的,所以每小时读取下一个的输出。

这里发生的情况是,您的 Arduino 代码运行了 10 次循环,并在其缓冲区填满之前写入了 10 行。您的 Python 代码将读取 10 行,每小时一次。 10 小时后,Arduino 放入缓冲区的较新行将具有不同的时间戳

因此,解决方案是从 Arduino 发送每小时更新(让arduino.readline 在 Python 中阻塞一个小时)或不断(每秒)从 Python 读取更新并每小时触发您的 Twitter 更新(例如,使用两个线程,一个用于读取和更新温度,另一个使用最新的本地数据每小时发布一次更新)。

【讨论】:

谢谢 nneonneo,这就是我的怀疑。我认为你的第二个建议可能是最好的一个,因为 Python 和 Arduino 之间的时间延迟同步不会 100% 准确 - 你必须考虑你的 delay() 值加上执行代码需要多长时间。即 arduino 上的一个小时延迟可能是 1 小时 + ~2ms【参考方案2】:

我会使用类似 twisted 的东西,它具有通过串行端口接收数据的非阻塞机制。 (Twisted 有一个事件循环)当接收到数据时,会调用一个注册的处理程序,所以 你不会得到完整的缓冲区和你遇到的阻塞行为。

我用它来接收/发送数据到/从 arduino 和馈送 cosm。

您可以在这里查看示例http://twistedmatrix.com/documents/current/core/examples/

【讨论】:

蒂姆,谢谢你的建议。我不熟悉 Twisted,但我会调查一下

以上是关于Python 串行读取线是不是会中断 Arduino 循环?的主要内容,如果未能解决你的问题,请参考以下文章

为啥python串行读取我写的最后一件事而不是我的串行设备的响应

stm32中外部中断进入中断以后,把中断线挂起位清0以后,在检测还有意义吗,不是已经clear了吗

Arduino/AVR:中断串行/I2C 通信是不是安全

使用 Python 串行库处理从串口读取的原始数据?

PySerial:如何在串行线上发送 Ctrl-C 命令

从串行读取数据块是不是比一次读取 1 个字符更快?