From fb870e9043314ed49924cf8f20e73ee85d70aa0a Mon Sep 17 00:00:00 2001 From: Mark Donners <60584210+donnersm@users.noreply.github.com> Date: Sun, 11 Jul 2021 14:39:22 +0200 Subject: [PATCH] Add files via upload --- Main Sketch/V1.0/FFT.h | 135 +++++ Main Sketch/V1.0/FFT_EPS32_V1.0.ino | 798 ++++++++++++++++++++++++++++ Main Sketch/V1.0/I2SPLUGIN.h | 79 +++ Main Sketch/V1.0/LEDDRIVER.h | 155 ++++++ Main Sketch/V1.0/PatternsHUB75.h | 462 ++++++++++++++++ Main Sketch/V1.0/PatternsLedstrip.h | 244 +++++++++ Main Sketch/V1.0/Settings.h | 200 +++++++ Main Sketch/V1.0/fire.h | 82 +++ Main Sketch/V1.0/logos.h | 93 ++++ 9 files changed, 2248 insertions(+) create mode 100644 Main Sketch/V1.0/FFT.h create mode 100644 Main Sketch/V1.0/FFT_EPS32_V1.0.ino create mode 100644 Main Sketch/V1.0/I2SPLUGIN.h create mode 100644 Main Sketch/V1.0/LEDDRIVER.h create mode 100644 Main Sketch/V1.0/PatternsHUB75.h create mode 100644 Main Sketch/V1.0/PatternsLedstrip.h create mode 100644 Main Sketch/V1.0/Settings.h create mode 100644 Main Sketch/V1.0/fire.h create mode 100644 Main Sketch/V1.0/logos.h diff --git a/Main Sketch/V1.0/FFT.h b/Main Sketch/V1.0/FFT.h new file mode 100644 index 0000000..478b89e --- /dev/null +++ b/Main Sketch/V1.0/FFT.h @@ -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 diff --git a/Main Sketch/V1.0/FFT_EPS32_V1.0.ino b/Main Sketch/V1.0/FFT_EPS32_V1.0.ino new file mode 100644 index 0000000..57113f1 --- /dev/null +++ b/Main Sketch/V1.0/FFT_EPS32_V1.0.ino @@ -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 +#include +#include "I2SPLUGIN.h" +#include +#include +#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) 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; yDemoTreshold)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 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 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; xdrawPixelRGB888(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;gTotalbnd)Totalbnd=bndcounter[g]; + } + + + for (int g=0;g 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 +} diff --git a/Main Sketch/V1.0/I2SPLUGIN.h b/Main Sketch/V1.0/I2SPLUGIN.h new file mode 100644 index 0000000..052c681 --- /dev/null +++ b/Main Sketch/V1.0/I2SPLUGIN.h @@ -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 +#include + +//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."); +} diff --git a/Main Sketch/V1.0/LEDDRIVER.h b/Main Sketch/V1.0/LEDDRIVER.h new file mode 100644 index 0000000..0fa0e92 --- /dev/null +++ b/Main Sketch/V1.0/LEDDRIVER.h @@ -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(leds, NUM_LEDS).setCorrection(TypicalSMD5050); + FastLED.setMaxPowerInVoltsAndMilliamps(LED_VOLTS, MAX_MILLIAMPS); + FastLED.setBrightness(BRIGHTNESSMARK); + FastLED.clear(); + #endif +} diff --git a/Main Sketch/V1.0/PatternsHUB75.h b/Main Sketch/V1.0/PatternsHUB75.h new file mode 100644 index 0000000..3f1d643 --- /dev/null +++ b/Main Sketch/V1.0/PatternsHUB75.h @@ -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= 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= 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= 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= 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= 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= 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= 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= 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(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;ydrawPixelRGB888(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(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;ydrawPixelRGB888(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= 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(NeededWidthdrawPixel(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(NeededWidthdrawPixel(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(NeededWidthdrawPixel(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(NeededWidthdrawPixel(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(NeededWidthdrawPixelRGB888(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 diff --git a/Main Sketch/V1.0/PatternsLedstrip.h b/Main Sketch/V1.0/PatternsLedstrip.h new file mode 100644 index 0000000..c1a1de6 --- /dev/null +++ b/Main Sketch/V1.0/PatternsLedstrip.h @@ -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;ydrawPixel(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;ydrawPixel(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;ydrawPixel(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 ** + ********************************************************************************************************************************/ diff --git a/Main Sketch/V1.0/Settings.h b/Main Sketch/V1.0/Settings.h new file mode 100644 index 0000000..07ed03e --- /dev/null +++ b/Main Sketch/V1.0/Settings.h @@ -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 +}; diff --git a/Main Sketch/V1.0/fire.h b/Main Sketch/V1.0/fire.h new file mode 100644 index 0000000..07fc1f4 --- /dev/null +++ b/Main Sketch/V1.0/fire.h @@ -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 ); + } +} diff --git a/Main Sketch/V1.0/logos.h b/Main Sketch/V1.0/logos.h new file mode 100644 index 0000000..d18695b --- /dev/null +++ b/Main Sketch/V1.0/logos.h @@ -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 +#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 +};