Introduction: Save 81 Seconds: Fast Arduino Bootload/Program for Production

About: Creator of the RGB Shades

Requires: AVRISP mkII and a Linux computer (or virtual machine)

This Instructable shows how to automate and speed up the installation of a bootloader and demo program on an Arduino-compatible device.

The Arduino bootloader and IDE make it incredibly easy to build a microcontroller device with cross-platform programming support and a wide base of existing tutorials and user experience. Out of the box, most Arduino-compatible devices are ready to plug into a computer and run custom programs. However, that requires some preparation by whoever made the device.

A PCB with an AVR microcontroller is not yet Arduino-compatible. Most importantly, the bootloader must be present. Usually, the bootloader must be installed using a piece of special programming hardware. Once installed, special hardware is not necessary...the bootloader makes it easy to load additional programs into the microcontroller with an ordinary USB or serial cable.

However, the bootloader alone doesn't do anything...it's also a good idea to have some program preloaded on the device, even if it just blinks an LED.

The Arduino IDE has all the features needed to install a bootloader on a bare microcontroller and then download a program to it. It'll be fine for one, five, or ten devices...but what if you have 100 to 500 devices that need programming and testing? At the time of writing, the Arduino 1.6 branch requires about 90 total seconds to install a bootloader using an AVRISP mkII programmer and then compile and download a program to that device. It's also a bulky process requiring a lot of mouse clicks, selecting a new serial port often, etc.

The following instructions show how to implement a system that will automatically install a bootloader+program each time a single key is pressed. Each cycle takes about 9 seconds.

Step 1: What You Will Need

