Become a subscriber (Free)

Join 29,000 other subscribers to receive subscriber sale discounts and other free resources.
Don't worry -- youre-mail address is totally secure. I promise to use it only to send you MicroZine.

Arduino Nano ISP : Using a Nano as an ISP programmer

How to use a Nano as an Arduino Nano 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: an In System Programmer.

The purpose of using a 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.

breadboard Nano as ISP to ATmega328P

You can use a lot of Arduino boards as ISP programmers ( suggests ATmega, 32U4 or ATtiny - common ones are "Arduino Uno" and "Arduino Nano"). 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 othe signal needed is a general purpose I/O pin 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!

Step One - Program the Programmer

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

Here the Nano is used as the 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 Two - Connect Programmer to Target

After programming the board to create the Arduino Nano 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         
D11 pin 17
  MISO D12
pin 18
pin 19
pin 1 (RSTn)
pin 20 (AVCC), pin 7 (VCC)
pin 22, pin 8
  Cap1 to GND (22pF)
pin 9
  Cap2 to GND (22pF)
pin 10
  16 MHz Crystal
pin 9 and pin 10

Arduino Nano 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 Nano ISP programmer to
bare-board Arduino chip schematic:
Nano as ISP schematic

Step Three - Select Bootloader Type

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

Arduino nano as ISP select programmer

Step Four - Burn Bootloader to Target

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

    Menu > Tools > Burn Bootloader

Burn bootloader to ATmega328P

IDE Burn bootloader Output

Burn Bootloader Fail : Arduino Nano 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 Nano 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 adaptor 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:

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

In many cases the serial interface adaptor 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 using a DTR signal from the serial interface. Without the DTR signal the programming sequence hangs. That is, unless you do a manual reset at the correct time - alternatively buy a serial adaptor 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-adaptor 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 adaptor 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 adaptor 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() {

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

New! Comments

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

Privacy Policy | Contact | About Me

Site Map | Terms of Use

Visit our Facebook Page:
To Visit Click Here

Recent Articles

  1. How the HMC5883L 3-axis digital magentomter works

    Find out the differences between the HMC5883L and the QMC5883L and whether they are compatible.

    Read more

  2. Arduino absolute value - abs() - secrets revealed...

    Secrets of Arduino absolute value abs() - Why it might fail, Why it may cause problems...and how to fix it.

    Read more

  3. Arduino Analog Output...Easy analog output generation

    Arduino Analog Output: How to create the most accurate PWM analog ouput and how to create analog PWM sine waves.

    Read more

  4. ACS758 secrets...

    Using the ACS758 to measure very high current

    Read more

  5. Arduino Voltage Reference Capabilities

    Arduino Voltage reference: Both the Uno and Nano have a built-in voltage reference: Find out how to make it more accurate. In addition find out how to use it to measure the supply voltage 1V8 ~ 5V5

    Read more

  6. DigitalWrite and equivalent fast macros. Speed up your code!

    Find out how digitalWrite() works...Now use 17x Faster macros!

    Read more

Readers Comments

"I wanted to thank
you so so so much
for all the information
you have provided in
your site it's


- Ranish Pottath

"This site really is
the best and my favorite.
I find here many useful
projects and tips."

- Milan


"Awesome site,
very, very easy and nice
to navigate!"

- Matt

Learn Microcontrollers

"Interested in

Sign up for The
Free 7 day guide:


"I am a newbie to PIC
and I wanted to say
 how great your
site has been for me."

- Dave


"Your site is a great
and perfect work.

- Suresh


"I couldn't find the correct
words to define
yourweb site.

Very useful, uncovered,
honest and clear.

Thanks so much for
your time and works.

- Anon

Back to Top