/* * December 2019 * Developed by Plastibots.com with guidnace from the below samples/write-ups. Please keep this info intact and give credit where due. * Based off a number of sources where credit is due: https://projectxero2one.com/rainbow-blaze-hardware-drool/ https://projectxero2one.com/flashing-rgb-leds-and-a-person-drooling/ https://www.eeweb.com/profile/max-maxfield/articles/handling-noise-when-working-with-the-msgeq7-audio-spectrum-analyzer https://learn.adafruit.com/vu-meter-baseball-hat?view=all Additonal references: https://www.instructables.com/id/Lumen-Histoire-IoT-App/ https://github.com/amiravni/MSGEQ7_ESP8266_WS2812/blob/master/MSGEQ7_ArduinoTest.ino https://www.eeweb.com/profile/max-maxfield/articles/tips-and-tricks-for-using-the-msgeq7-spectrum-analyzer https://github.com/engineertype/MSGEQ7/blob/master/MSGEQ7_Demo.ino https://rheingoldheavy.com/msgeq7-arduino-tutorial-01-getting-started/ https://www.instructables.com/id/ESP8266-controlling-Neopixel-LEDs-using-Arduino-ID/ https://blog.adafruit.com/2016/12/09/easy-arduino-msgeq7-breadboard-build-for-flashing-led-strip-lights/ https://github.com/Makuna/NeoPixelBus Hardware: Using these LED strips (x2) https://www.banggood.com/5M-45W-150SMD-WS2812B-LED-RGB-Colorful-Strip-Light-Waterproof-IP65-WhiteBlack-PCB-DC5V-p-1035640.html?p=R90804949020201412E4 (NO LONGER) Using this MIC: https://www.banggood.com/search/max4466.html?p=R90804949020201412E4&cur_warehouse=CN Using this NodeMCU ESP8266: http://www.banggood.com/Mini-NodeMCU-ESP8266-WIFI-Development-Board-Based-On-ESP-12F-p-1054209.html?p=R90804949020201412E4 MSGEQ7 2 band. 1 band also works: https://www.ebay.ca/itm/MSGEQ7-breakout-board-7-band-graphic-equalizer-for-audio-for-Arduino-RPi-PIC/301210655107?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649 v11 - switched over to ESP32 as ESP8266 sleep features are limited. Wanted to have a reliable wake on interrupt. In this case waking from a 5V signal from the 12V out of my audio system. // - Also added OTA method to allow wireless future updates. // - Switched to Makuna NeoPixelBus library top support ESP32 and NeoPixels - https://github.com/Makuna/NeoPixelBus v10- Added OptoIsolator circuit for 12 external trigger. Reads D6 LOW when 12V signal detected. HIGH when no 12V signal. v9 - cleaned up some bugs. v8 - integrating music reactive VU Meter component from MSGEQ7ProjectorEQV3 project code v7 - skip v6 - adding 2nd set of LED strip for under audio cabinet PARKED THIS FOR NOW - works but very slow and causes frequent crashes v5 - stable version with single set of LED strip for projector Written by Adafruit Industries. Distributed under the BSD license. This paragraph must be included in any redistribution. Redistribution and use in source and binary forms are permitted provided that the above copyright notice and this paragraph are duplicated in all such forms and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed by the . The name of the may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include //For Arduino OTA #include //For Arduino OTA #include //For Arduino OTA #include #include /* Comment this out to disable prints and save space */ //#define BLYNK_PRINT Serial #include #include #include //#include //#include //#include //#include #include //https://github.com/adafruit/Adafruit_NeoPixel //Blynk connection credentials char auth[] = "BLYNK AUTH HERE"; char ssid[] = "SSID"; char pass[] = "SSID PASSWORD"; const char* host = "esp32BsmtPixels"; //Arduino OTA host name #define EEPROM_SIZE 4 // define the number of bytes you want to access #define scrnPxlCount 216 // 216 Number of LEDs in pixel strip. #define cabinetPxlCount 73 //under cabinet LEDs - this has 73 pixels //testing is 56 #define screenHalfPxls scrnPxlCount/2 #define cabinetHalfPxls cabinetPxlCount/2 #define VISUALS 6 #define MSGEQ7_AIN 35 #define ResetPin 32 // MSGEQ7 --> 7 #define StrobePin 25 // MSGEQ7 --> 4 #define PixelPin 12 //Projector LEDs pin #define PixelPin2 14 //Cabinet LEDs pin #define TriggerPin 33 //12V Trigger to allow wakeup of unit //Projector LEDs variables #define scrnBarPixels 35 //with projector will be 50 testing 20 - defines the "height" of the side VU meter in pixels - side of projector #define topLeft 71 //with projector will be 50 testing 22 - for the left bar #define botLeft 36 //with projector will be 36 testing 0 - for the left bar #define topRight 146 //reversed //with projector will be 135 testing 34 - for the right bar #define botRight 181 //reversed //with projector will be 185 testing 54 - for the right bar //End Projector LEDs variables - myStrip //For ESP Sleep //interrups. In this case, its the 2 PIR pins defined below (35,39). Either will cause the ESP to wake up. int tmrSleep; const long sleepDelayMs = 60000; //60000 = 1 minute; //delay before ESP goes to sleep RTC_DATA_ATTR int bootCount = 0; // to show the # of times the system has rebooted SimpleTimer timer; // the timer object //End ESP Sleep //variables for MSGEQ7 const int filter = 80; //normalize out the noise when no music is playing const int TotalSamples = 8; const int TotalBands = 7; int VUPxl_Red = 0; int VUPxl_Grn = 0; int VUPxl_Blu = 255; int VUPxlPeak_Red = 255; int VUPxlPeak_Grn = 0; int VUPxlPeak_Blu = 0; int VUMode = 0; //allows switching of VU colours using Blynk int band[TotalBands] = {0}; //END variables for MSGEQ7 boolean debug = false; //Serial debugging //int iotStatus = 0; int LEDpattern = 1; //set default int lastLEDpattern = 0; int realColor = 0; int LEDbrightness = 0; //int reading; int previous = LOW; long times = 0; long debounce = 200; uint32_t redValue = 0; uint32_t greenValue = 0; uint32_t blueValue = 0; uint32_t redcheer = 0; uint32_t greencheer = 0; uint32_t bluecheer = 0; uint16_t gradient = 0; uint16_t thresholds[] = {1529, 1019, 764, 764, 764, 1274}; uint8_t palette = 0; uint8_t visual = 0; uint8_t volume = 0; uint8_t last = 0; float maxVol = 15; float avgBump = 0; float avgVol = 0; float shuffleTime = 0; int8_t pos[scrnPxlCount] = {-2}; uint8_t rgb[scrnPxlCount][3] = {0}; bool shuffle = true; bool bump = true; bool left = false; int8_t dotPos = 0; float timeBump = 0; float avgTime = 0; int tmrClearMsg; int msgShowDuration = 5000; //Projector LEDs Adafruit_NeoPixel screenPixels = Adafruit_NeoPixel(scrnPxlCount, PixelPin, NEO_GRB + NEO_KHZ800); //Under cabinet LEDs Adafruit_NeoPixel cabinetPixels = Adafruit_NeoPixel(cabinetPxlCount, PixelPin2, NEO_GRB + NEO_KHZ800); WebServer server(80); // For OTA //ARDUINO OTA WEBSERVER CONTENT ########################################################################## /* * Login page */ /* Style */ String style = ""; /* Login page */ String loginIndex = "
" "

