Foreword
I've recently been developing a few ESP8266 based IoT projects and found the core processor was struggling to carry out all the tasks I needed it to manage, so I decided to distribute some of the less important activities to a different microcontroller(s) in this way freeing up the ESP8266 to get on with its job of being an IoT device.
Given I wanted to publish my project to as wide an audience as possible I opted to use the Arduino IDE as the development platform of choice since it has such a widely supported community.
Design Constraints
In order to provision a reasonable spread of target devices allowing for the selection of an appropriate microcontroller for the application at hand, I settled on the following Atmel parts; ATMega328P, ATTiny84 and ATTiny85. To limit the complexity of the necessary programmer I constrained the choice of clock to internal for all devices and 16MHz external for only the ATMega328P and ATTiny84.
What follows is a collection of notes on programming with the Arduino and a description of how I put together a simple Arduino Uno based programmer for these devices (Pics above).
.
What parts do I need?
To build the programmer you will require the following parts
.
What software do I need?
Arduino IDE 1.6.9
.
What skills do I need?
.
Topics covered
.
Disclaimer
As always, you use these instructions at your own risk and they come unsupported.
There are two methods available for programming Atmel microcontrollers;
The former method (1) directly programmes the microcontroller via the SPI interface after first putting the device into reset. Unless instructed otherwise a compiled executable source programme is written to the device incrementally into code memory from where it is executed at start up. There are many ISP devices capable of programming Atmel devices, a few of which being (pic 1); AVRISPmkII, Atmel-ICE, Olimex AVR-ISP-MK2, Olimex AVR-ISP500. Picture 2 shows how the ISP device connects to the ATMega328P (oddly marked ICSP) on the Arduino Uno R3 board (pic 3 gives the ISP pin out). It it also possible to programme an Atmel microcontroller via it's SPI interface using an Arduino Uno as ISP (picture 4), here the Uno is being used to programme an ATMega328P.
The latter method (2) uses a small code stub known as a 'bootloader' permanently resident in executable code memory (usually locked to prevent accidental overwriting pic 5). This code is executed first thing upon power up or device reset and allows the microcontroller to re-programme itself with new code received via one of its interfaces from a source external to itself. The bootloader method is used by the Arduino IDE to re-programme Arduinos mapped as a USB comm port on the PC (Or MAC, Linux box etc., pic 6) and in the case of the Arduino Uno communicates with the Atmel device via it's serial interface on IC Pins 2 and 3 of the ATMega328P. Also the Arduino Uno (with the ATMega328P micrcontroller removed) can be used to programme an ATMega328P via the bootloader method effectively acting as a USB to serial adapter device (pic 7).
What is a USB to serial adapter?
A USB to serial adapter is a piece of hardware which plugs into your PCs USB port and looks like a serial com port (a legacy from earlier times when computers used a serial communications standard known as EIA-232, V24 or RS232) allowing you to send and receive serial data at the same electrical levels of the microcontroller. When you Select Tools -> Port -> COMx from the Arduino IDE you are connecting/interfacing your PC to your Arduino.
A device like this is sometimes referred to as an FTDI (pic 8, which is actually a brand name) or CH340G etc. USB to serial on the Arduino uno is achieved via an ATMega16U2-MU(R) IC ZU4 as in the Arduino Schematic below.
.
For clarity picture 9 identifies the two Atmel devices and their respective ISP connectors on the Arduino Uno R3.
.
Note 1 : If you choose to go down the FTDI device route ensure you purchase from a reputable seller as there have been a lot of cheap counterfeit devices on the market which have failed upon application of a windows update.
Check out the Dave Jones EEVblog rant 'EEVblog #676 - RANT: FTDI Bricking Counterfeit Chips' below;
https://www.youtube.com/watch?v=eU66as4Bbds
Note 2: It is also advisable to place a 'sacrificial' USB hub between your PC and the target device just in case you short something out (better still use an isolation USB device.). You will thank me for this advice.
Note 3 : Unless otherwise stated for 'ATMega328P' read 'ATMega328P-PU'
So how come there are so many ways to programme the Arduino?
Ok, so by now you are probably wondering why there are so many different ways to programme an Arduino. Well I suspect for Massimo Banzi it was about flexibility/extensibility and reducing the entry point to get as big a following as possible.
Or to quote the Arduino Introduction;
Put simply, if you only want to go as far as programming the native Arduino (Uno, Due, Nano, MEGA etc.) you only require a little knowledge of programming, a computer and USB lead which will allow you to create many different projects and truly be a part of the maker community.
Alternatively if you want to take the next step and embed an Arduino device or you break your Arduino board microcontroller and it's not an SMT part all you need is a little knowledge of programming, electronics and an Arduino Uno and you can re-programme a replacement or alternatively programme a very wide range of Atmel devices, opening up far more opportunities to create outstanding projects.
And all of this without the need for expensive electronics kit.
However, if you are a serious embedded systems developer you will use 'Atmel Studio' and an ISP/JTAG as this will allow you to directly set device configuration fuses, debug your code on the microcontroller along with register interrogation, stack traces and breakpoints etc. none of which are available with the Arduino IDE.
So why choose ISP or Bootloading?
Ok, so assuming you are reading this Instructable because you are at the point where you want to embed an ATMEL device programmed via the Arduino IDE, how would you make this choice?
To be honest, in reality there's not much between them.
If you use the ISP method you will save yourself the memory space the bootloader occupies and the start up/reset time will be quicker as the Arduino/ATMEL device will execute your code 'right out of the blocks' and not pause looking for serial data from the PC to upload.
Depending on what circuit you are going to embed your design into you could also use either method, though you may need more than a passing knowledge of electronics to competently achieve this. In the case where microcontroller I/O count is an issue and start up speed/code space are not a major consideration, you may choose to use the bootloader as this method only uses three pins (less the Clock line) one fewer that the ISP method.
It also depends upon what development paradigm you adopt;
Or
Here the latter is a better development method and is faster (you also don't run the risk of getting an IC pin stuck in your 'finger') but requires a good knowledge of electronics.
My general preference where performance isn't an issue is to burn the bootloader and use a serial programmer with the ATMEL device in the target system and develop code with the Arduino IDE.
Now here's where it may get a little more confusing...
Bear in mind, if you want to programme a 'factory fresh' Atmel microcontroller via a bootloader you will first need to programme the bootloader code on to the device using the ISP method. Though you can purchase ATMega328P microcontrollers with the bootloader already programmed, however, they will cost more.
If you want to use the ISP method you should always programme your Arduino with the bootloader at least once. This is to ensure you set the specific device configuration fuses for that microcontroller. This instruction is slightly misleading given for the ATTiny85/84 burning the bootloader in fact only sets device configuration fuses.
.
Consequently this Instructable details how to programme an Atmel device using the ISP method as this gives the most flexibility for developing code for a given microcontroller.
.
By way of example I have included circuits for the ATMega328P depicting ISP and Serial programming configurations for both 16MHz external and 8MHz internal clocks (pics 1 and 2 above).
The circuit design above (pic 1) details the necessary system level connections to programme either the ATMega328P, ATTiny84 or ATTiny85 via the SPI interface as an ISP programmer (Arduino As ISP with 'ArduinoISP' code loaded on the Arduino Uno connected to the prototype shield).
Although it may not be obvious from the diagram, all circuitry can be placed on the Arduino Shield Prototyping board such that no modifications to the Arduino Uno are necessary meaning it can be re-purposed if required.
The heart of the circuit is the Arduino Uno R3 which when programmed with the Built In Examples sketch : ArduinoISP will generate the source signals with which to program the target devices.
LED_P (LED2) or programming LED will flash during the programme cycle of any chip.
LED (LED1) is connected to Arduino programmatic Digital Pin3 and can be used to test your device with the modified blink programme 'ATTiny84-85-ATMega328_Blink.ino'. Digital Pin3 was specifically chosen as it will work interchangeably with all three devices; ATTiny84, ATTiny85 & ATMega328, giving a good indication your set up is working correctly.
Note 1 : C6 10uF Electrolytic Capacitor must be placed near to the Arduino Reset pin where it enters the prototyping Shield. Without this capacitor the programming device will not work. This is because the Arduino IDE asserts the DTR line prior to programming the Arduino which engages the bootloader. (See PDF file below, specifically Pin 13 U3). By including this capacitor the programming Arduino Uno does not reset, executing it's code which forwards the compilation download from the Arduino IDE to the target device.
Note 2 : Ensure you use the stackable Arduino headers (F/M on top, M on the bottom) as they can come in useful if you accidentally programme any device with the wrong clock source.
Note 3 : Only 'ONE' Atmel device can be programmed at any one time.
Pictures 2 ... 4 show the various build states during construction of the programmer.
Pictures 5 ... 7 show how to wire up the ATMega328P, ATTiny84 and ATTiny85 for programming via SPI with breadboard.
.
There are two parts to establishing your Arduino ISP Programmer, these are as follows;
Preparing your Arduino Uno
This is a relatively simple procedure and is as follows;
Preparing your Arduino IDE
This is also a two part process, 'out of the box' the Arduino IDE will allow you to programme the ATMega328P as this is the microcontroller on the Arduino Uno R3, however as a default it is assumed a 16MHz external clock is used.
Hence part one will be to add the capability to programme this device to use the internal 8MHz clock and part two to add ATTiny functionality.
Part 1 : Adding ATMega328P 8MHz Internal clock capability to the Arduino IDE
Part 2 : Adding ATTiny capability to the Arduino IDE
I did some 'shopping around' and found the best ATTiny Core which suited my purposes was the ATTiny Core by Spence Konde (aka Dr. Azzy). It can be found here.
Full installation instructions for which are here, or as follows;
Via Board Manager Installation.
.
OK, so what have I got now?
Once you have completed the above using your Arduino IDE you will be able to programme the following (see pic 8);
.
Note : If the new boards manager entries are not available the in 'Boards Manager' you may need to restart the Arduino IDE. See here for boards manager bug.
If you have followed all the above steps then you are now ready to programme your target device with your new Arduino ISP Programmer.
If you remember in step 2, I mentioned that if you have a factory fresh ATMEL device you will need to download the bootloader at least once such that you set the device fuses, the description which follows will show you how to do this along with how to download your code directly via SPI.
In the case of the ATMega328P programming the bootloader with your Arduino ISP Programmer will allow you to actually bootload code, whereas for the ATTiny85 and ATtiny84 it just results in setting the micrcontroller fuses.
For the ATMega328P
Initial set up
Bootloader Download
ISP Code Download
.
For the ATTiny85
Initial set up
Bootloader Download (This action just sets the microcontroller fuses)
ISP Code Download
.
For the ATTiny84
Initial set up
Bootloader Download (This action just sets the micrcontroller fuses)
ISP Code Download
.
Can I test what I've just done?
Yes, using your ISP programming prototype shield just insert a microcontroller of choice; ATMega328P, ATtiny85 or ATtiny84 and download the code contained in 'ATTiny84-85-ATMega328_Blink.ino' below. If you are successful, led 1 (Red Led in my build) will flash once a second.
.
Note : The 'ATTiny84-85-ATMega328_Blink.ino' blink programme below, assumes Tools->Pin Mapping->Counter Clockwise (like ATTinyCore) for ATTiny84 programming.
As I mentioned in step 2 there are two ways to develop your code on an ATMEL device, namely;
If you follow these instructions you will be able to use both methods for the ATMega328P running either an internal 8MHz clock (remove C1, C2 and Q1) or 16MHz external clock. If you are a novice developer I would recommend using a bootloader as it will work the same as your Arduino if you connect it as in picture 1 above. However, for the ATTiny85 and ATTiny84 only the ISP method is available.
Consequently if using the ISP methodology you would typically;
For completeness I included pictures of the Arduino pin equivalencies when you programme a given device (pics 2 ... 4).
.
Note 1 : Actually there is a common third technique known as cross platform development not covered here. Here is an example Instructable where I use this approach.
Note 2 : When programming with the bootloader/Serial adaptor(FTDI) configuration select the following;
Here are some typical gotchas I came across when using this programming/development method.
I've been using this programming device reliably for some time now without any issues, given the initial design contrants the end result fit the bill very well. My only wish would be to have been able to use a bootloader for the ATTiny85/84 as this would have made things a lot easier during the code debug phase.
.
On a personal note I learned a great deal about the Arduino and it's community given I needed to wade through 'tonnes of guff' to get to the truth about programming the various devices in all their glory (you can see evidence of this by the sheer number of links in the reference section and I only just 'scratched the surface').
In completing my research I was totally flabbergasted at how well the various git hub forums are supported, kudos to Spence Konde that is one dedicated guy.
Also the degree of foresight the Arduino creators must have had to come up with such a flexible all encompassing design is truly impressive.
.
Finally
A word of advice. Watch out for cheap Chinese knock off parts. When purchasing the 28 Way ZIF DIP sockets I thought I was getting a great deal on some 'TEX TOOL' parts.
At least that's what they looked like from the EBAY listing, actually being titled as such.
"4pack 28pin ZIF socket for DIL ICs Textool 0.3" Zero Insertion Force narrow DIP"
However, once I took delivery it was then I found out they were in fact 'TFX TDOL' clearly a choice of text remarkably similar to 'TEX TOOL' along with the green molding (check out the pic above).
What was it UK trading standards say... 'If it sounds too good to be true, it usually is.'
If only I had listened, then maybe the locking lever would be still working after more than 10 uses.
What is Arduino?
Excellent source for bootloading the ATTiny85
Atmel Microcontroller Signature Bytes
Arduino Uno R3 cct
ISP source
Atmel AVR
ATTiny Core - 1634, x313, x4, x41, x5, x61, x7, x8 and 828 for Arduino 1.6.x, by Spence Konde, aka Dr. Azzy
High-Low tech ATTiny Core
Arduino Playground - ArduinoOnOtherAtmelChips : Unofficial listing of support for other Atmel chips in Arduino IDE
Using an Arduino as an AVR ISP (In-System Programmer)
Using an Arduino as an FTDI for bootloading
Open twice boards manager bug
Arduino bootloader details
Wikipedia reference to Arduino
Programming the bootloader at least once to programme the fuses
Arduino prototyping shield
USB to serial
Programming ATMega328P with Arduino Uno using internal clock
Arduino Uno Standalone
EEVblog #676 - RANT: FTDI Bricking Counterfeit Chips!
Building an Arduino on a Breadboard
How to burn 1Mhz & 8Mhz bootloader using Arduino IDE 1.6.5-r5
EIA-232, V24, RS232
Arduino Products
Atmel Studio
.