Neopixels causing Teensy-LC to perpetually reboot

Status
Not open for further replies.

Pensive

Well-known member
Neopixels causing Teensy-LC to perpetually reboot (SOLVED)

Hi All

It doesn't matter if i use fastled or neopixel library, i've got the same problem with fastled palette, neopixel strandtest, no matter which one i choose; I previously had the last 15 of these neopixels wired up with a fairly heavy guage wire and they were rock solid. No resistors or capacitors - but it ran for an hour or so no problem. It wouldn't go above 128 brightness though, if i recall it hung and i assumed 128 was the max anyway. I guess not.

So my layout is - Neopixel data off pin 17, neopixel strand of 16 pixels with 5v power and ground coming form the USB cable, which in turn goes into a usb socket-tail and into the teensy.

Changes since it worked perfectly:
1) Added one more pixel (all of them are WS2812B),
2) joined the ground up with the ground pins of 16 buttons.
3) wired the run back through a 30cm ribbon cable (MUCH thinner gauge wire than the wire I was using before.)
4) Hot glued the neopixels in place
5) Soldered ribbon cable socket and ancillary bits back to the teensy on protoboard
6) soldered the reset pin from the teensy to the ribbon cable socket. This is currently unconnected to a switch.

I've checked continuity between all the pins, there are no unintentional joins.

Now they all light, and work briefly, before reboot takes place after 1 or 2 seconds at most. 4 second delay on init works.
While they do work - you get different colours on each LED so it can talk to them all briefly.

Measuring the 5v it goes up and down like a yo yo at the teensy-lc pins, as low as 3.8v and when it settles around 4.65volts it will run a little longer, and this usually occurs when i place the meter on the 5v and Ground on the Teensy.

So i tried power supply 2 with a new cable going straight into the teensy, to isolate the cable, power source, PC power supply etc. from being the cause.

ON power supply 2 - 1a 5v DC, with a different, 15cm usb cable straight into the teensy-lc, the voltage is more stable around 4.65 to 5.01. But it still reboots just the same, within a second or so.

The voltage is still fluctuating a bit, it stabilises once it's crashed.

I tried reducing the brightness to 32, it didn't make any difference, it doesn't appear to be current related in that respect.

I think the fluctating voltage is causing the Teensy to reboot. Is there anything i can do to fix this?
Anyone got any better ideas? I'll try an inline resistor?

The actual load is fairly low but perhaps there is some inrush issue or something.

Thanks in advance.

Please don't laugh at my prototype board :)

pics here:
image1.jpgimage2.jpgimage3.jpg
 
Last edited:
with the better power source, I'm getting a stable 5.2volts at the pins and 4.9v on the last neopixel, which is right through the cable run to the end.

It doesn't last long enough for me to measure the voltage on the data pin, which reads 0v once it has hung.

Two example bits of code below, i did re-order the fastled code to move some procedures around but it was working like this. The adafruit strandtest is vanilla apart from pin settings and led types.

Code:
#include <FastLED.h>

#define LED_PIN     17
#define NUM_LEDS    16
#define BRIGHTNESS  128
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];


#define UPDATES_PER_SECOND 100


// This example shows several ways to set up and use 'palettes' of colors
// with FastLED.
//
// These compact palettes provide an easy way to re-colorize your
// animation on the fly, quickly, easily, and with low overhead.
//
// USING palettes is MUCH simpler in practice than in theory, so first just
// run this sketch, and watch the pretty lights as you then read through
// the code.  Although this sketch has eight (or more) different color schemes,
// the entire sketch compiles down to about 6.5K on AVR.
//
// FastLED provides a few pre-configured color palettes, and makes it
// extremely easy to make up your own color schemes with palettes.
//
// Some notes on the more abstract 'theory and practice' of
// FastLED compact palettes are at the bottom of this file.






CRGBPalette16 currentPalette;
TBlendType    currentBlending;


extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;




void setup() {
    delay( 4000 ); // power-up safety delay
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    
    currentPalette = RainbowColors_p;
    currentBlending = LINEARBLEND;
}
void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
    
    for( int i = 0; i < NUM_LEDS; i++) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}












// There are several different palettes of colors demonstrated here.
//
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
//
// Additionally, you can manually define your own color palettes, or you can write
// code that creates color palettes on the fly.  All are shown here.




