Ledstrip/src/main.cpp

357 lines
11 KiB
C++

/*
* 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 <Arduino.h>
#include <Homie.h>
#include <Adafruit_NeoPixel.h>
#include <ArduinoJson.h>
#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;
}