Add files via upload

main
Mark Donners 2021-07-11 14:39:22 +02:00 zatwierdzone przez GitHub
rodzic 84aa514f4e
commit fb870e9043
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
9 zmienionych plików z 2248 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,135 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
// Depending on how many bands have been defined, one of these tables will contain the frequency
// cutoffs for that "size" of a spectrum display.
// Only one of the following should be 1, rest has to be 0
// WARNING amke sure your math add up.. if you select 24 bands on a 32 wide matrix....you'll need to adjust code
#define bands8 0
#define bands16 0
#define bands24 0
#define bands32 1
#define bands64 0
int CalibrationType=0; //0=none, 1=White, 2=Pink
char Filtername[4][6]={
"None", // see documentation on this one.
"Pink",
"White",
"Brown"
};
#if bands8
const int numBands = 8;
static int BandCutoffTable[8] =
{
20, 150, 400, 550, 675, 780, 900, 1200
};
static double BandCalibration_Pink[8]=
{ 4.08, 1.56, 1.00, 2.80, 3.23, 3.63, 6.19, 1.65 };
static double BandCalibration_White[8]=
{ 25.84, 3.43, 1.10, 2.95, 3.37, 3.39, 5.46, 1.00 };
static double BandCalibration_Brown[8]=
{ 2.72, 1.17, 1.00, 3.34, 4.83, 5.57, 11.18, 3.08 };
#endif
#if bands16
const int numBands = 16;
static int BandCutoffTable[16] =
{
40, 60, 100, 150, 250, 400, 650, 1000, 1600, 2500, 4000, 6250, 12000, 14000, 16000, 17000
};
static double BandCalibration_Pink[16]=
{ 4.52, 5.48, 5.54, 6.06, 2.98, 1.72, 1.49, 1.36, 1.00, 1.49, 2.04, 1.71, 2.19, 2.68, 1.85, 5.69 };
static double BandCalibration_White[16]=
{ 169.55, 148.58, 141.29, 124.24, 35.59, 10.76, 6.97, 5.18, 2.89, 4.19, 4.24, 1.99, 1.00, 1.60, 1.53, 5.48 };
static double BandCalibration_Brown[16]=
{ 1.81, 2.17, 2.49, 2.89, 1.57, 1.00, 1.10, 1.30, 1.22, 3.74, 113.96, 774.90, 7.76, 645.75, 2583.00, 7749.00 };
#endif
#if bands24
const int numBands = 24;
static int BandCutoffTable[24] =
{
40, 80, 150, 220, 270, 320, 380, 440, 540, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150,
3800, 4200, 4800, 5400, 6200, 7400, 12500
};
static double BandCalibration_Pink[24]=
{ 1.08, 1.19, 1.06, 1.21, 1.16, 1.09, 1.10, 1.15, 1.14, 1.31, 1.11, 1.05, 1.01, 1.00, 1.13, 1.34, 1.65, 1.68, 1.81, 1.78, 1.83, 2.02, 1.77, 1.18 };
static double BandCalibration_White[24]=
{ 152.55, 134.78, 38.14, 28.98, 103.60, 111.06, 102.83, 28.74, 29.98, 33.78, 12.07, 8.28, 6.79, 5.76, 7.29, 11.03, 13.72, 10.98, 14.86, 8.20, 9.17, 6.91, 3.95, 1.00 };
static double BandCalibration_Brown[24]=
{ 1.41, 1.61, 1.00, 1.30, 3.72, 4.18, 4.66, 2.20, 3.00, 3.46, 1.93, 1.93, 2.04, 2.33, 4.30, 16.74, 113.82, 626.00, 1043.33, 1565.00, 2086.67, 2086, 122.75, 2.86 };
#endif
int loopcounter=0;
double bndcounter[64];
#if bands32
const int numBands = 32;
static int BandCutoffTable[32] =
{
45, 90, 130, 180, 220, 260, 310, 350,
390, 440, 480, 525, 650, 825, 1000, 1300,
1600, 2050, 2500, 3000, 4000, 5125, 6250, 9125,
12000, 13000, 14000, 15000, 16000, 16500, 17000, 17500
};
static double BandCalibration_Pink[32]=
{ 1.17, 3.09, 3.07, 3.53, 3.95, 4.22, 4.43, 5.02, 5.59, 5.63, 6.27, 7.32, 1.90, 1.51, 1.66, 1.00, 1.31, 1.31, 2.58, 4.25, 1.78, 1.50, 2.75, 2.95, 2.34, 4.81, 2.41, 2.16, 2.08, 7.30, 9.01, 10.48 };
static double BandCalibration_White[32]=
{ 22.21, 65.51, 62.36, 60.53, 57.51, 52.28, 48.14, 49.53, 49.06, 50.49, 58.15, 60.89, 9.73, 6.36, 6.01, 3.17, 3.67, 3.59, 6.76, 9.03, 2.86, 1.91, 2.09, 1.16, 1.00, 2.08, 1.64, 1.62, 1.73, 4.89, 6.98, 9.08 };
static double BandCalibration_Brown[32]=
{ 1.00, 2.82, 3.26, 3.68, 4.21, 5.15, 5.57, 5.98, 7.06, 7.53, 9.94, 11.47, 3.22, 2.88, 3.53, 2.48, 3.88, 5.37, 43.13, 312.68, 224.49, 729.58, 2188.75, 2188.75, 12.35, 8755, 2188.75, 1250.71, 2918.33, 8755, 8755.00, 8755.00 };
#endif
#if bands64
const int numBands = 64;
static int BandCutoffTable[64] =
{
45, 90, 130, 180, 220, 260, 310, 350
, 390, 440, 480, 525, 565, 610, 650, 690
, 735, 780, 820, 875, 920, 950, 1000, 1050
, 1080, 1120, 1170, 1210, 1250, 1300, 1340, 1380
, 1430, 1470, 1510, 1560, 1616, 1767, 1932, 2113
, 2310, 2526, 2762, 3019, 3301, 3610, 3947, 4315
, 4718, 5159, 5640, 6167, 6743, 7372, 8061, 8813
, 9636, 10536, 11520, 12595, 13771, 15057, 16463, 18000
};
static double BandCalibration_Pink[64]=
{ 1.00, 3.16, 3.12, 3.46, 3.33, 3.56, 4.34, 4.29, 4.58, 5.75, 5.74, 6.64, 7.02, 7.22, 8.25, 8.69, 9.28, 9.65, 9.80, 10.24, 9.01, 10.62, 11.05, 10.71, 10.55, 11.31, 12.66, 11.77, 14.08,
16.30, 15.82, 15.28, 16.75, 20.22, 21.95, 19.97, 23.89, 2.97, 6.48, 4.28, 9.37, 9.71, 11.49, 12.89, 9.65, 10.46, 8.03, 5.54, 7.16, 7.42, 7.92, 8.76, 17.34, 8.32, 58.71, 194.92, 20.05, 168.03, 3.97, 2.78, 2.80, 1.65, 1.67, 2.69 };
static double BandCalibration_White[64]=
{ 20.92, 56.64, 53.90, 45.14, 40.24, 50.82, 42.75, 37.52, 41.75, 43.59, 46.32, 47.56, 49.68, 52.93, 51.11, 49.68, 57.37, 58.12, 52.31, 50.53, 49.96, 46.32, 45.84, 48.33, 49.41, 46.56,
47.56, 49.96, 53.90, 51.40, 61.76, 56.64, 58.51, 70.02, 71.72, 61.76, 77.33, 8.35, 17.20, 10.62, 25.41, 23.40, 19.63, 20.63, 14.87, 12.07, 8.42, 5.57, 5.71, 5.42, 5.28, 4.31, 4.19, 3.56, 5.19, 6.12, 4.32, 4.21, 2.07, 1.49, 1.24, 1.00, 1.08, 2.01 };
static double BandCalibration_Brown[64]=
{ 1.00, 2.71, 3.14, 3.83, 4.34, 4.98, 5.41, 6.29, 8.09, 9.41, 10.43, 12.42, 14.84, 15.60, 17.89, 20.46, 20.68, 24.28, 23.46, 27.31, 30.45, 33.95, 31.58, 34.10, 36.02, 39.55, 40.60,
48.56, 59.02, 67.90, 69.13, 71.71, 80.77, 91.35, 123.76, 134.61, 130.05, 18.44, 57.26, 62.38, 274.04, 426.28, 767.30, 1918.25, 306.92, 2557.67, 2557.67, 3836.50, 3000, 3000, 3836.50, 3000, 3000,
85.26, 3000, 3000, 99.65, 3000, 11.84, 13.46, 142.09, 2557.67, 7673.00, 2557.67 };
#endif

Wyświetl plik

