It is already two years since my latest post in which I played with the idea of proposing some improvements for the ArduinoISP sample sketch. I finally decided to make some time for this so I can scrap it from my bucket list. See Arduino issues 3321 and 3500.
Two kind of changes are targeted: changes to make ArduinoISP run on more Arduino models and changes that improve reliability.
The reliability changes are rather trivial, but nevertheless effective. I have found that ArduinoISP in all its simplicity works quite well but that there are only a few small unfortunate problems that ruined the user experience for a lot of people and gave ArduinoISP its bad reputation. That is a pity because they are easy to fix.
Seen this reputation I found it a good idea to describe a hand full of use cases I collected for testing the improvements. For some of these use cases it even not commonly known that ArduinoISP can handle them. The idea is to run this test suite on a representative set of Arduino models, and on the three operating systems supported by the IDE. Hopefully such a test report will give people confidence that ArduinoISP works reliably and that they will give it a try.
Arduino Uno, Due, Zero, Mega, Leonardo and Duemilanove (as a representative for ftdi based boards).
A more universal wiring
The official ArduinoISP tutorial and a zillion of other ones on the web, show how to obtain the MOSI, MISO, and SCK signals from an Arduino UNO’s pins 11, 12 and 13.
On an UNO, this will still work with the new sketch. But I prefer a wiring that obtains these signals from the Arduino’s SPI pin header. The new sketch always uses digital pin 10 to reset the target. The advantage of this wiring is that it works without changes or jumpers, on the UNO, Leonardo, DUE, Mega…
… TODO: diagram here …
I built a simple ‘universal ArduinoISP shield’ according to this wiring. It made testing on the set of Arduino models more practical.
5V – 3V3
Be careful with 3V3 boards like the DUE or Zero. See also here.
To make no mistakes when testing with all these boards, I took this approach:
– I always power the targets only from the programming Arduino. (No usb cable or other power supply connected to the target…)
– On the ‘universal ArduinoISP shield’ described above, a jumper connects the IORef pin of the programming Arduino is to the power pin of the shield’s outgoing SPI header. (The jumper is always in place in these tests). This way the target is automatically powered with 3V3 when programmed from the Due and with 5V when prgrammed from e.g. The UNO. (Well, the Duemilanove has no IORef pin so there I need an extra wire to the 5V)
ArduinoISP works only if the serial port that is used to connect the PC (avrdude) with ArduinoISP, does not autoreset. This is certainly one of the unfortunate problems mentioned above that costed ArduinoISP its reputation.
The good news is that on the Leonardo, the Due and the Zero, nothing has to be done: on these boards ArduinoISP by default uses the native USB port. This port does not autoreset.
On UNO, Duemilanove, Mega,… autoreset has to be disabled.
All test cases are carried out using the Arduino IDE 1.6.5, but avrdude 6.1 was used instead of the one shipped with the IDE. See further why.
I used CodingBadly’s attiny core and DrAzzy’s core for the tests with the attiny 841.
ArduinoISP uses the STK500v1 protocol which works with 16bit address values. For the AVR’s flash such an address is the address of a two byte word. So without extra measures, the protocol can only program the first 128MB of flash.
However, avrdude 6.1 comes with some clever fixes that do make it possible to program high addresses with stk500v1. This makes it possible to e.g. reliably burn the bootloader of an atmega2560 using ArduinoISP. (The bootloader is at the end of its 256 KB flash).
On linux, the IDE uses a shell script: <arduino install dir>/hardware/tools/avr/bin/avrdude. You can make the IDE pick the avrdude installed on your system by changing following lines:
export LD_LIBRARY_PATH="`dirname "$0"`/../lib/" exec -a "$0" "`dirname "$0"`/avrdude_bin" "$@"
exec -a "avrdude" avrdude $@ -v
Most ditributions come with an older version, you’ll have to build avrdude 6.1 from code and install it.
The test suite
I keep the tests here.
1. No target connected.
If no target is connected, ArduinoISP, will read in all ones on its MISO line. So it reads a device signature of 0xffffff. But the protocol between avrdude an ArduinoISP should still be able to correctly convey this bogus signature to avrdude. So the latter should output the dreaded:
avrdude: Device signature = 0xffffff avrdude: Yikes! Invalid device signature
The programming mode led (green) should light up briefly. The error led (red) should stay dark.
Programming again, should give the same result every time.
2. Burn UNO bootloader
From the “Tools” menu in the IDE: select Arduino/Genuino UNO as Board, select “Arduino as ISP” as programmer, and execute “Burn bootloader”
3. Burn arduino mega bootloader (requires programming above 128KB)
Same as above but select “Arduino/Genuino Mega or Mega 2560” as board.
4. Program an attiny85
Compared to an atmega, an attiny requires a much slower SPI clock to be programmed. So this is a good test case for Arduino’s with a fast hardware SPI clock (the sketch will switch to bitbang spi on those Arduino’s).
The Chaucer4K sketch is used in this testcase, just to test with something bigger than a small led blink sketch.
Tools>Board: ATtiny85 @ 1 MHz (internal oscillator; BOD disabled)
Just use the upload button to upload the sketch. (this works if the target’s fuses already have the correct value)
5. Program an attiny841
This testcase was add because the attiny841 can be programmed with ArduinoISP but it is very slow. Actually it still has to be investigated why.
Tools>Board: ATtiny841 @ 8 MHz (internal oscillator; BOD disabled)
Just use the upload button to upload the sketch.
6. Program an at89s52
The improved ArduinoISP adds support for the at89s52. (Every once in a while a question about this pops up in the Arduino forum.)
For convenience, in the ArduinoISP-Tests repo, there is a makefile that compiles a blink and a knight-rider example using sdcc.
7. Chaucer115 to 1284p: Program a big (115KB) sketch into an atmega 1284p
Just to test with a larger image.
8. Chaucer115 to mega: Program a big (115KB) sketch into an arduino mega
Same test, different target.
9. LongStoryShort: Program above 128KB.
An alternative for testing high program addresses.
These tests were borrowed from optiboot’s test suite. To obtain some volume, these sketches dump the first part of knight’s tale on the serial port and blink some leds to indicate activity.
First part of the ‘Knight’s Tale’, the first tale of the ‘Canterbury Tales’ by Geoffrey Chaucer.