#include #include #define PIN_LIGHT D5 #define PIN_LIGHT1 D6 #define PIN_LIGHT2 D7 #define PIN_LIGHT3 D8 #define PIN_SENSOR D0 #define FULL 255 #define LOWER 50 #define MINIMUM 1 #define OFF 0 int timeout = (1000-50); #define FW_NAME "esp-deckenlicht" #define FW_VERSION "1.0.1" int w0; int w1; int w2; int w3; int w0b, w1b, w2b, w3b; int step = 0; int strobo = 1; bool disco = false; int lastEvent = 0; //Fluorescent effect int fluorescentSet=0; bool fluorescentActive=false; long fluorescentLastActivated=0; #define FLUORESCENT_TIMEDIVIDE 10 int fluorescentTemp=0; #define FLUORESCENTUPDATEINTERVAL 20 long fluorescentLastUpdated=0; int fluorescentCurrentBrightness=0; //current brightness for effect duration #define FLUORESCENTTEMPMAX 400 bool lastSensorValue = false; HomieNode lightNode("strip", "strip"); HomieNode sensorNode("sensor", "sensor"); Bounce debouncer = Bounce(); bool speedHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "speed " << ": " << value << endl; timeout = value.toInt(); lightNode.setProperty("speed").send(value); return true; } bool stroboToggleHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "stroboToggle " << ": " << value << endl; lightNode.setProperty("stroboToggle").send(value); strobo *= -1; if (strobo == 1) { w0 = w1 = w2 = w3 = FULL; } else { w0 = w1 = w2 = w3 = OFF; } output(); } bool beatHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "beat " << ": " << value << endl; lightNode.setProperty("beat").send(value); if (step >= 4) { step = 0; } // Cycle each light from 255 to 50 to 1 to off switch (step) { case 0: w0 = FULL; w1 = OFF; w2 = MINIMUM; w3 = LOWER; break; case 1: w1 = FULL; w2 = OFF; w3 = MINIMUM; w0 = LOWER; break; case 2: w2 = FULL; w3 = OFF; w0 = MINIMUM; w1 = LOWER; break; case 3: w3 = FULL; w0 = OFF; w1 = MINIMUM; w2 = LOWER; break; default: w0 = w1 = w2 = w3 = 0; break; } output(); step++; } bool discoHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "disco " << ": " << value << endl; lightNode.setProperty("disco").send(value); if (value.toInt() == 0) { disco = false; // Return to previous state w0 = w0b; w1 = w1b; w2 = w2b; w3 = w3b; output(); } else { step = 0; w0b = w0; w1b = w1; w2b = w2; w3b = w3; disco = true; } return true; } bool fluorescentHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "fluorescent " << ": " << value << endl; lightNode.setProperty("fluorescent").send(value); fluorescentSet=value.toInt(); disco = false; if (fluorescentSet==0){ // turned off fluorescentActive=false; //set effect off w0 = 0; w1 = 0; w2 = 0; w3 = 0; }else{ //turned on if (w0==0 && w1==0 && w2==0 && w3==0){ //turned on and was off before //Initialization fluorescentActive=true; //start effect fluorescentLastActivated=millis(); fluorescentLastUpdated=millis(); fluorescentTemp=0; //"temperature" for warmup fluorescentCurrentBrightness=0; //brightness for effect duration } } output(); return true; } bool lightHandler(const HomieRange& range, const String& value) { Homie.getLogger() << "light " << ": " << value << endl; disco = false; w0 = value.toInt(); w1 = value.toInt(); w2 = value.toInt(); w3 = value.toInt(); lightNode.setProperty("light").send(value); output(); return true; } bool light0Handler(const HomieRange& range, const String& value) { Homie.getLogger() << "light0 " << ": " << value << endl; w0 = value.toInt(); disco = false; lightNode.setProperty("light0").send(value); output(); return true; } bool light1Handler(const HomieRange& range, const String& value) { Homie.getLogger() << "light1 " << ": " << value << endl; w1 = value.toInt(); disco = false; lightNode.setProperty("light1").send(value); output(); return true; } bool light2Handler(const HomieRange& range, const String& value) { Homie.getLogger() << "light2 " << ": " << value << endl; w2 = value.toInt(); disco = false; lightNode.setProperty("light2").send(value); output(); return true; } bool light3Handler(const HomieRange& range, const String& value) { Homie.getLogger() << "light3 " << ": " << value << endl; w3 = value.toInt(); disco = false; lightNode.setProperty("light3").send(value); output(); return true; } void output() { // * 4 to scale the input up for ESP Arduino default 10 bit PWM if (w0 == FULL) { analogWrite(PIN_LIGHT, 1023); } else { analogWrite(PIN_LIGHT, w0*4); } if (w1 == FULL) { analogWrite(PIN_LIGHT1, 1023); } else { analogWrite(PIN_LIGHT1, w1*4); } if (w2 == FULL) { analogWrite(PIN_LIGHT2, 1023); } else { analogWrite(PIN_LIGHT2, w2*4); } if (w3 == FULL) { analogWrite(PIN_LIGHT3, 1023); } else { analogWrite(PIN_LIGHT3, w3*4); } } void loopHandler() { if (disco) { if (millis() - lastEvent >= (1000-timeout) || lastEvent == 0) { lastEvent = millis(); if (step >= 4) { step = 0; } // Cycle each light from 255 to 50 to 1 to off switch (step) { case 0: w0 = FULL; w1 = OFF; w2 = MINIMUM; w3 = LOWER; break; case 1: w1 = FULL; w2 = OFF; w3 = MINIMUM; w0 = LOWER; break; case 2: w2 = FULL; w3 = OFF; w0 = MINIMUM; w1 = LOWER; break; case 3: w3 = FULL; w0 = OFF; w1 = MINIMUM; w2 = LOWER; break; default: w0 = w1 = w2 = w3 = 0; break; } output(); step++; } } if (fluorescentActive){ long _time=millis()-fluorescentLastActivated; //time since activated //mosquitto_pub -h raum.ctdo.de -t "homie/esp-deckenlicht/strip/fluorescent/set" -m "255" if (millis() > fluorescentLastUpdated+FLUORESCENTUPDATEINTERVAL){ //Update values fluorescentLastUpdated=millis(); /* fluorescentTemp+=random(0, 3); //min (inclusive), max (exclusive) fluorescentLastUpdated=millis(); if (random(0,256)fluorescentTemp*1.0/FLUORESCENTTEMPMAX*256){ //the colder, the more often if (fluorescentCurrentBrightness<5){ //not on if (random(0,50)==0){ //ignite fluorescentCurrentBrightness=fluorescentSet/100.0*random(50,100); } } if (fluorescentCurrentBrightness>20){ //minimum brightness fluorescentCurrentBrightness-=random(20,40); }else{ fluorescentCurrentBrightness+=random(2,3)-2; } } */ fluorescentTemp+=1+ random(0,20*fluorescentTemp/FLUORESCENTTEMPMAX); //fluorescentTemp+=3; if (random(0,80)==0){ //ignite fluorescentCurrentBrightness=fluorescentSet*random(50,100)/100; } if (fluorescentTemp>200){ // warm enough to glow if (fluorescentCurrentBrightness<20){ //if under glow brightness fluorescentCurrentBrightness+=5; //start glowing }else if(fluorescentCurrentBrightness>50){ //too bright to glow fluorescentCurrentBrightness-=random(0,30); //reduce intensity } }else{ //not warm enough to glow if (fluorescentCurrentBrightness>0){ fluorescentCurrentBrightness-=random(20,50); //reduce intensity } } if (fluorescentTemp>=FLUORESCENTTEMPMAX){ //finished fluorescentActive=false; fluorescentCurrentBrightness=fluorescentSet; //set disired value } if (fluorescentCurrentBrightness<0){ fluorescentCurrentBrightness=0; }else if (fluorescentCurrentBrightness>255){ fluorescentCurrentBrightness=255; } w0 = w1 = w2 = w3 = fluorescentCurrentBrightness; output(); } } bool sensorValue = debouncer.read(); if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) { sensorNode.setProperty("motion").send(sensorValue ? "true" : "false"); lastSensorValue = sensorValue; } } void setup() { Serial.begin(115200); Serial << endl << endl; pinMode(PIN_LIGHT, OUTPUT); pinMode(PIN_LIGHT1, OUTPUT); pinMode(PIN_LIGHT2, OUTPUT); pinMode(PIN_LIGHT3, OUTPUT); debouncer.attach(PIN_SENSOR,INPUT); debouncer.interval(50); Homie_setFirmware(FW_NAME, FW_VERSION); Homie_setBrand(FW_NAME); Homie.setLoopFunction(loopHandler); lightNode.advertise("speed").settable(speedHandler); lightNode.advertise("disco").settable(discoHandler); lightNode.advertise("beat").settable(beatHandler); lightNode.advertise("light").settable(lightHandler); lightNode.advertise("light0").settable(light0Handler); lightNode.advertise("light1").settable(light1Handler); lightNode.advertise("light2").settable(light2Handler); lightNode.advertise("light3").settable(light3Handler); lightNode.advertise("fluorescent").settable(fluorescentHandler); sensorNode.advertise("motion"); // Activate other PWM frequency. 1000 (1 KHz) is default analogWriteFreq(30000); // Restore last state output(); Homie.setup(); ArduinoOTA.setHostname(Homie.getConfiguration().deviceId); ArduinoOTA.begin(); } void loop() { Homie.loop(); debouncer.update(); ArduinoOTA.handle(); }