@ -0,0 +1,798 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
*********************************************************************************************************************************************************
* Version History *
* 1.0 First release, code extraced from 14 band spectrum analyzer 3.00 and modified to by used with FFT on a ESP32. No need for frequency board or *
* MCGEQ7 chips. *
* - HUB75 interface or *
* - WS2812 leds ( matrix/ledstrips) *
* - 8/16/32 or 64 channel analyzer *
* - calibration for White noise, pink noise, brown noise sensitivity included and selectable *
* - Fire screensaver *
* - Display of logo and interface text when used with HUB75 *
* *
*********************************************************************************************************************************************************
* Version FFT 1.0 release July 2021 *
*********************************************************************************************************************************************************
* Status | Description *
* Open | Some Hub75 displays use a combination of chipsets of are from a different productions batch which will not work with this libary *
* Open | Sometime the long press for activating/de-activating the autoChange Pattern mode doesn't work *
* Solved | When using 64 bands, band 0 is always at max value. This was caused by the array dize [64]-> solved by chnaging it to 65 *
* Not a bug | Different types of HUB75 displays require different libary settings.It is what it is and it all depends on what the distributer sends you.*
* | For into on the libary settings, see the library documentation on Github: https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA *
* Wish | Web interface. not possible without some heavy workaround cant use WIFI and ADC at same time *
* *******************************************************************************************************************************************************
* People who inspired me to do this build and figure out how stuff works:
* Dave Plummer https://www.youtube.com/channel/UCNzszbnvQeFzObW0ghk0Ckw
* Mrfaptastic https://github.com/mrfaptastic
* Scott Marley https://www.youtube.com/user/scottmarley85
* Brian Lough https://www.youtube.com/user/witnessmenow
* atomic14 https://www.youtube.com/channel/UC4Otk-uDioJN0tg6s1QO9lw
*
* Make sure your arduino IDE settings: Compiler warnings is set to default to make sure the code will compile */
#define VERSION "V1.0"
#include <FastLED_NeoMatrix.h>
#include <arduinoFFT.h>
#include "I2SPLUGIN.h"
#include <math.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include "FFT.h"
#include "LEDDRIVER.H"
#include "Settings.h"
#include "PatternsHUB75.h"
#include "PatternsLedstrip.h"
#include "fire.h"
#include "logos.h"
int skip=true;
int ButtonOnTimer=0;
int ButtonStarttime=0;
int ButtonSequenceCounter=0;
int ButtonOffTimer=0;
int ButtonStoptime=0;
int ButtonPressedCounter=0;
int ButtonReleasedCounter=0;
int ShortPressFlag=0;
int LongPressFlag=0;
int LongerPressFlag=0;
boolean Next_is_new_pressed= true;
boolean Next_is_new_release = true;
int PreviousPressTime=0;
#define up 1
#define down 0
int PeakDirection=0;
long LastDoNothingTime = 0; // only needed for screensaver
int DemoModeMem=0; // to remember what mode we are in when going to demo, in order to restore it after wake up
bool AutoModeMem=false; // same story
bool DemoFlag=false; // we need to know if demo mode was manually selected or auto engadged.
char LCDPrintBuf[30];
void setup() {
Serial.begin(115200);
Serial.println("Setting up Audio Input I2S");
setupI2S();
Serial.println("Audio input setup completed");
delay(1000);
#ifdef Ledstrip
SetupLEDSTRIP();
#endif
#ifdef HUB75
SetupHUB75();
if (kMatrixHeight>60){
dma_display->setBrightness8(100);
#if LogoBoot
drawLogo();
delay(2500);
#endif
}
#endif
}
void loop() {
size_t bytesRead = 0;
int TempADC=0;
if (skip==false)i2s_adc_disable(I2S_NUM_0);
skip=false; // we only want to skip this the very first loop run.
//Handle Userinterface
{
// set brightness and test if button is pressed
TempADC = analogRead(BRIGHTNESSPOT);
if (TempADC<10){ // ADC value < 10 so button is pressed
ButtonOffTimer=0;
ButtonOnTimer=millis()-ButtonStarttime;
ButtonStoptime=millis();
}
else { // no Button pressed so ADC value is not related to button and can be proccessed
ButtonOnTimer=0;
ButtonOffTimer=millis()-ButtonStoptime;
ButtonStarttime = millis();
// read potmeters and process
Peakdelay=map(analogRead(PEAKDELAYPOT),0,4095,1,100);
BRIGHTNESSMARK=map(TempADC,100,2100,BRIGHTNESSMIN,BRIGHTNESSMAX);
// dbgprint("potm:%d",BRIGHTNESSMARK);
#ifdef Ledstrip
FastLED.setBrightness(BRIGHTNESSMARK);
#endif
#ifdef HUB75
dma_display->setBrightness8(map(TempADC,100,2100,BRIGHTNESSMIN,BRIGHTNESSMAX));
#endif
}
if(ButtonOffTimer>ButtonTimeout){
ButtonStoptime=millis(); // time that no switch was presset will reset the counter.
ButtonSequenceCounter=0; // reset the sequencecounter
if (ShortPressFlag==1){
// Serial.printf("Short press detected\n");
buttonPushCounter = (buttonPushCounter + 1) % 13;
#ifdef HUB75
dma_display->clearScreen();
#endif
Serial.printf("Pattern Mode changed to: %d\n",buttonPushCounter);
ShortPressFlag=0;
}
}
if ((ButtonOnTimer>LongerPress)&&(ButtonOnTimer<(LongerPress+ShortPress))){LongerPressFlag=1;}
else if ((ButtonOnTimer>LongPress)&&(ButtonOnTimer<(LongPress+ShortPress))){LongPressFlag=1;}
else if ((ButtonOnTimer>ShortPress)&&(ButtonOnTimer<(2*ShortPress))){
ShortPressFlag=1;
if((millis()-PreviousPressTime)<ButtonSequenceRepeatTime){
ButtonSequenceCounter++;
dbgprint("Multible press counter: %d\n",ButtonSequenceCounter);
ShortPressFlag=0;
CalibrationType= (CalibrationType +1)% 4;
Serial.printf("Calibration table changed to: %s\n",Filtername[CalibrationType]);
sprintf(LCDPrintBuf,"Cal Filter: %s",Filtername[CalibrationType]);
DisplayPrint(LCDPrintBuf);
}
PreviousPressTime=millis();
}
if (LongerPressFlag==1){
dbgprint( "Longer press detected\n");
autoChangePatterns = !autoChangePatterns;
if(autoChangePatterns == true){
Serial.print("Patterns wil now change every few seconds\n");
DisplayPrint((char*) "Autochange ON");
}
else {
Serial.print("Automatically changing of pattern is now disabled\n");
DisplayPrint((char*) "Autochange OFF");
}
LongerPressFlag=0;
ShortPressFlag=0;
}
else if (LongPressFlag==1){
dbgprint("long press detected\n");
autoChangePatterns = !autoChangePatterns;
if(autoChangePatterns == true){
Serial.print("Patterns wil now change every few seconds\n");
DisplayPrint((char*) "Autochange ON");
}
else {
Serial.print("Automatically changing of pattern is now disabled\n");
DisplayPrint((char*)"Autochange OFF");
}
LongPressFlag=0;
ShortPressFlag=0;
}
} // end user interface
//############ Step 1: read samples from the I2S Buffer ##################
i2s_adc_enable(I2S_NUM_0);
i2s_read(I2S_PORT,
(void*)samples,
sizeof(samples),
&bytesRead, // workaround This is the actual buffer size last half will be empty but why?
portMAX_DELAY); // no timeout
if (bytesRead != sizeof(samples)){
Serial.printf("Could only read %u bytes of %u in FillBufferI2S()\n", bytesRead, sizeof(samples));
// return;
}
//############ Step 2: compensate for Channel number and offset, safe all to vReal Array ############
for (uint16_t i = 0; i < ARRAYSIZE(samples); i++) {
vReal[i] = offset-samples[i];
vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
#if PrintADCRAW
Serial.printf("%7d,",samples[i]);
#endif
#if VisualizeAudio
Serial.printf("%d\n",samples[i]);
#endif
}
#if PrintADCRAW
Serial.printf("\n");
#endif
//############ Step 3: Do FFT on the VReal array ############
// compute FFT
FFT.DCRemoval();
FFT.Windowing(vReal, SAMPLEBLOCK, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLEBLOCK, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLEBLOCK);
FFT.MajorPeak(vReal, SAMPLEBLOCK, samplingFrequency);
for (int i = 0; i < numBands; i++) {
FreqBins[i] = 0;
}
//############ Step 4: Fill the frequency bins with the FFT Samples ############
float averageSum = 0.0f;
for (int i = 2; i < SAMPLEBLOCK / 2; i++){
averageSum+=vReal[i];
if (vReal[i] > NoiseTresshold){
int freq = BucketFrequency(i);
int iBand = 0;
while (iBand < numBands){
if (freq < BandCutoffTable[iBand])break;
iBand++;
}
if (iBand > numBands)iBand = numBands;
FreqBins[iBand]+= vReal[i];
// float scaledValue = vReal[i];
// if (scaledValue > peak[iBand])
// peak[iBand] = scaledValue;
}
}
// bufmd[0]=FreqBins[12];
#if PrintRAWBins
for ( int y=0; y<numBands;y++){
Serial.printf("%7.1f,",FreqBins[y]);
}
Serial.printf("\n");
#endif
//############ Step 5: Determine the VU value and mingle in the readout...( cheating the bands ) ############ Step
float t=averageSum / (SAMPLEBLOCK / 2);
gVU = max(t, (oldVU * 3 + t) / 4);
oldVU = gVU;
if(gVU>DemoTreshold)LastDoNothingTime = millis(); // if there is signal in any off the bands[>2] then no demo mode
// Serial.printf("gVu: %d\n",(int) gVU);
for(int j=0;j<numBands;j++){
if (CalibrationType==1)FreqBins[j]*= BandCalibration_Pink[j];
else if (CalibrationType==2)FreqBins[j]*= BandCalibration_White[j];
else if (CalibrationType==3)FreqBins[j]*= BandCalibration_Brown[j];
}
//*
//############ Step 6: Averaging and making it all fit on screen
//for (int i = 0; i < numBands; i++) {
//Serial.printf ("Chan[%d]:%d",i,(int)FreqBins[i]);
//FreqBins[i] = powf(FreqBins[i], gLogScale); // in case we want log scale..i leave it in here as reminder
// Serial.printf( " - log: %d \n",(int)FreqBins[i]);
// }
static float lastAllBandsPeak = 0.0f;
float allBandsPeak = 0;
//bufmd[1]=FreqBins[13];
//bufmd[2]=FreqBins[1];
for (int i = 0; i < numBands; i++){
//allBandsPeak = max (allBandsPeak, FreqBins[i]);
if (FreqBins[i]> allBandsPeak){
allBandsPeak = FreqBins[i];
}
}
if (allBandsPeak < 1)allBandsPeak = 1;
// The followinf picks allBandsPeak if it's gone up. If it's gone down, it "averages" it by faking a running average of GAIN_DAMPEN past peaks
allBandsPeak = max(allBandsPeak, ((lastAllBandsPeak * (GAIN_DAMPEN-1)) + allBandsPeak) / GAIN_DAMPEN); // Dampen rate of change a little bit on way down
lastAllBandsPeak = allBandsPeak;
if (allBandsPeak < 80000)allBandsPeak = 80000;
for (int i = 0; i < numBands; i++){
FreqBins[i] /= (allBandsPeak * 1.0f);
}
// Process the FFT data into bar heights
for (int band = 0; band < numBands; band++) {
int barHeight = FreqBins[band]*kMatrixHeight-1; //(AMPLITUDE);
if (barHeight > TOP-2) barHeight = TOP-2;
// Small amount of averaging between frames
barHeight = ((oldBarHeights[band] * 1) + barHeight) / 2;
// Move peak up
if (barHeight > peak[band]) {
peak[band] = min(TOP, barHeight);
PeakFlag[band]=1;
}
bndcounter[band]+=barHeight; // ten behoeve calibratie
// if there hasn't been much of a input signal for a longer time ( see settings ) go to demo mode
if ((millis() - LastDoNothingTime) > DemoAfterSec && DemoFlag==false)
{ dbgprint("In loop 1: %d", millis() - LastDoNothingTime);
DemoFlag=true;
// first store current mode so we can go back to it after wake up
DemoModeMem=buttonPushCounter;
AutoModeMem=autoChangePatterns;
autoChangePatterns=false;
buttonPushCounter=12;
#ifdef HUB75
dma_display->clearScreen();
#endif
dbgprint("Automode is turned of because of demo");
}
// Wait,signal is back? then wakeup!
else if (DemoFlag==true && (millis() - LastDoNothingTime) < DemoAfterSec )
{ //("In loop 2: %d", millis() - LastDoNothingTime);
// while in demo the democounter was reset due to signal on one of the bars.
// So we need to exit demo mode.
#ifdef HUB75
dma_display->clearScreen();
#endif
buttonPushCounter=DemoModeMem; // restore settings
dbgprint ("automode setting restored to: %d",AutoModeMem);
autoChangePatterns=AutoModeMem;// restore settings
DemoFlag=false;
}
#if BottomRowAlwaysOn
if (barHeight==0)barHeight=1; // make sure there is always one bar that lights up
#endif
// Now visualize those bar heights
switch (buttonPushCounter) {
case 0:
#ifdef HUB75
PeakDirection=down;
BoxedBars(band, barHeight);
BluePeak(band);
#endif
#ifdef Ledstrip
changingBarsLS(band, barHeight);
#endif
break;
case 1:
#ifdef HUB75
PeakDirection=down;
BoxedBars2(band, barHeight);
BluePeak(band);
#endif
#ifdef Ledstrip
TriBarLS(band, barHeight);
TriPeakLS(band);
#endif
break;
case 2:
#ifdef HUB75
PeakDirection=down;
BoxedBars3(band, barHeight);
RedPeak(band);
#endif
#ifdef Ledstrip
rainbowBarsLS(band, barHeight);
NormalPeakLS(band, PeakColor1);
#endif
break;
case 3:
#ifdef HUB75
PeakDirection=down;
RedBars(band, barHeight);
BluePeak(band);
#endif
#ifdef Ledstrip
purpleBarsLS(band, barHeight);
NormalPeakLS(band, PeakColor2);
#endif
break;
case 4:
#ifdef HUB75
PeakDirection=down;
ColorBars(band, barHeight);
#endif
#ifdef Ledstrip
SameBarLS(band, barHeight);
NormalPeakLS(band, PeakColor3);
#endif
break;
case 5:
#ifdef HUB75
PeakDirection=down;
Twins(band, barHeight);
WhitePeak(band);
#endif
#ifdef Ledstrip
SameBar2LS(band, barHeight);
NormalPeakLS(band, PeakColor3);
#endif
break;
case 6:
#ifdef HUB75
PeakDirection=down;
Twins2(band, barHeight);
WhitePeak(band);
#endif
#ifdef Ledstrip
centerBarsLS(band, barHeight);
#endif
break;
case 7:
#ifdef HUB75
PeakDirection=down;
TriBars(band, barHeight);
TriPeak(band);
#endif
#ifdef Ledstrip
centerBars2LS(band, barHeight);
#endif
break;
case 8:
#ifdef HUB75
PeakDirection=up;
TriBars(band, barHeight);
TriPeak(band);
#endif
#ifdef Ledstrip
centerBars3LS(band, barHeight);
#endif
break;
case 9:
#ifdef HUB75
PeakDirection=down;
centerBars(band, barHeight);
#endif
#ifdef Ledstrip
BlackBarLS(band, barHeight);
outrunPeakLS(band);
#endif
break;
case 10:
#ifdef HUB75
PeakDirection=down;
centerBars2(band, barHeight);
#endif
#ifdef Ledstrip
BlackBarLS(band, barHeight);
NormalPeakLS(band, PeakColor5);
#endif
break;
case 11:
#ifdef HUB75
PeakDirection=down;
BlackBars(band, barHeight);
DoublePeak(band);
#endif
#ifdef Ledstrip
BlackBarLS(band, barHeight);
TriPeak2LS(band);
#endif
break;
case 12:
#ifdef HUB75
make_fire(); // go to demo mode
#endif
#ifdef Ledstrip
matrix->fillRect(0, 0, matrix->width(), 1, 0x0000); // delete the VU meter
make_fire();
#endif
break;
}
// Save oldBarHeights for averaging later
oldBarHeights[band] = barHeight;
}
// for calibration
//bndcounter[h]+=barHeight;
if (loopcounter==256){
loopcounter=0;
#if CalibratieLog
Calibration();
for(int g=0;g<numBands;g++)bndcounter[g]=0;
#endif
}
loopcounter++;
if (buttonPushCounter!=12) DrawVUMeter(0); // Draw it when not in screensaver mode
#if PrintRAWBins
Serial.printf("\n");
//delay(10);
#endif
// Decay peak
EVERY_N_MILLISECONDS(Fallingspeed){
for (byte band = 0; band < numBands; band++){
if(PeakFlag[band]==1){
PeakTimer[band]++;
if (PeakTimer[band]> Peakdelay){PeakTimer[band]=0;PeakFlag[band]=0;}
}
else if ((peak[band] > 0) &&(PeakDirection==up)){
peak[band] += 1;
if (peak[band]>(kMatrixHeight+10))peak[band]=0;
} // when to far off screen then reset peak height
else if ((peak[band] > 0)&&(PeakDirection==down)){ peak[band] -= 1;}
}
colorTimer++;
}
EVERY_N_MILLISECONDS(10)colorTimer++; // Used in some of the patterns
EVERY_N_SECONDS(SecToChangePattern) {
// if (FastLED.getBrightness() == 0) FastLED.setBrightness(BRIGHTNESSMARK); //Re-enable if lights are "off"
if (autoChangePatterns){
buttonPushCounter = (buttonPushCounter + 1) % 12;
#ifdef HUB75
dma_display->clearScreen();
#endif
}
}
#ifdef Ledstrip
delay(1); // needed to give fastled a minimum recovery time
FastLED.show();
#endif
} // loop end
// BucketFrequency
//
// Return the frequency corresponding to the Nth sample bucket. Skips the first two
// buckets which are overall amplitude and something else.
int BucketFrequency(int iBucket){
if (iBucket <= 1)return 0;
int iOffset = iBucket - 2;
return iOffset * (samplingFrequency / 2) / (SAMPLEBLOCK / 2);
}
void DrawVUPixels(int i, int yVU, int fadeBy = 0){
CRGB VUC;
if (i>(PANE_WIDTH/3)){
VUC.r=255;
VUC.g=0;
VUC.b=0 ;
}
else if (i>(PANE_WIDTH/5)){
VUC.r=255;
VUC.g=255;
VUC.b=0;
}
else{ // green
VUC.r=0;
VUC.g=255;
VUC.b=0;
}
#ifdef Ledstrip
int xHalf = matrix->width()/2;
// matrix->drawPixel(xHalf-i-1, yVU, CRGB(0,100,0).fadeToBlackBy(fadeBy));
// matrix->drawPixel(xHalf+i, yVU, CRGB(0,100,0).fadeToBlackBy(fadeBy));
matrix->drawPixel(xHalf-i-1, yVU, CRGB(VUC.r,VUC.g,VUC.b).fadeToBlackBy(fadeBy));
matrix->drawPixel(xHalf+i, yVU, CRGB(VUC.r,VUC.g,VUC.b).fadeToBlackBy(fadeBy));
#endif
#ifdef HUB75
int xHalf = PANE_WIDTH/2;
dma_display->drawPixelRGB888(xHalf-i-2,yVU,VUC.r,VUC.g,VUC.b); //left side of screen line 0
dma_display->drawPixelRGB888(xHalf-i-2,yVU+1,VUC.r,VUC.g,VUC.b); //left side of screen line 1
dma_display->drawPixelRGB888(xHalf+i+1,yVU,VUC.r,VUC.g,VUC.b); // right side of screen line 0
dma_display->drawPixelRGB888(xHalf+i+1,yVU+1,VUC.r,VUC.g,VUC.b);// right side of screen line 1
#endif
}
void DrawVUMeter(int yVU){
static int iPeakVUy = 0; // size (in LED pixels) of the VU peak
static unsigned long msPeakVU = 0; // timestamp in ms when that peak happened so we know how old it is
const int MAX_FADE = 256;
#ifdef HUB75
for(int x=0; x<PANE_WIDTH;x++){
dma_display->drawPixelRGB888(x,yVU,0,0,0);
dma_display->drawPixelRGB888(x,yVU+1,0,0,0);
}
#endif
#ifdef Ledstrip
matrix->fillRect(0, yVU, matrix->width(), 1, 0x0000);
#endif
if (iPeakVUy > 1){
int fade = MAX_FADE * (millis() - msPeakVU) / (float) 1000;
DrawVUPixels(iPeakVUy, yVU, fade);
}
int xHalf = (PANE_WIDTH/2)-1;
int bars = map(gVU, 0, MAX_VU, 1, xHalf);
bars = min(bars, xHalf);
if(bars > iPeakVUy){
msPeakVU = millis();
iPeakVUy = bars;
}
else if (millis() - msPeakVU > 1000)iPeakVUy = 0;
for (int i = 0; i < bars; i++)DrawVUPixels(i, yVU);
}
void Calibration(void){
Serial.printf("BandCalibration_XXXX[%1d]=\n{",numBands);
long Totalbnd=0;
for (int g=0;g<numBands;g++){
if (bndcounter[g]>Totalbnd)Totalbnd=bndcounter[g];
}
for (int g=0;g<numBands;g++){
bndcounter[g]=Totalbnd/bndcounter[g];
Serial.printf(" %2.2f",bndcounter[g]);
if(g<numBands-1)Serial.printf(",");
else Serial.print(" };\n");
}
}
//**************************************************************************************************
// D B G P R I N T *
//**************************************************************************************************
// Send a line of info to serial output. Works like vsprintf(), but checks the DEBUG flag. *
// Print only if DEBUG flag is true. Always returns the formatted string. *
// Usage dbgprint("this is the text you want: %d", variable);
//**************************************************************************************************
void dbgprint(const char * format, ...) {
if (DEBUG) {
static char sbuf[DEBUG_BUFFER_SIZE]; // For debug lines
va_list varArgs; // For variable number of params
va_start(varArgs, format); // Prepare parameters
vsnprintf(sbuf, sizeof(sbuf), format, varArgs); // Format the message
va_end(varArgs); // End of using parameters
if (DEBUG) // DEBUG on?
{
Serial.print("Debug: "); // Yes, print prefix
Serial.println(sbuf); // and the info
}
// return sbuf; // Return stored string
}
}
void make_fire() {
uint16_t i, j;
if (t > millis()) return;
t = millis() + (1000 / FPS);
// First, move all existing heat points up the display and fade
for (i = rows - 1; i > 0; --i) {
for (j = 0; j < cols; ++j) {
uint8_t n = 0;
if (pix[i - 1][j] > 0)
n = pix[i - 1][j] - 1;
pix[i][j] = n;
}
}
// Heat the bottom row
for (j = 0; j < cols; ++j) {
i = pix[0][j];
if (i > 0) {
pix[0][j] = random(NCOLORS - 6, NCOLORS - 2);
}
}
// flare
for (i = 0; i < nflare; ++i) {
int x = flare[i] & 0xff;
int y = (flare[i] >> 8) & 0xff;
int z = (flare[i] >> 16) & 0xff;
glow(x, y, z);
if (z > 1) {
flare[i] = (flare[i] & 0xffff) | ((z - 1) << 16);
} else {
// This flare is out
for (int j = i + 1; j < nflare; ++j) {
flare[j - 1] = flare[j];
}
--nflare;
}
}
newflare();
// Set and draw
for (i = 0; i < rows; ++i) {
for (j = 0; j < cols; ++j) {
// matrix -> drawPixel(j, rows - i, colors[pix[i][j]]);
CRGB COlsplit=colors[pix[i][j]];
#ifdef HUB75
dma_display->drawPixelRGB888(j,rows - i,COlsplit.r,COlsplit.g,COlsplit.b);
#endif
#ifdef Ledstrip
matrix -> drawPixel(j, rows - i, colors[pix[i][j]]);
#endif
}
}
}
void drawLogo(void){
#ifdef HUB75
// logo is 46 width and 54 high
int i=0;
int xyStart[2]={(kMatrixWidth/2)-23,2};
CRGB pix;
for (int y=0;y<50;y++){
for (int x=0;x<46;x++){
pix=logo[i];
i++;
dma_display->drawPixelRGB888(x+xyStart[0],y+xyStart[1],pix.r,pix.g,pix.b);
}
}
dma_display->fillRect(5, 53, kMatrixWidth-10, 11, dma_display->color444(0, 0, 0));
delay(1000);
dma_display->setTextSize(1);
dma_display->setTextWrap(false);
dma_display->setCursor(10,55);
dma_display->print("Spectrum FFT ");
dma_display->print(VERSION);
delay(2000);
dma_display->fillRect(5, 53, kMatrixWidth-10, 11, dma_display->color444(0, 0, 0));
dma_display->setTextColor(dma_display->color444(15,15,0));
dma_display->setCursor(10,55);
dma_display->print(" Mark Donners ");
delay(2000);
#endif
}
void DisplayPrint(char * text){
#ifdef HUB75
dma_display->fillRect(8, 8, kMatrixWidth-16, 11, dma_display->color444(0,0 , 0));
dma_display->setTextSize(1);
dma_display->setTextWrap(false);
dma_display->setCursor(10,10);
dma_display->print(text);
delay(1000);
dma_display->fillRect(8, 8, kMatrixWidth-16, 11, dma_display->color444(0,0 , 0));
#endif
}

