Burning a bootloader (OptiBoot) on an Arduino Pro Mini using an Arduino Uno

The other day I got asked to look into burning a smaller bootloader (Optiboot) onto an Arduino Pro Mini to save some space on it for actual program code. I used an Arduino Uno as in-system-programmer (ISP) to get the job done. I think there are plenty of sources that document this, but I wanted to keep track of my progress and share my findings.

SPOILER : It turned out to be simple to burn the Optiboot bootloader on the Pro Mini once you understand that it is the default bootloader for the Arduino Uno board. You simply need to burn the Arduino Uno bootloader on the Arduino Pro Mini. So in this case that means burning the Arduino Uno bootloader on an Arduino Pro Mini using an Arduino Uno. Are you still with me? I’ll explain the ride below.

Programming the Arduino Uno to Serve as ISP

The first thing to do is set up the Arduino Uno as an ISP. To do so connect the Arduino Uno to your PC (I’m on Windows) as you normally would and in the examples section open ArduinoISP.

arduinoisp

In Tools -> Board select Arduino/Genuino Uno and upload as you would upload any other script to the Uno.

boarduno

The Arduino Uno is now an in-system-programmer you can connect with any AVR compatible microcontroller (like the Arduino Pro Mini or other Arduinos) to program it.

Wiring

In my case I had to solder some headers onto the Arduino Pro Mini to be able to connect the pins I need to connect, which are: VCC, GND, RST, MISO, MOSI.

uno-pro-mini

VCC and GND are for power, RST is the reset line, SCK is a clock line (Serial Clock) and MISO and MOSI are for hooking up the Pro mini as a slave device of the Uno. MISO stands for: Master Input Slave Output and MOSI stands for Master Output Slave Input.

Burning a Bootloader (Not Optiboot)

Once the wiring is done the following settings need to be made to flash a bootloader to the Pro Mini:

  • Under Tools -> Board select Arduino Pro or Pro Mini.
  • Under Tools -> Processor select ATmega328 (5V, 16MHz).
  • Under Tools -> Programmer select Arduino as ISP (NOT ArduinoISP!!!)

Now you can burn the bootloader using Tools -> Burn Bootloader.

The question is however: which bootloader was burned to the Pro Mini? I needed a specific bootloader (Optiboot) to save up space and had no idea which bootloader I just burned to the Pro Mini. I guess the default one, but which is that? I figured out later that the first step is where I was going wrong. If you are here to get an answer on how to burn the Optiboot bootlaoder you can skip the following section and head to Burn Optiboot onto the Pro Mini.

The following section serves only as a bit of background that was part of my process in figuring out what bootloader I burned. It didn’t get me there directly, but is still interesting.

AVRDude

Having burned the default Pro Mini bootloader I realized Arduino IDE simply calls AVRDude to do so and I hoped to find an answer as to which bootloader I had now burned. I enabled more verbose logging in Arduino IDE to find out how it calls AVRDude.

I went to File ->  Preferences and enabled verbose output during both compilation and upload:

arduino-verbose-logging

I now burned the bootloader again using Tools -> Burn Bootloader to find the following log output (excerpt):

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM5 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m 

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM5
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us

Here you can clearly see that it simply runs avrdude with some of the settings we provided in Arduino IDE along with a reference to some configuration file named avrdude.conf. This is interesting, but the command itself doesn’t tell me which bootloader I just burned nor does the configuration file it references.

I figured that I could modify the avrdude command provided in the log to specify a specific bootloader should get the job done. After some quick googling I found something along these lines should work for a hex file named filename.hex:

"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude" -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -p atmega328p -c arduino -P COM5 -b 115200 -D -U flash:w:filename.hex:i

I had to wrap the file path in double quotes because of space in the path and even though I didn’t have any hex file named filename.hex I would see the following in the output (excerpt):

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: reading input file "filename.hex"
avrdude: can't open input file filename.hex: No such file or directory

This seemed promising. Apparently I’m able to upload a hex file this way using the command line by running avrdude.exe with different arguments. However, when trying to flash the bootloader of choice (OptiBoot) I would end up with some verification errors for reasons not obvious to me. I was probably doing something wrong on the command line or using a wrong hex file.

