Arduino Nano as an ISP Programmer

05.12.2015 Updated the photos.
 

In a previous post I showed how to make your own Arduino on a breadboard. The next step is programming it.
 

Using an Arduino Nano to program a ATmega328P chip

ArduinoISP_001_1600

There are many guides online on how to use an Arduino to program a ATmega chip, two goods ones are:
Using an Arduino as an AVR ISP (In-System Programmer)
Nick Gammon’s guide

If you google “using Arduino as a programmer” you will find most of the results are for using an UNO, very few are for the Nano. One Nano guide I did find is at Lets Make Robots This explains how to set up the Nano but it does not clearly show how to program a stand alone Atmega chip.

ArduinoAsProgrammerI assumed the Nano was the same as the Duemilanove and used the “Using an Arduino as an AVR ISP (In-System Programmer)” guide on the Arduino site. Unfortunately I couldn’t get it to work. After much google research I found that I needed to keep the reset pin on the Arduino Nano high by using a capacitor between the ground and the reset pin. I later found this is specific to certain Arduinos only.

 
 

Create the programmer

First we need to turn the Arduino Nano in to a programmer. This is done by uploading the ArduinoISP sketch. The ArduinoISP sketch is part of the Arduino software package and can be found in the examples folder.

Connect the Nano to the computer by USB as usual and load the AuduinoISP sketch in to the IDE. If you have already added a capacitor to RST & GND you need to remove it.

ArduinoISP_01

If you are using the Arduino 1.0 or later IDE you need to change the delay value of the heartbeat. Find


// this provides a heartbeat on pin 9, so you can tell the software is running.
uint8_t hbval=128;
int8_t hbdelta=8;
void heartbeat() {
if (hbval > 192) hbdelta = -hbdelta;
if (hbval < 32) hbdelta = -hbdelta;
hbval += hbdelta;
analogWrite(LED_HB, hbval);
delay(40);
}

and change the delay(40) to delay(20). Then compile and upload the sketch.

 

Status LEDS

If you look at the sketch, you will see that it recommends adding status LEDs. The LEDs are optional but I prefer to have them so I can see what is happening.


// Put an LED (with resistor) on the following pins:
// 9: Heartbeat - shows the programmer is running
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
// 7: Programming - In communication with the slave

I use a red LED for the heart beat and two white LEDs for error and programming.

Remove the power (USB lead) and add the resistors (220 or 330 ohm are good) and LEDS.
ArduinoISP_LEDs_01b_800
Reconnect the power and if everything is working you should see the LEDs quickly flicker and then the LED on pin 9 should pulse on/off.

If every is OK, disconnect the power and add the connections to the ATmega chip

 

Connecting the Arduino Nano ISP to the ATmega328P chip

Arduino_Nana_as_a_programmer

Connect the Arduino to the Atmega with wthe following connections:
Arduino D13 to ATmega pin 19 (SCK) – I used a green wire
Arduino D12 to ATmega pin 18 (MISO) – I used a blue wire
Arduino D11 to ATmega pin 17 (MOSI) – I used a orange wire
Arduino D10 to Atmega pin 1 (RESET) – I used a white wire
VCC to VCC
GND to GND

ArduinoISP_001_1600

ArduinoISP_002_1600

ArduinoISP_ATmegaBreadBoard_001_800

ArduinoISP_ATmegaBreadBoard_002_800

For more information on wiring the ATmega see arduino-on-a-breadboard

The Arduino renames the pins to make things easy for the user. The ATmega pins are shown below.
ATmega 328P pin layout

New ATmega chips are set to use the internal clock at 1MHz. We need to program the fuses so that the external 16MHz crystal is used. The easiest way to do this is to load a boot loader. This will set the fuses and we can over write the boot loader later.

 

Adding a new Arduino definition to the boards.txt file

When programming the ATmega chip you can select a suitable similar board in the Arduino board list but this will assume a boot loader is present and reduce the amount of program space available. We can create our own board definition that tells the Arduino IDE to use all available memory and use appropriate fuse settings. The different Arduino definitions are stored in a file called boards.txt. On Windows systems the boards.txt file is in the folder “\hardware\arduino” inside your Arduino installation folder. I normally search for it.

Rename the file to boards.BAK.
Open the boards.BAK file in a text editor, Notepad can be used, and save it in the same folder (“\hardware\arduino”) as boards.txt.

The boards.txt file contains options for various different Arduinos. These are arranged in groups and each Arduino model is separated by lines of #s.


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

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

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

We want to create out own entry for the bread board Arduino and it is easiest to use one of the existing entries. Copy the uno entry and paste at the top of the file.


# See: http://code.google.com/p/arduino/wiki/Platforms

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

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

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

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

Now edit the section you have just pasted.
Change the uno at the start of each line to something else. I used “atmegasa16, short for “atmega stand alone at 16Mhz”.
Give it a new name (atmegasa16.name=)- I used “ATmega Stand Alone (Arduino as ISP)”.
Since I am not using a boot loader I can use all of the program memory so I changed atmegasa16.upload.maximum_size to 32768.
I am using the ArduinoISP so I changed atmegasa16.upload.using to arduino:arduinoisp.
Change atmegasa16.bootloader.extended_fuses=0x07 to atmegasa16.bootloader.extended_fuses=0x05. This is the standard Arduino setting. (I will cover the basics of fuse settings in another post).

