Introduction
For me the main reason to program an Atmega via ISP is the fact that I use them in some projects as ‘stand alone’ processor without all other stuff that is normally available on an Arduino board. An accompanying benefit is the absence of the delay that is introduced by the standard Arduino bootloader during start-up.
Given that, I felt the need for a dedicated programmer with which I can easily program my (throughole) Atmega 328p processors. I decided that this programmer should have the following features:
- The Atmega chip, the target processor is fitted in a ZIP-socket for easy exchange.
- The board contains a 16Mhz crystal as external clock for the Atmega.
- The board contains an ISP header to program other Arduino’s via ISP.
- It uses a Arduino Nano as programmer.
- A single LED + resistor is added just to be able to run a testapplication on the Atmega.
- Idem Reset-button.
Some references
There are a lot of internet articles that describe how to load a program into a Atmega processor via ISP (In System Programming). Some recommended articles:
- https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP/
The ‘official’ documentation. - https://www.baldengineer.com/arduino-bootloader.html
A short introduction on the bootloader topic. - https://www.makerguides.com/what-does-burn-bootloader-do-in-arduino-ide/
Shows how to use an Arduino to program another Arduino or Atmega via ISP. It also explains the steps to take in the Arduino IDE. - https://www.martyncurrey.com/arduino-nano-as-an-isp-programmer/
A very good and detailed tutorial. Must read!
This article combines ‘all’ knowledge in one page and presents a complete programmer (PCB) including working instructions.
The schematic
The specifications above listed resulted in the following design (drawn with Eagle):
On the right side you see the Atmega 328p which has to be programmed, the target processor. In fact this will be a ZIP-socket, but the pinning is of course based on the Atmega. The Atmega has its own 16MHz crystal oscillator and the reset-pin is pulled up with R1. With push button P1 the Reset-input can be grounded to reset the Atmega. D1 prevents that also the SS-pin of the Nano is grounded when P1 is pressed. Both fysical pins 11 and 12 are connected to a LED. These pins support PWM (in Arduino terms: these are logical pins D5 and D6).
On the left side there are 2 15-pin female headers for an Arduino Nano. Pins D10..D13 are connected with a) the 6-pins ISP-connector SV2 and b) also to the Atmega pins.
The whole thing is powered from the USB-connection of the Arduino Nano.
Note: the 6-pins ISP-connector can be seen as an ISP-output. While the 6-pins connector on an Arduino board is an ISP-input! The difference is in pin 5. On an input connector this pin in connected to the reset pin of the device to be programmed. On an output connector this pin is driven by pin D10 (SCK) of the Arduino that acts as the programmer.
And that’s all!
The PCB
The PCB is is double sided and populated by a big ZIP socket for the target processor, two female pinheaders for the Arduino Nano and a couple of small components:
- A 16MHz crystal. This is needed by the target processor.
- There are two LEDs just to test the target processor with a blink-sketch.
- A Reset-button to reset the target processor.
- A 10uF capacitor on the Reset-line of the Arduino Nano (see below why).
Buy this Programmer
>> I sell this programmer. See the webshop for prices and shipping.
The programming procedure
To program a stand-alone Atmega 328 we have to follow this procedure:
- Upload the sketch ‘ArduinoISP’ into the Arduino Nano on the PCB, just as you would upload any other sketch to an Arduino Nano.
NB: Remove the Arduino from the PCB during this step! Otherwise the 10uF capacitor on the Reset-line will prevent uploading. - Configure the Arduino IDE: choose board ‘Arduino UNO’ and ‘Arduino as ISP’ as the programmer.
- Upload the bootloader into the 328 via menu ‘Tools’ | ‘Burn Bootloader’
- Open the sketch to upload in the 328 in the IDE.
- Upload this skech via menu ‘Sketch’ | ‘Upload Using Programmer’.
The sketch will be compiled and – when OK – will be uploaded tot the target processor. During uploading the on-board LEDs of the Nano (the programmer) will blink quite rapidly.
Remarks
@1: Sketch ‘Arduino ISP’
This is one of the example sketches that is installed with the Arduino IDE. You can find it under Menu File | Examples. This sketch turns the Nano into a programmer.
@2: Configue the IDE
You have to choose the ‘Arduino UNO’ because this mother of all Arduino boards contains a Atmega 328p chip.
@3: Burn bootloader
See section below ‘Why Burn Bootloader is needed’.
@5: Upload Using Programmer
The normal way of uploading a sketch is sending the hex-data via the USB link to the bootloader of the Arduino. But now the hex-file is sent to the ‘Programmer’. That why there is a special function to upload your sketch via the Programmer.
Test-sketch
A simple sketch that blinks both LEDs on the PCB:
/**
* Testapplication for PCB 2024-002 = Arduino ISP programmer V2.
*
* Makes the two LEDs on the PCB blinking.
*
* Outputs:
* - pin 11 = D5 (PWM) Green LED
* - pin 12 = D6 (PWM) Yellow LED
*
*
* Revision History
* ----------------
* 2024-02-26
* New.
*/
#define LED_GREEN 5
#define LED_YELLOW 6
void setup() {
/** Output pins: **/
pinMode (LED_GREEN, OUTPUT);
pinMode (LED_YELLOW, OUTPUT);
}
int LED_STATE = 0;
void loop() {
digitalWrite (LED_GREEN, LED_STATE);
LED_STATE = !LED_STATE;
digitalWrite (LED_YELLOW, LED_STATE);
delay (500);
}
Program another ArduinoISP
The 6-pins header on the PCB can be used to program another Arduino. Just link this header to the ISP-header on that other Arduino. For instance:
In the Arduino IDE choose the right board to program (Arduino Nano in this case) and choose programmer: “Arduino as ISP”:
NB: when you choose ‘Arduino Nano’ the IDE automatically selects a Processor ‘ATmega328P’. That’s OK.
For the rest: follow the steps 4 and 5 as mentioned above.
[Re]burn bootloader
When you have an Arduino that needs reburning the bootloader (for whatever reason) the only way to burn the bootloader is via ISP. So this tool can help you in such cases.
Warning
Because the Nano outputs 5V on the ISP-pins, you can only program other Arduino’s that also run on 5V!
Buy this programmer
>> I sell this programmer. See the webshop for prices and shipping.
Background info
This section gives some background info about burning bootloader, why the 10uF Capacitor is needed etc.
Why ‘Burn Bootloader’ is needed
First install the bootloader on the target processor. This sets the fuses of the Atmega which define the clock frequency and other things.
According to https://arduino.stackexchange.com/questions/32191/do-we-need-to-burn-bootloader-in-new-atmega328p-before-uploading-the-arduino-cod (answered by per1234, Dec 12, 2016) :
Tools > Burn Bootloader in the Arduino IDE does two things:
- Set fuses according to the settings in boards.txt for the Tools > Board selection
- Install the bootloader.
The latter is pointless since when you do an Upload Using Programmer the bootloader will be overwritten but the former is very important to do the first time you use a new chip (or anytime you want to change the fuses) to be sure that the correct fuses are set, which likely will be different from the default settings of the chip when you get it. Upload Using Programmer does not set fuses, the only way to do this via the Arduino IDE is Tools > Burn Bootloader.
And a remark on that (by Majenko Dec 12, 2016):
he act of burning the bootloader doesn’t burn the fuses. They are actually a completely separate command that is executed in sequence with burning the bootloader. You do not need to burn the bootloader to set the fuses, you can do them separately. Burning the bootloader is an “easy” way of doing it, however you should really learn how to control the fuses properly if you are going to work with bare chips.
About fuses: see https://www.allaboutcircuits.com/projects/atmega328p-fuse-bits-and-an-external-crystal-oscillator/.
Why the 10uF capacitor is needed
Here’s a little history about the auto-reset system:
Originally, when the Arduino used the FT232, the DRT signal would reliably reset it automatically. The operating system (all operating systems) would automatically assert DTR when the port was opened, and all was well.
Then, out of the blue, and without telling anyone, Future Tech removed that auto-DTR asserting from the FT232 driver for Windows. Since Windows doesn’t control DTR for you, but leaves it up to the driver or the software (and all other operating systems automatically control DTR for you – Windows has to do the opposite of everyone else – it’s in their remit…!) all of a sudden the boards stopped resetting properly for programming.
So Arduino added specific reset code into the IDE to get around the problem (interestingly enough: if you watch the DTR pin on Linux you see it being asserted multiple times when programming – both the OS and the IDE are toggling it).
But then Arduino moved to the ATmega8U2 (and later the ATmega16U2) chip which uses the standard CDC/ACM instead of the custom FT232 driver. Now the auto DTR assertion was working again, but they kept the manual assertion in the IDE to cope with older boards in Windows.
I guess they didn’t put the DTR assertion workaround in the bootloader programming code since you don’t really want DTR asserted at that point anyway.
So if you have an FT232-based Arduino and are running Windows I guess there is no need for the capacitor, since DTR won’t be asserted by the OS.
However in Linux and OS X, regardless of the USB chip, you will need the capacitor, since it will always assert DTR.
But then along came China and threw the CH340G into the works. Now we have a third option, with dodgy drivers from who knows where. And who has the slightest clue what they do? Do they assert DTR for you? Your guess is as good as mine. If it doesn’t, then you won’t need the capacitor. If it does, then you will.
It’s all such a mess now thanks to too many options and combinations. It’s simpler just to have the capacitor regardless, since it won’t stop it working if it’s not actually needed in your specific configuration.
I’ve tested this on a Windows machine and on a Linux laptop (Debian). On Linux the capacitor was indeed necessary.