Serial Communications Basics Using Pyserial

I'm trying to set up a serial connection between my Duemilanove (ATmega328) board and a Python program running on my PC (Windows XP). I thought a good test of my serial connection would be to make the Python program light an LED on the board. My attempt to emulate the great examples in these forums have yielded mixed results.

When I run the program the light does not blink. However, if I type ser.write("Hello World") in the Python console after the program closes the light does blink. Why doesn't it blink when the program runs?

Here's my Arduino sketch:

// Open a serial connection and flash LED when input is received

int ledRed = 4;      // LED connected to digital pin 4

void setup(){
  // Open serial connection.
  pinMode(ledRed, OUTPUT);     

void loop(){
  if(Serial.available() > 0){      // if data present, blink
        digitalWrite(ledRed, HIGH);
        digitalWrite(ledRed, LOW);

Here's my Python program:

## Open a serial connection with Arduino.

import serial
ser = serial.Serial("COM8", 9600)   # open serial port that Arduino is using
print ser                           # print serial config

print "Sending serial data"
ser.write("Hello World")

# Reminder to close the connection when finished
    print "Serial connection is still open."

When you open the serial port, the Arduino resets. During the reset it is not listening. Your problem may be that the ser.write happens before the reset is complete.

A short delay after the open is worth a try.

See for a python serial-to-net proxy that works with Bitlash or the terminal client of your choice.



You could also have the Arduino write to the serial port, in setup, and have the python script wait for serial data to be sent to it before it sends out serial data.

When the python script received data from the Arduino, you would know that it was ready to receive data.

I tried both of your suggestions and they worked! I wonder why Arduino resets when the PC opens the serial connection. I assume there’s a good reason for that.

Thanks for the suggestions. Billroy thanks for the bitty link, what a great tool. Can’t wait to test it out.

You can bypass the DTR reset issue with the Arduino on PySerial by editing the file in the python directory. It's usually located in lib\site-packages\serial.

Delete the compiled version of the file (serialWin32.pyc) and then edit the file, changing the line that reads: self._dtrState = win32.DTR_CONTROL_ENABLE to: self._dtrState = win32.DTR_CONTROL_DISABLE

This should now open the serial port without altering the DTR state.

I created a new module by copying the serial directory and renaming it serialArduino. That way, I could change my import serialArduino as serial without affecting other applications that might be expecting the serial module to operate with dtrState = DTR_CONTROL_ENABLE

DTR is used with a coupling capacitor to allow you to upload sketches without pressing the button.

Automatic (Software) Reset

Rather then requiring a physical press of the reset button before an upload, the Arduino Duemilanove is designed in a way that allows it to be reset by software running on a connected computer. One of the hardware flow control lines (DTR) of the FT232RL is connected to the reset line of the ATmega168 or ATmega328 via a 100 nanofarad capacitor. When this line is asserted (taken low), the reset line drops long enough to reset the chip. The Arduino software uses this capability to allow you to upload code by simply pressing the upload button in the Arduino environment. This means that the bootloader can have a shorter timeout, as the lowering of DTR can be well-coordinated with the start of the upload.

This setup has other implications. When the Duemilanove is connected to either a computer running Mac OS X or Linux, it resets each time a connection is made to it from software (via USB). For the following half-second or so, the bootloader is running on the Duemilanove. While it is programmed to ignore malformed data (i.e. anything besides an upload of new code), it will intercept the first few bytes of data sent to the board after a connection is opened. If a sketch running on the board receives one-time configuration or other data when it first starts, make sure that the software with which it communicates waits a second after opening the connection and before sending this data.

The Duemilanove contains a trace that can be cut to disable the auto-reset. The pads on either side of the trace can be soldered together to re-enable it. It’s labeled “RESET-EN”. You may also be able to disable the auto-reset by connecting a 110 ohm resistor from 5V to the reset line; see this forum thread for details.