OPENDROP V2.0 FIRMWARE BACKUP & RESTORE WITH AVRDUDE
Short overview
OpenDrop-v2.0-Firmware_avrdude_guide (this article as PDF, recommended!)
opendrop2.0_firmware (for OpenDrop V2.0 as ZIP)
This document & blog post is for people who:
- want to get a basic understanding for avrdude usage with a Sparkfun Pro Micro (or compatible) board
- (ATmega32U4 5V, 16 MHz)
- get firmware files for the OpenDrop v2.0 (four push buttons) – the firmware is NOT compatible with newer OpenDrop versions (v2.1 with joystick) – please use the GitHub download to compile & upload the Firmware yourself.
- aren’t afraid to get their hands dirty with command line stuff under Linux (and will bear the consequences – we are not liable for you breaking devices by following this guide! Use caution and check the commands – the difference between reading (r) and writing (w) is literally only one letter)
I had to repair a broken Arduino in one of our OpenDrop V2.0 units (with four push buttons). In the official GitHub repository ( -> https://github.com/GaudiLabs/OpenDrop ), the download will give you code for the OpenDrop v2.1 (with a joystick). Therefore I deemed the easiest solution would be to backup the firmware from another OpenDrop v2.0 device, and copy it to the new Arduino.
I used avrdude on a Raspberry Pi unit to back up the firmware, and write it onto the new Arduino. Backup requires several steps, and putting the Arduino into the proper state (also required for reading!).
Pitfalls I’ve encountered
- check that your USB cable includes wiring for data – the first cable I’ve tried will only power the Arduino, but it will not show up in the USB devices.
- Copy & pasting command line codes from most blogs might render some characters in a wrong way – consider using the PDF document I provide of this post, to ensure that the code is entered correctly
Set up & basic understanding
The OpenDrop v2.0 is driven by an Arduino device, which is compatible with the Sparkfun Pro Micro board. (For instance Deekrobot Pro Micro)
- ATmega32U4 (5V, 16 MHz)
- integrated microUSB port for power & programming
avrdude is used to read and write firmware files & settings from / to the Arduino.
I use a Raspberry Pi, since we are a Raspberry Pi approved reseller & I feel comfortable with using the Linux command line over Windows.
Installation of avrdude:
sudo apt-get install avrdude
Locating the port to use with avrdude
Unplug the mains power adapter from the OpenDrop, if it had been plugged in.
Plug in the Arduino microUSB cable into the Arduino, and into the Raspberry Pi. The device will beep.
Ensure that the Arduino shows up as a USB device:
/home/pi# lsusb
Bus 001 Device 005: ID 2341:8037 Arduino SA
Bus 001 Device 004: ID 0424:7800 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
If the Arduino SA entry does NOT show up, double-check your USB cable: some cables only transmit power, not data. This, by the way, was also the error why I could not use the Arduino IDE on Windows with this device – I was trying a wrong USB cable first!
Find the port, which the Sparkfun Pro Micro uses:
ls /dev/tty*
/dev/tty /dev/tty12 /dev/tty17 /dev/tty21 /dev/tty26 /dev/tty30 /dev/tty35 /dev/tty4 /dev/tty44 /dev/tty49 /dev/tty53 /dev/tty58 /dev/tty62 /dev/ttyACM0
/dev/tty0 /dev/tty13 /dev/tty18 /dev/tty22 /dev/tty27 /dev/tty31 /dev/tty36 /dev/tty40 /dev/tty45 /dev/tty5 /dev/tty54 /dev/tty59 /dev/tty63 /dev/ttyAMA0
/dev/tty1 /dev/tty14 /dev/tty19 /dev/tty23 /dev/tty28 /dev/tty32 /dev/tty37 /dev/tty41 /dev/tty46 /dev/tty50 /dev/tty55 /dev/tty6 /dev/tty7 /dev/ttyprintk
/dev/tty10 /dev/tty15 /dev/tty2 /dev/tty24 /dev/tty29 /dev/tty33 /dev/tty38 /dev/tty42 /dev/tty47 /dev/tty51 /dev/tty56 /dev/tty60 /dev/tty8
/dev/tty11 /dev/tty16 /dev/tty20 /dev/tty25 /dev/tty3 /dev/tty34 /dev/tty39 /dev/tty43 /dev/tty48 /dev/tty52 /dev/tty57 /dev/tty61 /dev/tty9
You are looking for something like /dev/ttyACM0, or /dev/ttyUSB0
In my case it was /dev/ttyACM0
This port will only be present, when the device is plugged in. To ensure that you have the correct port, you can try listing with the OpenDrop being connected, and the OpenDrop being disconnected (microUSB -> USB on the Pi). Compare the outputs. I assume that it will be /dev/ttyACM0 for you as well.
Create directory for backup
We will become the superuser, create the directory for the backup files, and change into it:
sudo su
mkdir /home/pi/opendrop2.0_bak
cd /home/pi/opendrop2.0_bak
Using avrdude
The reset button (Important, do not skip this part)
For avrdude to work, the SparkFun Pro Micro must be in the right system state. In order to put the SparkFun Pro Micro into the right system state, you must press the reset button (labeled RST) quickly two times after each other. The device will beep, and the LED will start to blink.
You must execute the avrdude command immediately after doing this, as the device will go back into the normal state after a short timeout.
For every command which I executed, I pressed the RST button two times after each other. Probably the commands could be combined into a shell script; since I like to use caution as not to brick the devices by using the wrong command line, I stepped through the process manually.
If you do not use the RST button as I have outlined, you will get errors from avrdude like:
Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding
Firmare backup: Reading – overview
We are going to back up
- flash
- eeprom
- hfuse
- lfuse
- efuse
Ref: https://www.hackster.io/rayburne/avr-firmware-duplicator (Careful, the avrdude settings in here are not correct for the OpenDrop / Sparkfun Pro Micro).
Firmware Backup: The commands
If not done yet, change into the directory you have prepared for the Firmware backup files, and become the super user (root). I am not sure if avrdude will work out of the box without root permissions – try it if you want.
Ensure that you use the right port (most probably /dev/ttyACM0). Ensure that you have the letter “r” after the reading target. r as in read; a letter w would use your destination file as source, to overwrite your Arduino Flash – without security prompt!
The letter r after the backup file name specifies the output type, it is important to get this right for the later restoration operation. If you are curious, read the manpage here: https://www.nongnu.org/avrdude/user-manual/avrdude_4.html
-p specifies the platform
-c the programmer
-P the port
-U specifies the operation (source/target:mode:target/source:file_mode)
Here, then, is the first command to use, and it’s output:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U flash:r:flash_backup_file_od2.0.hex:r
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading flash memory:
Reading | ################################################## | 100% 0.64s
avrdude: writing output file “flash_backup_file_od2.0.hex”
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Here’s the second command. By the way, you can change the filenames (in this case the eeprom_backup_file_od2.0.hex bit):
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U eeprom:r:eeprom_backup_file_od2.0.hex:r
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading eeprom memory:
Reading | ################################################## | 100% 1.76s
avrdude: writing output file “eeprom_backup_file_od2.0.hex”
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Then we will backup three different kinds of fuses. Here’s the first:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U hfuse:r:hfuse_backup_file_od2.0.hex:r
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading hfuse memory:
Reading | ################################################## | 100% 0.00s
avrdude: writing output file “hfuse_backup_file_od2.0.hex”
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
now the lfuse:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U lfuse:r:lfuse_backup_file_od2.0.hex:r
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading lfuse memory:
Reading | ################################################## | 100% 0.00s
avrdude: writing output file “lfuse_backup_file_od2.0.hex”
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Now the last command, the efuse:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U efuse:r:efuse_backup_file_od2.0.hex:r
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading efuse memory:
Reading | ################################################## | 100% 0.00s
avrdude: writing output file “efuse_backup_file_od2.0.hex”
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Remember that you need to press the RST button twice before each operation! It is not necessary to unplug the Arduino from the Raspberry Pi after executing the RST operation.
Creating a ZIP file
you can create a ZIP file using the following command (replace the paths as appropriate):
sudo zip -r /home/pi/opendrop2.0_bak.zip /home/pi/opendrop2.0_bak
Restoring the firmware
If you need to restore the firmware, use the following commands. Again, don’t forget to press the RST button twice before each command!
Run the commands from the correct directory as root. Ensure that you have the letter “w” for writing to the microcontroller (Arduino in this case).
Write the flash file:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U flash:w:flash_backup_file_od2.0.hex
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: NOTE: “flash” memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file “flash_backup_file_od2.0.hex”
avrdude: writing flash (32604 bytes):
Writing | ################################################## | 100% 2.98s
avrdude: 32604 bytes of flash written
avrdude: verifying flash memory against flash_backup_file_od2.0.hex:
avrdude: load data flash data from input file flash_backup_file_od2.0.hex:
avrdude: input file flash_backup_file_od2.0.hex contains 32604 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.76s
avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x7000
0x55 != 0x5f
avrdude: verification error; content mismatch
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Note: I tried to write several times, slightly varying the command. In each attempt I got the verification error; the firmware works fine, though – my superficial research showed it’s related to some wiring of the microcontroller’s periphery – it was inserted into the OpenDrop while I was doing the backup and restoration. I have decided that the results speak for themselves, and moved on to the restoration of the other parts. Your results might vary here. No guarantees given!
Restore the eeprom:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U eeprom:w:eeprom_backup_file_od2.0.hex
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file “eeprom_backup_file_od2.0.hex”
avrdude: input file eeprom_backup_file_od2.0.hex auto detected as raw binary
avrdude: writing eeprom (1024 bytes):
Writing | ################################################## | 100% 3.44s
avrdude: 1024 bytes of eeprom written
avrdude: verifying eeprom memory against eeprom_backup_file_od2.0.hex:
avrdude: load data eeprom data from input file eeprom_backup_file_od2.0.hex:
avrdude: input file eeprom_backup_file_od2.0.hex auto detected as raw binary
avrdude: input file eeprom_backup_file_od2.0.hex contains 1024 bytes
avrdude: reading on-chip eeprom data:
Reading | ################################################## | 100% 1.76s
avrdude: verifying …
avrdude: 1024 bytes of eeprom verified
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
Restore the fuses (Note: I’ve read something about some fuses being only resettable by a 12 V programmer. YMMV).
First hfuse:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U hfuse:w:hfuse_backup_file_od2.0.hex
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file “hfuse_backup_file_od2.0.hex”
avrdude: input file hfuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: writing hfuse (1 bytes):
Writing | | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against hfuse_backup_file_od2.0.hex:
avrdude: load data hfuse data from input file hfuse_backup_file_od2.0.hex:
avrdude: input file hfuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: input file hfuse_backup_file_od2.0.hex contains 1 bytes
avrdude: reading on-chip hfuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying …
avrdude: 1 bytes of hfuse verified
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
now lfuse:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U lfuse:w:lfuse_backup_file_od2.0.hex
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file “lfuse_backup_file_od2.0.hex”
avrdude: input file lfuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: writing lfuse (1 bytes):
Writing | | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against lfuse_backup_file_od2.0.hex:
avrdude: load data lfuse data from input file lfuse_backup_file_od2.0.hex:
avrdude: input file lfuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: input file lfuse_backup_file_od2.0.hex contains 1 bytes
avrdude: reading on-chip lfuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying …
avrdude: 1 bytes of lfuse verified
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
now efuse:
avrdude -p atmega32u4 -c avr109 -P /dev/ttyACM0 -U efuse:w:efuse_backup_file_od2.0.hex
Connecting to programmer: .
Found programmer: Id = “CATERIN”; type = S
Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.
Programmer supports the following devices:
Device code: 0x44
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file “efuse_backup_file_od2.0.hex”
avrdude: input file efuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: writing efuse (1 bytes):
Writing | | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against efuse_backup_file_od2.0.hex:
avrdude: load data efuse data from input file efuse_backup_file_od2.0.hex:
avrdude: input file efuse_backup_file_od2.0.hex auto detected as raw binary
avrdude: input file efuse_backup_file_od2.0.hex contains 1 bytes
avrdude: reading on-chip efuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying …
avrdude: 1 bytes of efuse verified
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done. Thank you.
That’s it – the firmware has been restored. You can unplug the OpenDrop / SparkFun Pro Micro from your Raspberry Pi now.
Useful links & references
- https://www.nongnu.org/avrdude/user-manual/avrdude_4.html
- https://askubuntu.com/questions/254835/how-can-i-know-the-usb-port
- https://forum.arduino.cc/index.php?topic=403201.0 (avrdude command for other target!)
- https://learn.sparkfun.com/tutorials/pro-micro–fio-v3-hookup-guide/introduction
- https://www.hackster.io/rayburne/avr-firmware-duplicator (avrdude command for other target!)
- https://forum.arduino.cc/index.php?topic=453997.0 (concerning the error with flash verification)