Wyświetl plik

@ -0,0 +1,79 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
#include <driver/i2s.h>
#include <driver/adc.h>
//Settings
const int samplingFrequency = 44100;
const int SAMPLEBLOCK = 1024;
const i2s_port_t I2S_PORT = I2S_NUM_0;
void setupI2S() {
Serial.println("Configuring I2S...");
esp_err_t err;
// The I2S config as per the example
const i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
.sample_rate = samplingFrequency,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // could only get it to work with 32bits
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // although the SEL config should be left, it seems to transmit on right
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // Interrupt level 1
.dma_buf_count = 2, // number of buffers
.dma_buf_len = SAMPLEBLOCK, // samples per buffer
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
// Configuring the I2S driver and pins.
// This function must be called before any I2S driver read/write operations.
err = adc_gpio_init(ADC_UNIT_1, ADC_CHANNEL_0); //step 1
if (err != ESP_OK) {
Serial.printf("Failed setting up adc channel: %d\n", err);
while (true);
}
err = adc_gpio_init(ADC_UNIT_1, ADC_CHANNEL_3); //step 1
if (err != ESP_OK) {
Serial.printf("Failed setting up adc channel: %d\n", err);
while (true);
}
err = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); //step 2
if (err != ESP_OK) {
Serial.printf("Failed installing driver: %d\n", err);
while (true);
}
err = i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_0);
if (err != ESP_OK) {
Serial.printf("Failed setting up adc mode: %d\n", err);
while (true);
}
Serial.println("I2S driver installed.");
}

Wyświetl plik

@ -0,0 +1,155 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
#include "Settings.h"
/* There are several options to display the data from the FFT.
* 1. Use a ledstrip like WS2812 or simular
* 2. Use a Hub75 display
* 3. Using both is possible but not recommended because of the required speed.
*/
// select one of these and comment out the other
//#define Ledstrip
#define HUB75
//Panel settings change to match your setup
#ifdef HUB75
#define PANEL_WIDTH 64
#define PANEL_HEIGHT 64 // Panel height of 64 will required PIN_E to be defined.
#define PANELS_NUMBER 2 // Number of chained panels, if just a single panel, obviously set to 1
// only need to match panel settings above
#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER
#define PANE_HEIGHT PANEL_HEIGHT
const uint8_t kMatrixWidth = PANEL_WIDTH * PANELS_NUMBER; // Matrix width --> number of columns in your led matrix
const uint8_t kMatrixHeight = PANEL_HEIGHT; // Matrix height --> number of leds per column
#endif
// Ledstrip settings
#define CHIPSET WS2812B // LED strip type
#define LED_PIN 21 // LED strip data
//#define SERPENTINE false // Set to false if you're LEDS are connected end to end, true if serpentine
#define COLOR_ORDER GRB // If colours look wrong, play with this
#define LED_VOLTS 5 // Usually 5 or 12
#define MAX_MILLIAMPS 2000 // Careful with the amount of power here if running off USB port
#ifdef Ledstrip
const uint8_t kMatrixWidth =32;//128; // Matrix width --> number of columns in your led matrix
const uint8_t kMatrixHeight = 16;//64; // Matrix height --> number of leds per column
#define PANE_WIDTH kMatrixWidth
#endif
#define BAR_WIDTH (kMatrixWidth /(numBands )) // If width >= 8 light 1 LED width per bar, >= 16 light 2 LEDs width bar etc
#define TOP (kMatrixHeight - 0) // Don't allow the bars to go offscreen
#define NeededWidth (BAR_WIDTH * numBands) // we need this to see if all bands fit or that we have left over space
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Total number of LEDs
CRGB leds[NUM_LEDS];
//***********************************************************************
// These are the settings for the Hub75 display
// pin settings, dont change unless you are using customized hardware
//***********************************************************************
#define A_PIN 23
#define B_PIN 19
#define C_PIN 5
#define D_PIN 17
#define E_PIN 22
#define LAT_PIN 18
#define OE_PIN 15
#define CLK_PIN 16
#define R1_PIN 33
#define B2_PIN 13
#define R2_PIN 14
#define G2_PIN 12
#define G1_PIN 26
#define B1_PIN 27
#ifdef HUB75
// placeholder for the matrix object
MatrixPanel_I2S_DMA *dma_display = nullptr;
#endif
// See manual if you need to change these settings
#ifdef Ledstrip
// FastLED_NeoMaxtrix - see https://github.com/marcmerlin/FastLED_NeoMatrix for Tiled Matrixes, Zig-Zag and so forth
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, kMatrixWidth, kMatrixHeight,
NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG +
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS);
/* // this one is used if you are using a ledstrip setup simular to the one from the acryllic spectrum analyzer
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, kMatrixWidth, kMatrixHeight,
NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE +
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ROWS);
*/
#endif
// See manual if you need to change these settings
void SetupHUB75(void){
#ifdef HUB75
HUB75_I2S_CFG mxconfig;
mxconfig.mx_height = PANEL_HEIGHT; // we have 64 pix heigh panels
mxconfig.mx_width = PANEL_WIDTH;
mxconfig.chain_length = PANELS_NUMBER; // we have 2 panels chained
mxconfig.gpio.e = E_PIN; // we MUST assign pin e to some free pin on a board to drive 64 pix height panels with 1/32 scan
mxconfig.gpio.r1 =R1_PIN;
mxconfig.gpio.g1 = G1_PIN;
mxconfig.gpio.b1 = B1_PIN;
mxconfig.gpio.r2 = R2_PIN;
mxconfig.gpio.g2 = G2_PIN;
mxconfig.gpio.b2 = B2_PIN;
mxconfig.gpio.a = A_PIN;
mxconfig.gpio.b = B_PIN;
mxconfig.gpio.c = C_PIN;
mxconfig.gpio.d = D_PIN;
mxconfig.gpio.e = E_PIN;
mxconfig.gpio.lat = LAT_PIN;
mxconfig.gpio.oe = OE_PIN;
mxconfig.gpio.clk = CLK_PIN;
mxconfig.driver = HUB75_I2S_CFG::MBI5124; // in case that we use panels based on FM6126A chip, we can change that
mxconfig.clkphase = true; // some panels need a reversed clockpulse I first encountered it in batch may 2021 PH3 64*64 V4.1 HX
mxconfig.latch_blanking = 4;
//mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
// OK, now we can create our matrix object
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
// dma_display->setLatBlanking(2);
// let's adjust default brightness to about xx%
dma_display->setBrightness8(50); // range is 0-255, 0 - 0%, 255 - 100%
//dma_display->setBrightness8(map(analogRead(BRIGHTNESSPOT),0,4095,10,BRIGHTNESSMAX));
// Allocate memory and start DMA display
if( not dma_display->begin() )
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
#endif
}
void SetupLEDSTRIP(void){
#ifdef Ledstrip
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
FastLED.setMaxPowerInVoltsAndMilliamps(LED_VOLTS, MAX_MILLIAMPS);
FastLED.setBrightness(BRIGHTNESSMARK);
FastLED.clear();
#endif
}

