Anyone using the ATTiny85 chip with FastLED?

Anyone using the ATTiny85 chip with FastLED? And I am talking about just the ATTiny85 chip itself not part of a Gemma or Trinket board. I am having some strange issues with code that I have used that works in one situation but fails in another.

Example:

#include <FastLED.h>

#define DATA_PIN 0 // change to Pin 0 for ATTiny
#define NUM_LEDS 65

CRGB strip[NUM_LEDS];
byte mode;

void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(strip, NUM_LEDS); // setup the strip
mode = 0;
}

void loop() {
// Some example procedures showing how to display to the pixels:
switch (mode)
{
case 0:
colorWipe(0x7f0000, 50); // Red
colorWipe(0x7f7f00, 50); // Yellow
colorWipe(0x007f00, 50); // Green
colorWipe(0x007f7f, 50); // Cyan
colorWipe(0x00007f, 50); // Blue
colorWipe(0xff007f, 50); // Magenta
break;
case 1:
// Send a theater pixel chase in…
theaterChase(0x7f7f7f, 50); // White
theaterChase(0x7f0000, 50); // Red
theaterChase(0x007f00, 50); // Green
theaterChase(0x00007f, 50); // Blue
break;
case 2:
colorSnake(0x7f0000, 10, 50); // Red
colorSnake(0x7f7f00, 10, 50); // Yellow
colorSnake(0x007f00, 10, 50); // Green
colorSnake(0x007f7f, 10, 50); // Cyan
colorSnake(0x00007f, 10, 50); // Blue
colorSnake(0xff007f, 10, 50); // Magenta
break;
default:
mode = -1;
}
mode++;
}

void colorWipe(uint32_t c, uint8_t wait) {
for(int i=0; i<NUM_LEDS; i++) {
strip[i] = c;
FastLED.show();
delay(wait);
}
}

void colorSnake(uint32_t c, int length, uint8_t wait)
{
for(int i=0; i<NUM_LEDS+length; i++)
{
if (i < NUM_LEDS) {strip[i] = c;}
if (i-length >= 0) {strip[i-length] = 0;}
FastLED.show();
delay(wait);
}
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
int i, j, q;
for (j=0; j<10; j++) { //do 10 cycles of chasing
for (q=0; q < 3; q++) {
for (i=0; i < NUM_LEDS; i=i+3) {
strip[i+q] = c; //turn every third pixel on
}
FastLED.show();

  delay(wait);
 
  for (i=0; i < NUM_LEDS; i=i+3) {
    strip[i+q] = 0;        //turn every third pixel off
  }
}

}
}

When I upload this to my ATTiny85, it runs. The first batch of the colorWipe run. Then the theaterChase sequence. But after the last of theaterChase instead of the colorSnake excuting, the theaterChase repeats endlessly! If I just put the sequences in the loop() without the case statement they work without fail. If I remove the theaterChase sequences (jues comment them out but leave in the case), the colorSnake sequence runs fine. Now this sequence executes fine using the original NeoPixel library without fail. Since I converted it to use FastLED I have had problems.

Any ideas? I really want to use FastLED instead of NeoPixel. so I really need some help here.

Thanks!

Its because you are writing past the end of the LEDs array - when q is 1, and i is 64 you are going to write location 65 which likely is where the mode variable lives. You are setting that to 0, so when you exit the theater chase, mode will then get incremented to 1 and put you back into theater chase.

Also known as a buffer overflow :wink:

For a quick fix - change your inner inner loops in theaterChase to:

for(i = 0; (i+q) < NUN_LEDS; i=i+3)

