Arduino ISP: Easily burn the bootloader back into an Arduino with an ISP programmer. Don't buy an ISP programmer; use another Arduino as a Free ISP.

Arduino ISP: Oh Nooooooo!

You bought that Arduino chip off the web...

...and it lost its bootloader.

What to do?

  • Buy a commercial AVR serial programmer?

  • But wait! - You can program the chip using any standard Arduino.
  • A commercial AVR serial programmer just generates digital output signals.

  • But an Arduino board just generates digital output signals!

  • Exactly, that's right they can do the same job.

So just get the correct program into your board, make a few connections and you'll program that chip.

On this page an Arduino Nano is used as an ISP (In System Programmer) but you can use an Arduino Uno and others as well.

Using the Nano as an Arduino ISP

Not having an AVR programmer I wanted to program an ATMega328P for use as a bare-board Arduino, and one convenient way is to use an Arduino board as a an ISP.

The purpose of using an ISP programmer is to put back the bootloader, which all Arduino boards need before you can upload a program using the Arduino IDE.

You may have bought an unprogrammed chip that needs a bootloader to get it working with the IDE and in that case you can use the method here to re-program the device (of course you need at least one device with the bootloader already installed e.g. Arduino Uno or Nano).

breadboard Nano as ISP to ATmega328P

You can choose from many different Arduino boards to program your target board (Arduino.cc suggests ATmega, 32U4 or ATtiny - common ones are "Arduino Uno" and "Arduino Nano" as the programming device).

The IDE probably just changes pins in the bootloader sketch for the different boards (hinted at in the bootloader sketch) to get the correct SPI pins the only other signal needed is a general purpose I/O pin which is used as a reset signal.

The ISP programming method simply uses the SPI interface to connect programmer and target by 4 signal lines:

  • RST    - ReSeT.
  • MOSI (SPI) - Master Out Slave In.
  • MISO (SPI) - Master In Slave Out.
  • SCK   (SPI) - Serial Clock.

Note: MOSI, MISO and SCK are the same SPI pins used in chips that use the SPI interface in your own projects. RST is a signal from any I/O pin (it is not the Arduino board reset signal).

These (SPI) signals are connected to the same pins on programmer (Nano) and target (here the ATMega328P on a solderless breadboard). Notice how the names of the signals allow direct connection between different chips because they include the sources and target names. This is very different to RS232 where you have to remember to cross over Rx and TX signals!

The connections are always the same for programmer and target boards. So all you need to re-program the bootloader into an Arduino, is another Arduino! (with a bootloader already programmed into the chip)

Step 1 - Program the Programmer

This sounds a bit odd, but you need to program the Arduino Nano that will be used as the Arduino ISP programmer with the ISP programming sketch. This turns the Arduino into an ISP programmer.

Here the Nano is used as the Arduino ISP programmer.

Select the Arduino ISP from the example programs in the IDE:

    Menu > File > Examples > 11.ArduinoISP > ArduinoISP

arduino as ISP selecting ISP sketch

From the Tools Menu select four options:
  • Board: "Arduino Nano". This is the programmer board in use.
  • Processor: ATmega328P.
  • Port : COMnn. The port your to which your Nano is attached.
  • Programmer : "Arduino as ISP".
They should all match the screen shot below - except for the Port number which you can find by clicking the port entry (as shown below).


arduino isp board port and chip settings for arduino nano

Program the sketch into the Nano.

    Menu > Sketch > Upload

Step 2 - Connect Programmer to Target

After programming the board to create the Arduino ISP programmer, disconnect the USB cable and make the connections to the target board.

You have to connect all the SPI wires (see breadboard layout below) but you don't really need to connect the LEDs. One you might find useful is the heartbeat LED but it is not essential. This will pulse slowly on and off, showing that the ISP program is active in the Nano.

In the breadboard layout below the LED connections are:

  • pin D7 : Yellow  : Programming.
  • pin D8 : Red      : Error.
  • pin D9 : Green   : Heartbeat.

TIP: Don't bother with the LEDs - See the screen shots of IDE output below - you can see the programming status easily on that.

You can choose which pins will be used for MOSI, MISO and SCK if you set PIN_MOSI, PIN_MISO and PIN_SCK to your desired pins - in the sketch (save the sketch as a different file to allow editing) - in this case the Ardino ISP sketch will use bit-banged SPI if these pins are not set to the standard SPI pins.