You should now have:


atmegasa16.name=ATmega328P Stand Alone (Arduino as ISP)
atmegasa16.upload.protocol=stk500
atmegasa16.upload.maximum_size=32768
atmegasa16.upload.speed=115200
atmegasa16.upload.using=arduino:arduinoisp
atmegasa16.bootloader.low_fuses=0xff
atmegasa16.bootloader.high_fuses=0xdf
atmegasa16.bootloader.extended_fuses=0x05
atmegasa16.bootloader.path=optiboot
atmegasa16.bootloader.file=optiboot_atmega328.hex
atmegasa16.bootloader.unlock_bits=0x3F
atmegasa16.bootloader.lock_bits=0x0F
atmegasa16.build.mcu=atmega328p
atmegasa16.build.f_cpu=16000000L
atmegasa16.build.core=arduino
atmegasa16.build.variant=arduino:standard

 

To read the new boards.txt file the Ardiono IDE must be restarted. After restarting you should have a new entry:
ArduinoISP_008

We should now be ready to program the ATmega chip.
Connect the Arduino Nano to the computer.

Set Fuses by Burning a Boot Loader

To make the ATmega chip use the external crystal we need to set certain fuses. An easy way to do this is burn a boot loader. When we upload a sketch later, the program memory is over written but the fuse settings are not.

Select the Board you have just created.
ArduinoISP_009

Set the Arduino as ISP as the programmer
ArduinoISP_010

Select Burn BootLoader.
ArduinoISP_012

If everything is OK then the programming LED on the Nano ISP should light (pin 10) and the LED on pin19 of the ATmega328P should flicker as the boot loader is uploaded.

 

Uploading sketches to the ATmega328P

Load the example Blink sketch
Make sure the board to be programmed is the Atmega stand alone and the programmer is set to Arduino as ISP.
In the main menu select Upload Using Programmer (or press Ctrl+Shift+U) and the Blink sketch should upload.
Note that you need to use the menu option not the upload icon.

ArduinoISP_013

 

Errors

Two common errors when programming stand alone chips are
avrdude: stk500_getsync(): not in sync: resp=0x00, and
stk500_getsync(): not in sync: resp=0x15

resp=0x00 means the programmer cannot communicate with the chip. This normally means the connections are not correct (check the wires, especially VCC and ground)or you tried to upload the sketch using the Upload button in the IDE. Remember to use the File menu option

resp=0x15 is very common when the Arduino ISP is resetting. A simple solution is to add a 10uF capacitor between reset and ground on the Arduino Nano (not the Atmega chip). This keeps the reset pin high and stops the Nano resetting. Another solution is to add a 120ohm resistor between reset and +5V but I couldn’t get this to work.
ArduinoISP_014_CAP_600

I have used a couple of different Nano’s as programmers, an original that doesn’t require the capacitor, and a clone (cheap China version) that does.

if you get the following error message


avrdude: stk500_program_enable(): protocol error, expect=0x14, resp=0x50
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

It means the ATmega is not resetting. Check the connection between Arduino pin10 and the ATmega pin 1.

 
 
 

17 thoughts on “Arduino Nano as an ISP Programmer

  1. Sir,
    u have a great tutorial. unfortunately i am having a problem while uploading the bootloader. I have cross checked the whole circuit many times but the following error is appearing again and again. Please help me.

    avrdude: Expected signature for ATMEGA328P is 1E 95 0F
    Double check chip, or use -F to override this check.

  2. Pingback: Problem when using arduino nano as isp and atmega328p-pu | Question and Answer

  3. I can’t believe how helpful this tutorial was. Thank you so much! I also want to note that I got the 0x14 _and_ the 0x15 errors originally. Some other tutorial said the first two 0x15 retries are normal, and to ignore them. However, I got no 0x15s when I added the 10uF cap, nor the 0x14 errors. works beautifully. Thanks again

  4. Good day

    Can you please inform me how I would achieve the following:
    I have setup arduino nano as isp programmer with standalone Atmega328p-pu.
    I have success with programming.

    However my application of the standalone chip requires me to communicate via serial and monitor some changes via Arduino IDE Serial Monitor

    Can you please inform me how I could achieve this

  5. Pingback: Arduino / ATmega 328P fuse settings | Martyn Currey

  6. Dear Martin,thanks for the wonderful detailed explanation,I am a newbie for Arduino.Can we upload the Sketches for the bootloaded AT328P in the same way.

    • Do you mean your AT328P already has the bootloader installed? If so, yes you can upload this way but the bootloader will be over-written/erased when uploading a new sketch.

      If using this method to upload sketches you do not need a bootloader. The bootloader is used to enable communication via serial/usb and since this method does not use usb the bootloader is not required.

  7. great, great work and explanation, thank you!
    I have build it and works perfectly (with the 10uF capacitor). I added a socket for a 3 pin ceramic resonator to test the ATMega328P chip with various frequency (16 and 20 Mhz).

  8. Thank you sir. Your tutorial helped me a lot!
    I successfully uploaded new sketch to my smd standalone arduino chip after weeks of trying. Hooo!

Leave a Reply

Your email address will not be published. Required fields are marked *


− 2 = seven

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>