#include "ESP8266WiFi.h" #include "ESP8266WebServer.h" #include "FastLED.h" #include "EEPROM.h" #include "FS.h" //required for SPIFFS //#include "spi.h" //SPI CLK = GPIO14 //SPI MOSI = GPIO13 //SPI MISO = GPIO12 #define DATA_PIN 7 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define NUM_LEDS 30 #define NUM_STRIPS 6 #define CHIPSET WS2812B //addresses to save data to EEPROM to preserve the state of fire simulation #define cs0Adr 0 #define cs1Adr 3 #define cs2Adr 6 #define cs3Adr 9 #define BriAdr 15 #define FpsAdr 16 #define SparkingAdr 17 #define CoolingAdr 18 #define EEPROMCheckAdr 20 //if this value is 250 we assume we have previously saved to EEPROM and load data from that CRGB leds[NUM_STRIPS * NUM_LEDS]; String inData; uint8_t FPS = 100; //FRAMES_PER_SECOND uint8_t SPARKING = 150; uint8_t COOLING = 90; uint8_t BRIGHTNESS = 100; uint8_t csRGB[4][3] = {{0, 0, 0}, {255, 0, 0}, {255, 127, 0}, {255, 255, 255}}; unsigned long previousMillis = 0; bool change = false; //if true we go to save to EEprom. unsigned long changeMillis = 0; //changes will be saved 1 minute after no change is applied to avoid EEPROM wear. bool initSetup = true; CRGBPalette16 gPal; ESP8266WebServer server(80); //Web server object. Will be listening in port 80 (default for HTTP) void setup() { EEPROM.begin(200); cWiFi(); setupFastLED(); loadConfig(); gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])); } inline void setupFastLED() { delay(1000); // sanity delay FastLED.addLeds(leds, NUM_STRIPS * NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(BRIGHTNESS); } void loop() { server.handleClient(); //Handling of incoming requests if (change) { if (millis() - changeMillis > 60000) { change = false; saveToEEPROM(); } } fire(); FastLED.show(); FastLED.delay(1000 / FPS); } void Fire2012WithPalette(int stripNo) { static byte heat[NUM_STRIPS][NUM_LEDS]; // Step 1. Cool down every cell a little for( int i = 0; i < NUM_LEDS; i++) { heat[stripNo][i] = qsub8( heat[stripNo][i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); } // Step 2. Heat from each cell drifts 'up' and diffuses a little for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[stripNo][k] = (heat[stripNo][k - 1] + heat[stripNo][k - 2] + heat[stripNo][k - 2] ) / 3; } // Step 3. Randomly ignite new 'sparks' of heat near the bottom if( random8() < SPARKING ) { int y = random8(5); heat[stripNo][y] = qadd8( heat[stripNo][y], random8(160,200) ); } // Step 4. Map from heat cells to LED colors for( int j = 0; j < NUM_LEDS; j++) { // Scale the heat value from 0-255 down to 0-240 // for best results with color palettes. byte colorindex = scale8( heat[stripNo][j], 240); CRGB color = ColorFromPalette( gPal, colorindex); leds[j+stripNo*NUM_LEDS] = color; } } void fire(){ for (int i=0; i= period * 1000) { // save the last time you blinked the LED previousMillis = currentMillis; return true; } else { return false; } } void EEPROMupdate(byte address, byte value) { if (EEPROM.read(address) != value) { EEPROM.write(address, value); EEPROM.commit(); } return; } void saveToEEPROM() { EEPROMupdate(BriAdr, BRIGHTNESS); EEPROMupdate(FpsAdr, FPS); EEPROMupdate(SparkingAdr, SPARKING); EEPROMupdate(CoolingAdr, COOLING); for (uint8_t i = 0; i < 4; i++) { for (uint8_t j = 0; j < 3; j++) { EEPROMupdate((i * 3 + j), csRGB[i][j]); } } } void handleCS0Change(){ csRGB[0][0] = str2int(server.arg("R")); csRGB[0][1] = str2int(server.arg("G")); csRGB[0][2] = str2int(server.arg("B")); gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])); changeMillis = millis(); change = true; } void handleCS1Change(){ csRGB[1][0] = str2int(server.arg("R")); csRGB[1][1] = str2int(server.arg("G")); csRGB[1][2] = str2int(server.arg("B")); gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])); changeMillis = millis(); change = true; } void handleCS2Change(){ csRGB[2][0] = str2int(server.arg("R")); csRGB[2][1] = str2int(server.arg("G")); csRGB[2][2] = str2int(server.arg("B")); gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])); changeMillis = millis(); change = true; } void handleCS3Change(){ csRGB[3][0] = str2int(server.arg("R")); csRGB[3][1] = str2int(server.arg("G")); csRGB[3][2] = str2int(server.arg("B")); gPal = CRGBPalette16( CRGB(csRGB[0][0],csRGB[0][1],csRGB[0][2]), CRGB(csRGB[1][0],csRGB[1][1],csRGB[1][2]), CRGB(csRGB[2][0],csRGB[2][1],csRGB[2][2]), CRGB(csRGB[3][0],csRGB[3][1],csRGB[3][2])); changeMillis = millis(); change = true; } void handleConf() { if (server.arg("brightness") != "") { BRIGHTNESS = str2int(server.arg("brightness")); FastLED.setBrightness(BRIGHTNESS); changeMillis = millis(); change = true; } if (server.arg("fps") != "") { FPS = str2int(server.arg("fps")); changeMillis = millis(); change = true; } if (server.arg("sparking") != "") { SPARKING = str2int(server.arg("sparking")); changeMillis = millis(); change = true; } if (server.arg("cooling") != "") { COOLING = str2int(server.arg("cooling")); changeMillis = millis(); change = true; } server.sendHeader("Connection", "close"); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", ""); //Returns the HTTP response } void loadConfig() { if (EEPROM.read(EEPROMCheckAdr) == 250) { BRIGHTNESS = EEPROM.read(BriAdr); SPARKING = EEPROM.read(SparkingAdr); COOLING = EEPROM.read(CoolingAdr); FPS = EEPROM.read(FpsAdr); if (FPS == 0) FPS = 100; for (uint8_t i = 0; i < 4; i++) { for (uint8_t j = 0; j < 3; j++) { csRGB[i][j] = EEPROM.read(i * 3 + j); } } }else{ EEPROMupdate(BriAdr,BRIGHTNESS); EEPROMupdate(FpsAdr,FPS); EEPROMupdate(CoolingAdr,COOLING); EEPROMupdate(SparkingAdr, SPARKING); for (uint8_t i = 0; i < 4; i++) { for (uint8_t j = 0; j < 3; j++) { EEPROMupdate((i*3+j) , csRGB[i][j]); } } EEPROMupdate(EEPROMCheckAdr, 250); } } void cWiFi() { WiFi.softAP("ElectroPeak's Flame", ""); //set a password here if you want i.e. WiFi.softAP("ElectroPeak's Flame", "12345678"); IPAddress myIP = WiFi.softAPIP(); server.on("/cs0", handleCS0Change); server.on("/cs1", handleCS1Change); server.on("/cs2", handleCS2Change); server.on("/cs3", handleCS3Change); server.on("/conf", handleConf); server.serveStatic("/", SPIFFS, "/", "max-age=86400"); server.begin(); //Start the server }