ESP32 Screen Pixels Login

" " " " " "
" "" + style; /* Server Index Page */ String serverIndex = "" "
" "" "" "" "

" "
" "

" "" + style; //ARDUINO OTA END WEBSERVER CONTENT ####################################################################### //###################################################################################### BLYNK_WRITE(V0) //All LEDs off { LEDpattern = -1; setAll(0, 0, 0); Blynk.virtualWrite(V5, 0); Blynk.virtualWrite(V6, 0); Blynk.virtualWrite(V1, "LEDs Off"); timer.restartTimer(tmrClearMsg); //timer.restartTimer(tmrSleep); //Ensure ESP doesnt go to sleep in the middle of this. } //###################################################################################### BLYNK_WRITE(V5) //Get Segmented Switch #1 Option from Blynk { Blynk.virtualWrite(V6, 0); //clear 2nd row option selection switch (param.asInt()) { case 1: { // Music LEDpattern = 1; break; } case 2: { // RGB Loop LEDpattern = 2; break; } case 3: { // Cylon LEDpattern = 3; break; } case 4: { // Twinkle LEDpattern = 4; break; } case 5: { // Twinkle Random LEDpattern = 5; break; } } lastLEDpattern = LEDpattern; Blynk.virtualWrite(V1, "Pattern Changed:" + String(LEDpattern)); timer.restartTimer(tmrClearMsg); //timer.restartTimer(tmrSleep); //Ensure ESP doesnt go to sleep in the middle of this. } //###################################################################################### BLYNK_WRITE(V6) //Get Segmented Switch #2 Option from Blynk { Blynk.virtualWrite(V5, 0); switch (param.asInt()) { case 1: { // Sparkle LEDpattern = 6; break; } case 2: { // Snow Sprinkle LEDpattern = 7; break; } case 3: { // Colour Wipe LEDpattern = 8; break; } case 4: { // Rainbow LEDpattern = 9; break; } case 5: { // Bouncing Balls LEDpattern = 10; break; } } lastLEDpattern = LEDpattern; Blynk.virtualWrite(V1, "Pattern Changed:" + String(LEDpattern)); timer.restartTimer(tmrClearMsg); } //Blynk.setProperty(V2, "label", "<< Select LED Mode"); //Update the label //Good example for setProperty parameter. https://github.com/blynkkk/blynk-library/blob/master/examples/More/SetProperty/SetProperty_MultiValue/SetProperty_MultiValue.ino BLYNK_WRITE(V8) // Music VU Mode LED Patterns { switch (param.asInt()) //allows changing the colour patterns { case 0: {VUPxl_Red=0, VUPxl_Grn=0, VUPxl_Blu=255, VUPxlPeak_Red=255, VUPxlPeak_Grn=0, VUPxlPeak_Blu=0, VUMode=0; break;} case 1: {VUPxl_Red=255, VUPxl_Grn=0, VUPxl_Blu=0, VUPxlPeak_Red=0, VUPxlPeak_Grn=0, VUPxlPeak_Blu=255, VUMode=0; break;} case 2: {VUPxl_Red=0, VUPxl_Grn=255, VUPxl_Blu=0, VUPxlPeak_Red=0, VUPxlPeak_Grn=0, VUPxlPeak_Blu=255, VUMode=0; break;} case 3: {VUPxl_Red=107, VUPxl_Grn=34, VUPxl_Blu=174, VUPxlPeak_Red=0, VUPxlPeak_Grn=0, VUPxlPeak_Blu=255, VUMode=0; break;} case 4: {VUPxl_Red=206, VUPxl_Grn=0, VUPxl_Blu=156, VUPxlPeak_Red=129, VUPxlPeak_Grn=0, VUPxlPeak_Blu=56, VUMode=0; break;} case 5: {VUPxl_Red=0, VUPxl_Grn=0, VUPxl_Blu=0, VUPxlPeak_Red=0, VUPxlPeak_Grn=0, VUPxlPeak_Blu=255, VUMode=1; break;} //this mode switches the main VU bars to a colour wheel break; } } //###################################################################################### BLYNK_WRITE(V4) // zeRGBa assigned to V4 { setAll(0, 0, 0); //clear all LEDs // get a RED channel value redValue = param[0].asInt(); // get a GREEN channel value greenValue = param[1].asInt(); // get a BLUE channel value blueValue = param[2].asInt(); Blynk.virtualWrite(V1, "Colour changed."); LEDpattern = 11; //for RGB lastLEDpattern = LEDpattern; Blynk.virtualWrite(V5, 0); Blynk.virtualWrite(V6, 0); timer.restartTimer(tmrClearMsg); } //###################################################################################### BLYNK_WRITE(V7) //LED Brightness Slider { int val = param.asInt(); EEPROM.put(0, val); //write val to EEPROM byte # 0. Note, no need to check if different as the put function only writes if the value is different. EEPROM.commit(); LEDbrightness = val; screenPixels.setBrightness(LEDbrightness); delay(200); cabinetPixels.setBrightness(LEDbrightness*0.7); //these are much brighter under the cabinet, so scale down delay(200); Blynk.virtualWrite(V1, "Brightness updated:" + String(val)); timer.restartTimer(tmrClearMsg); } //###################################################################################### BLYNK_CONNECTED() { } //###################################################################################### void clearBlynkStatMsg() { Blynk.virtualWrite(V1, " "); //timer.disable(tmrClearMsg); } //###################################################################################### /* Method to print the reason by which ESP32 has been awaken from sleep */ void print_wakeup_reason(){ esp_sleep_wakeup_cause_t wakeup_reason; wakeup_reason = esp_sleep_get_wakeup_cause(); switch(wakeup_reason) { case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break; } } //###################################################################################### void goToSleep() { Serial.print(F("Sleep triggered.")); Blynk.virtualWrite(V1, "ESP32 Pixels has gone to sleep..."); delay(100); setAll(0, 0, 0); //ensure all the Pixels are off delay(500); esp_deep_sleep_start(); //esp_light_sleep_start(); } //###################################################################################### void setup() { pinMode(PixelPin, OUTPUT); pinMode(ResetPin, OUTPUT); pinMode(StrobePin, OUTPUT); pinMode(TriggerPin, INPUT); Serial.begin(115200); Serial.println(); ++bootCount; //for ESP sleep feature Serial.println("Boot number: " + String(bootCount)); //Print the wakeup reason for ESP32 print_wakeup_reason(); esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,1); //1 = High, 0 = Low //If you were to use ext1, you would use it like //esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH); Serial.print("Going to sleep based on the timer setting of: ");Serial.print(sleepDelayMs/1000);Serial.println(" seconds"); Serial.print("Pin 33 Level: ");Serial.println(digitalRead(33)); EEPROM.begin(EEPROM_SIZE); // initialize EEPROM with predefined size LEDbrightness = EEPROM.read(0); //get the stored brightness level. delay(50); screenPixels.begin(); delay(200); screenPixels.setBrightness(LEDbrightness); delay(200); cabinetPixels.begin(); delay(200); cabinetPixels.setBrightness(LEDbrightness * 0.7); //scale down as these are much brighter //WiFi.hostname("ESP8266_ScreenLEDs"); //set the name as friendly - will show in Router device list. WiFi.setHostname("ESP32_ScrnPixels"); Blynk.begin(auth, ssid, pass); if (debug) {Serial.print(F("Connecting to Blynk"));} while (Blynk.connect() == false) { //Wait until connected if (debug) {Serial.println(".");} } if (debug) {Serial.println(F("WiFi Connected!"));} if (debug) {Serial.println(F(""));} Blynk.virtualWrite(V1, " "); Blynk.virtualWrite(V5, 0); Blynk.virtualWrite(V6, 0); Blynk.virtualWrite(V8, 0); //music mode Blynk.virtualWrite(V2, ""); Blynk.virtualWrite(V2, WiFi.localIP().toString()); tmrClearMsg = timer.setInterval(msgShowDuration, clearBlynkStatMsg); //timed delay for shutting off LEDs after they have come on. //#################################################################################################################### //Arduino OTA Stuff begin /*use mdns for host name resolution*/ if (!MDNS.begin(host)) { //http://esp32Pixels.local or use IPAddress/ e.g. http://192.168.2.141/ if (debug) {Serial.println("Error setting up MDNS responder!");} while (1) { delay(1000); } } if (debug) {Serial.println("mDNS responder started");} /*return index page which is stored in serverIndex */ server.on("/", HTTP_GET, []() { server.sendHeader("Connection", "close"); server.send(200, "text/html", loginIndex); }); server.on("/serverIndex", HTTP_GET, []() { server.sendHeader("Connection", "close"); server.send(200, "text/html", serverIndex); }); /*handling uploading firmware file */ server.on("/update", HTTP_POST, []() { server.sendHeader("Connection", "close"); server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); ESP.restart(); }, []() { HTTPUpload& upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { Serial.printf("Update: %s\n", upload.filename.c_str()); if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_WRITE) { /* flashing firmware to ESP*/ if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { //true to set the size to the current progress Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { Update.printError(Serial); } } }); server.begin(); if (debug) {Serial.println("Server.begin complete...");} //Arduino OTA Stuff end tmrSleep = timer.setInterval(sleepDelayMs, goToSleep); } void loop() { Blynk.run(); //must be here. Avoid any delay()'s. timer.run(); server.handleClient(); //web update - at the ready. unsigned long currentMillis = millis(); //for sleep feature if (digitalRead(TriggerPin) == 1) { //if the trigger pin is HIGH (receiver is on and Trigger out is sending signal), then don't start the sleep routine. //before going to sleep, ensure all LEDs are off etc. timer.restartTimer(tmrSleep); //Ensure ESP doesnt go to sleep by resetting the timer } if (debug) {Serial.print(" Pattern: ");} if (debug) {Serial.print(LEDpattern);} if (debug) {Serial.print(" Mic: ");} if (debug) {Serial.print(volume);} if (debug) {Serial.print(" Millis: ");} if (debug) {Serial.println(millis());} switch (LEDpattern) { case 1: { getDance(); //music mode on Blynk break; } case 2: { RGBLoop(LEDpattern); break; } case 3: { CylonBounce(random(0, 255), random(0, 255), random(0, 255), 4, 50, 100, LEDpattern); break; } case 4: { Twinkle(0xE3, 0x20, 0xD6, 20, 100, false, LEDpattern); break; } case 5: { TwinkleRandom(6, 100, false, LEDpattern); break; } case 6: { Sparkle(random(255), random(255), random(255), 100); break; } case 7: { SnowSparkle(0x10, 0x10, 0x10, 100, random(100,1000)); break; } case 8: { colorWipe(random(0, 255), random(0, 255), random(0, 255), 50, LEDpattern); break; } case 9: { theaterChaseRainbow(100, LEDpattern); break; } case 10: { BouncingBalls(random(0, 255), random(0, 255), random(0, 255), 3, LEDpattern); break; } case 11: { setLed(); //RGB Mode break; } //statBlink(3,500); } //Send the ESP off to light sleep after inactivity and if no patterns selected. /* if (currentMillis - prevSleepMillis >= sleepDelayMs) { // save the last time you blinked the LED prevSleepMillis = currentMillis; if (debug) {Serial.print(F(" Sleep triggered."));} delay(100); //this is for ESP32! esp_light_sleep_start(); //esp_deep_sleep_start(); } */ /* { for (int i=0; i <= screenPixels.numPixels(); i++) { screenPixels.setPixelColor(i, screenPixels.Color(0, 0, 0)); } screenPixels.show(); } */ /* for (int y = 0; y < PixelCount; y++) { if ((y>=74) && (y<=118)) { setPixel(y, 30, 0, 0); } else { setPixel(y, 150, 0, 0); } screenPixels.show(); //delay(300); //setPixel(y, 0, 0, 0); //screenPixels.show(); } */ /* for (int y = 0; y < PixelCount; y++ ) { setPixel(y, 200, 200, 200); screenPixels.show(); delay(300); setPixel(y, 0, 0, 0); screenPixels.show(); } */ /* for (int y = 78; y < 113; y++ ) { setPixel(y, 200, 200, 200); screenPixels.show(); delay(300); //setPixel(y, 0, 0, 0); //screenPixels.show(); } // 78-113 are pixels under bulkhead */ } /* void statBlink(int howmany, int howlong) { for (int i; i 0) { uint32_t col = ColorPalette(-1); int start = screenHalfPxls - (screenHalfPxls * (volume / maxVol)); int finish = screenHalfPxls + (screenHalfPxls * (volume / maxVol)) + screenPixels.numPixels() % 2; for (int i = start; i < finish; i++) { float damp = sin((i - start) * PI / float(finish - start)); damp = pow(damp, 2.0); uint32_t col2 = screenPixels.getPixelColor(i); uint8_t colors[3]; float avgCol = 0; float avgCol2 = 0; for (int k = 0; k < 3; k++) { colors[k] = split(col, k) * damp * pow(volume / maxVol, 2); avgCol += colors[k]; avgCol2 += split(col2, k); } avgCol /= 3.0, avgCol2 /= 3.0; if (avgCol > avgCol2) screenPixels.setPixelColor(i, screenPixels.Color(colors[0], colors[1], colors[2])); } } screenPixels.show(); } ////////////////////////////////////////////////////////////////////////////////////////// void PalettePulse() { fade(0.75); if (bump) gradient += thresholds[palette] / 24; if (volume > 0) { int start = screenHalfPxls - (screenHalfPxls * (volume / maxVol)); int finish = screenHalfPxls + (screenHalfPxls * (volume / maxVol)) + screenPixels.numPixels() % 2; for (int i = start; i < finish; i++) { float damp = sin((i - start) * PI / float(finish - start)); damp = pow(damp, 2.0); int val = thresholds[palette] * (i - start) / (finish - start); val += gradient; uint32_t col = ColorPalette(val); uint32_t col2 = screenPixels.getPixelColor(i); uint8_t colors[3]; float avgCol = 0, avgCol2 = 0; for (int k = 0; k < 3; k++) { colors[k] = split(col, k) * damp * pow(volume / maxVol, 2); avgCol += colors[k]; avgCol2 += split(col2, k); } avgCol /= 3.0, avgCol2 /= 3.0; if (avgCol > avgCol2) screenPixels.setPixelColor(i, screenPixels.Color(colors[0], colors[1], colors[2])); } } screenPixels.show(); } ////////////////////////////////////////////////////////////////////////////////////////////////////// void Traffic() { fade(0.8); if (bump) { int8_t slot = 0; for (slot; slot < sizeof(pos); slot++) { if (pos[slot] < -1) break; else if (slot + 1 >= sizeof(pos)) { slot = -3; break; } } if (slot != -3) { pos[slot] = (slot % 2 == 0) ? -1 : screenPixels.numPixels(); uint32_t col = ColorPalette(-1); gradient += thresholds[palette] / 24; for (int j = 0; j < 3; j++) { rgb[slot][j] = split(col, j); } } } if (volume > 0) { for (int i = 0; i < sizeof(pos); i++) { if (pos[i] < -1) continue; pos[i] += (i % 2) ? -1 : 1; if (pos[i] >= screenPixels.numPixels()) pos[i] = -2; screenPixels.setPixelColor( pos[i], screenPixels.Color( float(rgb[i][0]) * pow(volume / maxVol, 2.0), float(rgb[i][1]) * pow(volume / maxVol, 2.0), float(rgb[i][2]) * pow(volume / maxVol, 2.0)) ); } } screenPixels.show(); } ///////////////////////////////////////////////////////////////////////////////////////////// void Snake() { if (bump) { gradient += thresholds[palette] / 30; left = !left; } fade(0.975); uint32_t col = ColorPalette(-1); if (volume > 0) { screenPixels.setPixelColor(dotPos, screenPixels.Color( float(split(col, 0)) * pow(volume / maxVol, 1.5), float(split(col, 1)) * pow(volume / maxVol, 1.5), float(split(col, 2)) * pow(volume / maxVol, 1.5)) ); if (avgTime < 0.15) dotPos += (left) ? -1 : 1; else if (avgTime >= 0.15 && avgTime < 0.5 && gradient % 2 == 0) dotPos += (left) ? -1 : 1; else if (avgTime >= 0.5 && avgTime < 1.0 && gradient % 3 == 0) dotPos += (left) ? -1 : 1; else if (gradient % 4 == 0) dotPos += (left) ? -1 : 1; } screenPixels.show(); if (dotPos < 0) dotPos = screenPixels.numPixels() - 1; else if (dotPos >= screenPixels.numPixels()) dotPos = 0; } /////////////////////////////////////////////////////////////// void PaletteDance() { if (bump) left = !left; if (volume > avgVol) { for (int i = 0; i < screenPixels.numPixels(); i++) { float sinVal = abs(sin( (i + dotPos) * (PI / float(screenPixels.numPixels() / 1.25) ) )); sinVal *= sinVal; sinVal *= volume / maxVol; unsigned int val = float(thresholds[palette] + 1) //map takes a value between -PixelCount and +PixelCount and returns one between 0 and PixelCount * (float(i + map(dotPos, -1 * (screenPixels.numPixels() - 1), screenPixels.numPixels() - 1, 0, screenPixels.numPixels() - 1)) / float(screenPixels.numPixels())) + (gradient); val %= thresholds[palette]; uint32_t col = ColorPalette(val); screenPixels.setPixelColor(i, screenPixels.Color( float(split(col, 0))*sinVal, float(split(col, 1))*sinVal, float(split(col, 2))*sinVal) ); } dotPos += (left) ? -1 : 1; } else fade(0.8); screenPixels.show(); if (dotPos < 0) dotPos = screenPixels.numPixels() - screenPixels.numPixels() / 6; else if (dotPos >= screenPixels.numPixels() - screenPixels.numPixels() / 6) dotPos = 0; } /////////////////////////////////////////////////////////////////////// void Glitter() { gradient += thresholds[palette] / 204; for (int i = 0; i < screenPixels.numPixels(); i++) { unsigned int val = float(thresholds[palette] + 1) * (float(i) / float(screenPixels.numPixels())) + (gradient); val %= thresholds[palette]; uint32_t col = ColorPalette(val); screenPixels.setPixelColor(i, screenPixels.Color( split(col, 0) / 6.0, split(col, 1) / 6.0, split(col, 2) / 6.0) ); } if (bump) { randomSeed(micros()); dotPos = random(screenPixels.numPixels() - 1); screenPixels.setPixelColor(dotPos, screenPixels.Color( 255.0 * pow(volume / maxVol, 2.0), 255.0 * pow(volume / maxVol, 2.0), 255.0 * pow(volume / maxVol, 2.0) )); } bleed(dotPos); screenPixels.show(); } ////////////////////////////////////////////////////////////////// void Paintball() { if ((millis() / 1000.0) - timeBump > avgTime * 2.0) fade(0.99); if (bump) { randomSeed(micros()); dotPos = random(screenPixels.numPixels() - 1); uint32_t col = ColorPalette(random(thresholds[palette])); uint8_t colors[3]; for (int i = 0; i < 3; i++) colors[i] = split(col, i) * pow(volume / maxVol, 2.0); screenPixels.setPixelColor(dotPos, screenPixels.Color(colors[0], colors[1], colors[2])); for (int i = 0; i < 3; i++) colors[i] *= .8; screenPixels.setPixelColor(dotPos - 1, screenPixels.Color(colors[0], colors[1], colors[2])); screenPixels.setPixelColor(dotPos + 1, screenPixels.Color(colors[0], colors[1], colors[2])); } screenPixels.show(); } //////////////////////////////////////////////////// void Cycle() { for (int i = 0; i < screenPixels.numPixels(); i++) { float val = float(thresholds[palette]) * (float(i) / float(screenPixels.numPixels())) + (gradient); val = int(val) % thresholds[palette]; screenPixels.setPixelColor(i, ColorPalette(val)); } screenPixels.show(); gradient += 32; } ///////////////////////////////////////////////////// void CyclePalette() { if (shuffle && millis() / 1000.0 - shuffleTime > 30 && gradient % 2) { shuffleTime = millis() / 1000.0; palette++; if (palette >= sizeof(thresholds) / 2) palette = 0; gradient %= thresholds[palette]; maxVol = avgVol; } } ////////////////////////////////////////////////////// void CycleVisual() { if (shuffle && millis() / 1000.0 - shuffleTime > 30 && !(gradient % 2)) { shuffleTime = millis() / 1000.0; visual++; gradient = 0; if (visual > VISUALS) visual = 0; if (visual == 1) memset(pos, -2, sizeof(pos)); if (visual == 2 || visual == 3) { randomSeed(analogRead(MSGEQ7_AIN)); dotPos = random(screenPixels.numPixels()); } maxVol = avgVol; } } ////////////////////////////////////////////////////////////// void fade(float damper) { for (int i = 0; i < screenPixels.numPixels(); i++) { uint32_t col = screenPixels.getPixelColor(i); if (col == 0) continue; float colors[3]; for (int j = 0; j < 3; j++) colors[j] = split(col, j) * damper; screenPixels.setPixelColor(i, screenPixels.Color(colors[0] , colors[1], colors[2])); } } //////////////////////////////////////////////////////////////// void bleed(uint8_t Point) { for (int i = 1; i < screenPixels.numPixels(); i++) { int sides[] = {Point - i, Point + i}; for (int i = 0; i < 2; i++) { int point = sides[i]; uint32_t colors[] = {screenPixels.getPixelColor(point - 1), screenPixels.getPixelColor(point), screenPixels.getPixelColor(point + 1) }; screenPixels.setPixelColor(point, screenPixels.Color( float( split(colors[0], 0) + split(colors[1], 0) + split(colors[2], 0) ) / 3.0, float( split(colors[0], 1) + split(colors[1], 1) + split(colors[2], 1) ) / 3.0, float( split(colors[0], 2) + split(colors[1], 2) + split(colors[2], 2) ) / 3.0) ); } } } ///////////////////////////////////////////////////////////////////////////////// uint8_t split(uint32_t color, uint8_t i ) { if (i == 0) return color >> 16; if (i == 1) return color >> 8; if (i == 2) return color >> 0; return -1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t Rainbow(unsigned int i) { if (i > 1529) return Rainbow(i % 1530); if (i > 1274) return screenPixels.Color(255, 0, 255 - (i % 255)); if (i > 1019) return screenPixels.Color((i % 255), 0, 255); if (i > 764) return screenPixels.Color(0, 255 - (i % 255), 255); if (i > 509) return screenPixels.Color(0, 255, (i % 255)); if (i > 255) return screenPixels.Color(255 - (i % 255), 255, 0); return screenPixels.Color(255, i, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t Sunset(unsigned int i) { if (i > 1019) return Sunset(i % 1020); if (i > 764) return screenPixels.Color((i % 255), 0, 255 - (i % 255)); if (i > 509) return screenPixels.Color(255 - (i % 255), 0, 255); if (i > 255) return screenPixels.Color(255, 128 - (i % 255) / 2, (i % 255)); return screenPixels.Color(255, i / 2, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t Ocean(unsigned int i) { if (i > 764) return Ocean(i % 765); if (i > 509) return screenPixels.Color(0, i % 255, 255 - (i % 255)); if (i > 255) return screenPixels.Color(0, 255 - (i % 255), 255); return screenPixels.Color(0, 255, i); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t PinaColada(unsigned int i) { if (i > 764) return PinaColada(i % 765); if (i > 509) return screenPixels.Color(255 - (i % 255) / 2, (i % 255) / 2, (i % 255) / 2); if (i > 255) return screenPixels.Color(255, 255 - (i % 255), 0); return screenPixels.Color(128 + (i / 2), 128 + (i / 2), 128 - i / 2); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t Sulfur(unsigned int i) { if (i > 764) return Sulfur(i % 765); if (i > 509) return screenPixels.Color(i % 255, 255, 255 - (i % 255)); if (i > 255) return screenPixels.Color(0, 255, i % 255); return screenPixels.Color(255 - i, 255, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// uint32_t NoGreen(unsigned int i) { if (i > 1274) return NoGreen(i % 1275); if (i > 1019) return screenPixels.Color(255, 0, 255 - (i % 255)); if (i > 764) return screenPixels.Color((i % 255), 0, 255); if (i > 509) return screenPixels.Color(0, 255 - (i % 255), 255); if (i > 255) return screenPixels.Color(255 - (i % 255), 255, i % 255); return screenPixels.Color(255, i, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RGBLoop(int LP) { int getOut = 0; for (int j = 0; j < 3; j++ ) { if (getOut) {break;} // Fade IN for (int k = 0; k < 256; k++) { if (LP != lastLEDpattern){if (debug) {Serial.println(F("broken out of loop success"));}getOut=1; break;} switch (j) { case 0: setAll(k, 0, 0); break; case 1: setAll(0, k, 0); break; case 2: setAll(0, 0, k); break; } screenPixels.show(); delay(3); if ( j % 50 == 0) {Blynk.run();} //call blynk.run every 50th iteration. Keeps connection alive (hearbeat) } // Fade OUT for (int k = 255; k >= 0; k--) { if (LP != lastLEDpattern){if (debug) {Serial.println(F("broken out of loop success"));}getOut=1; break;} switch (j) { case 0: setAll(k, 0, 0); break; case 1: setAll(0, k, 0); break; case 2: setAll(0, 0, k); break; } screenPixels.show(); delay(3); if ( k % 50 == 0) {Blynk.run();} } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Strobe(byte red, byte green, byte blue, int StrobeCount, int FlashDelay, int EndPause, int LP) { for (int j = 0; j < StrobeCount; j++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setAll(red, green, blue); screenPixels.show(); delay(FlashDelay); setAll(0, 0, 0); screenPixels.show(); delay(FlashDelay); } delay(EndPause); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void HalloweenEyes(byte red, byte green, byte blue, int EyeWidth, int EyeSpace, boolean Fade, int Steps, int FadeDelay, int EndPause) { randomSeed(analogRead(MSGEQ7_AIN)); int i; int StartPoint = random( 0, scrnPxlCount - (2 * EyeWidth) - EyeSpace ); int Start2ndEye = StartPoint + EyeWidth + EyeSpace; for (i = 0; i < EyeWidth; i++) { setPixel(StartPoint + i, red, green, blue); setPixel(Start2ndEye + i, red, green, blue); } screenPixels.show(); if (Fade == true) { float r, g, b; for (int j = Steps; j >= 0; j--) { r = j * (red / Steps); g = j * (green / Steps); b = j * (blue / Steps); for (i = 0; i < EyeWidth; i++) { setPixel(StartPoint + i, r, g, b); setPixel(Start2ndEye + i, r, g, b); } screenPixels.show(); delay(FadeDelay); } } setAll(0, 0, 0); // Set all black delay(EndPause); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CylonBounce(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LP) { for (int i = 0; i < scrnPxlCount - EyeSize - 2; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setAll(0, 0, 0); setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 10 == 0) { if (debug) {Serial.println(F("CylonBounceWorking"));} Blynk.run(); } //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); for (int i = scrnPxlCount - EyeSize - 2; i > 0; i--) { if (LP != lastLEDpattern) { if (debug) {Serial.println(F("Broken out of Cylon Bounce"));} break; } setAll(0, 0, 0); setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 10 == 0) {if (debug) {Serial.println(F("CylonBounceWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void NewKITT(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay) { RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); LeftToRight(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); RightToLeft(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); OutsideToCenter(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); CenterToOutside(red, green, blue, EyeSize, SpeedDelay, ReturnDelay, LEDpattern); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CenterToOutside(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LP) { for (int i = ((scrnPxlCount - EyeSize) / 2); i >= 0; i--) { setAll(0, 0, 0); if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); setPixel(scrnPxlCount - i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(scrnPxlCount - i - j, red, green, blue); } setPixel(scrnPxlCount - i - EyeSize - 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 50 == 0) {if (debug) {Serial.println(F("CenterToOutsideWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void OutsideToCenter(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LP) { for (int i = 0; i <= ((scrnPxlCount - EyeSize) / 2); i++) { setAll(0, 0, 0); if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); setPixel(scrnPxlCount - i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(scrnPxlCount - i - j, red, green, blue); } setPixel(scrnPxlCount - i - EyeSize - 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 50 == 0) {if (debug) {Serial.println(F("OutsideToCenterWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void LeftToRight(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LP) { for (int i = 0; i < scrnPxlCount - EyeSize - 2; i++) { setAll(0, 0, 0); if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 50 == 0) {if (debug) {Serial.println(F("LeftToRightWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RightToLeft(byte red, byte green, byte blue, int EyeSize, int SpeedDelay, int ReturnDelay, int LP) { for (int i = scrnPxlCount - EyeSize - 2; i > 0; i--) { setAll(0, 0, 0); if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i, red / 10, green / 10, blue / 10); for (int j = 1; j <= EyeSize; j++) { setPixel(i + j, red, green, blue); } setPixel(i + EyeSize + 1, red / 10, green / 10, blue / 10); screenPixels.show(); delay(SpeedDelay); if ( i % 50 == 0) {if (debug) {Serial.println(F("RightToLeftWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(ReturnDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Twinkle(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne, int LP) { setAll(0, 0, 0); for (int i = 0; i < Count; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(random(scrnPxlCount), red, green, blue); screenPixels.show(); delay(SpeedDelay); if (OnlyOne) { setAll(0, 0, 0); } if ( i % 50 == 0) {if (debug) {Serial.println(F("TwinkleWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(SpeedDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void TwinkleRandom(int Count, int SpeedDelay, boolean OnlyOne, int LP) { setAll(0, 0, 0); for (int i = 0; i < Count; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(random(scrnPxlCount), random(0, 255), random(0, 255), random(0, 255)); screenPixels.show(); delay(SpeedDelay); if (OnlyOne) { setAll(0, 0, 0); } if ( i % 50 == 0) {if (debug) {Serial.println(F("TwinkleRandomWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } delay(SpeedDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sparkle(byte red, byte green, byte blue, int SpeedDelay) { int Pixel = random(scrnPxlCount); setPixel(Pixel, red, green, blue); screenPixels.show(); delay(SpeedDelay); setPixel(Pixel, 0, 0, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void SnowSparkle(byte red, byte green, byte blue, int SparkleDelay, int SpeedDelay) { setAll(red, green, blue); int Pixel = random(scrnPxlCount); setPixel(Pixel, 0xff, 0xff, 0xff); screenPixels.show(); delay(SparkleDelay); setPixel(Pixel, red, green, blue); screenPixels.show(); delay(SpeedDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void RunningLights(byte red, byte green, byte blue, int WaveDelay, int LP) { int Position = 0; for (int i = 0; i < scrnPxlCount * 2; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed Position++; // = 0; //Position + Rate; for (int i = 0; i < scrnPxlCount; i++) { setPixel(i, ((sin(i + Position) * 127 + 128) / 255)*red, ((sin(i + Position) * 127 + 128) / 255)*green, ((sin(i + Position) * 127 + 128) / 255)*blue); } screenPixels.show(); delay(WaveDelay); if ( i % 40 == 0) {if (debug) {Serial.println(F("RunningLightsWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void colorWipe(byte red, byte green, byte blue, int SpeedDelay, int LP) { for (uint16_t i = 0; i < scrnPxlCount; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i, red, green, blue); screenPixels.show(); delay(SpeedDelay); if ( i % 50 == 0) {if (debug) {Serial.println(F("ColourWipeWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void rainbowCycle(int SpeedDelay, int LP) { byte *c; uint16_t i, j; for (j = 0; j < 256*5; j++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed for (i = 0; i < scrnPxlCount; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed c = Wheel(((i * 256 / scrnPxlCount) + j) & 255); setPixel(i, *c, *(c + 1), *(c + 2)); } screenPixels.show(); delay(SpeedDelay); if ( j % 50 == 0) {if (debug) {Serial.println(F("RainbowCycleWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// byte* Wheel(byte WheelPos) { static byte c[3]; if (WheelPos < 85) { c[0] = WheelPos * 3; c[1] = 255 - WheelPos * 3; c[2] = 0; } else if (WheelPos < 170) { WheelPos -= 85; c[0] = 255 - WheelPos * 3; c[1] = 0; c[2] = WheelPos * 3; } else { WheelPos -= 170; c[0] = 0; c[1] = WheelPos * 3; c[2] = 255 - WheelPos * 3; } return c; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void theaterChase(byte red, byte green, byte blue, int SpeedDelay, int LP) { for (int j = 0; j < 10; j++) { //do 10 cycles of chasing for (int q = 0; q < 3; q++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed for (int i = 0; i < scrnPxlCount; i = i + 3) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i + q, red, green, blue); } screenPixels.show(); delay(SpeedDelay); for (int i = 0; i < scrnPxlCount; i = i + 3) { setPixel(i + q, 0, 0, 0); } } if ( j % 2 == 0) {if (debug) {Serial.println(F("TheatreChaseWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void theaterChaseRainbow(int SpeedDelay, int LP) { byte *c; for (int j = 0; j < 256; j++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed for (int q = 0; q < 3; q++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed for (int i = 0; i < scrnPxlCount; i = i + 3) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed c = Wheel( (i + j) % 255); setPixel(i + q, *c, *(c + 1), *(c + 2)); } screenPixels.show(); delay(SpeedDelay); for (int i = 0; i < scrnPxlCount; i = i + 3) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed setPixel(i + q, 0, 0, 0); } } if ( j % 50 == 0) {if (debug) {Serial.println(F("TheatreChaseRaimbowWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Fire(int Cooling, int Sparking, int SpeedDelay, int LP) { static byte heat[scrnPxlCount]; int cooldown; // Step 1. Cool down every cell a little for ( int i = 0; i < scrnPxlCount; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed cooldown = random(0, ((Cooling * 10) / scrnPxlCount) + 2); if (cooldown > heat[i]) { heat[i] = 0; } else { heat[i] = heat[i] - cooldown; } if ( i % 50 == 0) {if (debug) {Serial.println(F("FireWorking"));} Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) if ( i % 10 == 0) {Blynk.run();} //call blynk.run every 10th iteration. Keeps connection alive (hearbeat) } // Step 2. Heat from each cell drifts 'up' and diffuses a little for ( int k = scrnPxlCount - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3; } // Step 3. Randomly ignite new 'sparks' near the bottom if ( random(255) < Sparking ) { int y = random(7); heat[y] = heat[y] + random(160, 255); //heat[y] = random(160,255); } // Step 4. Convert heat to LED colors for ( int j = 0; j < scrnPxlCount; j++) { setPixelHeatColor(j, heat[j] ); } screenPixels.show(); delay(SpeedDelay); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setPixelHeatColor (int Pixel, byte temperature) { // Scale 'heat' down from 0-255 to 0-191 byte t192 = round((temperature / 255.0) * 191); // calculate ramp up from byte heatramp = t192 & 0x3F; // 0..63 heatramp <<= 2; // scale up to 0..252 // figure out which third of the spectrum we're in: if ( t192 > 0x80) { // hottest setPixel(Pixel, 255, 255, heatramp); } else if ( t192 > 0x40 ) { // middle setPixel(Pixel, 255, heatramp, 0); } else { // coolest setPixel(Pixel, heatramp, 0, 0); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BouncingBalls(byte red, byte green, byte blue, int BallCount, int LP) { if (debug) {Serial.println(F("BouncingBalls Started"));} float Gravity = -9.81; int StartHeight = 1; float Height[BallCount]; float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight ); float ImpactVelocity[BallCount]; float TimeSinceLastBounce[BallCount]; int Position[BallCount]; long ClockTimeSinceLastBounce[BallCount]; float Dampening[BallCount]; int whilecounter=0; for (int i = 0 ; i < BallCount ; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed ClockTimeSinceLastBounce[i] = millis(); Height[i] = StartHeight; Position[i] = 0; ImpactVelocity[i] = ImpactVelocityStart; TimeSinceLastBounce[i] = 0; Dampening[i] = 0.90 - float(i) / pow(BallCount, 2); } while (whilecounter<100) { whilecounter++; if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed for (int i = 0 ; i < BallCount ; i++) { if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed TimeSinceLastBounce[i] = millis() - ClockTimeSinceLastBounce[i]; Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i] / 1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i] / 1000; if ( Height[i] < 0 ) { Height[i] = 0; ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i]; ClockTimeSinceLastBounce[i] = millis(); if ( ImpactVelocity[i] < 0.01 ) { ImpactVelocity[i] = ImpactVelocityStart; } } Position[i] = round( Height[i] * (scrnPxlCount - 1) / StartHeight); } for (int i = 0 ; i < BallCount ; i++) { setPixel(Position[i], red, green, blue); if (LP != lastLEDpattern){break;} //allows to break out of looping when Blynk pattern is changed } screenPixels.show(); setAll(0, 0, 0); delay(100); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void BouncingColoredBalls(int BallCount, byte colors[][3]) { float Gravity = -9.81; int StartHeight = 1; float Height[BallCount]; float ImpactVelocityStart = sqrt( -2 * Gravity * StartHeight ); float ImpactVelocity[BallCount]; float TimeSinceLastBounce[BallCount]; int Position[BallCount]; long ClockTimeSinceLastBounce[BallCount]; float Dampening[BallCount]; int whilecounter=0; for (int i = 0 ; i < BallCount ; i++) { ClockTimeSinceLastBounce[i] = millis(); Height[i] = StartHeight; Position[i] = 0; ImpactVelocity[i] = ImpactVelocityStart; TimeSinceLastBounce[i] = 0; Dampening[i] = 0.90 - float(i) / pow(BallCount, 2); } while (whilecounter<100) { whilecounter++; for (int i = 0 ; i < BallCount ; i++) { TimeSinceLastBounce[i] = millis() - ClockTimeSinceLastBounce[i]; Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i] / 1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i] / 1000; if ( Height[i] < 0 ) { Height[i] = 0; ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i]; ClockTimeSinceLastBounce[i] = millis(); if ( ImpactVelocity[i] < 0.01 ) { ImpactVelocity[i] = ImpactVelocityStart; } } Position[i] = round( Height[i] * (scrnPxlCount - 1) / StartHeight); } for (int i = 0 ; i < BallCount ; i++) { setPixel(Position[i], colors[i][0], colors[i][1], colors[i][2]); } screenPixels.show(); setAll(0, 0, 0); delay(100); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setPixel(int Pixel, byte red, byte green, byte blue) { screenPixels.setPixelColor(Pixel, screenPixels.Color(red, green, blue)); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setAll(byte red, byte green, byte blue) { for (int i = 0; i < cabinetPxlCount; i++ ) { cabinetPixels.setPixelColor(i, cabinetPixels.Color(red, green, blue)); } cabinetPixels.show(); delay(100); for (int i = 0; i < scrnPxlCount; i++ ) { //setPixel(i, red, green, blue); screenPixels.setPixelColor(i, screenPixels.Color(red, green, blue)); } screenPixels.show(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void getReal() { if (realColor == 1) { //Candle redValue = 125; greenValue = 47; blueValue = 0; } else if (realColor == 2) { //40W Tungsten redValue = 125; greenValue = 97; blueValue = 43; } else if (realColor == 3) { //100 Tungsten redValue = 105; greenValue = 64; blueValue = 20; } else if (realColor == 4) { //Halogen redValue = 105; greenValue = 91; blueValue = 74; } else if (realColor == 5) { //Carbon Arc redValue = 105; greenValue = 100; blueValue = 94; } else if (realColor == 6) { //High Noon Sun redValue = 105; greenValue = 105; blueValue = 101; } else if (realColor == 7) { //Direct Sunlight redValue = 105; greenValue = 105; blueValue = 105; } else if (realColor == 8) { //Overcast Sky; redValue = 51; greenValue = 76; blueValue = 105; } else if (realColor == 9) { //Clear Blue Sky redValue = 0; greenValue = 56; blueValue = 155; } else if (realColor == 10) { //Warm Fluorescent redValue = 105; greenValue = 94; blueValue = 79; } else if (realColor == 11) { //Standard Fluorescent redValue = 94; greenValue = 105; blueValue = 100; } else if (realColor == 12) { //Cool White Fluorescent redValue = 62; greenValue = 85; blueValue = 105; } else if (realColor == 13) { //Full Spectrum Fluorescent redValue = 105; greenValue = 94; blueValue = 92; } else if (realColor == 14) { //Grow Light Fluorescent redValue = 105; greenValue = 89; blueValue = 97; } else if (realColor == 15) { //Black Light Fluorescent redValue = 37; greenValue = 0; blueValue = 105; } else if (realColor == 16) { //Mercury Vapor redValue = 66; greenValue = 97; blueValue = 105; } else if (realColor == 17) { //Sodium Vapor redValue = 105; greenValue = 59; blueValue = 28; } else if (realColor == 18) { //Metal Halide redValue = 92; greenValue = 102; blueValue = 105; } else if (realColor == 19) { //High Pressure Sodium redValue = 105; greenValue = 133; blueValue = 0; } setLed(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setLed() { for (int y = 0; y < scrnPxlCount; y++ ) { //setPixel(y, redValue, greenValue, blueValue); if ((y>=74) && (y<=118)) { //setPixel(y, 30, 0, 0); setPixel(y, int(redValue/5), int(greenValue/5), int(blueValue/5)); } else { setPixel(y, redValue, greenValue, blueValue); } } screenPixels.show(); delay(100); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setCheer() { for (int y = 0; y < scrnPxlCount; y++ ) { setPixel(y, redcheer, greencheer, bluecheer); } screenPixels.show(); delay(100); } void readMSGEQ7() { int tempVal, normalizedVal; digitalWrite(ResetPin, HIGH); digitalWrite(ResetPin, LOW); delayMicroseconds(80); for (int i = 0; i < TotalBands; i++) { digitalWrite(StrobePin, LOW); delayMicroseconds(40); tempVal = 0; for (int sample_count = 0; sample_count < TotalSamples; sample_count++) { //tempVal = tempVal + analogRead(MSGEQ7_AIN); //remove noise when idle - could be noise in wiring, EMF etc normalizedVal = constrain(analogRead(MSGEQ7_AIN), filter, 1023); normalizedVal = map(normalizedVal, filter,1023,0,1023); tempVal = tempVal + normalizedVal; } band[i] = tempVal / TotalSamples; digitalWrite(StrobePin, HIGH); delayMicroseconds(40); } } void updatePixelPeakHold(Adafruit_NeoPixel * myPixel, Adafruit_NeoPixel * myPixel2, int nValue, int nValue2, byte VUr, byte VUg, byte VUb, byte VUPeakr, byte VUPeakg, byte VUPeakb, int VUMode) { //inputs (projector screen led strip | under cabinet led strip | projector VU freq band | under cabinet VU freq band | VUColourRed | VUColourGreen | VUColourBlue| VUPeakColourRed | VUPeakColourGreen | VUPeakColourBlue | VU Display modde) int pixelOnCtn=0, pixelOnCtn2 = 0; static int peakPixel = 0, peakPixel2 = 0; static int peakHoldLoopCtn = 0,peakHoldLoopCtn2 = 0; //pixelOnCtn = map(nValue, 0, 1023, 0, scrnPxlCount/2); pixelOnCtn = map(nValue, 0, 1023, 0, scrnBarPixels); //for both left and right, max 50 pixels on sides pixelOnCtn2 = map(nValue2, 0, 1023, 0, cabinetHalfPxls); //under cabinet // Clear all pixels - projector screen for (int i = 0; i < scrnPxlCount; i++) //do all pixels not half { myPixel->setPixelColor(i, myPixel->Color(0, 0, 0)); } // Clear all pixels - under cabinet for (int i = 0; i < cabinetPxlCount; i++) //do all pixels not half { myPixel2->setPixelColor(i, myPixel2->Color(0, 0, 0)); } //Setup response on projector pixels //*************************************************************************************** if (pixelOnCtn > peakPixel) { peakPixel = pixelOnCtn; // New Peak Pixel Found! } else { peakHoldLoopCtn++; // Spend little time before decying down the peak pixel if (peakHoldLoopCtn >= 4) //the bigger the # the longer the delay - 5 is good { peakHoldLoopCtn = 0; // Time to decay down if (peakPixel > 0) { peakPixel = peakPixel - 1; } } if (peakPixel == 0) { //RIGHT BAR Clear peak pixel myPixel->setPixelColor(botRight - peakPixel, myPixel->Color(0, 0, 0)); //LEFT BAR Clear peak pixel myPixel->setPixelColor(botLeft + peakPixel, myPixel->Color(0, 0, 0)); } else { //RIGHT BAR Fill peak pixel with colour (R - 200, G - 200, B - 200) myPixel->setPixelColor(botRight - peakPixel, myPixel->Color(VUPxlPeak_Red, VUPxlPeak_Grn, VUPxlPeak_Blu)); //this is the peak pixel. //LEFT BAR Fill peak pixel with colour (R - 200, G - 200, B - 200) myPixel->setPixelColor(botLeft + peakPixel, myPixel->Color(VUPxlPeak_Red, VUPxlPeak_Grn, VUPxlPeak_Blu)); //this is the peak pixel. } } for (int i = 1; i < pixelOnCtn; i++) //fill the rest of the pixels { if(VUMode == 0) //default colour mode { //RIGHT BAR myPixel->setPixelColor(botRight - i + 1, myPixel->Color(VUr, VUg, VUb)); //shifts ahead to start at half in the middle of the strip and go to the right. //LEFT BAR myPixel->setPixelColor(botLeft + i - 1, myPixel->Color(VUr, VUg, VUb)); } else //use colour wheel { //RIGHT BAR myPixel->setPixelColor(botRight - i + 1, Wheel2(map(i,0,botRight+1,30,150))); //shifts ahead to start at half in the middle of the strip and go to the right. //LEFT BAR myPixel->setPixelColor(botLeft + i - 1, Wheel2(map(i,0,topLeft-1,30,150))); } } //*************************************************************************************** //END Setup response on projector pixels //Setup response on under cabinet pixels //*************************************************************************************** if (pixelOnCtn2 > peakPixel2) { // New Peak Pixel Found! peakPixel2 = pixelOnCtn2; } else { // Spend little time before decying down the peak pixel peakHoldLoopCtn2++; if (peakHoldLoopCtn2 >= 4) //the bigger the # the longer the delay - 5 is good { // Time to decay down peakHoldLoopCtn2 = 0; if (peakPixel2 > 0) { peakPixel2 = peakPixel2 - 1; } } if (peakPixel2 == 0) { //RIGHT BAR Clear peak pixel myPixel2->setPixelColor(peakPixel2 + cabinetHalfPxls, myPixel2->Color(0, 0, 0)); //LEFT BAR Clear peak pixel myPixel2->setPixelColor(cabinetHalfPxls - peakPixel2, myPixel2->Color(0, 0, 0)); } else { //RIGHT BAR Fill peak pixel myPixel2->setPixelColor(peakPixel2 + cabinetHalfPxls - 1, myPixel2->Color(VUPxlPeak_Red, VUPxlPeak_Grn, VUPxlPeak_Blu)); //this is the peak pixel. //LEFT BAR Fill peak pixel myPixel2->setPixelColor(cabinetHalfPxls - 1 - peakPixel2, myPixel2->Color(VUPxlPeak_Red, VUPxlPeak_Grn, VUPxlPeak_Blu)); //this is the peak pixel. } } for (int i = 1; i < pixelOnCtn2; i++) //fill the rest of the pixels { if (VUMode == 0) //default using colours { //myPixel2->setPixelColor(i-1, myPixel2->Color(r, g, b)); //RIGHT BAR myPixel2->setPixelColor(i + cabinetHalfPxls - 1, myPixel2->Color(VUr, VUg, VUb)); //shifts ahead to start at half in the middle of the strip and go to the right. //LEFT BAR myPixel2->setPixelColor(cabinetHalfPxls - i - 1, myPixel2->Color(VUr, VUg, VUb)); } else //use colour wheel { //SAMPLE myPixel->setPixelColor(botRight - i + 1, Wheel2(map(i,0,botRight+1,30,150))) //RIGHT BAR myPixel2->setPixelColor(i + cabinetHalfPxls - 1, Wheel2(map(i,0,cabinetHalfPxls-1,30,150))); //shifts ahead to start at half in the middle of the strip and go to the right. //LEFT BAR myPixel2->setPixelColor(cabinetHalfPxls - i - 1, Wheel2(map(i,0,cabinetHalfPxls-1,30,150))); } } //*************************************************************************************** //END Setup response on under cabinet pixels myPixel->show(); //show projector screen pixels myPixel2->show(); //show under cabinet pixels } // Input a value 0 to 255 to get a color value. // The colors are a transition r - g - b - back to r. uint32_t Wheel2(byte WheelPos) { if(WheelPos < 85) { return screenPixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return screenPixels.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return screenPixels.Color(0, WheelPos * 3, 255 - WheelPos * 3); } } //This is redundant now /* ////////////////////////////////////////////////////////////////////////////////////////////////////////////// void getPattern() { if (LEDpattern == 1) { RGBLoop(LEDpattern); } else if (LEDpattern == 2) { Strobe(random(0, 255), random(0, 255), random(0, 255), 10, 50, 1000, LEDpattern); } else if (LEDpattern == 3) { HalloweenEyes(0xff, 0x00, 0x00, 1, 2, true, random(5, 30), random(50, 150), random(500, 2000)); } else if (LEDpattern == 4) { CylonBounce(random(0, 255), random(0, 255), random(0, 255), 4, 50, 100, LEDpattern); } else if (LEDpattern == 5) { NewKITT(random(0, 255), random(0, 255), random(0, 255), 3, 10, 1000); } else if (LEDpattern == 6) { Twinkle(0xE3, 0x20, 0xD6, 20, 100, false, LEDpattern); } else if (LEDpattern == 7) { TwinkleRandom(6, 100, false, LEDpattern); } else if (LEDpattern == 8) { Sparkle(random(255), random(255), random(255), 100); } else if (LEDpattern == 9) { SnowSparkle(0x10, 0x10, 0x10, 100, random(100,1000)); } else if (LEDpattern == 10) { RunningLights(random(0, 255), random(0, 255), random(0, 255), 200, LEDpattern); } else if (LEDpattern == 11) { colorWipe(random(0, 255), random(0, 255), random(0, 255), 50, LEDpattern); } else if (LEDpattern == 12) { rainbowCycle(20, LEDpattern); } else if (LEDpattern == 13) { theaterChase(0xff,0,0,200, LEDpattern); } //else if (LEDpattern == 14) { // theaterChaseRainbow(100); //} else if (LEDpattern == 14) { Fire(55,120,15, LEDpattern); } else if (LEDpattern == 15) { BouncingBalls(random(0, 255), random(0, 255), random(0, 255), 3, LEDpattern); } else if (LEDpattern == 16) { byte colors[3][3] = { {0xE3, 0x30, 0x14}, {0x20, 0xE3, 0x19}, {0x17, 0x17, 0xE3} }; BouncingColoredBalls(3, colors); } } * / */