Posted on

FastLED & ATtiny85

Disclaimer: There are numerous ways of programming any one of the many AVR families of ICs, including custom programmers made by many vendors as well as using another Arduino in ISP mode. What I will talk about here is how to use Atmel tools in conjunction with the Arduino IDE for programming an ATtiny85. This is not limited to just that specific AVR though. By installing different cores for the Arduino IDE, one can write code in the IDE, taking advantage of the various libraries available for it, and then use Atmel Studio to upload it to the AVR itself. A process that can also be achieved if one uses a regular Arduino in ISP mode. However, using Atmel Studio goes much further than that. Ultimately, one can write code in Atmel Studio for any one of the AVRs in the entire family of AVRs, something the Arduino IDE can not do. This is just scratching the surface of what one can do with Atmel Studio.

This will be a long post. You’ve been warned.

With the recent release of FastLED (formerly known as FastSPI_LED), support for Adafruit’s Trinket hardware was added. The Trinket runs on an ATtiny85 which is a small, 8-pin PDIP package, or even smaller MLF package (4mm x 4mm.) Ideal for those small projects where you don’t need a massive ATmega to run just a few random patterns on an LED string. Olimex has a similar product called the OLIMEX-85. While I don’t have a problem with either products, they’re both excellent platforms, I do tend to work with bare ICs in my designs. In this case, I could’ve wired one up with a USB connector and installed the bootloader and all, but not having one handy, I choose the “other path” which is what I will describe below. The end result is that you will end up with a programmed ATtiny85 without it needing a USB connection nor the bootloader, which takes up space anyway. The ATtiny85 only has 8K worth of Flash memory.

Let’s start with what I have available to me, and where you can get them should you want to do the same thing:

  • First things first, I work on a Windows 7 64-bit machine. If you’re on something else, you’re going to have to figure out a couple of things for yourself, though the overall process should be relatively the same.
  • Bare ATtiny85 PDIP ICs: Mouser: http://goo.gl/aLcxLB – Digi-Key: http://goo.gl/iRiRQm. I use the ATtiny85V because it can run on a lower voltage than its counterpart. You’ll also notice it’s a little bit more expensive. If you don’t need to run it on very low voltage, you can get the cheaper one.
  • AVRISP mkII: Mouser: http://goo.gl/okQJns – Digi-Key: http://goo.gl/dIqNNs. I discovered that my Olimex AVRISP500 does not support ATtinys, so I had to get the AVRISP mkII since I wanted to work with some of the AVRs from the tiny family.
  • Atmel Studio 6.1: Free download from Atmel’s web site: http://goo.gl/ZYD6e. Yes, it’s a free download. You’ll have to register with Atmel’s web site before you can download it, but that also gives you access to free samples, should you want to request some.
  • Arduino IDE 1.0.x: Free download from the Arduino web site: http://goo.gl/F3iH. Somewhat of a given … Do yourself a favor and stick with the 1.0.x version.

And then the usual bits and pieces, a single 10K Ohms resistor, a single 0.1uF decoupling capacitor for the IC itself and I always use a big 1000uF capacitor for the LED strip I’m going to use, a breadboard, jumper wires, the LED strip itself which in my case is a 48 pixels per meter LPD8806 strip. Lastly you’ll need a 5V source and I use an old computer power supply for that. It outputs 30A on the 5V rail so that’s plenty to run a few meters of strip (500 pixels max, with no room for anything else.)

Since we know that FastLED will work with the Trinket, we need to grab the core files for the Trinket; the Arduino IDE does not have them. There are two ways of doing this and Adafruit would tell you ‘the fast way or the slow way‘. Since I have several other core files, I didn’t want to take Adafruit’s easy way, I didn’t want to end up with yet another copy of the IDE. But you certainly can. Either way, the instructions are all posted with the appropriate links to the various downloads. (http://goo.gl/4idT0F) As of today, 01/25/2014, there’s an error on the page regarding the installation of the linker file. It needs to go inside of the hardware\tools\avr\avr\bin folder – notice ‘avr’ listed twice in that path! I already sent them a note about it. Assuming you followed the instructions, you now have the core files for the Trinket installed in your Arduino IDE.

Now comes the fun part. The way you wire up the IC is very straight forward. You can follow its datasheet from Atmel’s web site. NOTE: I always save local copies of the datasheets so I don’t have to constantly go back to the manufacturer’s web site to look it up.

ATtiny85 Hookup

Put an 0.1uF decoupling capacitor across VCC and GND and a 10K Ohms pull-up on the RESET line to avoid it from floating. The other pins that I labeled are the MOSI, MISO, and SCK pins which is what you are going to connect the AVRISP mkII programmer to. The programmer comes with a 6-pin ribbon cable and the layout of those pins are:

ISP Connector

You’re going to connect all six of those pins to the matching pins on the ATtiny85. I use jumper wires for this: plug one end into the respective hole on the plug, and plug the other end into the breadboard.

You MUST supply an external voltage to the AVR. The programmer does not do this. All it does is read the voltage being supplied. So make sure you do that otherwise you will run into errors later. NOTE: I always use the same exact color wires for the same signals, so SCK is always going to be green, RESET is always white, etc., etc. Easy to remember as I tend to leave them plugged in to the programmer’s plug, and when I’m building several bare ICs on breadboards, I leave the wires there too, so it’s just a matter of matching up colors.

Next step is to open the Arduino IDE and load up a test sketch, or write one. First thing you need to do is pick the proper board once the IDE is up. I choose the 16MHz version for this example:

Arduino IDE

 

Why would one pick the 16MHz versus the 8MHz? That has to do with voltage. Page 168 of the datasheets gives us the following speed vs voltage ramps:

Speed Ramp

 

What this tells us is, the faster you want it to work, the more voltage you need to apply. And since I know my external power supply is feeding 5V, I can safely push it to 16MHz, however if you are only going to be working with 3.3V or lower, then pick the 8MHz option.

Next, either open one of the FastLED examples, or just write something to test out a string. If you decide to use one of the examples, make sure you adjust it to your specific setup, your LED strip type and which GPIO pins you’re using. I choose to first try the Blink example but honestly, it’s kinda boring (nothing against Daniel Garcia nor Mark Kriegsman.) So I quickly wrote a color cycle for the full strip:

#include "FastLED.h"

#define NUM_LEDS 48
#define DATA_PIN 0
#define CLOCK_PIN 2

CRGB leds[NUM_LEDS];

void setup()
  {
    FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, BRG>(leds, NUM_LEDS);
  }

void loop()
  {
    static uint8_t hue = 0;
    for (int px = NUM_LEDS - 1; px > 0; px--)
      {
        leds[px] = leds[px - 1];
      }
    leds[0] = CHSV(hue++, 255, 255);
    FastLED.show();
    delay(10);
  }

As you can see, I have the DATA_PIN defined as pin 0 and the CLOCK_PIN defined as 2. Frankly, they can be any of the GPIO pins, but I choose those two because they coincide with the ATtiny85’s MOSI and SCK pins. And the pin numbering comes from the way Adafruit created the core for this specific AVR. You can read more about the GPIO pins on their web site. (http://goo.gl/rT2yPP)

Once you have your code in, whether it’s a library example, or you wrote your own, click on the Compile icon in the IDE. Do not click on the Upload icon as that will try to upload code to a non-existing Trinket. All you want to do here is compile the code, nothing else. First to make sure there are no errors in your program and second because you need the final HEX file that it generates. We’re not using the Arduino IDE to upload to the ATtiny85.

Next step is opening Atmel Studio 6.1 (hereafter referred to as AS6.1). If you’ve never used it before, it may seem kinda daunting to look at the welcome screen. All we care about is it’s Device Programming method for now. Click on Tools and select Device Programming. A new window should pop up. Make sure you have your AVRISP mkII already plugged in to a USB port (you may have had to go through a driver installation process when you did that, I don’t remember.) If your programmer is not plugged in, the window will be devoid of information, the drop down will be empty and there’s nothing for you to do. If your programmer is plugged in, you’ll be able to see all the AVRs listed under the drop down menu. Under Tool, make sure you’ve selected the AVRISP mkII if it’s not already selected for you. Under Device, select the ATtiny85, and under Interface, pick ISP and hit the Apply button. It should now refresh the lower part of the window with more options:

Device-Programming

To the right of those options, you should click on the Read button to verify the programmer can actually read the AVR. At this point, if there’s a problem, it will give you an error message. Unfortunately, the error will simply tell you to check your wires. More often than not, that is the problem, your wires are reversed or just not connected correctly. Verify them and try reading again. If all is well, it will pop up both the Device Signature as well as the measured voltage. If for example you forgot to supply an external voltage to the AVR, you’ll get an error message telling you that the measured voltage is outside of the 0V-5.5V range required. You can probably guess how I know this … With everything working properly, the Device Signature should read 0x1E930B and the Target Voltage should be at or near the 5V that you’re supplying.

First, we need to set the correct fuses. Remember where you installed the Adafruit core files for the Trinket? Go back to that folder and find the boards.txt file. In my case, they reside in hardware\trinket\ because I renamed the folder. If you didn’t, it should be under hardware\attiny\ instead. Inside of that folder, you should find a boards.txt file. Open it. NOTE: Opening this file in Notepad won’t work because of the way the file gets translated. I recommend using Wordpad instead.

You’ll notice three distinct blocks of text in the file: gemma, trinket3, and trinket5. We’re only working with the Trinket here, and since I specifically picked the 16MHz version in the IDE, I’ll focus on the trinket5 block of text. Obviously if you picked the 8MHz version, you’ll be reading the trinket3 block of text. The lines of interest here are the fuses:

trinket5.bootloader.low_fuses=0xF1
trinket5.bootloader.high_fuses=0xD5
trinket5.bootloader.extended_fuses=0xFE

You’ll need those values for the three sets of fuses. Back in AS6.1, in the Device Programming window, on the left hand side, click on the Fuses option. Ignore the check boxes, just enter the values on the bottom half of the screen, matching what the boards.txt file told you, hit the Program button and watch the output:

Device-Programming-02

Hopefully it will program the registers and you’ll get an OK back. Now move up to the Memories option. This is where we are finally going to upload the code that you compiled in the Arduino IDE earlier. Where it says Flash (8KB), below that there’s a blank field with a browse button at the far right. It just has three dots on it. Click on that. Now for a neat trick: when you’re working with the Arduino IDE, it will always compile files in the Windows environment temp folder, always. And it will always have some obscure name. So how do you find your compiled program? Easy, use a variable that’s defined within the Windows environment. When you click on the browse button, a standard browse window pops up. At the top, in the address bar, type the following ‘%temp%‘ (without the ‘s) and hit return. It should’ve refreshed the window straight into the Windows temp folder. Tadaa! Now, if you sort the right panel by date, the last Arduino build folder should pop up at the top:

temp

Sorry, I have to blur things out. You know, NSA and all. 🙂 Anyway, dive into that build folder and you should see a HEX file. If you didn’t save your sketch in the Arduino IDE, the file name will be the current date. For example, in my case it’s called sketch_jan25a.cpp.hex. Select that file and click Open (bottom of the window.) Now all that’s left to do is click on the Program button in AS6.1 Device Programming window and watch the output again:

Device-Programming-03

And if you didn’t get an error, congratulations, you just programmed the ATtiny85! Grab a glass of wine … OH WAIT, the actual LED strip! How to connect that?

Remember my code specifies the DATA_PIN as 0 and CLOCK_PIN as 2? Following Adafruit’s pinouts, that coincides with the MOSI and SCK pins on the ATtiny85. So, for my LPD8806, the data pin goes to pin 0 and the clock pin to pin 2 on the AVR. Connect VCC and GND to the strip. I also connect a 1000uF capacitor across the VCC and GND. You can go ahead and disconnect the programmer because you don’t need it to run anything, or you can leave it connected if you’re going to be actively developing and re-uploading code. At this point your strip should be doing a pretty color cycle, assuming you used the code I posted above. NOTE: If you left the programmer connected, maybe because you plan on coding some more, be aware that when you power cycle the ATtiny85, the programmer will cause a subsequent reset to follow. So while your sketch will almost instantly start running when power gets reapplied, the programmer will reset it about a second or so later. This is expected behaviour. Don’t get caught up in it thinking something’s wrong with your code. If you’re not sure, just disconnect it entirely from the circuit.

Congratulations! You did it! Sit back and enjoy that glass of wine.

Now, you may wonder, why go through all this trouble when you can just as easy buy a Trinket from Adafruit and use it with the USB connector. After all they’re pretty cheap at less than $8 plus a couple more for shipping. Well, that’s certainly a possibility. In my case, I design and build custom boards. I also like having all of the memory available as opposed to having the bootloader take up part of that. In a minimalist design, all I would need is the ATtiny85 (which I would use in either the SOIC or MLF packages), a decoupling capacitor and pull-up resistor and pads or mounting holes for the programmer. Adding a strip would mean adding a single 1000uF capacitor (some folks don’t bother with this either, your mileage may vary) and a row of mounting holes to go with it. Add a button and a power LED and that’s it! That’s a pretty tiny design, much smaller than the Trinket, 10mm x 23mm (at current design.) Especially since it’s specifically designed to drive an LED strip, I don’t need the additional breakout pins nor mounting holes that the Trinket offers. And I also don’t need the bootloader installed, which saves ~2.75K on memory.

So there you have it. Take it or leave it. This is by no means my final word. It’s simply another method of programming an ATtiny85 to work with FastLED. Should you do this or buy a Trinket? That’s 100% entirely up to you. If you don’t want to, or can’t do what I did here, then I would highly recommend you get a Trinket (or equivalent.) They’re really nice, robust, and will have more options available for you. Chances are I will get one myself just to play with and add to my collection. On the other hand, if you want to do some hardware tinkering, let me know how it goes for you!