For my data loggers I use Python to open a serial port to Arduino Nano or Uno units that perform voltage and temperature measurements.

In operation, the Python program reads data from the serial port then adds a date and time and writes it to a CSV log file.

The code for opening the serial port looks like this:

import serial
import datetime
import os
ser = serial.Serial("/dev/ttyUSB0",9600)

Then the device itself provides data points every 60 seconds. So far, so good. It works well and gnuplot makes great plots from the data: https://www.sdsolarblog.com/montage

When I use a device that shows up as /dev/ttyUSB0 and upon running of this script it resets it by sending the serial RST signal as soon as the serial.Serial(...) command is executed.

When I use an Uno it shows up at /dev/ACM0 so the relevant code is

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

However, when using this port there is no reset signal sent, so it is very likely to get a partial line of input.

The read loop looks like this:

while True:
    linein = ser.readline()
    if len(linein)<7) : continue
    if len(linein)>50 : continue

...then it goes on to process data that is within those limits. But without a reset it is highly likely to get an invalid data string that fits within these length constraints. Only when starting the program. Afterwards it runs for days 24x7 just fine.

Problem: When using devices that Jessie assigns to /dev/ACM0 Python does not trigger the OS to send the RST signal like it does when using /dev/USB0

(I have not found a way to force Jessie to assign the serial port to /dev/USB0)

Question: In Jessie, how to deal with Python open of /dev/ttyACM0 not sending RST signal like it does with /dev/ttyUSB0

1 Answer 1


Finally found the solution, in Python 3.0 documentation of all places.

pySerial API


In serial.Serial class,

reset_input_buffer() Flush input buffer, discarding all its contents.

Changed in version 3.0: renamed from flushInput()

So I simply change my open sequence to be like so:

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

And it takes care of any erroneous data before the next scheduled string. This can include partial strings or even multiple lines.

This works regardless of whether the port is on /dev/ttyUSB0 or /dev/ttyACM0 or variations thereof.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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