4

我正在尝试从与 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
4

2 回答 2

6

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

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

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

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

于 2012-09-10T14:52:52.793 回答
1

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

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

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

于 2012-09-10T15:10:40.890 回答