The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Arduino Command Line Programming: Avrdude Puzzlement

For all the usual reasons, I’d like to compile & download Arduino programs from the command line, rather than through the (excellent!) IDE. That is supposed to work and, for most folks, apparently it does.

Not here, alas.

I’ve installed the 0012 Arduino Java IDE (x86 or x86_64 as appropriate) from http://code.google.com/p/arduino/ on three different systems, all with Kubuntu 8.04:

  • Dell Dimension 9150 – x86_64, which seemed like a good idea at the time
  • Dell Inspiron E1405
  • Dell Inspiron 8100

In all cases the IDE works perfectly, compiles & downloads programs just fine, and behaves exactly as you’d expect. I had a few minor quibbles with sorting out various paths & suchlike, but, on the whole, it has no troubles at all with either a Diecimila or a Sparkfun Arduino Pro (with a Sparkfun FTDI Basic USB gizmo).

I tweaked ~/.arduino/preferences.txt to include:

console.auto_clear=false
build.verbose=true
upload.verbose=true

Here’s the final step in the IDE compile-and-download dance. Backslashes indicate continuations of the same line; the original is all on single line:

hardware/tools/avrdude -Chardware/tools/avrdude.conf -v -v -v -v -pm168
-cstk500v1 -P/dev/ttyUSB0 -b19200 -D
-Uflash:w:/mnt/bulkdata/Above the Ground Plane/
2009-06 Solar Data Logger/Firmware/Logger/applet/Logger.hex:i 

avrdude: Version 5.4-arduino, compiled on Oct 22 2007 at 13:15:12
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

         System wide configuration file is "hardware/tools/avrdude.conf"
         User configuration file is "/home/ed/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port            : /dev/ttyUSB0
         Using Programmer      : stk500v1
         Overriding Baud Rate  : 19200
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
         AVR Part              : ATMEGA168

The IDE evidently does the reset-from-USB trick through the standard USB hardware.

I set up the command-line Makefile from http://www.arduino.cc/en/Hacking/CommandLine, although that’s for the 0011 IDE, then made the recommended tweaks. The make section does exactly what you’d expect: compiles the source program.

Running make upload fails every time, on every PC, with both boards. Indeed, in all cases, running avrdude on the command line produces the dreaded “not in sync” errors, showing that it’s unable to communicate with the Arduino board. Blipping the reset button on the Arduino board generally makes the USB transfer work fine, with the failures most likely due to my lack of dexterity & timing precision.

The usual debugging suggestions aren’t relevant, as they all assume there’s a basic communication failure caused by anything from a completely dead board to mysterious library incompatibilities. In this case, however, I have an existence theorem: the IDE works perfectly before and after the command-line failure.

It turns out that the IDE includes a specially patched avrdude, so I tried running that version from the directory where the IDE lives, using exactly the same command-line flags as the IDE does. Surprisingly, that doesn’t work. Again, backslashes indicate continuations of the same line and I added quotes to the file name to protect the blanks…

hardware/tools/avrdude -Chardware/tools/avrdude.conf -v -v -v -v -pm168
-cstk500v1 -P/dev/ttyUSB0 -b19200 -D
-Uflash:w:"/mnt/bulkdata/Above the Ground Plane/
2009-06 Solar Data Logger/Firmware/Logger/applet/Logger.hex":i

avrdude: Version 5.4-arduino, compiled on Oct 22 2007 at 13:15:12
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

         System wide configuration file is "hardware/tools/avrdude.conf"
         User configuration file is "/home/ed/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port            : /dev/ttyUSB0
         Using Programmer      : stk500v1
         Overriding Baud Rate  : 19200
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Recv: . [1e]
avrdude: stk500_getsync(): not in sync: resp=0x1e
avrdude: Send: Q [51]   [20]
avrdude: Recv: . [0f]
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x0f

There’s no difference between the /opt/arduino/lib/librxtxSerial.so and /usr/lib/librxtxSerial.so libraries, which normally causes some confusion on x86_64 systems. I think that means the x86_64 version of the IDE has the correct library.

I’ve also tried the stock Kubuntu avrdude, which is at V 5.5, to no avail.

Given that the IDE works, that I’m running the same avrdude executable, and that the libraries match, I’m not sure where to go from here.

While I’m generally dexterous enough to run make upload and blip the Arduino board’s reset button with my other hand, I’m bringing up a shield-like board that plugs atop the Arduino and, alas, lacks both a reset button and a hole over the Arduino’s button.

The board is, of course, that one.

Update: As a reasonable workaround, I’ve set the IDE up to use an external editor. Then I can tweak the programming, flip to the IDE, click the Download button, and away it goes. Not quite as easy as a full command-line solution, but close enough.

Comments