void SetupBlackAndWhiteStripedPalette()
{
    // 'black out' all 16 palette entries...
    fill_solid( currentPalette, 16, CRGB::Black);
    // and set every fourth one to white.
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
    
}


void SetupTotallyRandomPalette()
{
    for( int i = 0; i < 16; i++) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}


// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
    
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}
void ChangePalettePeriodically()
{
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;
    
    if( lastSecond != secondHand) {
        lastSecond = secondHand;
        if( secondHand ==  0)  { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
        if( secondHand == 10)  { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
        if( secondHand == 15)  { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
        if( secondHand == 20)  { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
        if( secondHand == 25)  { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
        if( secondHand == 30)  { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
        if( secondHand == 35)  { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
        if( secondHand == 40)  { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 45)  { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 50)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
        if( secondHand == 55)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
    }
}


// This function fills the palette with totally random colors.




// This function sets up a palette of black and white stripes,
// using code.  Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.










// This example shows how to set up a static color palette
// which is stored in PROGMEM (flash), which is almost always more
// plentiful than RAM.  A static PROGMEM palette like this
// takes up 64 bytes of flash.
const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
    CRGB::Red,
    CRGB::Gray, // 'white' is too bright compared to red and blue
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};




void loop()
{
    ChangePalettePeriodically();
    
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; /* motion speed */
    
    FillLEDsFromPaletteColors( startIndex);
    
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}




// Additionl notes on FastLED compact palettes:
//
// Normally, in computer graphics, the palette (or "color lookup table")
// has 256 entries, each containing a specific 24-bit RGB color.  You can then
// index into the color palette using a simple 8-bit (one byte) value.
// A 256-entry color palette takes up 768 bytes of RAM, which on Arduino
// is quite possibly "too many" bytes.
//
// FastLED does offer traditional 256-element palettes, for setups that
// can afford the 768-byte cost in RAM.
//
// However, FastLED also offers a compact alternative.  FastLED offers
// palettes that store 16 distinct entries, but can be accessed AS IF
// they actually have 256 entries; this is accomplished by interpolating
// between the 16 explicit entries to create fifteen intermediate palette
// entries between each pair.
//
// So for example, if you set the first two explicit entries of a compact 
// palette to Green (0,255,0) and Blue (0,0,255), and then retrieved 
// the first sixteen entries from the virtual palette (of 256), you'd get
// Green, followed by a smooth gradient from green-to-blue, and then Blue.


Code:
#include <Adafruit_NeoPixel.h>#ifdef __AVR__
  #include <avr/power.h>
#endif


#define PIN 17


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800);


// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.


void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code




  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}


void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  // Send a theater pixel chase in...
  theaterChase(strip.Color(127, 127, 127), 50); // White
  theaterChase(strip.Color(127, 0, 0), 50); // Red
  theaterChase(strip.Color(0, 0, 127), 50); // Blue


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


// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}


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


  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.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< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}


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


      delay(wait);


      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}


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


      delay(wait);


      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
 
Last edited:
From your initial description and number of Pixels I'd say you browned out the USB power with the LEDs, since Adafruit strand test goes straight to the bright colours, though 16 should have not been a problem,

http://softsolder.com/2015/11/27/neopixel-current-vs-arduino-power-supply-voltage/

Less clear why things are not working now you are using a wallwart, other than the possibility that something critical took a hit in the course of events.

I'm assuming you've already done so, but this may be a case where starting from 'blink' may be useful, and then try running code that just cycles one pixel on at a time, rather than the colour washes that strand test does.

For your eventual project would suggest some mid sized caps on the power rails to keep things stable, though still should have worked better than it is.
 
Try to use a Lithium battery if you couldn't afford/don't want extra power supplies.

I power all my kinds of LED toys/items/whatever,mostly with single(4.2V at full charged) lithium battery
and the controller with the same battery also (with ws2812 strips I actually used pro mini the most, but a few tries with teensy worked well)
my case I drive 72 WS2812(144 pixel per meter) with a arduino mini
in this case the micro controller had lower than 3.3V after regulated , would brown out when battery is driven to 3.4V( about 30% charge left)
or the voltage equal to battery if you skipped the power regulator, to pro mini/nano and other ATMEGA is fine and can work until the battery's done.

LC probably can take 4.2V fully charged battery as well.
but don't do this to teensy 3.1 or 3.2

the ws2812 can actually work down to 3V,where the battery is almost out of charge, the second case I drive the microcontroller(ATMEGA328, pro mini) with a power booster to 5V.
could work for 2 hours, with a 2000mAH battery
the strips were powered directly through battery

I guess you can do the same with teensy, with lithium powering the 5V booster for teensy(only for teensy, not LED strips), and the regulator on teensy could supply 3.3V voltage for stable signal.

-----
[edited]

did you said your LED blacks out? or stucked in bright colors?
if the former, it might be some place shorted that drained the power,
power insufficient problem usually occurs with the ws2812 LEDS stuck in bright color, remaining unchanged.

and please add serial.print("what ever you like") in your code loop to debug
to see if its the micro controller that's rebooting, if serial stops when crashes. or continues when the leds went wrong.

mostly my bug with FASTLED disappears after I use my lithium battery
in one rare case I tried the same items at another room, and it works, might be some sorcery to do with my phone.
 
Last edited:
For your eventual project would suggest some mid sized caps on the power rails to keep things stable, though still should have worked better than it is.

I didn't think they'd be necessary.

But they are.

I only had 220uF capacitors to hand (not really much of an electronics guy !!!), but i first added one, and suddenly it lasted around 3 seconds before hanging.
So I added another and it lasted 5 seconds.

I then added a third and it's been running for 5 minutes now, with the vanilla adafruit neopixel strandtest.
So it's stable with 660uF capacitor on the run.

so let this be a lesson to us all - be it 6, 16, or 60 neopixels, on USB, use a 1000uF capacitor!!!!!

But none of my pixels are burned =D YAY!!!!

Thanks for the help and just so you can all laugh at my terrible, terrible hack job (which will be fixed propoerly tomorrow!!), picture below of my "temporary fix".

thanks for the help, and always remember to RTFM, and then when you read it, DO WHAT IT SAYS!!!!

IMG_1908.jpg
 
did you said your LED blacks out? or stucked in bright colors?
if the former, it might be some place shorted that drained the power,
power insufficient problem usually occurs with the ws2812 LEDS stuck in bright color, remaining unchanged.

and please add serial.print("what ever you like") in your code loop to debug
to see if its the micro controller that's rebooting, if serial stops when crashes. or continues when the leds went wrong.

mostly my bug with FASTLED disappears after I use my lithium battery
in one rare case I tried the same items at another room, and it works, might be some sorcery to do with my phone.

The leds would light and then the board would totally freeze, and in many cases it would reset itself.

Basically the neopixels must have been pulling peaks of current at certain times which was starving the CPU, in some cases this cause a freeze, and it some cases it caused a reboot.

As you say, using a battery would solve this conundrum. but so does using a big ol' capacitor =D
 
I have to say, anyone who feels a little out of their depth with some of the electronics would do well to read this startlingly concise and understandable synopsis of circuit stability, and how you can get by without over-thinking it - by adafruit_support_mike.

https://forums.adafruit.com/viewtopic.php?f=47&t=39976#p200997


Addendum: it fixed the vanilla adafruit strandtest but fastled palette test is still cycling after a few seconds :-/
Fastled First light runs solid.

Defintiely getting there, it's clearly power issues.

I'll report back tomorrow once i've applied a nice fat 1000uF cap, and i'll put a resitor inline with the first pixel data pin as recommended as well.
 
Last edited:
I know i keep responding to my own thread but i keep finding titbits of info which might be useful to others;

Adafruit recommend between a 300 and 500 ohm resistor on the data pin of the first LED, between your board and the neopixel. (neopixel end, not board end).

and this is a detailed description of exactly why.

http://www.eetimes.com/author.asp?doc_id=1320518&page_number=2&piddl_msgpage=2#msgs


I've added a 470ohm resistor but it has not had any effect - at least I know my signal is probably a lot more stable than it was before.



I've done my calculations and it's possible the pixels could overload my board - i dont think this is the problem because 15 pixels worked fine, and at 60mA each peak, thats still 400mA higher than a standard USB socket.
With 16 pixels perhaps we are beginning to tip the balance, but reducing the brightness from 128 (50% - which should keep the current below 500mA peak anyway) down to 32, does not improve things, despite a theoretical peak of 120mA. So I dont think its current. I'll find out tomorrow.
 
Last edited:
@Pensive, I put your code on to my LC with 'neopixels', and as expected, it ran beautifully without resistor or cap on pin 17. I use a decent mA battery and a cut USB trace, and it runs for hours. full brightness. So, yep, give it plenty of juice, and USB supply isn't going to happen to any great extent.

Of course, best to put the resistor and cap in to save on burnt pixels, and I have had to resort to using the data to earth resistor also on one costume project as the pixels kept blowing (flora neopixels).
 
@Pensive, I put your code on to my LC with 'neopixels', and as expected, it ran beautifully without resistor or cap on pin 17. I use a decent mA battery and a cut USB trace, and it runs for hours. full brightness. So, yep, give it plenty of juice, and USB supply isn't going to happen to any great extent.

Of course, best to put the resistor and cap in to save on burnt pixels, and I have had to resort to using the data to earth resistor also on one costume project as the pixels kept blowing (flora neopixels).

can you tell me how many pixels please?

Using a battery is no good for me unfortunately. :-/

I'm making a usb midi device. I suppose it's conceivable I could add LiPo charger and use the battery on board as a massive capacitor / voltage stabiliser...adds a huge amount of cost / complexity / additional points of failure / maintenance issues / fire hazard and shipping devices with batteries can be more complicated to boot.

The whole point is you can just plug it into your laptop / ipad/ tablet / phone and it gets its power from there. I may need to resort to one of those leads which has two usb plugs on the end.

That being said modern devices are usually fitted with a high power socket like my telly is, for charging / connecting hard drives. perhaps this is a way forward. off to get the bigger capacitor in a minute.
 
I resoldered the Teensy LC VUSB pad trace and ran your first sketch again (the FastLed one, as i seem to have issues with adafruit sketches). This video might help. https://youtu.be/Oj9iOghkZSU

it might be that me using using an led strip is different to the power consumption you are seeing? BUT, this is the same as your original starting point, so perhaps n help to you at all...

EDIT - I am using a macbook pro mid 2012 spec, so USB3 i think, if that makes a difference
also typo fixed (desoldered changed to resoldered...
 
Last edited:
OK thank you mortonkopf!! that is most useful. It should be working, quite clearly.

I attached a 1000mF cap and it's still not stable.

I have a portable battery pack with a 2A usb output to try next, it's charging as we speak, and its enough to charge an ipad, so it should be plenty and shouldn't be phased by peak draw.

Gut feeling is pointing to the ribbon cable, and always was.

Failing that, in order of importance:

1) take neopixels off the ribbon cable and hardwire with nice thick cable. I now suspect the ribbon cable is creating resistance which increases exponentially during peak draw times, unnecessarily stressing the power source so much the volt drops at these times.
2) Change the first pixel in the run
3) change the slightly dim looking pixel (which was always dim and did not cause a problem in the previous configuration)
4) change the teensy. I have plenty of LCs in stock, this would allow me to eliminate the teensy from being the problem.
5) change to Teensy 3.2 and drop the voltage. This would give me more firepower and reduce power consumption, but i'd need to sort out a transformer circuit as the 3.3v pin won't be able to hack the neopixels. I would prefer to use a 3.2 anyway but wanted to run at 5v as recommended by Paul. If it wasnt a good idea, he wouldn't recommend it.

I'll post my findings when i get to the bottom of it.
 
Last edited:
If you can face cutting your wiring, I would have just the led string / strand connected in situ to the LC +ve -ve and pin 17, without anything else attached, just as a test. This would eliminate uncertainty, and allow a "current led setup" basic test.
 
Last edited:
Have done.

Used a whole new teensy to prove it - no cap at all, hardwired into pins with about 20cm of (Relatively) heavy guage wire and it all works perfectly off USB.
I confirmed with a counter printing to serial - the same sketch ran solidly for 15 minutes.

SO

it's either the ribbon, or the Teensy.

I'll wire it back in to the other teensy and answer that question later. I'm certain it is the ribbon.
 
It was the ribbon. the wire guage was too low resulting in a fluctuating voltage drop according to the load.

IT was only 15cm long so beware with your neopixels! use a decent bit of wire.

It worked without a cap when wired over a similiar length of wire, but with a heavier gauge.

I left a 220mF cap on the power pins for a little bit of balancing and protection, for good measure. Should be enough for 16 pixels.

I can now run at 255 brightness as well :)

thanks for your help everyone!!!

IMG_1910.jpg
 
Status
Not open for further replies.
Back
Top