5

I would like to read from the USB serial port from time to time in a loop. I can open the port and read data with:

import serial

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

while 1 : ser.readline()

An Arduino Uno is connected to the USB port of the RPi. The Arduino acts as a sensor and it will constantly produce readings.

I need some help in adding timing features to the above code. I want to open the port and read from it for a certain period of time. After that period of time, the port closes and the received data will be analysed. After a pause of several minutes, the port will reopen and the RPi will read data from it again. This continues in a loop. Any help is much appreciated.

2 Answers 2

2

All you would need to add, aside from closing the port when you're done ;), is import time and then use time.sleep(secs):

import serial, time

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

while 1:
    serial_line = ser.readline()

    print(serial_line) # If using Python 2.x use: print serial_line
    # Do some other work on the data

    time.sleep(300) # sleep 5 minutes

    # Loop restarts once the sleep is finished

ser.close() # Only executes once the loop exits

I don't know if pySerial is buffered (data sent while sleeping is stored or simply dropped), but I usually prefer to use a generator, if you don't explicitly need to wait. They seem a bit more flexible (in my opinion):

def serial_data(port, baudrate)
    ser = serial.Serial(port, baudrate)

    while True:
        yield ser.readline()

    ser.close()

for line in serial_data('/dev/ttyACM0', 9600):
    [...transform data...]

You might also be able to use the with syntax instead of the while, but I'm not too sure how that'd work with pySerial.

5
  • Thanks for your feedback. In your first example with pySerial, I would like for the serial port to reopen after a period of time. To do so, do I add another time.sleep() after ser.close in another loop?
    – wengzhe
    Commented Apr 30, 2014 at 18:35
  • It doesn't seem that pySerial closes the serial port after readline, so unless you're doing more work that uses the serial port, you can just move the ser.close() down. Commented Apr 30, 2014 at 18:46
  • Sorry, but what do you mean by moving the ser.close() down?
    – wengzhe
    Commented Apr 30, 2014 at 18:52
  • I was just editing my comment to clarify, but locked after 5 minutes :/ The ser.close() never runs until the while loop is done (which doesn't really ever occur since it's while 1/while true), so the serial port isn't actually closed between readline() calls. Since simply having a pySerial port open isn't blocking, that shouldn't be an issue. If the while loop only ran x number of times, and then you wanted to work on that the port again, just leave the port open until done (move ser.close() after all code that interacts with the port). Commented Apr 30, 2014 at 19:01
  • Note however that some methods are blocking during execution, readline being one of them if no timeout is provided during the serial object instantiation. In the first example, you're wanting to analyze some data between readline() calls, so let me see if my edit can clarify what you might do a bit. Commented Apr 30, 2014 at 19:06
0

Please download the Serial Library and install in Python Lib Folder. Then use the following script. Please modify loop to your requirements. The sys.argv[] are used for seeking Params at command line. You may omit this and hardcode as per your requirement.

import sys 
import serial
import time
param1 = sys.argv[1]
param2 = sys.argv[2]
#param2=sys.argv[3]
ard = serial.Serial(param1, param2, timeout=0)
RFIDNum = ard.readline() # read all characters in buffer
#time.sleep(1) 
print RFIDNum

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