Nano to Bare-board connections, and crystal+caps:

 Signal name         
Nano      
Bare-board
  MOSI
D11 pin 17
  MISO D12
pin 18
  SCK
D13
pin 19
  RESET
D10
pin 1 (RSTn)
  5V
5V
pin 20 (AVCC), pin 7 (VCC)
  0V
GND
pin 22, pin 8
  Cap1 to GND (22pF)
n/a
pin 9
  Cap2 to GND (22pF)
n/a
pin 10
  16 MHz Crystal
n/a
pin 9 and pin 10

Arduino ISP programmer connected to
 target bare-board Arduino chip:
breadboard Nano as ISP to ATmega328P
This is the schematic for the above (10pF should be 22pF as in list above).

Warning: Fritzing makes it really difficult to change component values (crystal capacitors) so I didn't! - also the schematic tool is bad (single net operation). I have not tried the PCB but have noticed it is not well regarded i.e. don't use it. Only use Fritzing for breadboard graphics as above.

Arduino ISP programmer to
bare-board Arduino chip schematic:
Nano as ISP schematic

Step 3 - Select Bootloader Type

Select the Arduino as ISP from the "Programmer:" Option:

Arduino nano as ISP select programmer

Step 4 - Burn Bootloader to Target

The next step is to program the target board (Arduino ISP) with the bootloader:

    Menu > Tools > Burn Bootloader

Burn bootloader to ATmega328P

IDE Burn bootloader Output

Burn Bootloader Fail : Arduino ISP

As an experiment I took out the Crystal before running the bootloader. This is the result:

Nano as ISP burn bootloader error

This is interesting as the PIC microcontrollers do not require a crystal to program them but they do require high voltage unlike the Arduino. It also means that the ATmega328P will be more susceptible to bricking if the fuses are set badly and a bad clock configuration is made. Using information on this page that can never happen as the Arduino IDE sets these fuses - I am talking about when you set the fuses yourself when using AVRDude.

Burn Bootloader Success : Arduino ISP

