/* * This is a little firmware for my ledstrip. * Normally befor sending it to git, I am testing it. But I can't test it while in school... * So the code here might work or not. But I should be able to garantee that it is working on a Node-MCU (ESP8266) when I tested it. * * TESTED: YES */ #include #include #include #include #define NUMPIXELS 56 #define PIN D1 //Includes + defines complete. //Declaring all Methods the make sure the compiler findes them. void reset(); void changeLedColor(); //Declaring very important Variables Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); HomieNode stripNode("strip", "Led Strip State"); //Declaring other Variables String thingToDo = ""; uint32_t color; long toDelay = 50; double fadeRed = 0; double fadeGreen = 0; double fadeBlue = 0; int brightness = 0; int nextLed = 0; //MQTT RECIEVE[devices/stripbed/strip/leds/set] (EVENT: Fired when MQTT Message has been recieved) bool onLedsShouldChange(String value){ char chars[value.length() + 1]; strcpy(chars, value.c_str()); //Transforming String into char array. StaticJsonBuffer<400> jsonBuffer; JsonObject& root = jsonBuffer.parseObject(chars); //Parsing JSON String if(!root.success()){ //Parsing succeed? Homie.setNodeProperty(stripNode, "last", "{\"state\":\"error\",\"id\":\"jsonParseError\",\"msg\":\"Failed to parse Data.\"}"); //Rückmeldung an den Broker das der String nicht geparsed werden konnte return false; //If not: sending Error Message and returning false. } String actionToDo = ""; const char* bitToStringy = root["action"]; //Getting: Action actionToDo = String(bitToStringy); //Transforming char* into String if(actionToDo == "off"){ for(int count = 0;count < NUMPIXELS; count++){ strip.setPixelColor(count, strip.Color(0, 0, 0)); //All Leds are set to black (off) } strip.show(); //Updating Ledstrip. Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); //Sending Success Message back to MQTT broker. thingToDo = ""; //Cancel all animation in loop. reset(); //Sets animation needed Variables to 0 return true; //Ends Method with Output: TRUE } else if(actionToDo == "oneColor"){ for(int count = 0;count < NUMPIXELS; count++){ strip.setPixelColor(count, strip.Color(root["red"], root["green"], root["blue"])); //Sets all Leds to RED/GREEN/BLUE values } strip.show(); Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); thingToDo = "oneColor"; //Not important for animation but for colorchange feature. reset(); return true; } else if(actionToDo == "inout"){ color = strip.Color(root["red"], root["green"], root["blue"]); //Sets color to the submitted color :) thingToDo = "inout"; //Sets Animation to inout Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); toDelay = root["time"]; //Sets delay to submitted value. reset(); return true; } else if(actionToDo == "colorchange"){ if(thingToDo == "inout"){ color = strip.Color(root["red"], root["green"], root["blue"]); //Sets the color of the ledstrip to a new color. toDelay = root["time"]; //Yeah even setting the speed of inout is possible. changeLedColor(); //Changes the color of the ledstrip. } else if(thingToDo == "oneColor"){ for(int count = 0;count < NUMPIXELS; count++){ strip.setPixelColor(count, strip.Color(root["red"], root["green"], root["blue"])); //Sets color again. Same result as sending oneColor again } strip.show(); } else{ if(thingToDo == ""){ Homie.setNodeProperty(stripNode, "last", "{\"state\":\"error\",\"id\":\"ledstripIsOff\",\"msg\":\"The Ledstrip is turn off right now.\"}"); //When Ledstrip is turned off. } else{ Homie.setNodeProperty(stripNode, "last", "{\"state\":\"error\",\"id\":\"colorChangeNotSupported\",\"msg\":\"ColorChange is not supported by the momently running animation.\"}"); //If a funktion is running which doesn't support a custom color (e.g. Colorfade). } return true; } Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); return true; } else if(actionToDo == "fadein"){ reset(); fadeRed = (double)root["red"] / 100.0; //Sets fadeRed to RED / 100. fadeGreen = (double)root["green"] / 100.0; //Sets fadeRed to GREEN / 100. fadeBlue = (double)root["blue"] / 100.0; //Sets fadeRed to BLUE / 100. thingToDo = "fadein"; Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); toDelay = root["time"]; return true; } else if(actionToDo == "colorfade"){ reset(); thingToDo = "colorfade"; fadeRed = 255.0; //fadeRed is a double. Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); toDelay = root["time"]; nextLed = root["leddiff"]; //Led Color Difference. Per Led if(nextLed >= 256){ nextLed == 255; } return true; } else if(actionToDo == "oneled"){ reset(); thingToDo = "oneLed"; for(int count = 0;count < root["leds"].size(); count++){ strip.setPixelColor((int)root["leds"][count]["id"], strip.Color((int)root["leds"][count]["red"], (int)root["leds"][count]["green"], (int)root["leds"][count]["blue"])); } strip.show(); Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); return true; } else if(actionToDo == "rgb"){ reset(); thingToDo = "rgb"; toDelay = root["time"]; brightness = root["brightness"]; Homie.setNodeProperty(stripNode, "last", "{\"state\":\"success\"}"); return true; } else{ Homie.setNodeProperty(stripNode, "last", "{\"state\":\"error\",id:\"unknownCommandError\",msg:\"No such Command.\"}"); //Jeder andere ACTION command wird hier als ungültig abgestempelt. return true; } } //Main Funktion #1 (Executed right after NodeMCU got power) void setup(){ strip.begin(); strip.show(); Homie.setFirmware("Ledstrip Control", "0.7"); //Firmware: Ledstrip Control: v0.6 (New feature: + 0.1 ; Bugfixe/Improvement of a feature: + 0.0.1) stripNode.subscribe("leds", onLedsShouldChange); //MQTT Subscribe Homie.registerNode(stripNode); //HomieNode REGISTER Homie.setup(); //Homie SETUP } //Declaring other Variables used by loop(); unsigned long startNextAction = 0; int momentStep = 0; //Main Funktion #2 (Executed like 27000 - 32000 times per second but not once befor setup.) void loop(){ Homie.loop(); if(thingToDo == ""){ return; } if(millis() - startNextAction <= toDelay){ //Delaying: Animation should not block Homie in any way. return; } if(thingToDo == "inout"){ // Inout animation if(momentStep == 0){ if(nextLed < NUMPIXELS){ strip.setPixelColor(nextLed, color); strip.show(); ++nextLed; startNextAction = millis(); } else if(nextLed == NUMPIXELS){ nextLed = NUMPIXELS - 2; strip.setPixelColor(NUMPIXELS - 1, strip.Color(0, 0, 0)); strip.show(); momentStep = 1; startNextAction = millis(); } } else if(momentStep == 1){ if(nextLed >= 0){ strip.setPixelColor(nextLed, strip.Color(0, 0, 0)); strip.show(); --nextLed; startNextAction = millis(); } else if(nextLed < 0){ nextLed = 1; strip.setPixelColor(0, color); strip.show(); momentStep = 0; startNextAction = millis(); } } } else if(thingToDo == "fadein"){ //FadeIn animation for(int count = 0;count < NUMPIXELS; count++){ strip.setPixelColor(count, strip.Color((int)(fadeRed * ((double)momentStep + 1)), (int)(fadeGreen * ((double)momentStep + 1)), (int)(fadeBlue * ((double)momentStep + 1)))); } strip.show(); ++momentStep; if(momentStep >= 100){ thingToDo = "oneColor"; reset(); } else{ startNextAction = millis(); } } else if(thingToDo == "colorfade"){ //Colorfade animation startNextAction = millis(); if(momentStep == 0){ fadeGreen = fadeGreen + (double) nextLed; if(fadeGreen >= 256.0){ fadeRed = fadeRed - (fadeGreen - 255.0); fadeGreen = 255.0; } if(fadeGreen == 255.0){ momentStep = 1; } } else if(momentStep == 1){ fadeRed = fadeRed - (double) nextLed; if(fadeRed < 0.0){ fadeBlue = fadeBlue + (fadeRed * -1.0); fadeRed = 0.0; } if(fadeRed == 0.0){ momentStep = 2; } } else if(momentStep == 2){ fadeBlue = fadeBlue + (double) nextLed; if(fadeBlue >= 256.0){ fadeGreen = fadeGreen - (fadeBlue - 255.0); fadeBlue = 255.0; } if(fadeBlue == 255.0){ momentStep = 3; } } else if(momentStep == 3){ fadeGreen = fadeGreen - (double) nextLed; if(fadeGreen < 0.0){ fadeRed = fadeRed + (fadeGreen * -1.0); fadeGreen = 0.0; } if(fadeGreen == 0.0){ momentStep = 4; } } else if(momentStep == 4){ fadeRed = fadeRed + (double) nextLed; if(fadeRed >= 256.0){ fadeBlue = fadeBlue - (fadeRed - 255.0); fadeRed = 255.0; } if(fadeRed == 255.0){ momentStep = 5; } } else if(momentStep == 5){ fadeBlue = fadeBlue - (double) nextLed; if(fadeBlue < 0.0){ fadeGreen = fadeGreen + (fadeBlue * -1.0); fadeBlue = 0.0; } if(fadeBlue == 0.0){ momentStep = 0; } } for(int count = NUMPIXELS - 1; count > 0; count--){ strip.setPixelColor(count, strip.getPixelColor(count - 1)); } strip.setPixelColor(0, strip.Color((int)fadeRed, (int)fadeGreen, (int)fadeBlue)); strip.show(); } else if(thingToDo == "rgb"){ //rgb LedStriptest animation (Fullversion will be added later). if(momentStep == 0){ if(nextLed < NUMPIXELS){ strip.setPixelColor(nextLed, strip.Color(brightness, 0, 0)); strip.show(); ++nextLed; } else if(nextLed == NUMPIXELS){ nextLed = 1; strip.setPixelColor(0, strip.Color(0, brightness, 0)); strip.show(); momentStep = 1; } } else if(momentStep == 1){ if(nextLed < NUMPIXELS){ strip.setPixelColor(nextLed, strip.Color(0, brightness, 0)); strip.show(); ++nextLed; } else if(nextLed == NUMPIXELS){ nextLed = 1; strip.setPixelColor(0, strip.Color(0, 0, brightness)); strip.show(); momentStep = 2; } } else if(momentStep == 2){ if(nextLed < NUMPIXELS){ strip.setPixelColor(nextLed, strip.Color(0, 0, brightness)); strip.show(); ++nextLed; } else if(nextLed == NUMPIXELS){ nextLed = 1; strip.setPixelColor(0, strip.Color(brightness, 0, 0)); strip.show(); momentStep = 0; } } startNextAction = millis(); } } void changeLedColor(){ if(momentStep == 0 && thingToDo == "inout"){ for(int count = 0; count <= (nextLed - 1); count++){ strip.setPixelColor(count, color); } strip.show(); } else if(momentStep == 1 && thingToDo == "inout"){ for(int count = nextLed; count >= 0; count--){ strip.setPixelColor(count, color); } strip.show(); } } void reset(){ nextLed = 0; momentStep = 0; startNextAction = 0; fadeRed = 0; fadeGreen = 0; fadeBlue = 0; }