13

I'm connecting from Pi to Arduino-clone board. The problem is, that I need to disable DTR line, in order to prevent Arduino from resetting on connect.

I have read that on RPi is not possible to control DTR, DCD and other lines. Is it this true for RPi globally or only for GPIO pins used for serial communication?

If it's possible to disable DTR on USB port, how do you accomplish that?

1
  • I haven't visited this q in a while; just came across it again. I might post this as an answer, since I coincidentally happen to be dusting off my Arduino skills; but another solution could be, rather than connect directly with USB, connect through a USB -> FTDI breakout board and just don't wire the DTR/RTS lines to the Arduino. E.g. content.instructables.com/ORIG/FD4/343G/GHI9CHD9/… but don't wire up the reset pin.
    – Jason C
    Sep 20 at 13:49
8

The properties of a USB serial converter have nothing to do with the hardware of the hosting system, but only with the USB serial chip itself, and the software stack of the hosting system.

The pi should be using stock Linux USB serial drivers.

Therefore, you can enable/disable the linkage of DTR to port open/close via the usual Linux method of clearing the hupcl setting as documented on the Arduino site and elsewhere:

stty -F /dev/ttyUSB0 -hupcl

Or replacing /dev/ttyUSB0 with whatever device file actually corresponds to your USB serial port (for example, the first Uno connected would likely be /dev/ttyACM0)

Even with regard to the PI's own native serial port, this behavior of DTR is ultimately under software control - anyone who argues otherwise is ignoring the fact that it is only the Linux driver, and not the hardware, which has any knowledge of the port being opened or closed. The actual port hardware can only tell that it is being read from or written to or reconfigured, none of which are actually synonymous with opening the serial device.

1
  • 1
    Will this only work as long as the hosting pi is not restarted? Aug 24 '19 at 22:16
6

@ChrisStrattons post describes how to use stty -F /dev/ttyUSB0 to avoid the hangup which results in a reset. Here is a snippet to do it in Python:

import termios

path = '/dev/ttyACM0'

# Disable reset after hangup
with open(path) as f:
    attrs = termios.tcgetattr(f)
    attrs[2] = attrs[2] & ~termios.HUPCL
    termios.tcsetattr(f, termios.TCSAFLUSH, attrs)

ser = serial.Serial(path, 9600)
# etc.

Note that the exact number may when replugging the USB cable, so I detect the path by globbing:

try:
    path = glob.glob('/dev/ttyACM*')[0]
except IndexError:
    # retry, error out, etc.
    pass
4
  • I've confirmed that this works in Ubuntu on either a generic x86_64 laptop and a Raspberry Pi 2.
    – Cerin
    Feb 9 '16 at 5:32
  • Is there any reason to use termios over, say, os.system("stty -F /dev/ttyUSB0 -hupcl")? Also, btw, I noticed this doesn't prevent the Arduino resetting the first time you connect to it after the host system is powered on; it prevents it from resetting on subsequent connects. Which is better than nothing. But I wish I could figure out how to stop it from toggling DTR.
    – Jason C
    Nov 22 '16 at 22:39
  • 2
    @JasonC Using termios saves a fork/exec (call) to an external program (stty). Not sure what to do about the DTR thing, I think I just accepted this "feature" and added some logic (custom handshake by writing/reading) to detect whether the Arduino and application on the Pi got in sync.
    – Lekensteyn
    Nov 22 '16 at 23:18
  • My ultimate solution was to add the stty command when the pi boots, followed by an echo to the port to force that first reset, and a 3 second delay to wait for arduino reset. Then I dont have to think about it any more after that or worry about it in Python scripts. I did it in rc.local but wherever. Cost is +3 second pi boot time.
    – Jason C
    Nov 23 '16 at 2:05
4

You can add a 120Ohm (or combination to make 120Ohm) resistor between RESET and 5V This will prevent reset completely. This is the least invasive as other solutions require either remove a resistor or capacitor from the board, it complicates uploads. Do not keep the resistor if you are programming. Remove it.

enter image description here

Leonardo boards do not reset even if DTR is triggered but the problem begins when you need to reset it remotely as sometimes it looses connection to Raspberry and you have to physically reset it.

6
  • 3
    I'm not sure this deserves a downvote. It sucks to do it, and isn't software based, but after some research it appears to be the go-to working hardware solution.
    – Jason C
    Nov 22 '16 at 22:35
  • @JasonC Not downvoting, but clearly disappointing since this permanently disables the auto restart, thus not suitable for applications where dynamic re-programming is required. Sep 20 at 11:40
  • @DavidRefoua I don't remember the context of this question but, maybe something could be hacked with e.g. a latching relay between the reset pin and resistor, and then you can toggle it on and off with a pulse from a digital out pin when necessary. Or an NC relay controlled from a separate arduino mini or something that you can issue disable/enable commands to for sw programming. I've seen latching relays on little PCBs on Adafruit or Sparkfun or both (can't remember).
    – Jason C
    Sep 20 at 13:40
  • 1
    @JasonC Yes, although a simple two NPN-transistor set-reset latch would be simpler and more cost-effective. Personally, I try to use these workarounds where DTR is not present (e.g. over RS485). When a USB-to-Serial chip is present, I would be disappointed to resort to hw-based methods, instead of simply disabling DTR from software (it's possible using CH340G on Linux and Windows). Thanks for the ideas, though! Sep 20 at 17:04
  • 1
    (Also, and I might be misguided, but I'm trying to think of a way to enable / disable that reset that can survive a hard power cycle; or at least default to "reset disabled" so it can be enabled through sw when you're about to program it. Although thinking about it I actually have no idea if a latching relay is persistent or not. Basically what this all comes down to is I have no idea what I'm talking about, I'm just procrastinating real life work by throwing half-baked ideas out onto the internet.)
    – Jason C
    Sep 20 at 18:14
0

If you use Seria and pySerial library, You can use :

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

-1

You can use PySerial. Here is an example on Python code:

port =serial.Serial(
    "/dev/ttyUSB0",
    baudrate=57600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    dsrdtr = False
    )

for more options check Pyserial.

4
  • 1
    This is not problem of library. I have alreadz tried 4 different libs, always same result - DTR commands are ignored.
    – jnovacho
    Sep 21 '13 at 19:12
  • If this is an accurate statement of something that works on another Linux, it should work on the pi as well, as the pi hardware is only hosting generic linux software, and not uniquely involved. Feb 14 '15 at 22:58
  • 1
    This doesn't work. On Linux, this still causes the Arduino to reset.
    – Cerin
    Feb 9 '16 at 4:51
  • 1
    Can confirm this does not work on whatever version of the Pi and Arduino I have (I don't know, sorry, I know nothing of these things, I don't want to know, I was just given a system to debug some code on, heh.) Also, not sure if it's related, but stty -F /dev/ttyUSB0 -cdtrdsr reports invalid argument: -cdtrdsr.
    – Jason C
    Nov 22 '16 at 22:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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