For the QLF project, I had to get my code onto an ATTINY 45, which wasn’t so difficult, but also to free up the RESET pin to act as a digital output, which a bit more doing.
My experience with microcontrollers, aside from some PIC activity a decade ago, has been confined to the Arduino, a prototyping platform that hides some of the complexity of creating projects built around some popular Atmel microcontrollers. There are many tools for developing code, transferring code to these chips, and setting the fuse options on these chips, but all I had on hand was my trusty Arduino, so I used it as a middleman to program the ATTINY 45. There are plenty of other options available to get the compiled code (a hex file) into the flash memory of the chip, for example, the USBtiny or the tiny AVR, or the over-the-top Atmel STK600 programmers.
While the ATTINY45’s were on order, I worked out the code using the Arduino itself – this is, after all, its job in life: to serve as a rapid prototyping platform. The circuit was laid out on a solderless prototyping board and jumped over to the Arduino for testing. I realized that I’d need to change some of the pins later, but otherwise the code within the Arduino IDE is the same, whether developing for the ATmega328 on my Arduino Duemilanove or for the ATTINY. There may be differences in the way the code compiles for the different chips, but all that is abstracted away.
With all of the code working when tethered for life support to the Arduino, I needed to migrate it over to ATTINY 45. I found instructions on how to use the Arduino as an in-system programmer (ISP) and how to connect it to the ATTINY on the High-Low Tech website. Their procedure worked for, using my Duemilanove board and version 1.0.1 of the Arduino environment. However, I have a couple comments on their recommended procedure — I didn’t see a place on their website to provide feedback, but it is possible that they’ll have corrected these items in the future:
1. The general idea of connecting the “ISP header” from the Arduino over to a target can be used to program a number of chips, including the ATTINY. The idea is to connect power, ground, MISO, MOSI, SCK, and RESET from one chip to the other. MOSI goes to MOSI, MISO goes to MISO (rather than crossed wiring). The picture shown on the instruction page is correct, but the pin numbering for the ATTINY described below the picture isn’t. It should read:
- ATtiny Pin 7 to Arduino digital output 13, physical pin 19 (or SCK of another programmer.
- ATtiny Pin 6 to Arduino digital output 12, physical pin 18 (or MISO of another programmer)
- ATtiny Pin 5 to Arduino digital output 11, physical pin 17 (or MOSI of another programmer)
- ATtiny Reset Pin (1) to Arduino digital output 16, physical pin 16 (or RESET of another programmer)
2. That tutorial recommends installing ATTINY-specific definition files into the Arduino IDE, and points towards a file found on github, https://github.com/damellis/attiny/. This file provides a mapping of the pins on the ATTINYx5. A number of basic arduino functions like the ability read and write to pins will work on the ATTINY, but not the tone() function. Instead of using installing the file from github, I found another core on Google Code, arduino-tiny. This provides not just a pin definition, but a number of libraries like serial, wire, and the tone function that I needed.
3. The 10uF capacitor shown in the picture will not be needed for all versions of arduino; having it probably doesn’t hurt anything, though.
So, to reiterate the main points of that tutorial, the major steps are:
- Write code for the ATTINY. Make sure it compiles. Save it.
- Close the arduino IDE, add the core definition files to the hardware subdirectory, relaunch the IDE.
- Upload the “Arduino as ISP” sketch to the Arduino. This comes with the Arduino distribution.
- Connect the Arduino to the ATTINY — six wires.
- Select the ATTINY from the “Boards” menu.
- Select “Arduino as ISP” from the “Programmer” menu. No change to the serial port settings, please.
- By default, without an external clock, the ATTINY will run at 1 Mhz. To get it run faster, make sure that 8Mhz is selected in the board menu, and choose the “burn bootloader” option. It doesn’t really burn a bootloader, but it does set the fuses appropriately in the ATTINY. This operation also wipes out the flash memory in the ATTINY.
- Load ATTINY code that you want transferred.
- Hit “upload”. The code should transit the Arduino and end up in the ATTINY.
If you want to modify the code, no problem – just edit and upload again.
Physical pin 1 of the ATTINY is typically used for RESET, but to use it for I/O, bit 7 of the high fuse (RSTDISBL) has to be set. Once this happens, the chip cannot be reprogrammed by the ISP method described above — it essentially becomes read-only, unless the chip is restored using a high-voltage programmer – an item that I don’t have on hand (although one can be made with some common parts thanks to various plans online plans). Once I was sure that the program behaved as desired, I looked for a way to manually set the fuses (short of using avrdude from the command line — I’m not quite there).
I came across a program called “hexloader” that can both upload hex files and set fuses without requiring anything beyond an Arduino in terms of equipment. Unless you modify the hexloader sketch, by default it uses other pins to connect to the ATTINY. Arduino digital pins 4, 5, 6, and 7 connect to ATTINY physical pins 7, 1, 6, and 5, respectively. Refer to the picture on the gammon.co.au website.
To change the fuse settings on the ATTINY, open the serial monitor and make sure that the line termination character is set to “newline”. Also, make sure that the serial speed matches up with the hexloader program. A menu will display in the serial monitor; choose “F” to access fuses. The low, high and extended fuse settings were 0x62, 0xDF, and 0xFF.
Adding a high bit in the 7th position to the high fuse, the desired high fuse setting is 0x5F. You could also consult an online fuse setting calculator to see what options are available.
Follow the menu settings to commit this change to the fuses. Once this is done, the hex loader program reports that it can no longer enter “program mode” — which makes sense, since the chip is no longer programmable.