Compare commits

..

7 Commits

8 changed files with 540 additions and 535 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@ -1,12 +1,12 @@
{
"name": "esp-deckenlicht",
"device_id": "esp-deckenlicht",
"name": "ledstoffroehre",
"device_id": "ledstoffroehre",
"wifi": {
"ssid": "CTDO-IoT",
"password": "12345678"
"password": ""
},
"mqtt": {
"host": "raum.ctdo.de",
"host": "mqtt.ctdo.de",
"port": 1883,
"auth": false
},

View File

@ -1,463 +0,0 @@
#include <Homie.h>
#include <ArduinoOTA.h>
#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 fluorescentCurrentBrightness0=0; //current brightness for effect duration
int fluorescentCurrentBrightness1=0;
int fluorescentCurrentBrightness2=0;
int fluorescentCurrentBrightness3=0;
#define FLUORESCENTTEMPMAX 400
int fluorescentAge=0;
#define FLUORESCENTAGEMAX 20
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
fluorescentCurrentBrightness0=0; //brightness for effect duration
fluorescentCurrentBrightness1=0;
fluorescentCurrentBrightness2=0;
fluorescentCurrentBrightness3=0;
}else{
fluorescentActive=false; //set effect off
w0 = w1 = w2 = w3 = fluorescentSet;
}
}
output();
return true;
}
bool fluorescentAgeHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "fluorescentAge " << ": " << value << endl;
fluorescentAge=value.toInt();
if (fluorescentAge<0){
fluorescentAge=0;
}else if(fluorescentAge>FLUORESCENTAGEMAX){
fluorescentAge=FLUORESCENTAGEMAX;
}
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 warmer, the more often
if (random(0,40)==0){ //ignite
fluorescentCurrentBrightness=fluorescentSet/100.0*random(50,100);
}
}
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;
}
}
*/
int fluorescentTempIncreaseMax=61-(fluorescentAge*3);
fluorescentTemp+=1+ random(0,fluorescentTempIncreaseMax *fluorescentTemp/FLUORESCENTTEMPMAX);
//fluorescentTemp+=3;
if (random(0,80)==0){ //ignite
fluorescentCurrentBrightness0=fluorescentSet*random(50,100)/100;
fluorescentCurrentBrightness1=fluorescentSet*random(50,100)/100;
fluorescentCurrentBrightness2=fluorescentSet*random(50,100)/100;
fluorescentCurrentBrightness3=fluorescentSet*random(50,100)/100;
}
if (fluorescentTemp>200){ // warm enough to glow
if (fluorescentCurrentBrightness0<20){ //if under glow brightness
fluorescentCurrentBrightness0+=5; //start glowing
}else if(fluorescentCurrentBrightness0>50){ //too bright to glow
fluorescentCurrentBrightness0-=random(0,30); //reduce intensity
}
if (fluorescentCurrentBrightness1<20){ //if under glow brightness
fluorescentCurrentBrightness1+=5; //start glowing
}else if(fluorescentCurrentBrightness1>50){ //too bright to glow
fluorescentCurrentBrightness1-=random(0,30); //reduce intensity
}
if (fluorescentCurrentBrightness2<20){ //if under glow brightness
fluorescentCurrentBrightness2+=5; //start glowing
}else if(fluorescentCurrentBrightness2>50){ //too bright to glow
fluorescentCurrentBrightness2-=random(0,30); //reduce intensity
}
if (fluorescentCurrentBrightness3<20){ //if under glow brightness
fluorescentCurrentBrightness3+=5; //start glowing
}else if(fluorescentCurrentBrightness3>50){ //too bright to glow
fluorescentCurrentBrightness3-=random(0,30); //reduce intensity
}
}else{ //not warm enough to glow
if (fluorescentCurrentBrightness0>0){
fluorescentCurrentBrightness0-=random(20,50); //reduce intensity
}
if (fluorescentCurrentBrightness1>0){
fluorescentCurrentBrightness1-=random(20,50); //reduce intensity
}
if (fluorescentCurrentBrightness2>0){
fluorescentCurrentBrightness2-=random(20,50); //reduce intensity
}
if (fluorescentCurrentBrightness3>0){
fluorescentCurrentBrightness3-=random(20,50); //reduce intensity
}
}
if (fluorescentTemp>=FLUORESCENTTEMPMAX){ //finished
fluorescentActive=false;
fluorescentCurrentBrightness0=fluorescentSet; //set disired value
fluorescentCurrentBrightness1=fluorescentSet; //set disired value
fluorescentCurrentBrightness2=fluorescentSet; //set disired value
fluorescentCurrentBrightness3=fluorescentSet; //set disired value
}
fluorescentCurrentBrightness0=_min(255,_max(0,fluorescentCurrentBrightness0));
fluorescentCurrentBrightness1=_min(255,_max(0,fluorescentCurrentBrightness1));
fluorescentCurrentBrightness2=_min(255,_max(0,fluorescentCurrentBrightness2));
fluorescentCurrentBrightness3=_min(255,_max(0,fluorescentCurrentBrightness3));
w0 = fluorescentCurrentBrightness0;
w1 = fluorescentCurrentBrightness1;
w2 = fluorescentCurrentBrightness2;
w3 = fluorescentCurrentBrightness3;
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);
lightNode.advertise("fluorescentage").settable(fluorescentAgeHandler);
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();
}

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@ -17,15 +17,48 @@ clock = pygame.time.Clock()
import time
FLUORESCENTTEMPMAX=400
fluorescentCurrentBrightness=0
fluorescentTemp=0
fluorescentActive=True
lamp0e=0
lamp0=0
lamp1e=0
lamp1=0
fluorescentSet=255
setbrightness0 = 0
#setbrightness1 = 0;
fluorescent0Active=False
#fluorescent1Active=False;
fluorescent0Age=10
#fluorescent1Age=10;
FLUORESCENTAGEMAX= 20
FLUORESCENTTEMPMAX= 1000
fluorescent0Temp=0
#fluorescent1Temp=0;
GLOWBRIGHTNESS= 50
flashprobability0=300 #the higher the lesser
flashprobabilitymin0=100 #the higher the lesser (at peak)
tempincreasemax0=10 #the higher the faster lightup
FLASHPROBABILITY_MIN=200
FLASHPROBABILITY_MAX=600
FLASHPROBABILITYMIN_MIN=100
FLASHPROBABILITYMIN_MAX=150
TEMPINCREASEMAX_MIN=5
TEMPINCREASEMAX_MAX=15
flashprobability0=random.randint(FLASHPROBABILITY_MIN,FLASHPROBABILITY_MAX)
flashprobabilitymin0=random.randint(FLASHPROBABILITYMIN_MIN,FLASHPROBABILITYMIN_MAX)
tempincreasemax0=random.randint(TEMPINCREASEMAX_MIN,TEMPINCREASEMAX_MAX)
fluorescent0Active=True #start
setbrightness0=255
def constrain(val, min_val, max_val):
return min(max_val, max(min_val, val))
# Loop as long as done == False
while not done:
@ -35,73 +68,35 @@ while not done:
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
if (fluorescent0Active):
fluorescent0Temp+=random.randint(1,tempincreasemax0)
if (random.randint(0,flashprobability0-constrain(fluorescent0Temp*flashprobability0/FLUORESCENTTEMPMAX,0,flashprobability0-flashprobabilitymin0))==0):
lamp0=setbrightness0*random.randint(30,100)/10
lamp0e=lamp0 #flash everything
lamp0-=20
lamp0e+=constrain(random.randint(-10,fluorescent0Temp*10/FLUORESCENTTEMPMAX) , 0, 10) #start glowing slowly
if (lamp0e>GLOWBRIGHTNESS):
lamp0e-=constrain(lamp0e-GLOWBRIGHTNESS,0,20) #make sides darker until glowbrightness
if fluorescent0Temp>=FLUORESCENTTEMPMAX:
fluorescent0Active=False
fluorescent0Temp=0
lamp0=setbrightness0
lamp0e=setbrightness0
print("finished")
'''
if (fluorescentActive):
fluorescentTemp+=random.randint(0,3 +1)
if (random.randint(0, 256+1) < fluorescentTemp*1.0/FLUORESCENTTEMPMAX*256):
if (random.randint(0, 40+1) ==0): #ignite
fluorescentCurrentBrightness=fluorescentSet*random.randint(50,100)/100
if (random.randint(0, 256+1) > fluorescentTemp*1.0/FLUORESCENTTEMPMAX*256):
if (fluorescentCurrentBrightness<5):
if (random.randint(0,50 +1)==0): #ignite
fluorescentCurrentBrightness=fluorescentSet*random.randint(50,100)/100
if (fluorescentCurrentBrightness>20):
fluorescentCurrentBrightness-=30
if (fluorescentTemp>=FLUORESCENTTEMPMAX):
fluorescentActive=False
fluorescentCurrentBrightness=fluorescentSet
lamp0=constrain(int(lamp0),0,255)
lamp0e=constrain(int(lamp0e),0,255)
clamp0 = (lamp0,lamp0,lamp0)
clamp0e = (lamp0e,lamp0e,lamp0e)
if (fluorescentCurrentBrightness>255):
fluorescentCurrentBrightness=255
if (fluorescentCurrentBrightness<0):
fluorescentCurrentBrightness=0
COLOR = (fluorescentCurrentBrightness,fluorescentCurrentBrightness,fluorescentCurrentBrightness)
else:
COLOR = (fluorescentSet,fluorescentSet,fluorescentSet)
'''
if (fluorescentActive):
fluorescentTemp+=1+ random.randint(0,20* fluorescentTemp/FLUORESCENTTEMPMAX)
#fluorescentTemp+=3
if (random.randint(0,80 +1)==0): #ignite
fluorescentCurrentBrightness=fluorescentSet*random.randint(50,100)/100
if (fluorescentTemp>200): #warm enough to glow
if (fluorescentCurrentBrightness<20): #if under glow brightness
fluorescentCurrentBrightness+=5 #start glowing
elif (fluorescentCurrentBrightness>50): #too bright for glow
fluorescentCurrentBrightness-=random.randint(0,30) #reduce intencity (flashing effect)
else: #not warm enough to glow
if (fluorescentCurrentBrightness>0): #too bright for glow
fluorescentCurrentBrightness-=random.randint(20,50) #reduce intencity (flashing effect)
if (fluorescentTemp>=FLUORESCENTTEMPMAX):
fluorescentActive=False
fluorescentCurrentBrightness=fluorescentSet
print("Finished")
if (fluorescentCurrentBrightness>255):
fluorescentCurrentBrightness=255
if (fluorescentCurrentBrightness<0):
fluorescentCurrentBrightness=0
COLOR = (fluorescentCurrentBrightness,fluorescentCurrentBrightness,fluorescentCurrentBrightness)
else:
COLOR = (fluorescentSet,fluorescentSet,fluorescentSet)
screen.fill(COLOR)
screen.fill(clamp0) #center
pygame.draw.rect(screen,clamp0e,(0,0,20,size[1])) #left edge
pygame.draw.rect(screen,clamp0e,(size[0]-20,0,20,size[1]))#right edge
pygame.display.flip()

