Simple Attiny programmer on Arduino

programmer1After I was really fed up always making the MOSI, MISO, Reset, SCK, Vcc and Ground connection with wires in order to program an Attiny85/45/13, I bought an USBASP programmer (real cheap).
Didn’t get that to work, always got the dreaded ‘Yikes, invalid device signature’ message, that is usually a sign of a bad connection. Couldn’t quickly locate it, maybe a rotten cable, but I didn’t want to lose more time so I put together a quick and simple Attiny programmer.

I know there are dozens of circuits and designs floating around on the internet, but I just never got around to actually making one, so if you are like me, this is just a little push to tell you to ‘just do it’ it takes maybe 10 minutes from scrap to programmer.

I got my inspiration from a Spanish site from a guy that inspired me to build my first Arduino, but when I checked there, the stripboard-illustrations of his programmer were gone.
No sweat, just simple to make one myself.
programmer2The idea is a little piece of stripboard that plugs in the necessary headers of the Arduino. A 20hole x 9 strips piece is enough, but I made that 22 holes, just to give a couple of small ‘wings’ to help me pull it out.
20×9 stripboard
male header 7 pins
male header 6 pins
2 LEDs
2 resistors 560-1k
1 electrolytic capacitor 10 uF (in fact I used a 33uF, that worked as well)
8 pins dil IC holder

The Arduino ISP offers 3 LEDs to keep track of status. I implemented 2: The heartbeat and the Error (D9 and D8). Adding the ‘Programming’ LED is a bit more of a hassle because that needs D7 which is just at the other side of the non standardized gap in the Arduino headers, But if you want you could add a slightly bend pin to slot into D7.
The board plugs in easily, but is not completely straight because of how the arduino headers line up, but it works great.

Just a word on the capacitor. In order to avoid that the Arduino will reset when the attiny program is uploaded, the reset pin must be kept high. there are two ways how that is usually done: a resistor (120 Ohm) to the Vcc or a capacitor (10uF) between earth and Reset. Both work well.
However, the capacitor is also the reason that you cannot upload the ArduinoISP program with the board inserted, so you have to pull it out. You could of course add a jumper to the board, or a small switch, to temporarily disconnect the capacitor

Make double sure and double check that you have not forgotten to make all of the necessary cuts in the stripboard. Check it after each cut, use a multimeter if necessary.
After you soldered it all up, check again that there are no stray connections or shorts. The reason for this is that you do not want to short any pins on your arduino or connect any pins to where they shouldn’t be connected. You do not want any of your Digital-Out pins to be connected to Ground when you pull them high.

Anyway, build it yesterday and works great. I have programmed more Attiny’s in half a day than I did in my life before.

For people that are new to programming an Attiny: The steps are as follows.
Make sure you have an Attiny core installed (There are many, try here or here , you also may want to check here)
Remove the programming board and upload the ‘ArduinoISP’ program to your Arduino.
Insert the program board and load the desired Attiny sketch.
Choose the proper Attiny setting under ‘Tools-Board’
Go to ‘File-Upload Using Programmer’ in older IDE-versions this might be just ‘Upload’
You may want to check here or here for more information on the programming.
important is to know that even with a succesful programming, you will get two error messages:
“avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny85”.
just ignore those messages.
If you are perfectionist, you can solve those error messages by edit file avrdude.conf, found in

programmer4programmer3(windows) C:\Program Files (x86)\arduino-1.0.6\hardware\tools\avr\etc
(Ubuntu) Home\Arduino-1.06\hardware\tools
Find the word Attiny85 and go down a few lines up to:

chip_erase_delay = 4500;
and add below these lines:
# Added to eliminate the bug to build.
pagel = 0xB3;
bs2 = 0xB4;
Find this section lower down and add the highlighted code:
memory “lock”
size = 1;
write = “1 0 1 0 1 1 0 0 1 1 1 x x x x x”,”x x x x x x x x 1 1 i i i i i i”;
read = “0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0″,”0 0 0 0 0 0 0 0 o o o o o o o o”;
min_write_delay = 9000;
max_write_delay = 9000;
Thanks baelza.bubba for putting me on track for that. If you have trouble understanding, check the two pictures. Understand that you dont HAVE to alter the file, it will all work. The alteration is just to get rid of the error messages.

Just a tip: when I was programming Attiny’s I used the setting for the 8MHz internal clock and found my timings to be far off. coincidence or not, it seemed they were a factor 8 off (slower). When I tried at 1 MHz, It all seemed OK again. This is caused by the following: The standard operating speed for the Attiny is 1Mhz, and it gets that by dividing the internal oscillator by 8. Where I presumed the 8MHz setting would set the proper fuses to tell the Attiny it shouldnt divide the internal oscillator anymore, it seems that it may not do that. The solution would be to first set the proper fuses by selecting ‘burn bootloader’ That doesnt burn the bootloader, but it does set the right fuses.

Just another tip: There are various Attiny cores and not all are full implementations. If you intend to use the ‘OneWire’ library, you may run into errors like :

/libraries/OneWire/OneWire.cpp:105: error: ‘digitalPinToBitMask’ was not declared in this scope
/libraries/OneWire/OneWire.cpp:106: error: ‘digitalPinToPort’ was not declared in this scope
/libraries/OneWire/OneWire.cpp:106: error: ‘portInputRegister’ was not declared in this scope

There is an easy fix for that:

• Locate and open OneWire.h
• Locate this section of code towards the top…

#if ARDUINO >= 100
#include “Arduino.h” // for delayMicroseconds, digitalPinToBitMask, etc
#else #include “WProgram.h” // for delayMicroseconds
#include “pins_arduino.h” // for digitalPinToBitMask, etc

