GyroGearloose
Member
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
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