Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to post twitter updates from a sensor interfaced with an Arduino. The Adruino loop has a 1s delay between reading sensor voltages. The Python code has a 1 hour delay between Twitter updates.

It seems that the Python script actually interupts the Arduino loop until it reads a new line on the serial port. Is this correct?

For example, despite the Arduino program running on a loop for 1 hour, it will only show a millis() counter value of 1001, after 2 hours it will show 2002. Without the Python script running and observing the serial monitor only, the Arduino code counts milliseconds as expected.

This wouldn't normally be a problem, but if you wanted, for example, to simultaneously run a data logger with millis() running continuously at a high acquisition rate it will be an issue. It's difficult to know what's going on since the serial monitor can't share the same port as the Python program.

Here's a sample of the Arduino code

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
}

And here's the section of the Python code in question:

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
share|improve this question
    
It shouldn't matter. Maybe it has to do with how you set up your serial port in the OS? Are you using Windows? Linux? OS X? –  Qiau Sep 10 '12 at 14:49
    
Windows. Hence how I defined the serial port as 'COM6'. I think it would be "/dev/ttlusb0" for Linux based systems –  areid Sep 10 '12 at 15:53

2 Answers 2

up vote 5 down vote accepted

Serial.write (and any functions that depend on it, like Serial.print) will block if the output buffer is full. The output buffer can only be drained if the other end (i.e. your Python script or the Serial Monitor) reads from the port.

Serial Monitor constantly reads the serial port output, so the buffer doesn't fill up. However, since your Python script reads only a single line of output each hour, the buffer is persistently full. Because the serial port is buffered, every hour, you read the next second of output.

What's happening here is that your Arduino code runs, say, 10 loops and writes 10 lines before its buffer fills. Your Python code will read the 10 lines, once per hour. After 10 hours, the newer lines that the Arduino has been putting in the buffer will have different timestamps.

The solution, then, is to either send hourly updates from the Arduino (letting arduino.readline block for an hour in Python) or read updates constantly (every second) from Python and firing your Twitter updates every hour (e.g. use two threads, one to read and update the temperature, the other to post updates every hour using the newest local data).

share|improve this answer
    
Thanks nneonneo, that's what I suspected. I think your second suggestion is probably the best one, since time delay synchronization between Python and Arduino won't be 100% accurate - you have to account for your delay() value PLUS however long the code takes to execute. i.e. an hour delay on the arduino will probably be 1 hour + ~2ms –  areid Sep 10 '12 at 15:44

I would use something like twisted which has a non-blocking mechanism for receiving data via the serial, port. (Twisted has an event loop) When data is received a registered handler is called, so you won't get full buffers and the blocking behavior you are experiencing.

I use it to receive/send data to/from an arduino and feed cosm.

You can see examples here http://twistedmatrix.com/documents/current/core/examples/

share|improve this answer
    
Tim, thanks for the suggestion. I'm not familiar with Twisted but I'll look into it –  areid Sep 10 '12 at 16:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.