Interestingly there are tools that basically do the same thing: simply run avrdude.exe with some arguments, yet provide a Graphical User Interface to do so because command line interfaces suck if you don’t use them in an automated fashion.

An example of such a tool is XLoader, but that one didn’t work out for me when I tried. Arduino IDE also seems to be doing the same thing: run avrdude.exe to flash the bootloader, so there must be some way to specify which bootloader in it. As it turns out there is a way to do this, but it isn’t very obvious.

Burn Optiboot onto the Pro Mini

The bootloader I wanted to burn is called OptiBoot and can be found at https://github.com/Optiboot/optiboot. It turns that it is even the default for the Arduino Uno, so all I had to do differently when Burning a Bootloader is select the Arduino Uno as board. The first step becoming:

  • Under Tools -> Board select Arduino/Genuino Uno

So to sum it up:

  • Under Tools -> Board select Arduino/Genuino Uno.
  • Under Tools -> Processor select ATmega328 (5V, 16MHz).
  • Under Tools -> Programmer select Arduino as ISP

 (EDIT: These last two steps that I have striked through are not available in Arduino IDE. I seem to have made an error while documenting these steps. Please refer to the comment section at the end to see what is up. Over there Daniel gives some feedback indicating the mistake. Sorry for any inconvenience)

Now you can burn the bootloader using Tools -> Burn Bootloader.

So, that is it right? Well, I’m not really satisified even though the job is done. If you look at the documentation the answers are there, but what is up with this magic about what bootloader is flashed on what board in the first place?

Boards Configuration

I dug a bit deeper and learned that there is a place where all the boards are defined. On my system I found the file in:

c:\program files(x86)\Arduino\hardware\arduino\avr\boards.txt

This is where Arduino IDE specifes which hex file to upload as bootloader and gives a whole new meaning to the boards section in Arduino IDE for me. Let’s look at an excerpt of the configuration for the board we have now selected, the Arduino/Genuino Uno:

##############################################################

uno.name=Arduino/Genuino Uno

uno.vid.0=0x2341
uno.pid.0=0x0043
uno.vid.1=0x2341
uno.pid.1=0x0001
uno.vid.2=0x2A03
uno.pid.2=0x0043
uno.vid.3=0x2341
uno.pid.3=0x0243

uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.maximum_data_size=2048
uno.upload.speed=115200

uno.bootloader.tool=avrdude
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0xFD
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.board=AVR_UNO
uno.build.core=arduino
uno.build.variant=standard

It specifies the hex file right there under the uno.bootloader.file configuration value.

At least I found a match between the board and the bootloader, explaining why it works with this board selected. This also gives an opportunity to change the hex file and thus changing which bootloader is uploaded to a specific board. I could go to the config section for the Pro Mini and set this bootloader as the default and not deal with this in the future. Too bad for me this was a one-time job and I don’t care about future calls, but at least it was educational and I got to write this blog post.

2 thoughts on “Burning a bootloader (OptiBoot) on an Arduino Pro Mini using an Arduino Uno

  1. In the title “Burn Optiboot onto the Pro Mini” there is a question: If it is selected as you say …

    Tools -> Board Arduino / Genuino Uno, does not appear as below:
    Tools -> ATmega328 Processor (5V, 16MHz).
    Because the Arduino / Genuino Uno board has been selected, ie to display Tools -> Processor ATmega328 (5V, 16MHz), you must select: Tools -> Board: “Arduino Nano” -> Arduino Nano.

    What do you say about it?

    1. Hi Daniel,

      Thank you for your feedback!

      Unfortunately I cannot reproduce the steps I have documented in this blog post at the moment. When I wrote this post I figured out how to burn the Optiboot bootloader on the Pro Mini for a friend of mine and used his board, which I currently cannot access.

      However, you most definitely are right that the steps listed are wrong. You seem to be right in that you can select “Arduino Nano” instead and just continue with the steps as listed, because it is mentioned on the OptiBoot Github page that Optiboot is the default bootloader for the Arduino Nano as of 2018. Great catch!

      Another option might be to just execute the first step and skip the selection of the processor and such, which are indeed not available like you mentioned.

      Again, I cannot verify all this right now. I will try to do so soon and then update accordingly. For now I’ll just add a note with your finding and reference this comment section with your feedback.

      Thank you.

Leave a Reply

Your email address will not be published.