Wait on Arduino auto-reset using pySerial

arduino, pyserial, python

Solution

The Arduino IDE's monitor toggle's the assigned DTR pin of the port when connected. Where this toggling causes a reset on the Arduino. Noting that the DTR is toggled after the Monitor has opened the Serial port and is ready to receive data. In your case the below example should do the same.

Import serial

arduino = serial.Serial('/dev/ttyS0',
                     baudrate=9600,
                     bytesize=serial.EIGHTBITS,
                     parity=serial.PARITY_NONE,
                     stopbits=serial.STOPBITS_ONE,
                     timeout=1,
                     xonxoff=0,
                     rtscts=0
                     )
# Toggle DTR to reset Arduino
arduino.setDTR(False)
sleep(1)
# toss any data already received, see
# http://pyserial.sourceforge.net/pyserial_api.html#serial.Serial.flushInput
arduino.flushInput()
arduino.setDTR(True)

with arduino:
    while True:
        print(arduino.readline())

I would also add the compliment to the DTR for the Arduino's with AVR's using built-in USB, such as the Leonoardo, Esplora and alike. The setup() should have the following while, to wait for the USB to be opened by the Host.

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
}

It will have no effect for FTDI's based UNO's and such.

Problem

I'm trying to read lines from an Arduino board with a very simple code (for the sake of showcasing the problem) on Linux. Python code: ``` # arduino.py import serial arduino = serial.Serial('/dev/ttyACM0') with arduino: while True: print(arduino.readline()) ``` Arduino code: ``` // simpleWrite.ino long ii = 0; void setup() { // initialize serial communications at 9600 bps: Serial.begin(9600); } void loop() { Serial.println(ii); ii++; } ``` As the board auto-resets when the serial connection is opened, the first bytes are likely garbage. After a second or two everything works fine. This is a typical output: ``` $ python arduino.py b'09\r\n' b'540\r\n' b'541\r\n' b'542\r\n' b'543\r\n' b'544\r\n' b'545\r\n' b'546\r\n' b'547\r\n' b'548\r\n' b'549\r\n' b'550\r\n' b'551\r\n' b'552\r\n' b'553\r\n' b'554\r\n' b'555\r\n' b'556\r\n' b'557\r\n' b'55\xfe0\r\n' # <---- Here the board restarted b'1\r\n' b'2\r\n' b'3\r\n' b'4\r\n' b'5\r\n' b'6\r\n' b'7\r\n' b'8\r\n' b'9\r\n' b'10\r\n' ``` However, I see the Arduino IDE Serial Monitor doesn't have this problem, and properly shows a delay (while restarting) and then prints all the lines starting from the first one. Is there a way to emulate this behaviour in Python using pySerial? That is, discarding all the output before restarting and nothing more? Perhaps through some low-level functions? I tried looking at the relevant Arduino source code, but I don't know Java and it didn't help. Note: Of course I could sleep for, say, three seconds, discard everything and start from there, but I would probably discard some of the first lines too. Edit: Apparently, this problem doesn't exist on Windows and the accepted solution was not necessary.

Original source