9 responses to “Arduino Command Line Programming: Avrdude Puzzlement”

  1. Oedipus McGillicuddy Avatar
    Oedipus McGillicuddy

    In case this problem is still current …

    Yeah, the problem you’re having is that the Java GUI does something besides just calling avrdude. It raises DTR on the serial line, which tells the Arduino to reset. Yes, the Makefile that ships with the Arduino software is wrong, wrong, wrong.

    Try installing Perl’s serial module (package libdevice-serialport-perl in Ubuntu) and then running this Perl script:

    #!/usr/bin/perl
    use Device::SerialPort;
    Device::SerialPort->new(“/dev/ttyUSB0”)->pulse_dtr_on(100);

    This will reset the Arduino; just upload with avrdude immediately after running this.

    1. Ed Avatar

      When I installed Arduino 15, I made a casual attempt to do the command-line thing again and wound up in a twisty maze of directory twiddling, as Things Have Changed since 11. At which point, of course, I gave up and used the external editor workaround, having Other Things To Do.

      The next time I twiddle the laptop on the electronics bench, I’ll try the whole command-line thing again.

      While I have the hood up, I’ll bolt your routine right into the makefile, too, which would get my reflexes out of the loop… a definite improvement.

      Thanks!

  2. Marc Delisle Avatar
    Marc Delisle

    I am having a similar problem, check out the version of avrdude that the Java Gui is using(probably version 5.4).

    Version 5.4 works from the command line, the newest version of avrdude (5.6) does not (apparently you have to manually reset).

    I think that the bug/feature request at http://savannah.nongnu.org/bugs/?26703 is related to this.

    I guess I need to downgrade for now.

    Marc

  3. Samuel A. Falvo II Avatar

    Based on my personal experiences with the Arduino platform so far, I’ve come to the conclusion that it’s just not worth the investment. Spend the extra $25 and get the external programmer, and use a stock AVRDude installation. Take that piece of sh!t IDE and shove it out the window.

    I purchased the Arduino _precisely_ because I didn’t want to invest in an external programmer — everything should be programmable via USB. I’ve been trying to get my code running for the last three days now. NOTHING. As far as I’m concerned, the Arduino platform is fundamentally broken.

    I know lots of people are doing wonderful things with it, but if I can’t get my stuff working on it, following instructions from all over the web (including arduino.cc), then something’s seriously, seriously, seriously wrong.

    I have __NO__ problems getting Intellasys multi-Forth-core chips working. None what-so-ever. In two days of hacking, I had one generating 640×480 VGA output. With the Arduino, I can’t even get the damn thing to signal my name in morse code in that time period.

    In all likeliness, I will NOT be purchasing another Arduino EVER again. I’ll just go straight to purchasing blank microcontrollers and using an external programmer. I’m done with this crap.

    1. Ed Avatar

      The problem for both of us is that the “what we want to do” lies outside the Arduino’s intent.

      Basically, the Arduino board & its surrounding software were designed for folks who want to treat the whole computer part of a project as a component, not a separate project unto itself. So a microcontroller on a breakout board with an IDE that suppresses all the hocus-pocus lets them write a program consisting of maybe a few hundred lines, tops, without any expertise in electronics or programming, then bolt it into an artwork and move on.

      That’s not to be sniffed at, despite the fact that the whole structure doesn’t make sense for folks who (can) hammer out the production prototype of a complex embedded system over a long weekend.

      A reasonable compromise, for me at least, is jamming the IDE into “use external editor” mode, then writing the code in something more capable. Save the file, flip to the IDE, tap Ctrl-U to upload the code, maybe click the serial monitor to catch some debugging output, and it Just Works.

      If I cared, I’d figure out why the command-line stuff doesn’t seem to be compatible with the current IDE (even beyond the AVRDude conflicts) and fix it. That’s not really my current most-itchy spot, though…

      1. Samuel A. Falvo II Avatar

        Thanks to the great help I’ve received on the #arduino IRC channel, I’ve been able to refine what’s happening. Given a C file “morse.c”, the following commands will program the Arduino 2009:

        $ avr-gcc -mmcu=atmega328p -Os -o morse morse.c

        Obviously, compiles your code. :)

        $ avr-objcopy -j .text -j .data -O ihex morse morse.hex

        This creates an Intel HEX-file from the binary produced above.

        $ sudo avrdude -D -c stk500v1 -b 57600 -p m328p -P /dev/ttyUSB0 -U flash:w:morse.hex:i
        $ sudo avrdude -D -c arduino -b 57600 -p m328p -P /dev/ttyUSB0 -U flash:w:morse.hex:i

        Either of these commands will work to actually program the part. (I suspect the “arduino” programmer is just an alias for stk500v1.) The missing link, for me at least, was the -U option, which explicitly tells avrdude to update flash (flash), that we’re writing to it (w), from the source hex file “morse.hex”, and it’s in Intel HEX format (i).

        That seems to do the trick for me. Maybe this will be helpful for others who read this post too.

        My faith in Arduino has, at long last, been restored. ;)

        1. Ed Avatar

          Excellent!

          Thanks for sharing the Right Way. This post is one of the top hits among all the Arduino-related stuff I’ve written so far: there’s considerable interest in the topic.

          Now, the fact that avrdude must run with root privileges remains puzzling, as the Arduino IDE accomplishes the same thing in user mode. I wonder what trickery allows that?

  4. Jonathan Avatar
    Jonathan

    Actually, here’s another piece to “The Right Way”: Edit the avrdude.conf file ($(INSTALL_DIR)/hardware/tools/avrdude.conf), find the programmer line for the stk500v1, and add this line to the block:

    reset = 4;

    That plus the perl script mentioned above actually seems to reset my arduino and allow avrdude to work its magic. Either one on its own would not.

    If anyone is curious, I got that line by typing in an incorrect programmer on the avrdude command line. It described the available programmers, including a few that had reset commands. One of them reset with !dtr, so I looked up that section and saw “reset = ~4;”.

    1. Ed Avatar

      Even with that hint, it took me a while to find the spots in the avrdude.conf file that explain what’s going on…

      I would never have found that on my own! (And, in fact, didn’t.)

      Thanks!