23
platformio.ini Normal file
View File

@ -0,0 +1,23 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:d1_mini]
platform = espressif8266 @ 2.5.0 #using old esp version, because of "obsolete API, use ::begin(WiFiClient, url)" error. Try again if fix available in platformio over vscode
board = d1_mini
framework = arduino
monitor_port = /dev/ttyUSB0
monitor_speed = 115200
lib_deps =
ArduinoJson@6.16.1 #dependency of homie. using older version because of "ambiguous overload for operator|" error
Homie@3.0.0
thomasfredericks/Bounce2@^2.71

389
src/main.cpp Normal file
View File

@ -0,0 +1,389 @@
#include<Arduino.h>
#include<Homie.h>
#include<ArduinoOTA.h>
// homie/ledstoffroehre/lamp/fluorescent0/set
#define PIN_LAMP0_EDGE D5
#define PIN_LAMP0 D6
#define PIN_LAMP1_EDGE D7
#define PIN_LAMP1 D8
#define PIN_SENSOR D0
#define PIN_BUTTON0 D2
#define PIN_BUTTON1 D3
//#define FULL 255
//#define LOWER 50
//#define MINIMUM 1
//#define OFF 0
//int timeout = (1000 - 50);
#define FW_NAME "ledstoffroehre"
#define FW_VERSION "1.0.2"
bool fluorescentHandler(const HomieRange& range, const String& value);
void resetLamp1();
void resetLamp0();
void loopHandler();
void output();
bool lamp1Handler(const HomieRange& range, const String& value);
bool lamp0Handler(const HomieRange& range, const String& value);
bool lampHandler(const HomieRange& range, const String& value);
bool fluorescent1QualityHandler(const HomieRange& range, const String& value);
bool fluorescent0QualityHandler(const HomieRange& range, const String& value);
bool fluorescentQualityHandler(const HomieRange& range, const String& value);
bool fluorescent1Handler_change(String value);
bool fluorescent1Handler(const HomieRange& range, const String& value);
bool fluorescent0Handler_change(String value);
bool fluorescent0Handler(const HomieRange& range, const String& value);
int lamp0e=0;
int lamp0=0;
int lamp1e=0;
int lamp1=0;
long fluorescentLastUpdated=0; //global
#define FLUORESCENTUPDATEINTERVAL 20
long fluorescent0LastActivated = 0;
long fluorescent1LastActivated = 0;
int setbrightness0 = 0;
int setbrightness1 = 0;
bool fluorescent0Active=false;
bool fluorescent1Active=false;
int fluorescent0Quality=10; // 0 to 100
int fluorescent1Quality=10;
#define FLUORESCENQUALITYMAX 100
#define FLUORESCENTTEMPMAX 1000
int fluorescent0Temp=0;
int fluorescent1Temp=0;
#define GLOWBRIGHTNESS 10
int flashprobability0=300; //the higher the lesser
int flashprobabilitymin0=100; //the higher the lesser (at peak)
int tempincreasemax0=10; //the higher the faster lightup
int flashprobability1=300; //the higher the lesser
int flashprobabilitymin1=100; //the higher the lesser (at peak)
int tempincreasemax1=10; //the higher the faster lightup
#define FLASHPROBABILITY_MIN 100
#define FLASHPROBABILITY_MAX 600
#define FLASHPROBABILITYMIN_MIN 50
#define FLASHPROBABILITYMIN_MAX 100 //should not be more than FLASHPROBABILITY_MIN
#define TEMPINCREASEMAX_MIN 1
#define TEMPINCREASEMAX_MAX FLUORESCENTTEMPMAX/20
bool lastSensorValue = false;
HomieNode lightNode("lamp", "lamp", "lamp");
HomieNode sensorNode("sensor", "sensor","sensor");
Bounce debouncer = Bounce();
Bounce debouncer_btn0 = Bounce();
Bounce debouncer_btn1 = Bounce();
bool fluorescentHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "fluorescent " << ": " << value << endl;
lightNode.setProperty("fluorescent").send(value);
setbrightness0 = value.toInt();
setbrightness1 = value.toInt();
fluorescent0Temp=0;
fluorescent1Temp=0;
if (setbrightness0 == 0 || setbrightness1 == 0) { // turned off
resetLamp0();
resetLamp1();
} else { //turned on
//Initialization
fluorescent0Active = true; //start effect
fluorescent1Active = true; //start effect
}
output();
return true;
}
bool fluorescent0Handler(const HomieRange& range, const String& value) {
return fluorescent0Handler_change(value);
}
bool fluorescent0Handler_change(String value){
Homie.getLogger() << "fluorescent0 " << ": " << value << endl;
lightNode.setProperty("fluorescent0").send(value);
setbrightness0 = value.toInt();
fluorescent0Temp=0;
if (setbrightness0 == 0) { // turned off
resetLamp0();
} else { //turned on
//Initialization
fluorescent0Active = true; //start effect
}
output();
return true;
}
bool fluorescent1Handler(const HomieRange& range, const String& value) {
return fluorescent1Handler_change(value);
}
bool fluorescent1Handler_change(String value){
Homie.getLogger() << "fluorescent1 " << ": " << value << endl;
lightNode.setProperty("fluorescent1").send(value);
setbrightness1 = value.toInt();
fluorescent1Temp=0;
if (setbrightness1 == 0) { // turned off
resetLamp1();
} else { //turned on
//Initialization
fluorescent1Active = true; //start effect
}
output();
return true;
}
void resetLamp0(){
fluorescent0Active = false; //set effect off
fluorescent0LastActivated = millis();
lamp0e=0;
lamp0=0;
float speedpercent=fluorescent0Quality*1.0/FLUORESCENQUALITYMAX;
flashprobability0=random(FLASHPROBABILITY_MIN,FLASHPROBABILITY_MAX);
flashprobabilitymin0=random(FLASHPROBABILITYMIN_MIN,FLASHPROBABILITYMIN_MAX);
tempincreasemax0=TEMPINCREASEMAX_MIN+speedpercent*(TEMPINCREASEMAX_MAX-TEMPINCREASEMAX_MIN);//random(TEMPINCREASEMAX_MIN,TEMPINCREASEMAX_MAX);
}
void resetLamp1(){
fluorescent1Active = false; //set effect off
fluorescent1LastActivated = millis();
lamp1e=0;
lamp1=0;
float speedpercent=fluorescent1Quality*1.0/FLUORESCENQUALITYMAX;
flashprobability1=random(FLASHPROBABILITY_MIN,FLASHPROBABILITY_MAX);
flashprobabilitymin1=random(FLASHPROBABILITYMIN_MIN,FLASHPROBABILITYMIN_MAX);
tempincreasemax1=TEMPINCREASEMAX_MIN+speedpercent*(TEMPINCREASEMAX_MAX-TEMPINCREASEMAX_MIN);
}
bool fluorescentQualityHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "fluorescentAge " << ": " << value << endl;
fluorescent0Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
fluorescent1Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
return true;
}
bool fluorescent0QualityHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "fluorescent0Quality " << ": " << value << endl;
fluorescent0Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
return true;
}
bool fluorescent1QualityHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "fluorescent1Quality " << ": " << value << endl;
fluorescent1Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
return true;
}
bool lampHandler(const HomieRange& range, const String& value) {
Homie.getLogger() << "lamp0,1 " << ": " << value << endl;
lamp0 = value.toInt();
lamp0e = value.toInt();
lamp1 = value.toInt();
lamp1e = value.toInt();
lightNode.setProperty("lamp0").send(value);
lightNode.setProperty("lamp1").send(value);
fluorescent0Active = false;
fluorescent1Active = false;
output();
return true;
}
bool lamp0Handler(const HomieRange& range, const String& value) {
Homie.getLogger() << "lamp0 " << ": " << value << endl;
lamp0 = value.toInt();
lamp0e = value.toInt();
lightNode.setProperty("lamp0").send(value);
fluorescent0Active = false;
output();
return true;
}
bool lamp1Handler(const HomieRange& range, const String& value) {
Homie.getLogger() << "lamp1 " << ": " << value << endl;
lamp1 = value.toInt();
lamp1e = value.toInt();
lightNode.setProperty("lamp1").send(value);
fluorescent1Active = false;
output();
return true;
}
void output() {
// * 4 to scale the input up for ESP Arduino default 10 bit PWM
analogWrite(PIN_LAMP0_EDGE, constrain(lamp0e * 4,0,1023));
analogWrite(PIN_LAMP0, constrain(lamp0 * 4,0,1023));
analogWrite(PIN_LAMP1_EDGE, constrain(lamp1e * 4,0,1023));
analogWrite(PIN_LAMP1, constrain(lamp1 * 4,0,1023));
}
void loopHandler()
{
//mosquitto_pub -h raum.ctdo.de -t "homie/ledstoffroehre/lamp/fluorescent0/set" -m "255"
if (millis() > fluorescentLastUpdated + FLUORESCENTUPDATEINTERVAL) { //Update values
fluorescentLastUpdated = millis();
if (fluorescent0Active) {
//long _time = millis() - fluorescent0LastActivated; //time since activated
fluorescent0Temp+=random(1,tempincreasemax0);
if (random(0,flashprobability0-constrain(fluorescent0Temp*flashprobability0/FLUORESCENTTEMPMAX,0,flashprobability0-flashprobabilitymin0))==0)
{
lamp0=setbrightness0*random(30,100)/10;
lamp0e=lamp0; //flash everything
}
lamp0-=40;
if (random(0,100)>95){
lamp0e+=constrain(random(0,fluorescent0Temp*10/FLUORESCENTTEMPMAX) , 0, 10); //start glowing slowly
}
if (lamp0e>GLOWBRIGHTNESS)
{
lamp0e-=constrain(lamp0e-GLOWBRIGHTNESS,0,20); //make sides darker until glowbrightness
}
if (fluorescent0Temp>=FLUORESCENTTEMPMAX){
fluorescent0Active=false;
lamp0=setbrightness0;
lamp0e=setbrightness0;
}
lamp0=constrain(lamp0, 0,255);
lamp0e=constrain(lamp0e, 0,255);
output();
}
if (fluorescent1Active) {
//long _time = millis() - fluorescent0LastActivated; //time since activated
fluorescent1Temp+=random(1,tempincreasemax1);
if (random(0,flashprobability1-constrain(fluorescent1Temp*flashprobability1/FLUORESCENTTEMPMAX,0,flashprobability1-flashprobabilitymin1))==0)
{
lamp1=setbrightness1*random(30,100)/10;
lamp1e=lamp1; //flash everything
}
lamp1-=40;
if (random(0,100)>95){
lamp1e+=constrain(random(0,fluorescent1Temp*10/FLUORESCENTTEMPMAX) , 0, 10); //start glowing slowly
}
if (lamp1e>GLOWBRIGHTNESS)
{
lamp1e-=constrain(lamp1e-GLOWBRIGHTNESS,0,20); //make sides darker until glowbrightness
}
if (fluorescent1Temp>=FLUORESCENTTEMPMAX){
fluorescent1Active=false;
lamp1=setbrightness1;
lamp1e=setbrightness1;
}
lamp1=constrain(lamp1, 0,255);
lamp1e=constrain(lamp1e, 0,255);
output();
}
}
bool sensorValue = debouncer.read();
if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) {
sensorNode.setProperty("motion").send(sensorValue ? "true" : "false");
lastSensorValue = sensorValue;
}
bool btn0 = debouncer_btn0.read();
bool btn1 = debouncer_btn1.read();
if (!btn0){ //btn0 turns off
fluorescent0Handler_change("0");
fluorescent1Handler_change("0");
}
if (!btn1){ //btn1 turns of
fluorescent0Handler_change("255");
fluorescent1Handler_change("255");
}
}
void setup() {
Serial.begin(115200);
Serial << endl << endl;
pinMode(PIN_LAMP0_EDGE, OUTPUT);
pinMode(PIN_LAMP0, OUTPUT);
pinMode(PIN_LAMP1_EDGE, OUTPUT);
pinMode(PIN_LAMP1, OUTPUT);
debouncer_btn0.attach(PIN_BUTTON0, INPUT_PULLUP);
debouncer_btn0.interval(10);
debouncer_btn1.attach(PIN_BUTTON1, INPUT_PULLUP);
debouncer_btn1.interval(10);
debouncer.attach(PIN_SENSOR, INPUT);
debouncer.interval(50);
Homie_setFirmware(FW_NAME, FW_VERSION);
Homie_setBrand(FW_NAME);
Homie.setLoopFunction(loopHandler);
lightNode.advertise("lamp").settable(lampHandler);
lightNode.advertise("lamp0").settable(lamp0Handler);
lightNode.advertise("lamp1").settable(lamp1Handler);
lightNode.advertise("fluorescent").settable(fluorescentHandler);
lightNode.advertise("fluorescentquality").settable(fluorescentQualityHandler);
lightNode.advertise("fluorescent0").settable(fluorescent0Handler);
lightNode.advertise("fluorescent0Quality").settable(fluorescent0QualityHandler);
lightNode.advertise("fluorescent1").settable(fluorescent1Handler);
lightNode.advertise("fluorescent1Quality").settable(fluorescent1QualityHandler);
sensorNode.advertise("motion");
// Activate other PWM frequency. 1000 (1 KHz) is default
analogWriteFreq(20000);
// Restore last state
output();
Homie.setup();
ArduinoOTA.setHostname(Homie.getConfiguration().deviceId);
ArduinoOTA.begin();
}
void loop() {
Homie.loop();
debouncer.update();
debouncer_btn0.update();
debouncer_btn1.update();
ArduinoOTA.handle();
}