Teensy driving led strip crashes when adding audio

yoctoflop

New member
I've got a teensy 3.6 running a modified version of the "DemoReel100" example in the FastLED library, driving a strip of 150 WS2812B LEDs. When I attempt to add generated code from the teensy audio GUI webpage, it will run for a little bit. Once I go to a certain pattern ("sinelon") it just completely crashes once the lights hit the end.

main code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=583,367
AudioAnalyzeRMS          rms1;           //xy=865,387
AudioConnection          patchCord1(i2s1, 0, rms1, 0);
AudioControlSGTL5000     audioShield;     //xy=1047,245
// GUItool: end automatically generated code

#include "FastLED.h"

#define NUM_LEDS 150
#define BUTTON_PIN 4
#define FASTLED_ALLOW_INTERRUPTS 0

CRGB leds[NUM_LEDS];
uint8_t movement = 0;
uint8_t patternNumber = 0;
long lastDebounceTime = 0;
uint8_t ccc = 0;
int audio = 0;
int cylonNumber = 0;

void setup() {
  FastLED.addLeds<WS2812B, 3, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(96);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), nextPattern, FALLING);
}

typedef void (*funcptr[]) ();
funcptr patterns = {rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm, randomRainbow, randomRG, cylon, candyCane, snowFlake};

void loop() {
  patterns[patternNumber]();
  FastLED.show();
  FastLED.delay(1000 / 120);
  movement++;
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void nextPattern()
{
  if ((millis() - lastDebounceTime) > 300) {
    // add one to the current pattern number, and wrap around at the end
    patternNumber = (patternNumber + 1) % ARRAY_SIZE( patterns);
    lastDebounceTime = millis();
  }
}

patterns:
Code:
void rainbow() {
  fill_rainbow( leds, NUM_LEDS, movement, 2);
}

void rainbowWithGlitter()
{
  // built-in FastLED rainbow, plus some random sparkly glitter
  rainbow();
  addGlitter(80);
}

void confetti()
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, 10);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( movement + random8(64), 200, 255);
}

void sinelon()
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, 20);
  int pos = beatsin16(13, 0, NUM_LEDS);
  leds[pos] += CHSV( movement, 255, 192);
}

void bpm()
{
  // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
  uint8_t BeatsPerMinute = 62;
  CRGBPalette16 palette = PartyColors_p;
  uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
  for ( int i = 0; i < NUM_LEDS; i++) { //9948
    leds[i] = ColorFromPalette(palette, movement + (i * 2), beat - movement + (i * 10));
  }
}

void juggle() {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, 20);
  byte dothue = 0;
  for ( int i = 0; i < 8; i++) {
    leds[beatsin16(i + 7, 0, NUM_LEDS)] |= CHSV(dothue, 200, 255);
    dothue += 32;
  }
}

void randomRainbow()
{
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(random(0, 255), 255, 255);
  }
  delay(50);
}

void randomRG()
{
  if (random(0, 100) > 75) {
    leds[0] = CRGB(255, 0, 0);
  }
  else {
    leds[0] = CRGB(0, 255, 0);
  }
  for (int i = NUM_LEDS; i > 0; i--) {
    leds[i] = leds[i - 1];
  }
  delay(10);
}

void cylon() {
  leds[cylonNumber] = CHSV(cylonNumber % 255, 255, 255);
  delay(10);
  fadeToBlackBy( leds, NUM_LEDS, 20);
  cylonNumber++;
  if (cylonNumber > NUM_LEDS) {
    cylonNumber = 0;
  }
}

void candyCane() {
  if (ccc < 6) {
    leds[0] = CRGB(255, 0, 0);
  } else {
    leds[0] = CRGB(255, 255, 255);
  }
  if (ccc > 9) {
    ccc = 0;
  }
  ccc++;
  for (int i = NUM_LEDS; i > 0; i--) {
    leds[i] = leds[i - 1];
  }
  delay(10);
}

void snowFlake()
{
  fadeToBlackBy( leds, NUM_LEDS, 10);
  leds[random16(NUM_LEDS)] = CRGB(255, 255, 255);
  leds[random16(NUM_LEDS)] = CRGB(255, 255, 255);
  leds[random16(NUM_LEDS)] = CRGB(255, 255, 255);
}

////////////////////////////////////internal patterns////////////////////////////////////

void addGlitter( fract8 chanceOfGlitter)
{
  if ( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;
  }
}

Here's a video of the problem. https://www.youtube.com/watch?v=Fjx0_EUO4iI. You can see it hang at the end of the LED strip.
Does anyone know the cause of this?
 
Last edited:
Does the crash magically go away if you use a smaller number of LEDs that update in much less than 1 audio block time (2.9 ms)? Perhaps try only 20 or 40 LEDs, just as a simple test?

Of course also double check your power supply. But in the video I see all the LEDs on long before the problem happens, so power problems seem less likely in this case.
 
I think mlu got it. I was noticing weird variable corruption when I was printing some random variables to serial. It must have been writing to memory locations related to audio and crashing the teensy. Making sure that index NUM_LEDS was not being modified anywhere, and replacing it with NUM_LEDS-1 seems to have fixed the problem.
 
I am experiencing a similar issue. It does seem to have something to do with the audio. I was able to determine the hanging is inside of FastLED.show(); It seems to be random any only occurs when audio is playing. #define FASTLED_ALLOW_INTERRUPTS 0 does seem to change the behavior.

It also seems to happen when subsequent FastLED.show() calls are made too fast. I was able create a temporary work around by limiting the updates using something like the following. (TimerCounter is just set my millis somewhere else in the code)

if (TimerCounter - lastShow > 17) // temporary to prevent crash, limit to 60fps
{
FastLED.show();
lastShow = TimerCounter;
}
 
Last edited:
Back
Top