• Change into:

#if ARDUINO >= 100
#include “Arduino.h” // for delayMicroseconds, digitalPinToBitMask, etc
#include “pins_arduino.h” // for digitalPinToBitMask, etc
#else #include “WProgram.h” // for delayMicroseconds
#include “pins_arduino.h” // for digitalPinToBitMask, etc

• Save and close OneWire.h

• No need to restart the Arduino IDE
The problem is not with the library but with the core. It is just easier to fix in the library

And yet another tip: If you are trying to use the Attiny with the LCD library from F. Malpertida, you may run in some error messages that have to do with the print.h and print.cpp files of the core.
These can be fixed. There are two publications on how to do that, but most likely, using the proper core will solve that without having to change anything.   Useful info also here.

15 thoughts on “Simple Attiny programmer on Arduino”

  1. I followed your tutorial and added a led from the tinys pin 4 with a resistor to ground (using blink d4 to test it quickly) and a switch between the cap and reset pins (as you explained to upload the isp conveniently).
    Uploading with the cap switched away works great, but when I try to upload something to the tiny I get:
    Sketch uses 386 bytes (37%) of program storage space. Maximum is 1,024 bytes.
    Global variables use 8 bytes of dynamic memory.
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

    Any thoughts?

    1. That usually means that there isnt a good connection. I am a bit puzzled by what you tell me about your uploading process. Why do you want to switch the cap away during uploading? That is exactly when you need it.
      What I tried to explain in the article is that you need a capacitor for the uploading (“programming”) but that you could switch the capacitor off (say with a jumper) in order to upload your ISP program to the UNO.
      Ofcourse when you then try to upload something into the Attiny, you need that capacitor again.
      So, for now I presume you did connect the capacitor again and then during programming you get the error. Basically it means there is no communication with your board. can be many causes. I am wondering if you do all the steps right, so I will just walk you through it:
      Remove the programming board
      Go to “Tools-Programmer-Arduino as ISP”
      Go to Examples and upload the Arduino as ISP sketch
      When that is done, insert the programmer board with a chip.
      Load the desired program in your IDE
      go to “Tools-Board-Attiny85” (or Attiny 13 or 24 or 45)
      Then go to “File-Upload Using Programmer”
      That should do it.
      Now you have added an LED with a resistor from d4 to ground on the programmer board right? D4 is pin 3. That is not used by the programmer so that should be OK.
      Let me know if this works

      1. I use this sketch:
        // Blink sketch to test ATtiny Chips

        // +-\/-+
        // ADC0 (D 5) PB5 1|* |8 Vcc
        // ADC3 (D 3) PB3 2| |7 PB2 (D 2) ADC1
        // ADC2 (D 4) PB4 3| |6 PB1 (D 1) PWM1
        // GND 4| |5 PB0 (D 0) PWM0
        // +—-+

        const int LED_PIN = 4; // digital pin
        const int DELAY_TIME = 1000; // time between blinks [ms]

        void setup() {
        pinMode(LED_PIN, OUTPUT);

        void loop() {
        digitalWrite(LED_PIN, LOW);
        digitalWrite(LED_PIN, HIGH);

        And upload just as explained. Sorry about the confusion with the cap. I meant the following: I switch away the cap, when uploading the ArduinoISP sketch to the UNO. Then I flip the switch so there is a cap between ground and reset. Then I choose ATtiny, Board ATtiny13, 9.6Mhz (internal) and “Arduino as ISP”. Then Upload using Programmer.
        I get no feedback, only done uploading and
        Sketch uses 386 bytes (37%) of program storage space. Maximum is 1,024 bytes.
        Global variables use 8 bytes of dynamic memory.

        After that the LED on pin 3 (digital 4) is high permanently. No switching off, no flashing.
        I rebuilt the wiring on a breadboard with exctly the same results.
        I’ve got a SE thread about that:

        Thanks for any suggestions and help!

      2. Please forget the comment below. I found the error of my board (a broken pin I didn’t check until the tip).
        However uploading a blink sketch gives no errors at all. And delay doesn’t work! I’m uploading with 9.6MHz (internal) oszillator. Burning a bootloader gives:
        “efuse” memory type not defined for part “ATtiny13”
        Error while burning bootloader.
        And a normal blink sketch does light the led permanently. With digitalWrite(LED,LOW), I can turn it off,… but delays in between take no effect at all!

    1. interesting boards.txt. I saw what I presume to be your question there. The new boards.txt you have indeed adds some extra possibilities. Yet, the boards.txt I describe works as I describe. I put them side by side and looked at the differences. Those are actually very minimal, apart from the fact yr new boards text adds a number of specific programming options, as well as a menu for GCC flags.
      The essential differences are:
      i set lock bits
      i have ‘build core’ defined as arduino instead of attiny13 (because I define that under the ‘variant core’. Change that though if you have an ‘efuse error’)
      i define the uploadprotocol as ArduinoISP rather than usbtiny
      So all in all it is a minimal difference
      I have no maximum data size defined.
      It is the same (Smeezekitty) core

      1. Yeah, I didn’t clean all the extra features like the compiler flags. And yes, changes are minimal! However your boards refused to upload anything (actually it looked like it did nothing at all with those settings, I have no idea what happened). I guess the main differences are the fuses and maybe the programmer (usbtiny).
        Just wanted to give a heads up to those having trouble. Maybe you delete some of my spam^^…

      2. still that is surprising as they work for me. I am sure it is a small difference in settings somewhere but I am happy it works for you. It is certainly not Spam, thanks for all the info

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.