Python errors when receiving data from Arduino

Hi,

I'm using an Arduino to collect sensor data which is compiled into a string. The data is recorded perhaps once every five minutes. From the Arduino it is going to be sent over USB to a computer running a Python program that will eventually store the data in an SQLLite database.

I've installed the Python serial library and tested that it is correctly installed and can talk to the Arduino.

My problem is that when I want to send data from the Arduino to the PC. I've written a test program to show my (lack of) understanding which sends the value of a counter once every second. The minimal Arduino program looks like this:

int counter = 0;

void setup() {

Serial.begin(9600); // set the baud rate
Serial.println("Ready"); // print "Ready" once
}

void loop() {

Serial.println(counter); // send the data back in a new line
counter++;
delay(1000); // delay for 1 second
}

And the Python program looks like this:

from time import sleep
import serial
ser = serial.Serial('/dev/tty.usbmodem1d21', 9600)

newInput = ""
while True:
newInput = ser.readline()
print newInput # Read the newest output from the Arduino
sleep(1) # Delay for one second

On the Arduino side, the serial monitor shows numbers counting up normally. On the Python side I get output such as:

1
2
4

or

231
23

These are always followed by an error message:

Traceback (most recent call last):
File "/Users/mikerichards/Desktop/sqlTest.py", line 7, in
newInput = ser.readline()
File "/Library/Python/2.7/site-packages/serial/serialposix.py", line 460, in read
raise SerialException('device reports readiness to read but returned no data (device disconnected?)')
SerialException: device reports readiness to read but returned no data (device disconnected?)

I'm guessing all of these problems are caused by lack of synchronisation between the Arduino and the computer, but I can't find a way of getting the Python program to regularly pick up the correct data without missing any values and without trying to take data from an empty buffer.

If anyone has a solution how I can do this, please let me know. I'm very much a beginner with both Arduino and Python so I'm probably making all sorts of newbie errors here. I have tried Google searches and some tutorials, but I keep ending up with the same problem.

Many thanks in advance,

Mike.

Are you certain this is the correct device?

ser = serial.Serial('/dev/tty.usbmodem1d21', 9600)

Mine is /dev/ttyACM0, and has an open() call.

ser = serial.Serial('/dev/ttyACM0', 9600) 
ser.open()

in Arduino you should always check if there is data available.
Maybe this is also true for python... before calling a readline

I use this to check for available characters. I don't know about readline.

  x = ser.read()
  if x > 0:

quick try, skipping the sleep ...

#
#  AUTHOR: Rob Tillaart
#    DATE: 2013-10-16
# PURPOSE: capture serial output into a txt file.
#
import sys, os, serial, datetime

def capture():
    print "Start capture"
    ser = serial.Serial(30, 115200, timeout=0)  # PORTNRS are zero based
    while (1):
        line = ser.readline()
        if (line != ""):
            print line[:-1]         # strip \n
            
            # write to file
            filename = str(datetime.date.today()) + ".log"
            text_file = open(filename, "a")
            text_file.write(line)
            text_file.close()

""" -------------------------------------------
MAIN APPLICATION
"""  
capture()

give it a try..

Thanks everyone. I'm going to be in a meeting all day, so I'll give your ideas a go later.

Many thanks for the quick replies. Hopefully this will fix it.

Mike.

Hi Rob, everyone,

Apologies for the delay in getting back. Thanks for the sample program (above). I tried it on my Mac and I got:

Start capture

Traceback (most recent call last):
File "/Users/mikerichards/Desktop/fromRob.py", line 25, in
capture()
File "/Users/mikerichards/Desktop/fromRob.py", line 10, in capture
ser = serial.Serial(30, 9600, timeout=0) # PORTNRS are zero based
File "/Library/Python/2.7/site-packages/serial/serialutil.py", line 261, in init
self.open()
File "/Library/Python/2.7/site-packages/serial/serialposix.py", line 278, in open
raise SerialException("could not open port %s: %s" % (self._port, msg))
SerialException: could not open port 30: [Errno 2] No such file or directory: '/dev/cuad30'

According to the Arduino environment it is currently connected to /dev/tty.usbmodem1d21

(I'm running Python 2.7.5 and Arduino 1.0.5 on a Mac if it helps at all).

I'm sure I'm doing something silly, but I can't see what it is. Of course if there's a better way of doing it (foolproof is good :wink: ) please let me know.

Many thanks,

Mike.

Use this to check if there is anything in the buffer.

if ser.inWaiting():
                newInput = ser.readline()
                print newInput

.inWaiting() returns the number of chars in the buffer.

As for your other problem I can't help you there

ser = serial.Serial(30, 9600, timeout=0)

The example I gave was for a win7 PC, as you are on a MAC you should patch the serial port name in the constructor

something like: ser = serial.Serial('/dev/tty.usbmodem1d21', 9600, timeout=0) ??