Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: periodic freeze with FastLED

  1. #1

    periodic freeze with FastLED

    I am working on a simple VU-meter with additional mic input (Karaoke).
    The bare audio works fine, but when I use FastLED I get a periodic freeze. Roughly every 30 seconds the Teensy stops, emitting a beep for 2 seconds and then continues (most of the time). Any hints are highly appreciated.


    This is my setup:
    Teensy 4.1,
    AudioShield for Teensy 4.0
    i2s1 input: Audio from PC
    i2s2 input: SPH0645 Microphone on pins 3, 4, 5
    Vol pot A1
    mic gain pot A17
    66 APA102 LEDs on Data pin 16, Clock pin 17


    CPU Speed: 150 MHz
    Optimize: faster

    Code:
    #include <FastLED.h>
    FASTLED_USING_NAMESPACE
    #define DATA_PIN    16          // green
    #define CLK_PIN     17          // yellow
    #define LED_TYPE    APA102
    //#define LED_TYPE    WS2812
    #define COLOR_ORDER BGR
    #define NUM_LEDS    66          
    CRGB leds[NUM_LEDS];
    #define BRIGHTNESS          16
    uint8_t H = 0; 
    uint8_t gHue = 0; // rotating "base color" used by many of the patterns
    
    
    /*
    xxxxxxxxxxxxxxxxxx|x|xxxxxxxxxxxxxxxxxx 
    1               18   20              37 
    
    
    xxxxxxxxxxxxxxxxxx|xx|xxxxxxxxxxxxxxxxxx 
    1               32    35              66 
    
    
    xxxxxxxxxxxxxxxxxx|xx|xxxxxxxxxxxxxxxxxx 
    1               71    74             144 
    */
    
    
    uint8_t startL  = NUM_LEDS/2 -1;          // automatic (if NUM_LEDs is an even number)
    uint8_t middle1 = NUM_LEDS/2;
    uint8_t middle2 = NUM_LEDS/2 +1;
    uint8_t startR  = NUM_LEDS/2 +2;
    
    
    /*
    uint8_t startL  = 32;
    uint8_t middle1 = 33;
    uint8_t middle2 = 34;
    uint8_t startR  = 35;
    */
    /*
    uint8_t startL  = 71;
    uint8_t middle1 = 72;
    uint8_t middle2 = 73;
    uint8_t startR  = 74;
    */
    /*
    uint8_t startL  = 18;
    uint8_t middle1 = 19;
    uint8_t middle2 = 19;
    uint8_t startR  = 20;
    */
    
    
    #define ARRAY_SIZE 16        // we have 2x 7 bands and 2 peaks
    uint8_t data[ARRAY_SIZE];    // read vector
    
    
    #include <Audio.h>
    //#include <Wire.h>
    //#include <SPI.h>
    //#include <SD.h>
    //#include <SerialFlash.h>
    
    
    const int myInput = AUDIO_INPUT_LINEIN;
    //const int myInput = AUDIO_INPUT_MIC;
    
    
    // GUItool: begin automatically generated code
    AudioInputI2S2           i2s2_Mic;         //xy=197,482
    AudioInputI2S            audioInput;     //xy=218,276
    AudioFilterStateVariable filter1;        //xy=329,486
    AudioAnalyzePeak         peak_R;         //xy=397,394
    AudioAnalyzePeak         peak_L;         //xy=402,179
    AudioAnalyzeFFT256       myFFT_R;        //xy=445,350
    AudioAnalyzeFFT256       myFFT_L;        //xy=457,225
    AudioAmplifier           amp1;           //xy=478,451
    AudioMixer4              mixerL;         //xy=699,255
    AudioMixer4              mixerR;         //xy=701,343
    AudioAnalyzeFFT256       mic_fft;        //xy=842,553
    AudioOutputI2S           audioOutput;    //xy=909,305
    AudioConnection          patchCord1(i2s2_Mic, 0, filter1, 0);
    AudioConnection          patchCord2(audioInput, 0, myFFT_L, 0);
    AudioConnection          patchCord3(audioInput, 0, peak_L, 0);
    AudioConnection          patchCord4(audioInput, 0, mixerL, 0);
    AudioConnection          patchCord5(audioInput, 1, myFFT_R, 0);
    AudioConnection          patchCord6(audioInput, 1, peak_R, 0);
    AudioConnection          patchCord7(audioInput, 1, mixerR, 0);
    AudioConnection          patchCord8(filter1, 2, amp1, 0);         // (filter1, [0 1 2], 0); for Low- Band- and High Pass filter 
    AudioConnection          patchCord9(amp1, mic_fft);
    AudioConnection          patchCord10(amp1, 0, mixerL, 1);
    AudioConnection          patchCord11(amp1, 0, mixerR, 1);
    AudioConnection          patchCord12(mixerL, 0, audioOutput, 0);
    AudioConnection          patchCord13(mixerR, 0, audioOutput, 1);
    AudioControlSGTL5000     sgtl5000_1;     //xy=421,554
    AudioControlSGTL5000     audioShield;    //xy=603,555
    // GUItool: end automatically generated code
    
    
      float level_L[7], level_R[7], level_mic[7];
      uint8_t i;
      uint8_t pegel_L[7], pegel_R[7], pegel_mic[7];
      elapsedMillis fps =0;
      uint16_t Bass, Mid, Trem, Bass_L, Mid_L, Trem_L, Bass_R, Mid_R, Trem_R;
      uint8_t  leftPeak, rightPeak, micPeak;
    
    
    
    
    void audioInputFFT() {
        if (myFFT_L.available() && myFFT_R.available()) {
        // 7 Bands @ 256 bins                      // one band is 172 Hz
        level_L[0] =  myFFT_L.read(0)*255;             // Bass  20 ..  150Hz = bin 0
        level_R[0] =  myFFT_R.read(0)*255;             
        level_L[1] =  myFFT_L.read(1, 2)*255;          // Mid  150 ..  2000Hz = bin 1..12
        level_R[1] =  myFFT_R.read(1, 2)*255;
        level_L[2] =  myFFT_L.read(3, 6)*255;
        level_R[2] =  myFFT_R.read(3, 6)*255;
        level_L[3] =  myFFT_L.read(7, 14)*255;
        level_R[3] =  myFFT_R.read(7, 14)*255;
        level_L[4] =  myFFT_L.read(15, 30)*255;        // Trem 2000 .. 20000Hz = bin 13 .. 122
        level_R[4] =  myFFT_R.read(15, 30)*255;
        level_L[5] =  myFFT_L.read(31, 61)*255;
        level_R[5] =  myFFT_R.read(21, 61)*255;
        level_L[6] =  myFFT_L.read(62, 122)*255;
        level_R[6] =  myFFT_R.read(62, 122)*255;
        
        for (i=0; i<7; i++) {
          pegel_L[i] = level_L[i];
          pegel_R[i] = level_R[i];
    //      Serial.print("L "); Serial.print(pegel_L[i]); Serial.print("\t");
    //      Serial.print("R "); Serial.print(pegel_R[i]); Serial.println("\t");
          } // end pegel
      } // end myFET
    }   // end audioInputFFT
    
    
    void micInputFFT() {
       if (mic_fft.available()) {
        level_mic[0] =  mic_fft.read(0)*255;                 
        level_mic[1] =  mic_fft.read(2, 3)*255;               // changed from (1, 3) to (2, 3)
        level_mic[2] =  mic_fft.read(4, 10)*255;
        level_mic[3] =  mic_fft.read(11, 28)*255;
        level_mic[4] =  mic_fft.read(29, 74)*255;
        level_mic[5] =  mic_fft.read(75, 195)*255;
        level_mic[6] =  mic_fft.read(196, 511)*255;   
    
    
          for (i=0; i<7; i++) {
          pegel_mic[i] = level_mic[i];
                  }   
       }
    }
    
    
    void add_mic() {
    // mic is mono, that's why we add the same value to L and R 
    delay(2);  
      level_L[0] =  level_L[0];
      level_R[0] =  level_R[0];
      level_L[1] = (level_L[1] + level_mic[1]);
      level_R[1] = (level_R[1] + level_mic[1]);
      level_L[2] = (level_L[2] + level_mic[2]);
      level_R[2] = (level_R[2] + level_mic[2]); 
      level_L[3] = (level_L[3] + level_mic[3]);
      level_R[3] = (level_R[3] + level_mic[3]); 
      level_L[4] = (level_L[4] + level_mic[4]);
      level_R[4] = (level_R[4] + level_mic[4]); 
      level_L[5] = (level_L[5] + level_mic[5]);
      level_R[5] = (level_R[5] + level_mic[5]); 
      level_L[6] = (level_L[6] + level_mic[6]);
      level_R[6] = (level_R[6] + level_mic[6]); 
    
    
        for (i=0; i<7; i++) {
          pegel_L[i] = level_L[i];
          pegel_R[i] = level_R[i];
        }
    //Serial.print(pegel_L[0]); Serial.print("  "); Serial.print(pegel_L[1]); Serial.print("  "); Serial.print(pegel_L[2]); Serial.print("  "); Serial.print(pegel_L[3]); Serial.print("  "); Serial.print(pegel_L[4]); Serial.print("  "); Serial.print(pegel_L[5]); Serial.print("  "); Serial.print(pegel_L[6]); Serial.println("  "); 
     }
    
    
    void combine2data(){
    data[0] = level_L[1];
    data[1] = level_L[2];
    data[2] = level_L[3];
    data[3] = level_L[4];
    data[4] = level_L[5];
    data[5] = level_L[6];
    data[6] = level_L[7];
    
    
    data[7] = level_R[1];
    data[8] = level_R[2];
    data[9] = level_R[3];
    data[10] = level_R[4];
    data[11] = level_R[5];
    data[12] = level_R[6];
    data[13] = level_R[7];
    
    
    data[14] = (data[0] + data[1] + data[2] +  data[3] +  data[4] +  data[5] +  data[6]) /8;
    data[15] = (data[7] + data[8] + data[9] + data[10] + data[11] + data[12] + data[13]) /8;
    
    
    // we have 66 LEDs in total, with 2 in the middle we have 32 on each side.
    // data is 0..255, that's why we divide the 
    
    
    //pegel_L = data[14];
    //pegel_R = data[15];
    //Serial.print(pegel_L); Serial.print("  "); Serial.println(pegel_L);
    
    
    //Serial.print(data[14]); Serial.print("  "); Serial.print(-data[15]); Serial.print("  "); Serial.print(data[15]-data[14]); Serial.print("  "); Serial.println(0);  
    //if ((data[14] > 250) || ((data[15]) > 250)) { Serial.print(data[14]); Serial.print("  "); Serial.print(-data[15]); Serial.println("  "); }
    // it looks like it never exceeds 255
    
    
    // we have 66 LEDs in total, with 2 in the middle we have 32 on each side.
    // data is 0..255, that's why we divide the value with 8
    uint8_t PEGEL_L = data[14];
    uint8_t PEGEL_R = data[15];
    //Serial.print(PEGEL_L); Serial.print("  "); Serial.print(-PEGEL_R); Serial.print("  "); Serial.println(0);
    //Serial.println(PEGEL_R - PEGEL_L); 
    }
    
    
    void SerialPlotOnMonitor(){
    // print data for serial plotter
    Serial.print(data[14]);                   // extract certain values out of the 14 bytes (here peak L and R)
    Serial.print(" ");
    Serial.print(-data[15]);                  // we only have two values. Let's make the right channel negative
    Serial.print(" ");       
    Serial.print(data[14] - data[15]);       // print the delta (wow !!)
    Serial.print(" ");
    Serial.print("0");                         // print the middle line ;)
    Serial.print(" ");
    Serial.println(); 
    }
    
    
    void VU_solid(){
    leds[middle1] = CRGB::White;                   // we do something with the intentional blank LED in the middle
    leds[middle2] = CRGB::White;
    for (uint8_t PEGEL_L = startL; PEGEL_L >= (startL - data[14]); PEGEL_L--) {     
      if (PEGEL_L <= 0) { PEGEL_L = 0; }
      leds[PEGEL_L] = CRGB::Blue;                 // left side is blue
    }
    for (uint8_t PEGEL_R = startR; PEGEL_R < (data[15] + startR); PEGEL_R++) {    //start with LEDno 20
      leds[PEGEL_R] = CRGB::Red;                  // right side is red
      FastLED.show();
      }
    }
    
    
    void colorCoolOff(){
      FastLED.delay(10);
      fadeToBlackBy( leds, NUM_LEDS, 20);        // higher values more hectic, lower values smoother
        FastLED.show();
    }
    
    
    void setup() {
      AudioMemory(15);        // determine value with AudioMemoryUsageMax(); 
      filter1.frequency(120); // filter out DC & extremely low frequencies  looks like we should use 90Hz as corner frequency @fft1024 and 120Hz @fft256
      amp1.gain(8.5);         // amplify sign to useful range
    
    
      audioShield.enable();
      audioShield.inputSelect(myInput);
    //  audioShield.volume(0.5);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.5);
      
      // Configure the window algorithm to use
      myFFT_L.windowFunction(AudioWindowHanning256);
      myFFT_R.windowFunction(AudioWindowHanning256);
      mic_fft.windowFunction(AudioWindowHanning256);
      //myFFT.windowFunction(NULL);
      FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
    //  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
      FastLED.setBrightness(BRIGHTNESS);  // set master brightness control
      FastLED.clear();
      FastLED.show();
    }
    
    
    void loop() {
    
    
    // reading the pots must be in the loop. Subroutine does not work
        float vol = analogRead(A1);     // read the shield's volume pot
        vol = vol / 1024;               // orig. setting but VERY loud, however good for cell phone input
    //    vol = vol / 1536;             // (1024 *3/2) is good for my headset
    //    Serial.println(vol);
        sgtl5000_1.volume(vol);         // write it out
    
    
        int mic = analogRead(A17);      // read the external mic pot (A17 is right next to Gnd)
        mic = mic / 100;                // this is a range of 0..10
    //  Serial.println(mic);
        amp1.gain(mic);                 // write it out
    
    
    audioInputFFT();
    micInputFFT();
    add_mic();
    combine2data();
    SerialPlotOnMonitor();
    VU_solid();
    colorCoolOff();
    delay(15);
    
    
    }  // end loop

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    469
    Probably a lack of power or of bulk decoupling on the LED supply - I make it 4A peak needed for 66 of
    those RGB leds, so the supply and decoupling needs to be up to the heavy load they pose and the
    rapid current fluctuation.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •