Disable DTR in pyserial from code
arduino, pyserial, python, serial-port
Solution
You ought to be able to disable DTR before opening the port, like this:
com = serial.Serial()
com.port = port
com.baudrate = baud
com.timeout = 1
com.setDTR(False)
com.open()
However, doing so on the current release of pyserial (2.6) on Windows throws the following exception:
..., line 315, in setDTR
ValueError: Attempting to use a port that is already open
This seems to be a bug which is fixed in the latest version of the source, SVN revision 445 on 29th December 2011 (see http://pyserial.svn.sourceforge.net/viewvc/pyserial/trunk/pyserial/serial/serialwin32.py?view=log) with comment:
allow setRTS, setDTR before opening on Win32 (to set initial state), doc update
Which looks like it may have just missed the 2.6 release (uploaded on 2nd November 2011 see: https://pypi.python.org/pypi/pyserial).
Furthermore, looking at the current implementation of `setDTR()` for POSIX (in serialposix.py) it looks like this bug is not fixed and an exception is thrown if the port is not open, so a cross-platform solution looks unlikely.
Problem
I'm trying to use pyserial to send data to an arduino. But when I open the COM port it sets DTR low and resets the board. However, I have my arduino code setup such that I have to put it into serial receive mode by holding two buttons for 1 second. I would rather not have to do the serial input on boot of the arduino, if possible. Apparently you can modify serialWin32.py file, changing the line that reads: ``` self._dtrState = win32.DTR_CONTROL_ENABLE ``` to: ``` self._dtrState = win32.DTR_CONTROL_DISABLE ``` But, is there a way to just disable this directly in my python script? I also need to do this for all systems. I would rather not force people to change their base serial config just to use this script. The serial port is opened as follows: ``` com = serial.Serial(port, baud, timeout=1); ``` Update: In the end I found a solution that works fine for my setup. Since I didn't need to do Serial data all the time, only when I put the device into serial receive mode I found a way to disable the reset on serial connect from the arduino itself. Many posts have said you can disable DTR reset by placing a ~100 Ohm resistor between 5V and reset. But I didn't want this to be a permanent thing. So, instead I placed a resistor between PD5 and reset. Then, in software: ``` void setup() { //....... DDRD &= ~(_BV(PD5)); //Set PD5 as input initially PORTD |= (_BV(PD5)); //Set high //....... } inline void setResetDisable(bool state) { if(state) DDRD |= (_BV(PD5)); //Set PD5 as output to put 5V on reset line else DDRD &= ~(_BV(PD5)); //set back to input mode } ``` So now, when I want to be in serial mode, I call setResetDisable(true) which throws 5V on that 100 ohm resistor and the reset pin, preventing DTR from pulling it low and resetting the chip :) I then just call setResetDisable(false) when I leave serial mode so the chip can be programmed as normal.