include dualcolor code again with ifdefs
This commit is contained in:
parent
b001ba10b3
commit
c73f91c2e7
225
src/main.cpp
225
src/main.cpp
|
@ -5,6 +5,14 @@
|
|||
|
||||
//Upload config: platformio run --target uploadfs
|
||||
|
||||
#define TISCHLICHT
|
||||
//#define KUECHENLICHT
|
||||
|
||||
|
||||
#ifdef TISCHLICHT
|
||||
#define DUALCOLOR
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Homie.h>
|
||||
|
||||
|
@ -15,7 +23,11 @@
|
|||
bool enableHandler(const HomieRange& range, const String& value);
|
||||
bool fadetimeHandler(const HomieRange& range, const String& value);
|
||||
bool brightnessHandler(const HomieRange& range, const String& value);
|
||||
#ifdef DUALCOLOR
|
||||
bool temperatureHandler(const HomieRange& range, const String& value);
|
||||
#endif
|
||||
void loopHandler();
|
||||
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max);
|
||||
|
||||
//#define DEBUG //turns on continuous serial debug printing
|
||||
|
||||
|
@ -23,19 +35,38 @@ void loopHandler();
|
|||
HomieNode lightNode("light", "Light", "light"); //paramters: topic, $name, $type
|
||||
|
||||
|
||||
#ifdef TISCHLICHT
|
||||
#define LED_WW 14 //D5 = GPIO14 (pin5)
|
||||
#define LED_CW 12 //D6 = GPIO12 (pin6)
|
||||
#endif
|
||||
#ifdef KUECHENLICHT
|
||||
#define LED_PWM D5
|
||||
#endif
|
||||
|
||||
#define LED_PWM D5
|
||||
#ifdef TISCHLICHT
|
||||
#define BTN_A 13 //D7 = GPIO13 (pin 7)
|
||||
#define BTN_B 15 //D8 = GPIO15 (pin 10)
|
||||
#endif
|
||||
#ifdef KUECHENLICHT
|
||||
#define BTN_A D7
|
||||
#endif
|
||||
|
||||
#define BTN_A D7
|
||||
|
||||
#define PWM_MAX 1023 //10 bit dac
|
||||
#define PWM_FREQUENCY 1000 //default: 1000 Hz
|
||||
|
||||
#ifdef TISCHLICHT
|
||||
#define PWM_FREQUENCY 500 //default: 1000 Hz
|
||||
#endif
|
||||
#ifdef KUECHENLICHT
|
||||
#define PWM_FREQUENCY 1000 //default: 1000 Hz
|
||||
#endif
|
||||
|
||||
|
||||
boolean enable=false;
|
||||
float enable_fadevalue=0; //0=off, 1=on
|
||||
float enable_fadevalue_change_per_loop=0.01; //fixed value. For manual calculatoin: enable_fadevalue_change_per_loop=_difference/fadetime*UPDATETIME;
|
||||
|
||||
float set_brightness=2; //0 to 1
|
||||
float set_brightness=2; //0 to 2. 1 is maximum brightness with full color range still possible. 2 is full brightness regardless of possible color temp
|
||||
#define BRIGHTNESS_MIN 0.0
|
||||
#define BRIGHTNESS_MAX 2.0 //if temperature is in between both strips brightness of 2 means both are at full power. otherwise brightness will be clipped
|
||||
#define BRIGHTNESSCURVE 1.4
|
||||
|
@ -43,6 +74,17 @@ float brightness=set_brightness;
|
|||
float brightness_change_per_loop=0; //will be calculated by Handler
|
||||
|
||||
|
||||
#ifdef TISCHLICHT
|
||||
#define TEMPERATURE_MIN 2760 //temperature of warm white leds
|
||||
#define TEMPERATURE_MAX 5640 //temperature of cold white leds
|
||||
#endif
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
float set_temperature=(TEMPERATURE_MAX+TEMPERATURE_MIN)/2;
|
||||
float temperature=set_temperature;
|
||||
float temperature_change_per_loop=0; //will be calculated by Handler
|
||||
#endif
|
||||
|
||||
uint16_t fadetime=0; //0=instant. value is time in milliseconds
|
||||
#define FADETIME_MIN 0
|
||||
#define FADETIME_MAX 60000
|
||||
|
@ -55,12 +97,21 @@ long last_updatetime=0;
|
|||
long last_buttonupdatetime=0;
|
||||
uint8_t btnAstate=0; //for button state machine
|
||||
long btnAtime=0;
|
||||
#ifdef DUALCOLOR
|
||||
uint8_t btnBstate=0; //for button state machine
|
||||
long btnBtime=0;
|
||||
#endif
|
||||
#define BTNHOLDTIME 1000
|
||||
|
||||
boolean holdDirection_brightness=false;
|
||||
#ifdef DUALCOLOR
|
||||
boolean holdDirection_temperature=false;
|
||||
#endif
|
||||
|
||||
#define HOLDBRIGHTNESSCHANGE_PER_LOOP 0.01 //depends on BUTTONUPDATETIME. BUTTONUPDATETIME/1000/HOLDBRIGHTNESSCHANGE_PER_LOOP=seconds to change a full cycle(0 to 1)
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
#define HOLDTEMPERATURECHANGE_PER_LOOP 10.0 // (TEMPERATURE_MAX-TEMPERATURE_MIN)*BUTTONUPDATETIME/1000/HOLDBRIGHTNESSCHANGE_PER_LOOP=seconds to change a full cycle (min to max)
|
||||
#endif
|
||||
boolean flag_updatePWM=false; //if manually set brightness or temperature, set this flag
|
||||
|
||||
//Debug
|
||||
|
@ -70,15 +121,35 @@ long last_debugupdatetime=0;
|
|||
//To check if values changed (for mqtt response)
|
||||
boolean known_enable=!enable; //start with differend known values, actual values will be send first
|
||||
float known_set_brightness=set_brightness+1;
|
||||
#ifdef DUALCOLOR
|
||||
float known_set_temperature=set_temperature+1;
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("Hello");
|
||||
pinMode(LED_PWM, OUTPUT);
|
||||
analogWriteFreq(PWM_FREQUENCY);
|
||||
analogWrite(LED_PWM, PWM_MAX); //high = off
|
||||
|
||||
pinMode(BTN_A, INPUT);
|
||||
analogWriteFreq(PWM_FREQUENCY);
|
||||
#ifdef TISCHLICHT
|
||||
pinMode(LED_WW, OUTPUT);
|
||||
pinMode(LED_CW, OUTPUT);
|
||||
analogWrite(LED_CW, PWM_MAX); //high = off
|
||||
analogWrite(LED_WW, PWM_MAX); //high = off
|
||||
#endif
|
||||
#ifdef KUECHENLICHT
|
||||
pinMode(LED_PWM, OUTPUT);
|
||||
analogWrite(LED_PWM, PWM_MAX); //high = off
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TISCHLICHT
|
||||
pinMode(BTN_A, INPUT);
|
||||
pinMode(BTN_B, INPUT);
|
||||
#endif
|
||||
#ifdef KUECHENLICHT
|
||||
pinMode(BTN_A, INPUT);
|
||||
#endif
|
||||
|
||||
|
||||
Homie_setFirmware(FW_NAME, FW_VERSION);
|
||||
Homie_setBrand(FW_NAME);
|
||||
|
@ -87,6 +158,9 @@ void setup() {
|
|||
lightNode.advertise("brightness").settable(brightnessHandler);
|
||||
lightNode.advertise("fadetime").settable(fadetimeHandler);
|
||||
lightNode.advertise("enable").settable(enableHandler);
|
||||
#ifdef DUALCOLOR
|
||||
lightNode.advertise("temperature").settable(temperatureHandler);
|
||||
#endif
|
||||
|
||||
|
||||
Homie.setup();
|
||||
|
@ -138,10 +212,48 @@ void loopHandler() {
|
|||
}
|
||||
// #### END Button A Check ####
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
// #### Button B ####
|
||||
boolean flag_btnBpress=false; //short press on release
|
||||
boolean flag_btnBholdstart=false; //long press on start
|
||||
boolean flag_btnBhold=false; //long press after long press time
|
||||
boolean flag_btnBholdrelease=false; //long press on release
|
||||
|
||||
if (digitalRead(BTN_B)) { //Button State Machine
|
||||
switch (btnBstate) {
|
||||
case 0: //was not pressed
|
||||
btnBstate=1;
|
||||
btnBtime=loopmillis; //start timer
|
||||
break;
|
||||
case 1: //was pressed last time checked
|
||||
if (loopmillis>btnBtime+BTNHOLDTIME) {
|
||||
btnBstate=2;
|
||||
flag_btnBholdstart=true;
|
||||
}
|
||||
break;
|
||||
case 2: //button hold time reached
|
||||
flag_btnBhold=true;
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
if (btnBstate==1) { //short press
|
||||
btnBstate=0; //reset state
|
||||
flag_btnBpress=true;
|
||||
}else if(btnBstate==2) { //long press released
|
||||
flag_btnBholdrelease=true;
|
||||
btnBstate=0; //reset state
|
||||
}
|
||||
}
|
||||
// #### END Button B Check ####
|
||||
#endif
|
||||
|
||||
|
||||
//Button handling
|
||||
#ifdef DUALCOLOR
|
||||
if (flag_btnApress || flag_btnBpress){ //short press either button
|
||||
#else
|
||||
if (flag_btnApress){ //short press button
|
||||
#endif
|
||||
enable = !enable; //switch on/off
|
||||
flag_updatePWM=true; //update pwm values
|
||||
}
|
||||
|
@ -179,6 +291,35 @@ void loopHandler() {
|
|||
|
||||
}
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
// Button B Longpress Handling
|
||||
if (flag_btnBholdstart) {
|
||||
/* //Change only hold direction at extremes
|
||||
if (set_temperature>=TEMPERATURE_MAX) { //if hold started with brightness at one extreme
|
||||
holdDirection_temperature=false; //direction decrease
|
||||
}
|
||||
if (set_temperature<=TEMPERATURE_MIN) { //if hold started with brightness at one extreme
|
||||
holdDirection_temperature=true; //direction increase
|
||||
}
|
||||
*/
|
||||
holdDirection_temperature=!holdDirection_temperature; //change direction everytime
|
||||
}
|
||||
if (flag_btnBhold) { //brightness
|
||||
if (holdDirection_temperature) {
|
||||
set_temperature += HOLDTEMPERATURECHANGE_PER_LOOP;
|
||||
}else{
|
||||
set_temperature -= HOLDTEMPERATURECHANGE_PER_LOOP;
|
||||
}
|
||||
set_temperature = constrain(set_temperature, TEMPERATURE_MIN, TEMPERATURE_MAX);
|
||||
|
||||
temperature=set_temperature; //change immediately
|
||||
flag_updatePWM=true; //update pwm values
|
||||
}
|
||||
if (flag_btnBholdrelease) {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -196,6 +337,16 @@ void loopHandler() {
|
|||
flag_updatePWM=true; //force update
|
||||
}
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
float old_temperature = temperature; //store last temperature
|
||||
if ( (temperature_change_per_loop<0 && temperature>set_temperature) || (temperature_change_per_loop>0 && temperature<set_temperature)) { //if temperature not reached
|
||||
temperature += temperature_change_per_loop;
|
||||
if ( ( old_temperature <= set_temperature && set_temperature <= temperature ) || ( old_temperature >= set_temperature && set_temperature >= temperature ) ) { //overshot set value
|
||||
temperature = set_temperature;
|
||||
}
|
||||
flag_updatePWM=true; //force update
|
||||
}
|
||||
#endif
|
||||
|
||||
//Sleep
|
||||
if ( (!enable && enable_fadevalue>0) || (enable && enable_fadevalue<1) ) { //not fully turned off or on
|
||||
|
@ -210,16 +361,35 @@ void loopHandler() {
|
|||
}
|
||||
|
||||
//calculate and update pwm
|
||||
#ifdef DUALCOLOR
|
||||
if (brightness != set_brightness || temperature != set_temperature || flag_updatePWM) { //if target not reached
|
||||
#else
|
||||
if (brightness != set_brightness || flag_updatePWM) { //if target not reached
|
||||
#endif
|
||||
flag_updatePWM=false; // reset flag
|
||||
//calculate pwm values
|
||||
#ifdef DUALCOLOR
|
||||
uint16_t pwmCW;
|
||||
uint16_t pwmWW;
|
||||
float temp=mapFloat(temperature, TEMPERATURE_MIN, TEMPERATURE_MAX, 0.0,1.0); //0=warmwhite, 1=coldwhite
|
||||
pwmCW=pow((brightness*enable_fadevalue)/2.0, BRIGHTNESSCURVE) *2.0 *temp *PWM_MAX; //calculate brightness for led stripe, scale to 0-1, ^2, rescale to 0-2, scale for pwm
|
||||
pwmWW=pow((brightness*enable_fadevalue)/2.0, BRIGHTNESSCURVE) *2.0 *(1-temp) *PWM_MAX;
|
||||
if (pwmCW>PWM_MAX) { pwmCW=PWM_MAX; } //limit
|
||||
if (pwmWW>PWM_MAX) { pwmWW=PWM_MAX; } //limit
|
||||
|
||||
analogWrite(LED_WW, PWM_MAX-pwmWW); //full pwm is led off
|
||||
analogWrite(LED_CW, PWM_MAX-pwmCW); //full pwm is led off
|
||||
#else
|
||||
uint16_t pwm;
|
||||
pwm=pow((brightness*enable_fadevalue)/2.0, BRIGHTNESSCURVE) *2.0 *PWM_MAX; //calculate brightness for led stripe, scale to 0-1, ^2, rescale to 0-2, scale for pwm
|
||||
|
||||
|
||||
if (pwm>PWM_MAX) { pwm=PWM_MAX; } //limit
|
||||
|
||||
analogWrite(LED_PWM, PWM_MAX-pwm); //full pwm is led off
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +403,12 @@ void loopHandler() {
|
|||
lightNode.setProperty("brightness").send(String(set_brightness));
|
||||
known_set_brightness=set_brightness;
|
||||
}
|
||||
#ifdef DUALCOLOR
|
||||
if (known_set_temperature!=set_temperature) {
|
||||
lightNode.setProperty("temperature").send(String(set_temperature));
|
||||
known_set_temperature=set_temperature;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -327,6 +503,33 @@ bool fadetimeHandler(const HomieRange& range, const String& value) { //fadetime
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef DUALCOLOR
|
||||
bool temperatureHandler(const HomieRange& range, const String& value) {
|
||||
if (range.isRange) {
|
||||
return false; //if range is given but index is not in allowed range
|
||||
}
|
||||
Homie.getLogger() << "temperature " << ": " << value << endl;
|
||||
//lightNode.setProperty("temperature").send(value); //done in main loop
|
||||
|
||||
if (value.toFloat() >= TEMPERATURE_MIN && value.toFloat() <= TEMPERATURE_MAX) {
|
||||
set_temperature=value.toFloat();
|
||||
}else {
|
||||
Homie.getLogger() << "Value outside range" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
float _difference=set_temperature-temperature;
|
||||
if (fadetime>0) {
|
||||
temperature_change_per_loop = _difference/fadetime*UPDATETIME;
|
||||
} else { //special case for instant change
|
||||
temperature_change_per_loop = _difference;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool enableHandler(const HomieRange& range, const String& value) { //change on off
|
||||
if (range.isRange) {
|
||||
return false; //if range is given but index is not in allowed range
|
||||
|
|
Loading…
Reference in New Issue