Wyświetl plik

@ -0,0 +1,462 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
/*
// Tools
CRGB HsvToRgb(uint8_t h, uint8_t s, uint8_t v){
CHSV hsv = CHSV(h, s, v);
CRGB rgb;
hsv2rgb_spectrum(hsv, rgb);
return rgb;
}
*/
#ifdef HUB75
/*
* First all the bar patterns
*/
/******************************************************************
* Pattern name: ColorBars Bars
*******************************************************************/
void ColorBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
dma_display->drawPixelRGB888(x,y,(band+1)*40,(band+1)*30,255-((band+1)*70)); //middle
// dma_display->drawPixelRGB888(x,y,band*40,band*30,150-(band*10)); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Red Bars
*******************************************************************/
void RedBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
dma_display->drawPixelRGB888(x,y,250,0,0); //middle
// dma_display->drawPixelRGB888(x,y,band*40,band*30,150-(band*10)); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Twins
*******************************************************************/
void Twins(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if((band & 1)==1)dma_display->drawPixelRGB888(x,y,250,0,0);
else dma_display->drawPixelRGB888(x,y,250,250,0); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Twins 2
*******************************************************************/
void Twins2(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if((band & 1)==1)dma_display->drawPixelRGB888(x,y,250,0,250);
else dma_display->drawPixelRGB888(x,y,0,250,250); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Tri Color Bars
*******************************************************************/
void TriBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if (y < (PANEL_HEIGHT/4)) dma_display->drawPixelRGB888(x, y,TriBar_RGB_Top ); //Top
else if (y > (PANEL_HEIGHT/2)) dma_display->drawPixelRGB888(x, y, TriBar_RGB_Bottom ); // bottom
else dma_display->drawPixelRGB888(x,y,TriBar_RGB_Middle); //middle
//else dma_display->drawPixelRGB888(x,y,TriBar_Color_Middle_RGB); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Boxed bars
*******************************************************************/
void BoxedBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if (y==(TOP - barHeight))dma_display->drawPixelRGB888(x,y,250,0,0);
else if (x==xStart)dma_display->drawPixelRGB888(x,y,250,0,0); // Border left side of the bars
else if(x==xStart+BAR_WIDTH-1)dma_display->drawPixelRGB888(x,y,250,0,0); // Border right side of the bars
else dma_display->drawPixelRGB888(x,y,0,0,250);
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Boxed bars 2
*******************************************************************/
void BoxedBars2(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if (y==(TOP - barHeight))dma_display->drawPixelRGB888(x,y,250,250,250);
else if (x==xStart)dma_display->drawPixelRGB888(x,y,250,250,250); // Border left side of the bars
else if(x==xStart+BAR_WIDTH-1)dma_display->drawPixelRGB888(x,y,250,250,250); // Border right side of the bars
else dma_display->drawPixelRGB888(x,y,0,0,250);
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Boxed bars 3
*******************************************************************/
void BoxedBars3(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
if (y==(TOP - barHeight))dma_display->drawPixelRGB888(x,y,0,255,0);
else if (x==xStart)dma_display->drawPixelRGB888(x,y,0,255,0); // Border left side of the bars
else if(x==xStart+BAR_WIDTH-1)dma_display->drawPixelRGB888(x,y,0,255,0); // Border right side of the bars
else dma_display->drawPixelRGB888(x,y,200,200,0);
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/******************************************************************
* Pattern name: Center Bars
*******************************************************************/
void centerBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int center = TOP/2;
if (barHeight>(kMatrixHeight-6))barHeight=kMatrixHeight-6;
// Serial.printf( "barheight: %d \n",barHeight);
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = 0; y <= (barHeight/2); y++) {
// if(y >= TOP - barHeight){
if(y==(barHeight/2)){
dma_display->drawPixelRGB888(x,center+y,Center_RGB_Edge); //edge
dma_display->drawPixelRGB888(x,center-y-1,Center_RGB_Edge); //edge
}
else {
dma_display->drawPixelRGB888(x,center+y,Center_RGB_Middle); //middle
dma_display->drawPixelRGB888(x,center-y-1,Center_RGB_Middle); //middle
}
}
for (int y= barHeight/2;y<TOP;y++){
dma_display->drawPixelRGB888(x, center+y+1, 0, 0, 0); // make unused pixel bottom black
if((center-y-2)>1)dma_display->drawPixelRGB888(x, center-y-2, 0, 0, 0); // make unused pixel top black except those of the VU meter
}
}
}
/******************************************************************
* Pattern name: Center Bars 2
*******************************************************************/
void centerBars2(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int center = TOP/2;
if (barHeight>(kMatrixHeight-6))barHeight=kMatrixHeight-6;
// Serial.printf( "barheight: %d \n",barHeight);
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = 0; y <= (barHeight/2); y++) {
// if(y >= TOP - barHeight){
if(y==(barHeight/2)){
dma_display->drawPixelRGB888(x,center+y,Center_RGB_Edge2); //edge
dma_display->drawPixelRGB888(x,center-y-1,Center_RGB_Edge2); //edge
}
else {
dma_display->drawPixelRGB888(x,center+y,Center_RGB_Middle2); //middle
dma_display->drawPixelRGB888(x,center-y-1,Center_RGB_Middle2); //middle
}
}
for (int y= barHeight/2;y<TOP;y++){
dma_display->drawPixelRGB888(x, center+y+1, 0, 0, 0); // make unused pixel bottom black
if((center-y-2)>1)dma_display->drawPixelRGB888(x, center-y-2, 0, 0, 0); // make unused pixel top black except those of the VU meter
}
}
}
/******************************************************************
* Pattern name: Black Bars
*******************************************************************/
void BlackBars(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 2; y--) {
if(y >= TOP - barHeight){
dma_display->drawPixelRGB888(x,y,0,0,0); //middle
}
else {
// leds[i].fadeToBlackBy( 64 );
dma_display->drawPixelRGB888(x,y,0,0,0);
}
}
}
}
/*
* All the Peak Patterns
*/
/******************************************************************
* Peak name: Red Peaks
*******************************************************************/
void RedPeak(int band) {
// #ifdef Ledstrip
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
// matrix->drawPixel(x, peakHeight, CHSV(0,255,0));
dma_display->drawPixelRGB888(x,peakHeight,255,0,0);
}
// #endif
}
/******************************************************************
* Peak name: White Peaks
*******************************************************************/
void WhitePeak(int band) {
// #ifdef Ledstrip
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
// matrix->drawPixel(x, peakHeight, CHSV(0,255,0));
dma_display->drawPixelRGB888(x,peakHeight,255,255,255);
}
// #endif
}
/******************************************************************
* Peak name: Blue peaks
*******************************************************************/
void BluePeak(int band) {
// #ifdef Ledstrip
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
// matrix->drawPixel(x, peakHeight, CHSV(0,255,0));
dma_display->drawPixelRGB888(x,peakHeight,0,0,255);
}
// #endif
}
/******************************************************************
* Peak name: Double Peak
*******************************************************************/
void DoublePeak(int band) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
// matrix->drawPixel(x, peakHeight, CHSV(0,255,0));
dma_display->drawPixelRGB888(x,peakHeight,0,0,255);
dma_display->drawPixelRGB888(x,peakHeight+1,0,0,255);
}
}
/******************************************************************
* Pattern name: Tri Color Peak
*******************************************************************/
void TriPeak(int band) {
int xStart = BAR_WIDTH * band;
if(NeededWidth<kMatrixWidth)xStart+= (kMatrixWidth-NeededWidth)/2;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (peakHeight < (PANEL_HEIGHT/4)) dma_display->drawPixelRGB888(x,peakHeight,TriBar_RGB_Top); //Top red
else if (peakHeight > (PANEL_HEIGHT/2)) dma_display->drawPixelRGB888(x,peakHeight,TriBar_RGB_Bottom); //green
else dma_display->drawPixelRGB888(x,peakHeight,TriBar_RGB_Middle); //yellow
}
}
#endif

Wyświetl plik

@ -0,0 +1,244 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
/********************************************************************************************************************************
* ** SUB Rountines related to Paterns and Peaks **
********************************************************************************************************************************/
#ifdef Ledstrip
//************ Mode 0 ***********
void changingBarsLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix -> drawPixel(x, y, CHSV(ChangingBar_Color));
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
//************ Mode 1 ***********
void TriBarLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
if (y < (kMatrixHeight/3)) matrix -> drawPixel(x, y, CHSV(TriBar_Color_Top)); //Top red
else if (y > (1 *kMatrixHeight/2)) matrix -> drawPixel(x, y, CHSV(TriBar_Color_Bottom)); //green
else matrix -> drawPixel(x, y, CHSV(TriBar_Color_Middle)); //yellow
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
void TriPeakLS(int band) {
int xStart = BAR_WIDTH * band;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (peakHeight < 4) matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Top_Peak)); //Top red
else if (peakHeight > 8) matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Bottom_Peak)); //green
else matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Middle_Peak)); //yellow
}
}
//************ Mode 2 ***********
void rainbowBarsLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix -> drawPixel(x, y, CHSV(RainbowBar_Color));
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
void NormalPeakLS(int band, int H, int S, int V) {
int xStart = BAR_WIDTH * band;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
matrix -> drawPixel(x, peakHeight, CHSV(H, S, V));
}
}
//************ Mode 3 ***********
void purpleBarsLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix -> drawPixel(x, y, ColorFromPalette(purplePal, y * (255 / (barHeight + 1))));
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
// for peaks see mode 2
//************ Mode 4 ***********
void SameBarLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix -> drawPixel(x, y, CHSV(SameBar_Color1)); //blue
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
// for peaks see mode 2
//************ Mode 5 ***********
void SameBar2LS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix -> drawPixel(x, y, CHSV(SameBar_Color2)); //blue
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
// for peaks see mode 2
//************ Mode 6 ***********
void centerBarsLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
int center= TOP/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (barHeight % 2 == 0) barHeight--;
if (barHeight < 0) barHeight = 1; // at least a white line in the middle is what we want
int yStart = ((kMatrixHeight - barHeight) / 2);
for (int y = yStart; y <= (yStart + barHeight); y++) {
int colorIndex = constrain((y - yStart) * (255 / barHeight), 0, 255);
matrix -> drawPixel(x, y, ColorFromPalette(heatPal, colorIndex));
}
for (int y= barHeight/2;y<TOP;y++){
matrix->drawPixel(x, center+y+1, CRGB(0, 0, 0)); // make unused pixel bottom black
matrix->drawPixel(x, center-y-2, CRGB(0, 0, 0)); // make unused pixel bottom black
}
}
}
//************ Mode 7 ***********
void centerBars2LS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
int center= TOP/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (barHeight % 2 == 0) barHeight--;
if (barHeight < 0) barHeight = 1; // at least a white line in the middle is what we want
int yStart = ((kMatrixHeight - barHeight) / 2);
for (int y = yStart; y <= (yStart + barHeight); y++) {
int colorIndex = constrain((y - yStart) * (255 / barHeight), 0, 255);
matrix -> drawPixel(x, y, ColorFromPalette(markPal, colorIndex));
}
for (int y= barHeight/2;y<TOP;y++){
matrix->drawPixel(x, center+y+1, CRGB(0, 0, 0)); // make unused pixel bottom black
matrix->drawPixel(x, center-y-2, CRGB(0, 0, 0)); // make unused pixel bottom black
}
}
}
//************ Mode 8 ***********
void centerBars3LS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
int center= TOP/2;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (barHeight % 2 == 0) barHeight--;
if (barHeight < 0) barHeight = 1; // at least a white line in the middle is what we want
int yStart = ((kMatrixHeight - barHeight) / 2);
for (int y = yStart; y <= (yStart + barHeight); y++) {
int colorIndex = constrain((y - yStart) * (255 / barHeight), 0, 255);
matrix -> drawPixel(x, y, ColorFromPalette(markPal2, colorIndex));
}
for (int y= barHeight/2;y<TOP;y++){
matrix->drawPixel(x, center+y+1, CRGB(0, 0, 0)); // make unused pixel bottom black
matrix->drawPixel(x, center-y-2, CRGB(0, 0, 0)); // make unused pixel bottom black
}
}
}
//************ Mode 9 ***********
void BlackBarLS(int band, int barHeight) {
int xStart = BAR_WIDTH * band;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
for (int y = TOP; y >= 0; y--) {
if(y >= TOP - barHeight){
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
else {
matrix->drawPixel(x, y, CRGB(0, 0, 0)); // make unused pixel in a band black
}
}
}
}
void outrunPeakLS(int band) {
int xStart = BAR_WIDTH * band;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
matrix -> drawPixel(x, peakHeight, ColorFromPalette(outrunPal, peakHeight * (255 / kMatrixHeight)));
}
}
//************ Mode 10 ***********
void TriPeak2LS(int band) {
int xStart = BAR_WIDTH * band;
int peakHeight = TOP - peak[band] - 1;
for (int x = xStart; x < xStart + BAR_WIDTH; x++) {
if (peakHeight < 4) matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Top_Peak2)); //Top red
else if (peakHeight > 8) matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Bottom_Peak2)); //green
else matrix -> drawPixel(x, peakHeight, CHSV(TriBar_Color_Middle_Peak2)); //yellow
}
}
//************ Mode 10 ***********
// for peaks see mode 1
#endif
/********************************************************************************************************************************
* ** END SUB Rountines related to Paterns and Peaks **
********************************************************************************************************************************/