This is the result when you have successfully programmed the bootloader (it is also the reason that you don't really need the LEDs as you can see success or failure from the IDE status screen):

Arduino Nano as ISP bootloader burn success

Using the Bare-Board Arduino

Using the bare-board Arduino requires that you have a USB to serial adapter that connects to the RX and Tx pins of the Arduino chip.

Note: The signals Rx and Tx must be crossed over at the ATmega328p. So:

  • Adapter-Rx connects to 328P-Tx.
  • Adapter-Tx connects to 328P-Rx.

In many cases the serial interface adapter will only have four connections:

  1. 5V
  2. GND
  3. Rx
  4. Tx

This presents a problem as the Arduino schematic shows that the Arduino is reset at a specific time using another RS232 serial interface signal DTR (Data Terminal Ready). Its original function was obviously not a reset signal but it can be controlled by the sending PC and is activated (sent low) before the start of a programming data block (see scope trace signals below).

Without the DTR signal the programming sequence hangs. That is, unless you do a manual reset at the correct time - alternatively buy a serial adapter with the DTR signal as an output (and add the 100nF capacitor - see schematic below).

Arduino Reset Problem

On Arduino boards another external signal starts bootloader - in fact it resets the board - this extra signal is called DTR (or Data Terminal Ready) - it is a separate output from the serial interface. A bootloader is only active for a few seconds at power up, or after a reset, after which control is passed to the 'previously-loaded' program.

When an RS232 transmission is started the sending equipment asserts DTR and this signal is used to perform a target reset (so the bootloader wakes up). In the Arduino Schematic a 100nF capacitor sits between this signal and the reset input of the ATMega328p (which is also pulled up by a 10k resistor - see C5 in the circuit below).

Arduino reset using DTR signal

This combination is used since DTR only changes state at the start and end of a sequence of byte transmissions. The idea is that when DTR goes low the Reset input is pulled low momentarily and then it is slowly pulled up to 5V by the 10k pull-up (RN1D). It is a sort of cheat reset method using the characteristics of capacitors to do the job.

The signal trace below shows the capacitor action - showing the reset pin of the Arduino (This is 1V/div and 500us/div, the voltage between blue horizontal lines is 4.7V - the lower blue line is 0V):

Arduino Reset input capacitor C5 via DTR

This reset system works because the reset input has a hysteresis level of 0.1V (at 5V supply) which creates a clean signal in the microcontroller that ignores noise on the slowly rising input.

For the reset pin VIL= 0.1VCC MAX and VIH=0.9VCC MIN. For the above trace thresholds are 0.1*4.7 = 0.47V and 0.9*4.7=4.23V and gives an low reset signal of duration ~ 1.5ms.

In the trace below, when DTR goes high, a high voltage spike is created with a peak value of 9.12V! The scope settings are :at 2V/div, 5ms/div, high blue line is at 9.12V, yellow horizontal signal is at 4.7V:

Arduino Reset input capacitor C5 via DTR going high

Note: The reason that the ATmega328P can handle this higher voltage is that the RESET input pin is specified for operation up to 13V, probably for high voltage programming. You can not do this on other pins!

The time between DTR low and DTR high depends on how long the programming takes - for the the blink sketch it is 1.9seconds.

Programming Arduino without DTR

It is possible to program the bare-board Arduino using a 4-connection-serial-adapter but only if you use a manual reset button on the target board. The key thing to get right is to push the reset button at the correct time during the programming process. This does mean you have to keep an eye on the IDE and what it is doing!

Alternatively: Remember to buy a serial to USB adapter that has a breakout pin with the DTR signal available - add the 100nF capacitor between DTR and the reset pin, and the 10k pull-up from the reset pin to 5V, and it's ready to go.

Here is the setup for a 4-connector USB to serial adapter connected to the bare-board Arduino:

Bare board Arduino connected to USB to Serial adaptor

Note: Pin 2 of the ATmega328p is Rx, and pin 3 is Tx.

Bare Board Programming Failure

If you don't push the reset button at all then you will get this IDE status message:

programming failure bare board Arduino

If you push-and-release the button too soon the compiler will be still compiling and programming will fail.

If you push-and-release the button too late you will get a programming failure message.

Bare Board Programming Success

However if you push and release the button just after the "Uploading" text appears in the IDE then you get the following:

programming success bare board Arduino

Simple Bare Board Blink Sketch

You can try out the following sketch on the bare-board Arduino (attach an LED via 1k resistor to D13 and to ground - pin 19 of the ATmega328P):

// Simple slow-fast blink on built in LED Arduino D13.

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
   for (int i=0;i<2;i++) {
      digitalWrite(LED_BUILTIN, HIGH);   // Turn the LED on.
      delay(200);
      digitalWrite(LED_BUILTIN, LOW);    // Turn the LED off.
      delay(200);
   }
   for (int i=0;i<5;i++) {
      digitalWrite(LED_BUILTIN, HIGH);   // Turn the LED on.
      delay(50);
      digitalWrite(LED_BUILTIN, LOW);    // Turn the LED off.
      delay(50);
   }
   delay(400);
}

Conclusions

The purpose of using an Arduino ISP (In-System Programming) is to reprogram the bootloader onto an Arduino-compatible chip like the ATmega328p. This is necessary when the bootloader is lost, such as when buying an empty/unprogrammed chip.

An Arduino board like the Uno or Nano can be used as a free and easy ISP programmer to burn the bootloader back onto the target chip, instead of requiring a separate commercial AVR programmer. All that's needed are basic SPI connections between the programmer Arduino and target chip.

The Arduino IDE is configured to use another Arduino as the programmer, by loading a special bootloader sketch onto the programmer board. Connections are then made between the SPI pins of both boards.

Burning the bootloader successfully resets the target chip so it can be programmed from the IDE again. Issues may occur without a reset line or crystal on the target.

After successful bootloader burning, the bare/target chip can be used as a standalone Arduino once connected to a computer via a USB-to-serial adapter. Correct wiring of Tx and Rx lines is important.

Manual resetting may be needed if the adapter lacks a DTR line, which is normally used by the Arduino design to reset the chip before uploading code. With the right reset method (that is detailed above), simple sketches can then be loaded and run on the bare chip Arduino.

In summary, an Arduino ISP allows easy reprogramming of the bootloader when it's lost, without requiring a separate programmer hardware purchase - another Arduino board will work as the programmer.


Written by John Main who has a degree in Electronic Engineering.

Note: Parts of this page were written using chatgpt as a research assistant.



Comments

Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.




Privacy Policy | Contact | About Me

Site Map | Terms of Use