Here’s the scenario
Imagine that you have an Arduino Uno running as a web server and you want to open a serial connection to it. Or, you have a MakerBot or RepRap that has a Arduino Mega 2560 as a part of the motherboard, it’s building from SD card, and you want to pause it, get temperature readouts, etc.
Naturally you connect the USB cable, open a serial connection — and it resets! For the web server it might not be all that bad but for the MakerBot you might have just blown a 3 hour print 2.75 hours in!
Fix it if it nags you
So I have been doing firmware work on my MakerBot which requires updating the firmware a lot. Unfortunately MakerBot — in order to fix the more problematic of the two sides of auto-reset — decided to cut a trace on the Arduino motherboard to completely disable auto-reset. I like auto-reset when I upload a lot, but hate it when using the Arduino and it resets when I don’t want it to.
So, I decided to fix it.
Background
The newer Arduino Mega, the 2650, along with the smaller but more common Arduino Uno both use an ATmega8u2 USB-capable uC instead of the traditional FTDI chip. This is great for many reasons but for me it means it is reprogrammable.
Locate the problem
The auto-reset is triggered on connection from OS X and Linux by the DTR line (old-time modem control line speak for a flag getting sent over USB) getting raised during connection and dropped on disconnect. This doesn’t happen on Windows normally, but avrdude and the Arduino software both do it manually.
During programming, the DTR is raised for about 1 second, lowered, then raised again to start the programming communications.
I added a check to the USB serial firmware that resides on the 8u2 that checks for that specific timing before performing the reset. I have tested it on OS X and it works: reset doesn’t happen during repeated connect/disconnects, but does for programming from the Arduino environment.
Try it, you might like it
You can download the firmware .hex file for either the Mega 2560 or the Uno from GitHub. The source code is available too, of course.
Instructions for installation are here and doesn’t require any special tools.
Please leave a comment and let me know either way how the testing goes.
-Rob
Great hack!!! I flashed it on my Arduino Uno R2 (I'm using Windows 7) and is working but with 2 anomalies:
ReplyDelete1) after the new ATmega8u2 firmware is running the device is detected on windows with different VID/PID:
USB\VID_03EB&PID_204B&REV_0001
instead the ones of the original firmware:
USB\VID_2341&PID_0001&REV_0001
so windows is not able to automatically peek the correct driver, no big problem: i forced the correct driver and the arduino is now running flawlessly
2) I uploaded a simple sketch that echoes the input I type on serial and I notice that every time I connect on serial arduino is recieving this on serial:
ðððððð
6 letter "eth" lowercase :-)
http://it.wikipedia.org/wiki/%C3%90
not a problem, but very strange!
thanks!
Hi, i think i found the origin of the two anomalies:
ReplyDeleteThe first is a bug in the official source
in this file:
https://github.com/giseburt/Arduino/blob/auto-reset-fix/hardware/arduino/firmwares/arduino-usbserial/Descriptors.c
row 68 and 70, those are vid&pid used for test!
the correct VID for Arduinos is 0x2341
and the PID must be ARDUINO_MODEL_PID
I tryed building myself the firmware but the hex file I obtain won't load on FLIP: I get "address out of range" when I load it
I installed the toolchain following this post
http://hunt.net.nz/users/darran/weblog/a4091/
and building against LUFA 100807 as specified but I obtain an hex file that's not good...
could you give me a hint on how to correctly build the ATmega8u2 firmware?
about the second anomaly: I found out it happens only with the serial monitor of the arduino-ide so I think it's the ide trying to force a reset when I open serial monitor.
So I would like my software to force the reset. You mentioned that avr dude and the Arduino software do this "manually". I would like to do this from a C++ program running on Windows 7. BTW, I believe Putty does this also. Any idea how?
ReplyDeleteYou should be able to prevent the DTR triggering under Mac OS by doing this:
ReplyDeletenohup sleep 999 < /dev/cu.usbmodem3d11 &
stty -f /dev/cu.usbmodem3d11 -hupcl
(where cu.usbmodem3d11 is the serial port your Arduino is connected to, of course)
Something similar, if not the same, should work for other Unices.