Wyświetl plik

@ -0,0 +1,200 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
#pragma once
// Debug features should default be off!
#define PrintRAWBins 0 // set to 1 if you want to print the RAW FFT BIN values of each pass to the serial port
#define PrintADCRAW 0 // Set to 1 if you want to print the RAW ADC Values's of each pass to the serial port--> that is a lot of samples!!
#define VisualizeAudio 0 // Sends the raw ADC values from buffer to serial plotter...that is a lot of data!!
#define CalibratieLog 0 // a tool tell help with calibrating to noise input signal
int DEBUG = 0 ; // When debug=1, extra information is printed to serial port. Turn of if not needed--> DEBUG=0
#define DEBUG_BUFFER_SIZE 100 // Debug buffer size
//Options Change to your likings
#define BottomRowAlwaysOn 1 // if set to 1, bottom row is always on. Setting only applies to LEDstrip not HUB75
#define Fallingspeed 5 // Falling down factor that effects the speed of falling tiles
#define LogoBoot 1 // Show logo on boot when set to 1, only works in combination with HUB75
int Peakdelay = 60; // Delay before peak falls down to stack. Overruled by PEAKDEALY Potmeter
#define GAIN_DAMPEN 2 // Higher values cause auto gain to react more slowly
#define SecToChangePattern 10 // number of seconds that pattern changes when auto change mode is enabled
#define MAX_VU 5000 // How high our VU could max out at. Arbitarily tuned.
int buttonPushCounter = 0; // This number defines what pattern to start after boot (0 to 12)
bool autoChangePatterns = true; // After boot, the pattern will not change automatically.
int NoiseTresshold = 1500; // this will effect the upper bands most.
#define DemoAfterSec 6000 // if there is no input signal during this number of milli seconds, the unit will go to demo mode
#define DemoTreshold 500 // this defines the treshold that will get the unit out of demo mode
#define BRIGHTNESSMAX 255 // Max brightness of the leds...carefull...to bright might draw to much amps!
int BRIGHTNESSMARK= 50; // Default brightnetss, however, overruled by the Brightness potmeter
int BRIGHTNESSMIN = 20; // Min brightness
//buttonstuf don't change unless you know what you are doing
#define ShortPress 45
#define LongPress 2000
#define LongerPress 4000
#define ButtonTimeout 200
#define ButtonSequenceRepeatTime 200
//Controls //don't change unless you are using your own hardware design
#define BRIGHTNESSPOT 2
#define PEAKDELAYPOT 4
// Other stuff don't change
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
char PeakFlag[numBands]; // the top peak delay needs to have a flag because it has different timing while floating compared to falling to the stack
int PeakTimer[numBands]; // counter how many loops to stay floating before falling to stack
uint8_t colorTimer = 0;
volatile float gVU = 0; // Instantaneous read of VU value
volatile float oldVU = 0; // Previous read of VU value
#define ADC_INPUT ADC1_CHANNEL_0
uint16_t offset = (int)ADC_INPUT * 0x1000 + 0xFFF;
double vReal[SAMPLEBLOCK];
double vImag[SAMPLEBLOCK];
int16_t samples[SAMPLEBLOCK];
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
byte peak[65] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // The length of these arrays must be >= NUM_BANDS
int oldBarHeights[65] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // so they are set to 65
float FreqBins[65] = {0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/****************************************************************************
* Colors of bars and peaks in different modes, changeable to your likings *
****************************************************************************/
// Colors mode 0
#define ChangingBar_Color y * (255 / kMatrixHeight) + colorTimer, 255, 255
// no peaks
// Colors mode 1 These are the colors from the TRIBAR when using Ledstrip
#define TriBar_Color_Top 0 , 255, 255 // Red CHSV
#define TriBar_Color_Bottom 95 , 255, 255 // Green CHSV
#define TriBar_Color_Middle 45, 255, 255 // Yellow CHSV
#define TriBar_Color_Top_Peak 0 , 255, 255 // Red CHSV
#define TriBar_Color_Bottom_Peak 95 , 255, 255 // Green CHSV
#define TriBar_Color_Middle_Peak 45, 255, 255 // Yellow CHSV
// Colors mode 1 These are the colors from the TRIBAR when using HUB75
#define TriBar_RGB_Top 255 , 0, 0 // Red CRGB
#define TriBar_RGB_Bottom 0 , 255, 0 // Green CRGB
#define TriBar_RGB_Middle 255, 255, 0 // Yellow CRGB
#define TriBar_RGB_Top_Peak 255 , 0, 0 // Red CRGB
#define TriBar_RGB_Bottom_Peak 0 , 255, 0 // Green CRGB
#define TriBar_RGB_Middle_Peak 255, 255, 0 // Yellow CRGB
// hub 75 center bars
#define Center_RGB_Edge 255 , 0, 0 // Red CRGB
#define Center_RGB_Middle 255, 255, 0 // Yellow CRGB
// hub 75 center bars 2
#define Center_RGB_Edge2 255 , 0, 0 // Red CRGB
#define Center_RGB_Middle2 255, 255, 255 // Yellow CRGB
// Colors mode 2
#define RainbowBar_Color (x / BAR_WIDTH) * (255 / numBands), 255, 255
#define PeakColor1 0, 0, 255 // white CHSV
// Colors mode 3
#define PeakColor2 0, 0, 255 // white CHSV
DEFINE_GRADIENT_PALETTE( purple_gp ) {
0, 0, 212, 255, //blue
255, 179, 0, 255 }; //purple
CRGBPalette16 purplePal = purple_gp;
// Colors mode 4
#define SameBar_Color1 0 , 255, 255 //red CHSV
#define PeakColor3 160, 255, 255 // blue CHSV
// Colors mode 5
#define SameBar_Color2 160 , 255, 255 //blue CHSV
#define PeakColor4 0, 255, 255 // red CHSV
// Colors mode 6
DEFINE_GRADIENT_PALETTE( redyellow_gp ) {
0, 200, 200, 200, //white
64, 255, 218, 0, //yellow
128, 231, 0, 0, //red
192, 255, 218, 0, //yellow
255, 200, 200, 200 }; //white
CRGBPalette16 heatPal = redyellow_gp;
// no peaks
// Colors mode 7
DEFINE_GRADIENT_PALETTE( outrun_gp ) {
0, 141, 0, 100, //purple
127, 255, 192, 0, //yellow
255, 0, 5, 255 }; //blue
CRGBPalette16 outrunPal = outrun_gp;
// no peaks
// Colors mode 8
DEFINE_GRADIENT_PALETTE( mark_gp2 ) {
0, 255, 218, 0, //Yellow
64, 200, 200, 200, //white
128, 141, 0, 100, //pur
192, 200, 200, 200, //white
255, 255, 218, 0,}; //Yellow
CRGBPalette16 markPal2 = mark_gp2;
// Colors mode 9
// no bars only peaks
DEFINE_GRADIENT_PALETTE( mark_gp ) {
0, 231, 0, 0, //red
64, 200, 200, 200, //white
128, 200, 200, 200, //white
192, 200, 200, 200, //white
255, 231, 0, 0,}; //red
CRGBPalette16 markPal = mark_gp;
// Colors mode 10
// no bars only peaks
#define PeakColor5 160, 255, 255 // blue CHSV
// These are the colors from the TRIPEAK mode 11
// no bars
#define TriBar_Color_Top_Peak2 0 , 255, 255 // Red CHSV
#define TriBar_Color_Bottom_Peak2 95 , 255, 255 // Green CHSV
#define TriBar_Color_Middle_Peak2 45, 255, 255 // Yellow CHSV
/******************************************************************
* Setting below are only related to the demo Fire mode *
*******************************************************************/
#define FPS 25 /* Refresh rate 15 looks good*/
/* Flare constants */
const uint8_t flarerows = 8; //8 /* number of rows (from bottom) allowed to flare */
const uint8_t maxflare = 50;//4; /* max number of simultaneous flares */
const uint8_t flarechance = 50; /* 50chance (%) of a new flare (if there's room) */
const uint8_t flaredecay = 14; /* decay rate of flare radiation; 14 is good */
/* This is the map of colors from coolest (black) to hottest. Want blue flames? Go for it! */
const uint32_t colors[] = {
0x000000,
0x100000,
0x300000,
0x600000,
0x800000,
0xA00000,
0xC02000,
0xC04000,
0xC06000,
0xC08000,
0x807080
};

Wyświetl plik

@ -0,0 +1,82 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
/* This part of the code ( the fire part) has been adapted and heavly alterted from
* Patrick Rigney (https://www.toggledbits.com/)
* Github: https://github.com/toggledbits/MatrixFireFast */
#pragma once
#include "Settings.h"
#define MAT_W kMatrixWidth /* Size (columns) of entire matrix */
#define MAT_H kMatrixHeight /* and rows */
const uint16_t rows = MAT_H;
const uint16_t cols = MAT_W;
const uint16_t xorg = 0;
const uint16_t yorg = 0;
uint8_t pix[rows][cols];
const uint8_t NCOLORS = (sizeof(colors)/sizeof(colors[0]));
uint8_t nflare = 0;
uint32_t flare[maxflare];
const uint8_t phy_h = MAT_W;
const uint8_t phy_w = MAT_H;
unsigned long t = 0; /* keep time */
uint16_t pos( uint16_t col, uint16_t row ) {
uint16_t phy_x = xorg + (uint16_t) row;
uint16_t phy_y = yorg + (uint16_t) col;
return phy_x + phy_y * phy_w;
}
uint32_t isqrt(uint32_t n) {
if ( n < 2 ) return n;
uint32_t smallCandidate = isqrt(n >> 2) << 1;
uint32_t largeCandidate = smallCandidate + 1;
return (largeCandidate*largeCandidate > n) ? smallCandidate : largeCandidate;
}
// Set pixels to intensity around flare
void glow( int x, int y, int z ) {
int b = z * 10 / flaredecay + 1;
for ( int i=(y-b); i<(y+b); ++i ) {
for ( int j=(x-b); j<(x+b); ++j ) {
if ( i >=0 && j >= 0 && i < rows && j < cols ) {
int d = ( flaredecay * isqrt((x-j)*(x-j) + (y-i)*(y-i)) + 5) / 10;
uint8_t n = 0;
if ( z > d ) n = z - d;
if ( n > pix[i][j] ) { // can only get brighter
pix[i][j] = n;
}
}
}
}
}
void newflare() {
if ( nflare < maxflare && random(1,101) <= flarechance ) {
int x = random(0, cols);
int y = random(0, flarerows);
int z = NCOLORS - 1;
flare[nflare++] = (z<<16) | (y<<8) | (x&0xff);
glow( x, y, z );
}
}

Wyświetl plik

@ -0,0 +1,93 @@
/********************************************************************************************************************************************************
* *
* Project: FFT Spectrum Analyzer *
* Target Platform: ESP32 *
* *
* Version: 1.0 *
* Hardware setup: See github *
* Spectrum analyses done with analog chips MSGEQ7 *
* *
* Mark Donners *
* The Electronic Engineer *
* Website: www.theelectronicengineer.nl *
* facebook: https://www.facebook.com/TheelectronicEngineer *
* youtube: https://www.youtube.com/channel/UCm5wy-2RoXGjG2F9wpDFF3w *
* github: https://github.com/donnersm *
* *
********************************************************************************************************************************************************/
//This file is only to display the logo, If you don't like the logo comment out: drawLogo(); around line 81 in the main sketch
//You can also change it. It's a jpg converted to RGB 46x50px
// Image Size : 46x50 pixels
// Memory usage : 4600 bytes
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
#define PROGMEM
#elif defined(__arm__)
#define PROGMEM
#endif
// 'logo RGB', 46x50px
const unsigned long logo [] PROGMEM = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffd42a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffae0e, 0x00faad09, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fbac0a, 0x00faa708, 0x00000000, 0x00000000, 0x00000000, 0x00faab0a, 0x00faa908, 0x00000000, 0x00000000, 0x00000000, 0x00fba607, 0x00faaa08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00feb917, 0x00ffff55, 0x00000000, 0x00000000, 0x00000000, 0x00faae0c, 0x00fab30b, 0x00ffaa08, 0x00000000, 0x00000000, 0x00fabd0c, 0x00fac70d, 0x00ffff7f, 0x00000000, 0x00000000, 0x00fab00a, 0x00fab30d, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffb40a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00feb917, 0x00faaa0a, 0x00faa708, 0x00000000, 0x00000000, 0x00ffaa0b, 0x00fadf11, 0x00fabd04, 0x00000000, 0x00000000, 0x00fad013, 0x00fffa1e, 0x00ffa707, 0x00000000, 0x00fba600, 0x00fade0d, 0x00fbbe11, 0x00000000, 0x00000000, 0x00000000, 0x00faa708, 0x00fbb00b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fab60e, 0x00fac10d, 0x00ffa108, 0x00000000, 0x00faa404, 0x00faed37, 0x00faee2b, 0x00fe9c00, 0x00000000, 0x00ffef3c, 0x00dee958, 0x00fca900, 0x00000000, 0x00fed612, 0x00ffff45, 0x00ffbe07, 0x00000000, 0x00000000, 0x00fab808, 0x00fac211, 0x00ffff7f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaf0f, 0x00ffbf15, 0x00000000, 0x00000000, 0x00000000, 0x00fbad09, 0x00faf124, 0x00facc04, 0x00ffbf00, 0x00ffaf00, 0x00f9e35c, 0x00ffffa7, 0x00fec800, 0x00e78f00, 0x00bcb85f, 0x008d9982, 0x00c7a01c, 0x00c5851c, 0x00d4d069, 0x00b7bf75, 0x00d88e00, 0x00000000, 0x00feb900, 0x00fdf926, 0x00fac611, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00feac10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00feae0d, 0x00fab00a, 0x00faa909, 0x00000000, 0x00000000, 0x00fe9e00, 0x00fadf36, 0x00fbff7a, 0x00fbbf00, 0x00fa9100, 0x00feee52, 0x00f5f9da, 0x00c5bd4c, 0x00c2ae88, 0x00dadff1, 0x00f7f6ff, 0x00e4ecf8, 0x00dae7fc, 0x00d7dcf2, 0x0092929b, 0x00a3844c, 0x00c7941c, 0x00d7d548, 0x00f2f33f, 0x00ffbd00, 0x00000000, 0x00000000, 0x00faa609, 0x00faaf0b, 0x00fbab0b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fca80a, 0x00fad317, 0x00fac304, 0x00ff9b00, 0x00000000, 0x00fbc70a, 0x00fbffcf, 0x00faff95, 0x00ffcb00, 0x00f5dd22, 0x00bfc8c1, 0x00d8deff, 0x00ffffff, 0x00ffffff, 0x00f3f3f5, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00f7ffff, 0x00dfe9fa, 0x00ccd9e6, 0x00cec083, 0x0090660c, 0x00000000, 0x00ffc500, 0x00f9d717, 0x00fab90e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fac90e, 0x00faff53, 0x00fad62a, 0x00fa9f00, 0x00faa800, 0x00fdfc8f, 0x00ffffff, 0x00f9fd5b, 0x00b6ac38, 0x00e5e7fb, 0x00ffffff, 0x00f3f3f3, 0x00a9aaae, 0x00e4e4e6, 0x00ffffff, 0x00fbfbfb, 0x00fdfdfd, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x008c9ad5, 0x00846a39, 0x00dee82f, 0x00fdf423, 0x00fea408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fead09, 0x00ffac0f, 0x00000000, 0x00000000, 0x00000000, 0x00fa9e00, 0x00fae94f, 0x00fbffda, 0x00fbf166, 0x00fcc700, 0x00f8e83f, 0x00e7e8d7, 0x00bbbba5, 0x00c8cbdf, 0x00ffffff, 0x00f4f4f4, 0x00939599, 0x00b8b9bd, 0x00ffffff, 0x00c4c5c7, 0x00eaebec, 0x00ffffff, 0x00ffffff, 0x00fdfdfd, 0x00ececec, 0x00b5b6c7, 0x00949169, 0x00e4e174, 0x00d0dde3, 0x00d8dd74, 0x00fcbd05, 0x00000000, 0x00000000, 0x00000000, 0x00ffff7f, 0x00ffaf0b, 0x00ffff55, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaf0f, 0x00faac0a, 0x00fabc0f, 0x00fcab05, 0x00fea900, 0x00000000, 0x00fcb800, 0x00fbffa7, 0x00fbffff, 0x00ffff97, 0x00f4ed55, 0x00868565, 0x00aeadac, 0x00ffffff, 0x00ffffff, 0x00bbbcc0, 0x009c9da0, 0x00e8eaee, 0x00b2b7d2, 0x00b8bbc9, 0x00ffffff, 0x00d7d8db, 0x00f0f0f0, 0x00ffffff, 0x00fefefe, 0x00dadae7, 0x00a2a07b, 0x00bfbe85, 0x00ffffba, 0x00fef61d, 0x00ffff00, 0x00ffaa00, 0x00fba300, 0x00fbbb10, 0x00fab50c, 0x00fbaa09, 0x00ffff7f, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffa405, 0x00facd12, 0x00fbf434, 0x00fbd836, 0x00fcc107, 0x00fca700, 0x00fbde2b, 0x00fbffda, 0x00fffffe, 0x00ecebc8, 0x00b0b0ab, 0x00f2f2f7, 0x00efefed, 0x00aeaeb0, 0x0077777b, 0x009a9ca2, 0x009599a4, 0x00837c53, 0x00837a55, 0x00575759, 0x00c3c6cf, 0x00f8f9f9, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00d0d1f2, 0x00a7ab76, 0x00c08b00, 0x00f6ae00, 0x00fdcf1f, 0x00faed3d, 0x00fae519, 0x00fbab09, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffa309, 0x00fbe534, 0x00fbffb3, 0x00fcffbc, 0x00fced75, 0x00fbe83f, 0x00fdfa9b, 0x00fffff0, 0x00b4b1a4, 0x00efeffa, 0x00cacacc, 0x0077767a, 0x008a8b8d, 0x009a9ca4, 0x00595e80, 0x00978d51, 0x00e0c322, 0x0047402e, 0x002c281b, 0x00827b68, 0x00b7bac8, 0x00bebfc3, 0x00f0f0f0, 0x00ffffff, 0x00fdfdfd, 0x00ffffff, 0x00ffffff, 0x00beb9cc, 0x0084895a, 0x00d7eea5, 0x00feff55, 0x00fbab00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffa712, 0x00fbe75b, 0x00fcfff0, 0x00fcffff, 0x00fcffdb, 0x00fefcc7, 0x00ffffd9, 0x00cbcac5, 0x00d9d9e1, 0x005e5c67, 0x0094949b, 0x00c1c3ca, 0x00a7aaac, 0x007e7664, 0x00f9da5c, 0x00b5a135, 0x00868db3, 0x00767772, 0x004e3807, 0x004b3c35, 0x00898e96, 0x00e0e0e4, 0x00ffffff, 0x00fefefe, 0x00fdfdfd, 0x00c1c0c0, 0x009ea1aa, 0x00bdc5e1, 0x00f2f465, 0x00fbae00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffae0c, 0x00fbad09, 0x00fab50e, 0x00fcaf0b, 0x00fbab03, 0x00ffa80f, 0x00fcb625, 0x00fcef84, 0x00fcffe7, 0x00fcfcf0, 0x00ffffee, 0x00f5f5d7, 0x00c5bfd1, 0x00a9a7bd, 0x0095939f, 0x00a8a8ad, 0x00c0c3d2, 0x007e7d73, 0x00857003, 0x00fdde38, 0x00998837, 0x009fa4c2, 0x0078797f, 0x004d451c, 0x0060615b, 0x007c7e84, 0x00a2a2a2, 0x00e6e5e4, 0x00ffffff, 0x00ffffff, 0x00c4c4cd, 0x0070746a, 0x00fefb4d, 0x00fed900, 0x00ff9c00, 0x00fba600, 0x00fbaa03, 0x00fcb310, 0x00fbb00b, 0x00fbac09, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaa0a, 0x00faa606, 0x00fbc811, 0x00fbf62a, 0x00fbf16f, 0x00fbea7c, 0x00fbe578, 0x00fdf0a8, 0x00fcfcde, 0x00f4f7fa, 0x00fefdf1, 0x00d4c5d7, 0x009a8bb8, 0x00928faa, 0x00a09eb0, 0x00b1b1b8, 0x00c6c8cb, 0x009698a8, 0x00605a32, 0x00f5da22, 0x00c1a931, 0x00878cab, 0x008a8e93, 0x005d531a, 0x008c8581, 0x0085888e, 0x006f7072, 0x0088888b, 0x00afafaf, 0x00f0f0ef, 0x00ffffff, 0x00daded7, 0x00c8bd33, 0x00bd9e15, 0x00dfca46, 0x00fdf070, 0x00faf736, 0x00fada12, 0x00faac09, 0x00faaa08, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffa809, 0x00fbca17, 0x00fbfe79, 0x00fbfff2, 0x00ffffff, 0x00ffffee, 0x00f8f7f2, 0x00f6f7ff, 0x00fbf7fe, 0x00e3d1e1, 0x00c3b6d7, 0x00ada8b8, 0x009f9bac, 0x008b8a99, 0x00a1a1a5, 0x00d4d9e4, 0x00686f8f, 0x0099820d, 0x00ffea1a, 0x0086895e, 0x005a6355, 0x00b98d46, 0x00df9263, 0x00726760, 0x00818a94, 0x006e6f72, 0x00606063, 0x00868687, 0x00cececd, 0x00ffffff, 0x00cdd0ef, 0x007f89b5, 0x00ddeee0, 0x00ffff9c, 0x00fadb1e, 0x00faab02, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fcac08, 0x00fee144, 0x00e6edd7, 0x00d8e1fe, 0x00efeeff, 0x00ffffff, 0x00fdfaff, 0x00fffaf1, 0x00dbd2ec, 0x00988faf, 0x00696077, 0x0095949f, 0x007b7e87, 0x00737f8a, 0x00937b77, 0x008f7e6e, 0x00b1a852, 0x00946e1a, 0x005c4227, 0x00e8a87d, 0x00ffbf80, 0x00ab9281, 0x00a5b4c3, 0x009fa1a5, 0x00909295, 0x00717174, 0x00565557, 0x0085868b, 0x008b8ead, 0x00d2d592, 0x00fef74a, 0x00fbb000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffbf3f, 0x00ffa706, 0x00fbac00, 0x00fcc11b, 0x00f4ea82, 0x00dce9f0, 0x00dbd7ff, 0x00eef3ff, 0x00eceeff, 0x00fcebe9, 0x00ece1c9, 0x00a29ac1, 0x007a7999, 0x00757e94, 0x005a585e, 0x00906d54, 0x00ffd0a5, 0x00a5a2ab, 0x005d4d5f, 0x006a4f49, 0x002a211d, 0x00c38e68, 0x00ffca8c, 0x00be916f, 0x0074818c, 0x00838d97, 0x00afb5be, 0x00a9a9ac, 0x00818186, 0x003c3d51, 0x00888a51, 0x00d6d91f, 0x00efb800, 0x00fca600, 0x00ffa400, 0x00fe9d0c, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaa0e, 0x00fba808, 0x00faba0d, 0x00fbdc13, 0x00fbe944, 0x00fbf38f, 0x00fcfcbd, 0x00ffffbf, 0x00e6ebe6, 0x00c9d8fd, 0x00ccb9f6, 0x00ccb6f9, 0x00cbc6e7, 0x00e7d49b, 0x00cfc168, 0x005b5062, 0x006b555f, 0x00645752, 0x00b5825a, 0x00a4846d, 0x004e5357, 0x00d9dde0, 0x008ba6bb, 0x00080505, 0x00dd9e70, 0x00ffdc9e, 0x00edaf80, 0x00302b27, 0x006b4d36, 0x008b7362, 0x009ea5ad, 0x00bbbdc3, 0x008c8d91, 0x00959587, 0x00868677, 0x00f2f197, 0x00fffd88, 0x00faeb58, 0x00fae11b, 0x00fac80e, 0x00faab0a, 0x00fbaa0b,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffb40a, 0x00faa809, 0x00fbb80d, 0x00fbda0d, 0x00fbf652, 0x00fbffc0, 0x00ffffdd, 0x00fffee4, 0x00c8d5f9, 0x0091b1fe, 0x009d73cc, 0x009257bb, 0x0099abf2, 0x00d5d3d9, 0x00d9d69d, 0x00a59165, 0x00986f65, 0x004d4b4f, 0x004e392d, 0x0080593c, 0x00655347, 0x00a7abaf, 0x00aca39e, 0x00e1aa7a, 0x00ffbd86, 0x00b07f5c, 0x00cf9a6f, 0x00ac7a55, 0x00d48950, 0x009e795e, 0x00929fac, 0x00aaabaf, 0x00c7c9ca, 0x008789a8, 0x00b8b6bc, 0x00ffffff, 0x00fbffc1, 0x00fbfe69, 0x00fae519, 0x00fac40b, 0x00fbaa09, 0x00ffaa0a,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaa15, 0x00fbaa00, 0x00ffbc00, 0x00edcd47, 0x00a7bcf5, 0x00baccf6, 0x008d9ff7, 0x005e53ba, 0x00895e99, 0x005f67d3, 0x00a6bbff, 0x00a9bfff, 0x00f8f8d0, 0x00c5d0ba, 0x003e4859, 0x00764c2f, 0x00ffcf95, 0x00f0ac79, 0x00a36c43, 0x00e2965b, 0x00fab578, 0x00b37f58, 0x00443226, 0x006f513c, 0x00c68d63, 0x008b6f59, 0x008a9098, 0x00b8bbc0, 0x00b7b8c0, 0x007c7f9a, 0x006c6d5a, 0x00f1f057, 0x00fede26, 0x00fabc00, 0x00fcac00, 0x00ff9e06, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffa200, 0x00e0ba40, 0x00b8cded, 0x00ccd7ea, 0x007c8edb, 0x003c337a, 0x00b795a4, 0x003b52ce, 0x005b6dcf, 0x00a0b5ff, 0x00e3f2f5, 0x00d7c28c, 0x0077513e, 0x00b2805d, 0x00f3b584, 0x00cf9366, 0x00e7a672, 0x00d0a786, 0x00897160, 0x00675950, 0x008d7360, 0x00f1a367, 0x006b482d, 0x00647586, 0x00c4c9d1, 0x00a0a0a6, 0x006f6f70, 0x00949386, 0x00e3e3b2, 0x00ffff73, 0x00fad704, 0x00faa500, 0x00ffaa00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffaa55, 0x00faad04, 0x00facf19, 0x00fbf774, 0x00ffffc8, 0x00ffffe3, 0x009eb2ff, 0x006681ea, 0x004d5ca7, 0x00977da2, 0x0058549d, 0x005f7bec, 0x00bed4ff, 0x00ffffdd, 0x00c5a170, 0x00997059, 0x00edc59f, 0x00e69c63, 0x005a3f2b, 0x007d8489, 0x00b8c2cc, 0x00f8ffff, 0x009da9b2, 0x00322418, 0x00cc9a71, 0x00a5978b, 0x009ea3a8, 0x009b9c9e, 0x00686971, 0x005d5b43, 0x00eeedb7, 0x00ffffe8, 0x00faf9ff, 0x00fbffeb, 0x00fbff95, 0x00fade32, 0x00fab606, 0x00ffa707, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffbf1f, 0x00faa906, 0x00fab40a, 0x00fae10e, 0x00faff3d, 0x00faff98, 0x00ffff9c, 0x00d5dbc2, 0x00c0ccdc, 0x007086e4, 0x00325dff, 0x003c4fcf, 0x003b44bb, 0x001131bb, 0x006e73af, 0x00f7f9d8, 0x0089805c, 0x00d4a588, 0x00ffd492, 0x00a97a55, 0x0090959a, 0x00bac5d1, 0x00a3a5aa, 0x00acabac, 0x00c2c2bf, 0x00a7a6a6, 0x00b8c2cc, 0x00c8d0d8, 0x00d8d7d8, 0x00dededf, 0x00b1b1b1, 0x00d4d4d0, 0x00a7a7ac, 0x00a9a657, 0x00ffffa3, 0x00fbffa4, 0x00fbffa6, 0x00faff5f, 0x00faf017, 0x00fac10d, 0x00faa608, 0x00feac10,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffad09, 0x00ffb40d, 0x00ffb611, 0x00ffb302, 0x00ffbb00, 0x00ffb800, 0x00faed0d, 0x00bac44d, 0x0025209c, 0x006b5c95, 0x007e80b3, 0x00696697, 0x0045353f, 0x008c592f, 0x00ece5aa, 0x00b6af90, 0x00c68a63, 0x00a37453, 0x009299a2, 0x00aab4bf, 0x00737274, 0x006c757c, 0x00c0c6cc, 0x00c2c1c3, 0x00c9cbd0, 0x00898b90, 0x00818184, 0x00868689, 0x009e9fa0, 0x00fefeff, 0x00fafbff, 0x00b8b7b3, 0x00f1f06f, 0x00fce200, 0x00faaf00, 0x00fbb400, 0x00fbb200, 0x00fab10e, 0x00fcb40c, 0x00fcac0a, 0x00feaf11,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00feae28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00ffb505, 0x00fefe3d, 0x00d3b477, 0x00d89167, 0x00ffc26d, 0x00d3934f, 0x00bb9d70, 0x00e5c290, 0x009f6641, 0x00c49e77, 0x00e9f0be, 0x00788088, 0x007f899a, 0x007e8388, 0x00555c62, 0x004e555d, 0x007a6656, 0x00ccbdb2, 0x00bbc1c9, 0x00717275, 0x00bbbaba, 0x00f4f4f3, 0x00f1f1f0, 0x00aeaeae, 0x00919194, 0x00b1b0a5, 0x00e6e4c9, 0x00fffffd, 0x00faf581, 0x00fabe00, 0x00ff9900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00eb8b1d, 0x0049250c, 0x0034110d, 0x003d1d0d, 0x0046230d, 0x0043200e, 0x00421e0c, 0x003c250a, 0x0036181b, 0x006a3b1a, 0x00e2a052, 0x007b5e4b, 0x00846e5b, 0x00ebc4a1, 0x00ffc58f, 0x00dfa275, 0x0084543b, 0x00bfba91, 0x00d8dcbe, 0x0071747a, 0x004a4849, 0x0071655c, 0x00c5b09e, 0x00ffc183, 0x00ce9162, 0x008c959d, 0x00acaeb1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00a8a8b5, 0x00b9b570, 0x00ffffb6, 0x00faffcb, 0x00fbffff, 0x00fbffb2, 0x00fad521, 0x00fb9e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00ffbf3f, 0x0073420f, 0x00373600, 0x008e9500, 0x00635300, 0x00191600, 0x003c3500, 0x00363100, 0x00483800, 0x00928b00, 0x00221700, 0x008a522b, 0x00d7a77e, 0x00f8bd8b, 0x00ad8465, 0x00d0ab8d, 0x00d69e74, 0x00be7d57, 0x00b19c76, 0x00dce2b7, 0x008d8f96, 0x00828a9a, 0x00a0724d, 0x00ffdc96, 0x00e8a16a, 0x009f9187, 0x00848a91, 0x00c7c7c7, 0x00cececf, 0x00dfdfdf, 0x00fbfbfb, 0x00ffffff, 0x00ffffff, 0x00cacba6, 0x00faf018, 0x00fbd112, 0x00fae041, 0x00faf37d, 0x00faff4e, 0x00fae113, 0x00faac0a, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00ffb233, 0x0044220d, 0x00836d00, 0x00eeca00, 0x00816200, 0x00bf9700, 0x00bf9100, 0x00be9100, 0x00f3c100, 0x00b39900, 0x00321600, 0x00eb9f60, 0x00e5b48b, 0x008d684e, 0x00b99e85, 0x00e7bc93, 0x00bb8863, 0x00f5af7d, 0x00d29e70, 0x00949b85, 0x00c6c7c2, 0x007a8487, 0x00836e63, 0x00af7d51, 0x00978a82, 0x0093a0ae, 0x008d8c8c, 0x00b5b4b4, 0x00c2c2c3, 0x00ececed, 0x00ececeb, 0x00b2b2b1, 0x00ffffff, 0x00d7daf4, 0x00d8dc6f, 0x00fec400, 0x00fb9200, 0x00faac00, 0x00fbb803, 0x00fbcb15, 0x00fab70c, 0x00fca807, 0x00ffbf3f, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00743c14, 0x00806800, 0x004c3400, 0x003b2d00, 0x00fffa00, 0x00b58a00, 0x008b6a00, 0x00cdbf00, 0x00291b00, 0x00765636, 0x00dab681, 0x00986a4e, 0x00e3b283, 0x00bf936f, 0x00caa488, 0x00bd8e6b, 0x00f2ab7a, 0x00ca986e, 0x00e8edb3, 0x00d7d6ad, 0x00b0afa6, 0x00848993, 0x00474f5a, 0x00b5bec6, 0x00979699, 0x00a2a1a0, 0x00cececf, 0x00d4d4d4, 0x00d3d3d5, 0x00dedfe0, 0x00c2c1bf, 0x00979696, 0x00c5c5c7, 0x00d1dde2, 0x00ffff82, 0x00faaa00, 0x00000000, 0x00000000, 0x00000000, 0x00ffbf3f, 0x00ffb10b, 0x00ffbf3f, 0x00000000,
0x00000000, 0x00000000, 0x00ffb624, 0x007c4d0d, 0x00be9900, 0x00332700, 0x00b08600, 0x00dfb400, 0x00ab8200, 0x00d19f00, 0x00f4e000, 0x00482a00, 0x00bea952, 0x00d9cb84, 0x00e9a688, 0x009d775c, 0x00a58c7d, 0x00ffe6bc, 0x00d89e77, 0x00d0926d, 0x00b99986, 0x00aec2b3, 0x00dbe5d5, 0x00f3feff, 0x008b97a6, 0x008b98a9, 0x008c94a0, 0x00727b86, 0x00bbbcc2, 0x00fdffff, 0x00ffffff, 0x00e9f4ff, 0x00b2bbc7, 0x00e5eefc, 0x00c0cde6, 0x00656c6f, 0x00e8df65, 0x00ffffb6, 0x00fffe35, 0x00ffb900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00ff9621, 0x003d2901, 0x00332a00, 0x00000000, 0x00423300, 0x003f2b00, 0x00342700, 0x005e4800, 0x008e8000, 0x003a2101, 0x00be860c, 0x00ca9318, 0x00804d2f, 0x00c38447, 0x00ffbd71, 0x00bc7337, 0x00eba15e, 0x00ffb161, 0x00b38a63, 0x00b2967c, 0x00b08f69, 0x00a28265, 0x00805d38, 0x00997a5d, 0x008f6845, 0x00bb9e7c, 0x00ffffff, 0x00fff3d4, 0x00c79e7f, 0x00d7b28e, 0x00ecdece, 0x00ac9784, 0x00d6b797, 0x00a47d58, 0x00c97f00, 0x00dfb617, 0x00f2d538, 0x00db990e, 0x00f0871b, 0x00ffa127, 0x00c06718, 0x00c76d1b, 0x00fea930, 0x00000000,
0x00000000, 0x00000000, 0x00975a11, 0x00000001, 0x00000005, 0x000c0504, 0x00000004, 0x00000000, 0x00000005, 0x00000002, 0x00000000, 0x00000001, 0x00351b08, 0x002c0c00, 0x003b2200, 0x00573209, 0x002e0f00, 0x00271b00, 0x002f1500, 0x006f450f, 0x002e1200, 0x00311200, 0x002d0900, 0x00351400, 0x00341600, 0x002d0a00, 0x00371700, 0x004b2808, 0x00cda35c, 0x003f1d00, 0x00270900, 0x001b0000, 0x009a601f, 0x00864f11, 0x00290700, 0x00532a00, 0x003a180c, 0x00290e00, 0x00230600, 0x00220b09, 0x003c250a, 0x00351a05, 0x00241807, 0x001b0d05, 0x00713f0e, 0x00feb12c,
0x00000000, 0x00f99622, 0x00472a0a, 0x00cb8f31, 0x00ffd041, 0x00ffea47, 0x008d641d, 0x00614014, 0x00ffce3d, 0x001a1105, 0x00000000, 0x009f6a20, 0x00f5d23e, 0x00ffd23d, 0x00e7af32, 0x00000000, 0x00896c1e, 0x00ffe444, 0x00ac7c24, 0x00020300, 0x00cfa129, 0x00e2b531, 0x00fdcf36, 0x00d1a028, 0x006b4c14, 0x00eec734, 0x00e9cd37, 0x007e6014, 0x00000000, 0x0075570e, 0x00ffef3d, 0x00d6b62f, 0x00000000, 0x002f1d00, 0x00dfda38, 0x001b1705, 0x002b2409, 0x00e9c82f, 0x002d2109, 0x00e1c42d, 0x0046390e, 0x00272208, 0x00fff335, 0x00e5d02e, 0x00322a09, 0x00be6916,
0x00000000, 0x00b05d12, 0x00654c14, 0x00ffe23e, 0x00ac7724, 0x00bca12c, 0x0047330d, 0x00d4a92a, 0x00fac431, 0x00000000, 0x00060301, 0x00fed633, 0x00d7ad2d, 0x00ab9226, 0x007c6017, 0x00725514, 0x00fff639, 0x00ffdd30, 0x00ffff3a, 0x00503b0d, 0x0097761c, 0x00fff537, 0x00e7cc2d, 0x00735814, 0x00c9a322, 0x00f3d72f, 0x00fad72e, 0x00f1cb29, 0x003e320a, 0x00fff531, 0x00edcb28, 0x00ffff34, 0x0040330a, 0x005d510f, 0x00ffff3c, 0x00816a14, 0x00c2a51e, 0x00d5b822, 0x0061510f, 0x00ffff2e, 0x0058480c, 0x00f8de25, 0x00fff229, 0x00ffff34, 0x00958a16, 0x007f370d,
0x00000000, 0x0071370c, 0x008a7d1a, 0x00ffff31, 0x008c8e17, 0x002b2203, 0x00000000, 0x00ffff35, 0x00816e13, 0x00000000, 0x004e410c, 0x00ffff32, 0x00beb01c, 0x0070610d, 0x00000000, 0x00e1c822, 0x00ecd222, 0x00624f0d, 0x00a2991b, 0x00000000, 0x002c2c05, 0x00ffff2f, 0x00150f01, 0x00000000, 0x00fffb26, 0x00d7c31c, 0x00f2e923, 0x00998815, 0x008a7d14, 0x00fff224, 0x009b8713, 0x00ffff26, 0x00483a0a, 0x00bcad19, 0x00ffff26, 0x00ddc31d, 0x00ffff26, 0x00655a0d, 0x00a79615, 0x00d1bc19, 0x006b5d0d, 0x00ffff27, 0x0068550b, 0x009e9414, 0x003e3a08, 0x00c26918,
0x00ff9f2a, 0x0058360b, 0x00c8c51c, 0x00f3f724, 0x00ffff2c, 0x00352d08, 0x004a450a, 0x00ffff2a, 0x00121201, 0x00000000, 0x00a39316, 0x00feff26, 0x00feff27, 0x00ae9e18, 0x00040100, 0x00ffff28, 0x00958813, 0x00000000, 0x00000000, 0x00000000, 0x00cbb21a, 0x00fff223, 0x00000000, 0x00423b09, 0x00ffff27, 0x00ffff26, 0x00e0d01e, 0x000c0800, 0x00dec51d, 0x00ccad19, 0x00c8a919, 0x00e5c51d, 0x003d3008, 0x00ffe422, 0x00ffde20, 0x00ffe522, 0x00fedd21, 0x00423208, 0x00fbd421, 0x007c630f, 0x00a68815, 0x00f8d722, 0x00000000, 0x00000000, 0x0065360c, 0x00feb429,
0x00c46618, 0x005c4e0c, 0x00ffff25, 0x00917d12, 0x0068590d, 0x00080501, 0x00c9af1a, 0x00efd41f, 0x000a0701, 0x00060501, 0x00f5d420, 0x00d9bc1c, 0x0060570e, 0x00291c05, 0x0067510d, 0x00ffe925, 0x00856510, 0x00d1b91e, 0x003f3008, 0x00000000, 0x00ffe524, 0x00b48715, 0x00000000, 0x00be9317, 0x00efca21, 0x00d0aa1c, 0x00d59e1a, 0x00412c08, 0x00ffd523, 0x00a17614, 0x00ffc922, 0x00825b10, 0x00674d0d, 0x00ffc221, 0x00b97e16, 0x00ffdf26, 0x00ab7815, 0x004f370a, 0x00ffcd24, 0x005e3e0c, 0x00f3af1e, 0x00b17615, 0x00b57e17, 0x00815b10, 0x008c5011, 0x00000000,
0x0079400e, 0x00977913, 0x00ffff2b, 0x00ffd424, 0x00fbbb20, 0x005b410b, 0x00ffc822, 0x00ffe627, 0x00d0981a, 0x0062440c, 0x00ffdf27, 0x00ffcb24, 0x00ffe127, 0x005f410c, 0x0076540f, 0x00ffe228, 0x00ffcb24, 0x00ffe728, 0x00151003, 0x00493009, 0x00fff82d, 0x00342106, 0x00080501, 0x00ffd828, 0x00c37817, 0x00ed941d, 0x00d18b1a, 0x0057390b, 0x00ffc927, 0x00ffaf22, 0x00ffc325, 0x00402508, 0x00f99f1f, 0x00b36f16, 0x005e380b, 0x00ffed2f, 0x0074450e, 0x00b66f17, 0x00ff9b1f, 0x00362007, 0x00ffb425, 0x00ffa222, 0x00ffd02a, 0x0070480e, 0x00955212, 0x00000000,
0x0054320a, 0x00473809, 0x007f6212, 0x00876912, 0x004e3509, 0x001d1604, 0x00a36d14, 0x00916812, 0x004f3108, 0x002f1a04, 0x00aa7917, 0x00915810, 0x00a57315, 0x00170e03, 0x00000000, 0x00b37a18, 0x00ca8f1c, 0x00421a04, 0x00000000, 0x006b430d, 0x00a87217, 0x00000000, 0x00170c02, 0x009e6915, 0x003f2006, 0x00ac6615, 0x00351904, 0x00000000, 0x00a36014, 0x00b27216, 0x005b2c08, 0x00000000, 0x00b17117, 0x00210e02, 0x00000000, 0x008e5b11, 0x00261303, 0x00905312, 0x00522707, 0x00000000, 0x00965412, 0x00bb7f1c, 0x005e320c, 0x00381f07, 0x00faa220, 0x00000000,
0x00be7118, 0x004a2909, 0x003b1b06, 0x003b1d07, 0x004b300b, 0x00442507, 0x00000000, 0x00010304, 0x000a0604, 0x00211b08, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00151507, 0x00000000, 0x00000000, 0x00151809, 0x002b1b09, 0x00000000, 0x00000000, 0x001f1a09, 0x000e0a03, 0x00000000, 0x00030403, 0x00000000, 0x00080404, 0x00161106, 0x00000000, 0x000c0e07, 0x00000004, 0x00241b09, 0x00000000, 0x00000002, 0x00171309, 0x00000004, 0x00100c05, 0x00000000, 0x00080806, 0x001e1609, 0x00000000, 0x00120b01, 0x003f2d09, 0x00de871c, 0x00000000, 0x00000000,
0x00000000, 0x00ffb226, 0x00fea924, 0x00fea924, 0x00fec638, 0x008b4810, 0x006f6516, 0x00ffff38, 0x00ffff38, 0x00f0c92a, 0x000f0b04, 0x00f6d730, 0x008b731a, 0x000a0603, 0x00fff437, 0x0032290a, 0x00675314, 0x00ffff3e, 0x00ffe637, 0x001e1906, 0x000f0b04, 0x00ffed3a, 0x0033280a, 0x00b18623, 0x00eab72e, 0x00000000, 0x00fbc634, 0x00795d18, 0x005c4314, 0x00fff541, 0x00fff640, 0x00fac233, 0x001a1107, 0x00dba32f, 0x00ffee40, 0x00ffff47, 0x007a5d1a, 0x0036250d, 0x00ffe943, 0x00ffde41, 0x00745c1e, 0x00703e0b, 0x00ffba29, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fe9c27, 0x004a2f09, 0x00dfdd20, 0x00b5b01c, 0x00818517, 0x00544c0c, 0x00413e0a, 0x00ffff33, 0x009f9218, 0x00817313, 0x00fee727, 0x003a3509, 0x00fff32b, 0x00ddca23, 0x00ffff34, 0x004b430c, 0x006c5c11, 0x00ffe72a, 0x00221d05, 0x00ffed2d, 0x00e8c826, 0x005a4b0f, 0x00fff430, 0x0040370b, 0x00d7b725, 0x00bfaa25, 0x0080771c, 0x005b4b10, 0x0055460f, 0x00fff334, 0x007e6118, 0x0090851e, 0x00221c06, 0x00bf9b23, 0x00d4b82c, 0x00ebc42e, 0x00dabd2b, 0x0055300a, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00be6116, 0x0049430a, 0x00ffff26, 0x00c1b719, 0x0069560c, 0x00000000, 0x009c9015, 0x00ffff2a, 0x00d2c21b, 0x00faef22, 0x00867b10, 0x006b650e, 0x00ffff25, 0x00141701, 0x0069680d, 0x00101002, 0x00ebe120, 0x008f8311, 0x003a3908, 0x00ffff2b, 0x00e8db1f, 0x00e5d820, 0x00c4b61a, 0x002f2e06, 0x00ffff29, 0x00ccc91c, 0x00746e0c, 0x00000000, 0x00a89918, 0x00ffff2b, 0x00949e17, 0x00191700, 0x00000000, 0x00ffff2b, 0x00c9b91c, 0x00eee224, 0x00696c11, 0x006f340d, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00713b0e, 0x0073640f, 0x00f2d622, 0x00dacd20, 0x00917813, 0x00000000, 0x00e7ba1e, 0x00fad221, 0x00ffce20, 0x00fff126, 0x00403308, 0x00b59817, 0x00e4c01d, 0x009b7d13, 0x006b500d, 0x00171503, 0x00ffff26, 0x00342c06, 0x00927f13, 0x00ffeb24, 0x00eed01e, 0x00ffff29, 0x0061550c, 0x0060570c, 0x00f7f723, 0x00d7de20, 0x009d9115, 0x00000100, 0x00e4d41e, 0x00d7d91e, 0x00e8e922, 0x00242205, 0x00353207, 0x00ffff27, 0x00ffff28, 0x00bbbe19, 0x00180d02, 0x00eb8a1e, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00fea924, 0x004c2d09, 0x00cd8c19, 0x00c88519, 0x0048320a, 0x00180b03, 0x00372707, 0x00ffb721, 0x00865510, 0x00ffb420, 0x00df971b, 0x003c2808, 0x00fcb520, 0x009b6c12, 0x00ffd825, 0x00946d13, 0x005c460c, 0x00ffbd21, 0x00191203, 0x00fac020, 0x00986a12, 0x00c59319, 0x00ffde25, 0x00342606, 0x00c59819, 0x00d5a81c, 0x00483f0b, 0x001b1003, 0x003b3007, 0x00fff127, 0x007a5f0f, 0x00513c0a, 0x00020000, 0x00bb9a18, 0x00d8b91d, 0x00b9a019, 0x00bea318, 0x005e320b, 0x00ffcc33, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00c06f17, 0x005b370b, 0x00ffb126, 0x00ffaf25, 0x00ffcb2b, 0x00502f0a, 0x00a76415, 0x00fc941f, 0x000b0301, 0x00ffc629, 0x00a15d14, 0x00030200, 0x00ffb726, 0x00ffab24, 0x00ffbc26, 0x00392007, 0x00ec921d, 0x00b06915, 0x005d390c, 0x00ffcb28, 0x000b0401, 0x00ee951d, 0x00fd9c1e, 0x00412808, 0x00ffc125, 0x00ffc125, 0x00ffe22b, 0x00603f0c, 0x00885b11, 0x00ffe22a, 0x00ffd227, 0x00ffb521, 0x00372507, 0x00ffca25, 0x00996112, 0x00ef9e1d, 0x00b18016, 0x005e340b, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00a86514, 0x00060301, 0x0054380c, 0x004e2d0a, 0x0051310b, 0x00000000, 0x003a2208, 0x002d1906, 0x00000000, 0x004b300b, 0x00241405, 0x00130b03, 0x00482709, 0x00724d11, 0x00512b0a, 0x00000000, 0x0053300a, 0x00000000, 0x00170d03, 0x0049280a, 0x00000000, 0x00412408, 0x001e0e04, 0x00000000, 0x0054370b, 0x004d2a09, 0x0051320a, 0x00000000, 0x00251705, 0x004d330b, 0x0051380b, 0x00231304, 0x00000000, 0x0054350b, 0x00060300, 0x004d3109, 0x00080401, 0x00bb7018, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00fb951f, 0x007b490f, 0x004c2b09, 0x004d2d09, 0x004d2b09, 0x00864f10, 0x005c370b, 0x006e410d, 0x00cc7919, 0x004d2b09, 0x00865010, 0x00ec901e, 0x004f2e09, 0x003b2007, 0x00452908, 0x00824e10, 0x0051300a, 0x0074450e, 0x0070420d, 0x004d2d09, 0x00cc7a1a, 0x006e410d, 0x005f390c, 0x007d4b0f, 0x004d2b09, 0x004d2d09, 0x004d2b09, 0x007f4b10, 0x00673c0d, 0x004d2809, 0x004d2909, 0x0061380c, 0x00834d10, 0x004d2a09, 0x0073430f, 0x00502d0a, 0x007e490f, 0x00ffa125, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 816)
const int epd_bitmap_allArray_LEN = 1;
const unsigned long* epd_bitmap_allArray[1] = {
logo
};