There are a few things needed to exactly duplicate this approach:
  1. A computer or virtual machine with Ubuntu (or other Debian-based distro) installed. It can be relatively lightweight; this process was developed on a Parallels virtual machine with Peppermint OS installed (http://peppermintos.com/).
  2. An AVRISP mkII programmer. Many other programmers will work with small configuration changes (STK500, USBTiny, AVR Dragon, etc) but this is a fairly common AVR ISP programmer and the demonstration here uses it.
  3. Some way to attach the ISP to your application board. We like SparkFun's pogo adapter to make a good temporary contact with pads, but it's fine to solder a header to your board and use the AVRISP's 6-pin connector.
  4. A USB or serial cable (whichever you plan to use for your Arduino program downloads).

That's it...once you have a working Linux system with an internet connection, you're ready for the next step.

Step 2: Install Necessary Software

We'll be using Arduino-Makefile (https://github.com/sudar/Arduino-Makefile) to install the bootloader and download the Arduino program.

Open a terminal window and install two packages with the following command:

sudo apt-get install python-serial arduino-mk

The computer should download and install the necessary software. If this is a newly installed operating system, it may be a good idea to run "sudo apt-get update && sudo apt-get upgrade" first.

Next, your user needs permission to access external devices. Type the following command, substituting your own username for "username" below:

sudo usermod -a -G dialout username

You will need to log out and log back in (or restart) before the above command takes effect.

The AVRISP mkII doesn't need any extra drivers, but you will still need to inform the system about it. Type the following commands:

sudo gedit /etc/udev/rules.d/80-avrisp.rules

An editing window will appear. Insert the following line:

ATTR{idVendor}=="03eb",ATTR{idProduct}=="2103",MODE="660",GROUP="dialout"

Save and exit. Then restart the udev service:

sudo service udev restart

Next, we will configure Arduino-MK.

Step 3: Configure Arduino-MK

This step may not be necessary in the future when more updated versions of Arduino-MK are available. If you choose to set up Arduino-MK directly from Github you will likely not have any issues. However, at the time of writing, the Arduino-MK available through apt-get will not correctly recognize the AVRISP mkII on USB.

Run the following command:

sudo gedit /usr/share/arduino/Arduino.mk

An editing window will appear. Look for the following line (it may help to just search for "usbtiny"):

ifneq ($(strip $(ISP_PROG)),$(filter $(ISP_PROG), usbasp usbtiny))

Add "avrispmkii" to the list to make the line look like this:

ifneq ($(strip $(ISP_PROG)),$(filter $(ISP_PROG), usbasp usbtiny avrispmkii))

Save and exit.

Next, we will set up a custom makefile for your project.

Step 4: Create a Makefile

Assuming you already have an Arduino sketch that you want to program into your device, go to the sketch folder. In my case, the project is named RGBShades:

cd ~/sketchbook/RGBShades

Create a makefile:

gedit Makefile

The contents of the makefile will depend on the exact specifications of your processor, what bootloader you want to install, etc. However, if your hardware is functionally identical to an existing Arduino-compatible board, it can be simple:

BOARD_TAG = pro5v328
ARDUINO_PORT = /dev/ttyUSB*
ISP_PROG = avrispmkII
ISP_PORT = usb
include /usr/share/arduino/Arduino.mk

In the above case, the BOARD_TAG selected is from the default boards.txt definition in the Arduino software. It corresponds to the Arduino Pro Mini with ATmega328 at 5V and 16MHz. The ARDUINO_PORT will typically be /dev/ttyUSB0 if your device is the only USB-serial device plugged in at the moment, but the wildcard asterisk allows other port numbers since sometimes it will appear as another number. If you have other USB-serial devices you will need to watch what ports are already used, and choose the one that appears when your device-to-be-programmed is plugged in.

The Makefile below is what we actually use for the RGBShades project:

ARDUINO_QUIET = 1
BOARDS_TXT = ~/sketchbook/hardware/RGBShades/boards.txt BOARD_TAG = RGBShades ARDUINO_PORT = /dev/ttyUSB* AVRDUDE_OPTS = -q ISP_PROG = avrispmkii ISP_PORT = usb include /usr/share/arduino/Arduino.mk

The BOARDS_TXT points to a custom board file that selects some alternate parameters and bootloader options. The alternate boards.txt file contains the BOARD_TAG RGBShades. A couple of other options are added to reduce the amount of text scrolling by while programming devices. Fairly important: the default AVRDUDE_OPTS will disable verification (with the -V option), so it's a good idea to set AVRDUDE_OPTS yourself. This will make sure to read back the uploaded program and make sure your device was programmed successfully. In practice, we saw a failed program once every 50-100 attempts, so verification is always a good safeguard.

The RGBShades board.txt file is included below for completeness:

##############################################################
RGBShades.name=RGB Shades
RGBShades.upload.protocol=arduino
RGBShades.upload.maximum_size=32256
RGBShades.upload.speed=115200
RGBShades.bootloader.low_fuses=0xFF
RGBShades.bootloader.high_fuses=0xDE
RGBShades.bootloader.extended_fuses=0x05
RGBShades.bootloader.unlock_bits=0x3F
RGBShades.bootloader.lock_bits=0x0F
RGBShades.bootloader.path=optiboot
RGBShades.bootloader.file=optiboot_atmega328.hex
RGBShades.build.mcu=atmega328p
RGBShades.build.f_cpu=16000000L
RGBShades.build.core=arduino
RGBShades.build.variant=eightanaloginputs
##############################################################

Since the RGBShades code also required an external library (FastLED) this was installed as usual in the ~/sketchbook/libraries/ folder.

Next, we will create a script to automate the programming process.

Step 5: Create an Automation Script

With the configuration already done so far, you can easily install the bootloader and upload programs using the "make burn_bootloader" and "make upload" commands in a terminal. However, let's make it all work with a single keypress.

In your sketch folder (in our case RGBShades) create a bash script:

gedit avrflasher

An editing window will appear. Insert the following:

#!/bin/bash
set -e
keyPress=""
while [ "$keyPress" != "q" ] ; do echo "Burning bootloader..." make burn_bootloader
echo "Uploading sketch..." make upload read -s -p "Press q to quit, any other key to repeat:" -n1 keyPress
echo done

Save and exit. Then make the file executable:

chmod 755 avrflasher

Assuming that everything in the previous steps went well, you're ready to program a lot of devices! Plug your device into USB, make sure it's powered up, and connect the AVRISP.

./avrflasher

The code should start by installing the bootloader. If that's successful, it will try to download a program over USB. If that works, it's ready for you to connect a new device and restart the process by pressing any key (other than q, which will quit). The first run may take 30+ seconds since it's recompiling your program and a lot of the supporting libraries, but subsequent programming attempts should only take about 9 seconds (as tested on a virtual machine running on an i5 laptop).

Step 6: Program Lots and Lots of New Arduino-compatibles!

We hope this helps someone save time on what is always a tedious task. It's certainly helped us!

Running some numbers...we currently have about 500 devices to program. At 90 seconds per device using the Arduino IDE, that's 12.5 hours spent waiting for programming. A tenfold decrease to 9 seconds means only 1.25 hours spent waiting for programming to finish!

If you have questions about getting this working, or information to add to what we have here, we'd love to see it in the comments.

Thanks!