(remember to change both of them!

You know what they say that two sets of eyes is better than one in progrsmming. LOL

Now that I see it it makes me wonder why this worked in the original code. Oh I bet there is an over/under flow check in the NeoPixel library. And if I change to order of my array and my mode it will not happen because even if it overwrites beyond it would not affect my globals.

Well I have to go back and verify all the code to make sure I am not overwriting past the end of my array.

Thanks for the second pair of eyes! And to think I used to do this professionally! LOL Well I used to be more vigilant. Time to put that back into practice.

I just moved before strip and it worked. But I know as a programmer that you should never allow access beyond the bounds of your array. This code came from the strandtest.ino from the examples for the NeoPixel library. I just made the changes to work with FastLED. I should have made sure that the routines were solid, but in all honesty I was lazy and they worked! LOL

I will be changing the code to make sure array bounds are not violated.

I hop my experience helps someone else out when they have a “strange” problem.

I am trying to get FastLED code running on a bare ATtiny85. Can you point me to the best info on this? Do you still have to perform some voodoo with the Trinket core? I can get things to compile for an Uno but I get errors if I try to compile for the ATtiny. Thanks for any help on this!

The only tiny officially supported by the library at the moment is the trinket/gemma.

Thanks Daniel- The FastLED benefits are great- It would be good to see simple support for the bare ATtinys at some point.

@Daniel_Kaye I have it working on a bare ATtiny85 and it is working great. You do have to have the support in the Arduino IDE. There is a package on GitHub that I have been using. I have been using my Arduino as an ISP Programmer. I have taken the NeoPixel strandtest and adapted it for use with FastLED. It is working. I set mine up to use pin 0 for the data but any will work. Make sure you burn the bootloader before you upload. This only has to be done once on a fresh chip. After that you can upload many times. I am still working on my setup to allow me to program it in circuit instead of pulling out the mc and plugging it into the programmer.

I can post my code if it helps. Let me know.

Hi Don- I use the AVRISP MKII programmer in circuit with the Arduino IDE for programming ATtinys and it works great. A few questions if you don’t mind:
Can you point me to the package on GitHub?
What board are you selecting under the Arduino IDE Board menu?
I am curious what you needed to adapt from the strand test example so yes it would be great to see your code. Thanks!

Hi Daniel,

I found which version of the ATTiny Core I am using which you can find here: GitHub - damellis/attiny: ATtiny microcontroller support for the Arduino IDE

The board I selected is ATtiny85 (Internal 8MHz clock). When using a new chip (and it does not hurt to do it anyway) burn the bootloader before uploading your sketch. This also sets the fuses.

Here is the modified NeoPixel strandtest sketch using FastLED and this one I used on my ATtiny85 using Pin 0 for data:

#include <FastLED.h>

#define DATA_PIN 0 // change to Pin 0 for ATTiny
#define NUM_LEDS 65

CRGB strip[NUM_LEDS];

void setup() {
//FastLED.addLeds<NEOPIXEL, DATA_PIN, RGB>(strip, NUM_LEDS); // setup the strip
FastLED.addLeds<WS2812, DATA_PIN, RGB>(strip, NUM_LEDS); // setup the strip
//fill_solid( &(strip[0]), NUM_LEDS /number of leds/, CRGB::Black ); // set them all to off
//FastLED.show(); // then display the strip
}

void loop() {
// Some example procedures showing how to display to the pixels:
colorWipe(CRGB::Red, 50); // Red
colorWipe(CRGB::Green, 50); // Green
colorWipe(CRGB::Blue, 50); // Blue
// Send a theater pixel chase in…
theaterChase(CRGB::White, 50); // White
theaterChase(CRGB::Red, 50); // Red
theaterChase(CRGB::Blue, 50); // Blue

rainbow(20);
rainbowCycle(20);
theaterChaseRainbow(50);
}

void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<NUM_LEDS; i++) {
strip[i] = c;
FastLED.show();
delay(wait);
}
}

void rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
for(i=0; i<NUM_LEDS; i++) {
strip[i].setHue((i+j) & 255);
}
FastLED.show();
delay(wait);
}
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< NUM_LEDS; i++) {
strip[i].setHue(((i * 256 / NUM_LEDS) + j) & 255);
}
FastLED.show();
delay(wait);
}
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
uint16_t i,j,q;
for (j=0; j<10; j++) { //do 10 cycles of chasing
for (q=0; q < 3; q++) {
for (i=0; i+q < NUM_LEDS; i=i+3) {
strip[i+q] = c; //turn every third pixel on
}
FastLED.show();

  delay(wait);
 
  for (i=0; i+q < NUM_LEDS; i=i+3) {
    strip[i+q] = 0;        //turn every third pixel off
  }
}

}
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
uint16_t i,j,q;
for (j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (q=0; q < 3; q++) {
for (i=0; i+q < NUM_LEDS; i=i+3) {
strip[i+q].setHue((i+j) % 255); //turn every third pixel on
}
FastLED.show();

  delay(wait);
 
  for (i=0; i+q < NUM_LEDS; i=i+3) {
    strip[i+q] = 0;        //turn every third pixel off
  }
}

}
}

Notice that I replaced the Wheel() function with setHue from the FastLED. Also note that the NeoPixel library automatically ignores out of bound array indexes so I had to add that in a couple of places. But other than those two things, the adaptation was fairly straight forward. Once you get the ATtiny Core installed (in the hardware folder) and you compile check without errors, you should be able to upload the sketch and it should do its thing.

Let me know how it goes. I will try to help you with any errors. It has been working for me without fail. The advantage of using a plain ATting85 over a Trinket/Gemma is you get 2.5K more programming space since there is no need for the bootloader. :slight_smile:

Oh one more thing I did and it drove me nuts. You should apply this fix: https://github.com/TCWORLD/ATTinyCore/tree/master/PCREL%20Patch%20for%20GCC

If you have any problems with uploading sketches greater than 4K on the ATtiny85, this will fix that. I think I installed the latest version of the AVR compiler which had this fix already. But this is easier. Hope this helps!

Really appreciate your help- I have been using the arduino-tiny core https://code.google.com/p/arduino-tiny/ successfully with the ATtiny85 and the adafruit library and have now looked at and tried to figure out how to install the damellis core to see if that is the problem but I am not sure I am installing it properly and I can’t find instructions on the install.

Here are the errors I get when I try to compile your example:

FastLED01.cpp.o: In function CLEDController& CFastLED::addLeds<WS2812, (unsigned char)0, (EOrder)10>(CRGB*, int, int)': /Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/FastLED.h:154: undefined reference to__cxa_guard_acquire’
/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/FastLED.h:154: undefined reference to __cxa_guard_release' FastLED01.cpp.o: In functionL_1431’:
/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:110: undefined reference to timer0_millis' /Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:110: undefined reference totimer0_millis’
/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:110: undefined reference to timer0_millis' /Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:110: undefined reference totimer0_millis’
/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:112: undefined reference to timer0_millis' FastLED01.cpp.o:/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/clockless_trinket.h:112: more undefined references totimer0_millis’ follow

Try the 3.1 branch - that at least gets rid of references to timer0_millis :slight_smile:

For the rest of your errors, try adding the following to the end of FastLED.cpp:

namespace __cxxabiv1
{
extern “C” void __cxa_pure_virtual (void) {}
/* guard variables */

/* The ABI requires a 64-bit type.  */
<i>_extension_</i> typedef int <i>_guard __attribute_</i>((mode(__DI__)));

extern "C" int __cxa_guard_acquire (__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);

extern "C" int __cxa_guard_acquire (__guard *g)
{
	return !*(char *)(g);
}

extern "C" void __cxa_guard_release (__guard *g)
{
	*(char *)g = 1;
}

extern "C" void __cxa_guard_abort (__guard *)
{

}

}

Thank you for pointing me to the 3.1 branch. All the timer0_millis errors have vanished. The FastLED.cpp file I installed as part of the newer branch appeared to already have the section above at the end before the #endif (or I am missing something?)

Just a few remaining errors:

FastLED01.cpp.o: In function CLEDController& CFastLED::addLeds<WS2812, (unsigned char)0, (EOrder)10>(CRGB*, int, int)': /Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/FastLED.h:172: undefined reference to __cxa_guard_acquire’
/Applications/Arduino.app/Contents/Resources/Java/libraries/FastLED/FastLED.h:172: undefined reference to `__cxa_guard_release’