got dimming working, dimming from ldr, can be testet via webbrowser; dynamic dimmer_t used for both dimmers, can be selected via dimmer_type_t (DIM_STUFEN, DIM_LDR)

This commit is contained in:
Simon Schmidt 2021-07-08 02:54:08 +02:00
parent 6cc52dc460
commit 7643961ed2
2 changed files with 114 additions and 155 deletions

View File

@ -2,100 +2,94 @@
// #define DEBUG_TIMING // #define DEBUG_TIMING
/* /*
- dimmt stufe (0 - 15, PCA9685 outputs) mit linearen ticks - dimmer_tick: increment pwm jeden tick, bis anim beendet
von idle bis active pwm - return: fsm_pend.anim_beendet
- return false solange gedimmt wird
- return true bei nächster stufe
*/ */
bool Treppe::dimm_stufe(uint8_t stufe) bool Treppe::dimmer_tick(dimmer_t* dimmer, bool dim_type)
{ {
if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN) dimmer->pwm += dimmer->delta_pwm;
dimmer_stufe.pwm += dimmer_stufe.delta_pwm; Serial.printf("%.0f", dimmer->pwm);
else
dimmer_stufe.pwm -= dimmer_stufe.delta_pwm;
Serial.printf("%3.0f", dimmer_stufe.pwm);
pwmController.setChannelPWM(stufe, static_cast<uint16_t>(dimmer_stufe.pwm));
dimmer_stufe.tick++; if(dim_type == DIM_STUFEN) {
if (dimmer_stufe.tick >= dimmer_stufe.ticks) pwmController.setChannelPWM(dimmer->stufe, static_cast<uint16_t>(dimmer->pwm));
} else { // DIM_LDR
pwmController.setAllChannelsPWM(static_cast<uint16_t>(dimmer->pwm));
}
dimmer->tick++;
if (dimmer->tick < dimmer->ticks)
{ {
Serial.println(""); Serial.print("-");
return false; return false;
} }
Serial.print(" - "); Serial.println("");
return true;
}
if(dim_type == DIM_LDR) {
/* Serial.printf("DIM_LDR: start: %d, ziel: %d\n",
- dimmt treppe (all PCA9685 outputs) mit linearen ticks dimmer->start_pwm, dimmer->ziel_pwm);
von idle bis active brightness return true;
- return false solange gedimmt wird }
- return true bei ende else // DIM_STUFEN
*/
bool Treppe::dimm_treppe()
{
// needs to be in state machine
return true;
}
/*
- nach dem dimmen einer stufe wird die stufe weitergezählt
- abbruch am ende => anim_beendet = true;
*/
void Treppe::anim_tick()
{
if (!dimm_stufe(dimmer_stufe.stufe))
{ {
// Serial.printf("anim_tick(): stufe: %d, start: %d, ziel: %d, current %f\n", Serial.printf("DIM_STUFEN: stufe: %d, start: %d, ziel: %d\n",
// stufe, start_pwm, ziel_pwm, current_pwm); dimmer->stufe, dimmer->start_pwm, dimmer->ziel_pwm);
if (fsm_outputs.laufrichtung == LR_HOCH) if (fsm_outputs.laufrichtung == LR_HOCH)
{ {
if (dimmer_stufe.stufe >= stufen - 1) if (dimmer->stufe >= stufen - 1)
{ return true;
anim_beendet = true; dimmer->stufe++;
return;
}
dimmer_stufe.stufe++;
} }
else else // LR_RUNTER
{ {
if (dimmer_stufe.stufe <= 0) if (dimmer->stufe <= 0)
{ return true;
anim_beendet = true; dimmer->stufe--;
return;
}
dimmer_stufe.stufe--;
} }
dimmer_stufe.tick = 0; dimmer->tick = 0;
dimmer_stufe.pwm = dimmer_stufe.start_pwm; dimmer->pwm = dimmer->start_pwm;
} }
return false;
} }
// startbedingunen für animation // startbedingunen für animation
void Treppe::start_animation() void Treppe::start_animation( dimmer_t* dimmer, bool dim_type,
uint16_t on_pwm, uint16_t off_pwm)
{ {
anim_beendet = false; fsm_pend.anim_beendet = false;
if (fsm_outputs.laufrichtung == LR_HOCH) if(dim_type == DIM_STUFEN) {
dimmer_stufe.stufe = 0; if (fsm_outputs.laufrichtung == LR_HOCH)
else dimmer->stufe = 0;
dimmer_stufe.stufe = stufen - 1; else
dimmer->stufe = stufen - 1;
dimmer->ticks = time_per_stair / INT_TIME; // [ms]
}
else { // DIM_LDR
dimmer->ticks = time_ldr / INT_TIME; // [ms]
}
if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN) if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN)
{ {
dimmer_stufe.start_pwm = idle_pwm_ist; dimmer->start_pwm = off_pwm;
dimmer_stufe.ziel_pwm = active_pwm; dimmer->ziel_pwm = on_pwm;
dimmer->delta_pwm = (float)(on_pwm - off_pwm)
/ (float)dimmer->ticks;
} }
else else
{ {
dimmer_stufe.start_pwm = active_pwm; dimmer->start_pwm = on_pwm;
dimmer_stufe.ziel_pwm = idle_pwm_ist; dimmer->ziel_pwm = off_pwm;
dimmer->delta_pwm = (float)(off_pwm - on_pwm)
/ (float)dimmer->ticks;
} }
dimmer_stufe.tick = 0; dimmer->tick = 0;
dimmer_stufe.pwm = dimmer_stufe.start_pwm; dimmer->pwm = dimmer->start_pwm;
Serial.printf("stufe %d, ticks %d, delta %f, start %d, ziel %d\n",
dimmer->stufe, dimmer->ticks, dimmer->delta_pwm, dimmer->start_pwm, dimmer->ziel_pwm);
} }
void Treppe::print_state_on_change() void Treppe::print_state_on_change()
@ -210,17 +204,11 @@ bool Treppe::check_ldr()
float ldr = read_ldr(); float ldr = read_ldr();
if (ldr < ldr_schwelle) { if (ldr < ldr_schwelle) {
idle_pwm_soll = idle_pwm_max; active = 1;
active = true;
} }
if (ldr > ldr_schwelle + LDR_HYS) { if (ldr > ldr_schwelle + LDR_HYS) {
idle_pwm_soll = 0; active = 0;
active = false;
} }
if (idle_pwm_soll != idle_pwm_ist) {
}
activate_idle_pwm(active);
return active; return active;
} }
@ -240,7 +228,7 @@ void Treppe::task()
fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN); fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN);
fsm_inputs.sensor_unten = read_sensor(SENSOR_UNTEN); fsm_inputs.sensor_unten = read_sensor(SENSOR_UNTEN);
fsm_inputs.anim_beendet = anim_beendet; fsm_inputs.anim_beendet = fsm_pend.anim_beendet;
#ifdef DEBUG_TIMING #ifdef DEBUG_TIMING
Serial.print("2:"); Serial.print("2:");
@ -271,42 +259,37 @@ void Treppe::task()
fsm_outputs.status == ST_AUFDIMMEN_RUNTER || fsm_outputs.status == ST_AUFDIMMEN_RUNTER ||
fsm_outputs.status == ST_ABDIMMEN_RUNTER ) fsm_outputs.status == ST_ABDIMMEN_RUNTER )
{ {
if(anim_beendet) if(fsm_pend.anim_beendet)
start_animation(); start_animation(&dimmer_stufen, DIM_STUFEN, active_pwm, idle_pwm_ist);
else else
anim_tick(); fsm_pend.anim_beendet = dimmer_tick(&dimmer_stufen, DIM_STUFEN);
} }
else if ( fsm_outputs.status == ST_AUFDIMMEN_LDR ||
fsm_outputs.status == ST_ABDIMMEN_LDR )
{
if(fsm_pend.anim_beendet)
start_animation(&dimmer_ldr, DIM_LDR, idle_pwm_ist, 0);
else
fsm_pend.anim_beendet = dimmer_tick(&dimmer_ldr, DIM_LDR);
}
else if ( fsm_outputs.status == ST_RUHEZUSTAND )
{
if ( fsm_pend.ldr_changed ) {
fsm_pend.ldr_changed = false;
fsm_outputs.dimmrichtung = DR_AUFDIMMEN;
start_animation(&dimmer_ldr, DIM_LDR, idle_pwm_soll, idle_pwm_ist);
idle_pwm_ist = idle_pwm_soll;
}
if(!fsm_pend.anim_beendet) {
fsm_pend.anim_beendet = dimmer_tick(&dimmer_ldr, DIM_LDR);
}
}
#ifdef DEBUG_TIMING #ifdef DEBUG_TIMING
Serial.print("5:"); Serial.print("5:");
Serial.println(micros()-m); Serial.println(micros()-m);
m=micros();
#endif #endif
// else if (fsm_outputs.status == ST_DIMMEN_LDR) {
// if(anim_beendet) {
// berechne_dimmer();
// anim_beendet = false;
// }
// anim_beendet = dimm_treppe();
// }
#ifdef DEBUG_TIMING
Serial.print("6:");
Serial.println(micros()-m);
#endif
}
void Treppe::berechne_dimmer()
{
dimmer_stufe.ticks = time_per_stair / INT_TIME; // [ms]
dimmer_stufe.delta_pwm = (float)(active_pwm - idle_pwm_ist)
/ (float)dimmer_stufe.ticks;
dimmer_ldr.ticks = time_ldr / INT_TIME; // [ms]
dimmer_ldr.delta_pwm = (float)(idle_pwm_soll - idle_pwm_ist)
/ (float)dimmer_ldr.ticks;
} }
void Treppe::setup() void Treppe::setup()
@ -326,8 +309,7 @@ void Treppe::setup()
pinMode(OE, OUTPUT); pinMode(OE, OUTPUT);
digitalWrite(OE, 0); digitalWrite(OE, 0);
Serial.printf("dimmer_stufe.delta_pwm %f\n", dimmer_stufe.delta_pwm); Serial.printf("Treppe: stufen=%d\n", stufen);
Serial.printf("Treppe: initial parameters: stufen=%d\n", stufen);
} }
void Treppe::set_idle_prozent(const int prozent) void Treppe::set_idle_prozent(const int prozent)
@ -339,42 +321,22 @@ void Treppe::set_idle_prozent(const int prozent)
void Treppe::set_idle_pwm_max(const uint16_t new_pwm) void Treppe::set_idle_pwm_max(const uint16_t new_pwm)
{ {
if(new_pwm > active_pwm) { if(new_pwm > active_pwm) {
idle_pwm_max = active_pwm; idle_pwm_soll = active_pwm;
} else { } else {
idle_pwm_max = new_pwm; idle_pwm_soll = new_pwm;
} }
Serial.printf("Treppe: idle_pwm_max=%d\n", idle_pwm_max); Serial.printf("Treppe: idle_pwm_soll=%d\n", idle_pwm_soll);
berechne_dimmer(); fsm_pend.ldr_changed = true;
activate_idle_pwm(true);
}
void Treppe::activate_idle_pwm(bool active)
{
static uint16_t last_pwm = 0;
if (fsm_outputs.status == ST_RUHEZUSTAND || fsm_outputs.status == ST_INAKTIV_LDR)
{
idle_pwm_ist = idle_pwm_max * active;
if (idle_pwm_ist != last_pwm)
{
// Dimming Function for all LEDS ?
berechne_dimmer();
pwmController.setAllChannelsPWM(idle_pwm_ist);
last_pwm = idle_pwm_ist;
}
}
} }
void Treppe::set_active_pwm(uint16_t _active_pwm) void Treppe::set_active_pwm(uint16_t _active_pwm)
{ {
active_pwm = _active_pwm; active_pwm = _active_pwm;
berechne_dimmer();
Serial.printf("Treppe: active_pwm=%d\n", active_pwm); Serial.printf("Treppe: active_pwm=%d\n", active_pwm);
} }
void Treppe::set_time_per_stair(uint16_t _time_per_stair) void Treppe::set_time_per_stair(uint16_t _time_per_stair)
{ {
time_per_stair = _time_per_stair; time_per_stair = _time_per_stair;
berechne_dimmer();
Serial.printf("Treppe: time_per_stair=%d\n", time_per_stair); Serial.printf("Treppe: time_per_stair=%d\n", time_per_stair);
} }

View File

@ -16,18 +16,23 @@
class Treppe { class Treppe {
private: private:
const uint8_t stufen; const uint8_t stufen;
const uint16_t time_ldr = 300; const uint16_t time_ldr = 500;
uint16_t time_per_stair = 300; // dimmtime per stair [ms] uint16_t time_per_stair = 300; // dimmtime per stair [ms]
uint16_t idle_pwm_max = 100; uint16_t idle_pwm_max = 100;
uint16_t idle_pwm_ist = 0; uint16_t idle_pwm_ist = idle_pwm_max;
uint16_t idle_pwm_soll = 0; uint16_t idle_pwm_soll = 0;
uint16_t active_pwm = 700; uint16_t active_pwm = 700;
uint16_t ldr_schwelle = 2; // activation value for FSM [lx] uint16_t ldr_schwelle = 2; // activation value for FSM [lx]
struct fsm_pending_inputs_t {
bool anim_beendet = true;
bool sensor_unten = false;
bool sensor_oben = false;
bool ldr_changed = false;
};
fsm_pending_inputs_t fsm_pend;
bool anim_beendet = true; struct dimmer_t {
struct dimmer_stufe_t {
uint8_t stufe = 0; uint8_t stufe = 0;
uint16_t ticks = 0; uint16_t ticks = 0;
uint16_t tick = 0; uint16_t tick = 0;
@ -37,18 +42,12 @@ private:
uint16_t start_pwm = 0; uint16_t start_pwm = 0;
uint16_t ziel_pwm = 0; uint16_t ziel_pwm = 0;
}; };
dimmer_stufe_t dimmer_stufe; enum dimmer_type_t {
DIM_STUFEN=0,
struct dimmer_ldr_t { DIM_LDR=1
uint16_t ticks = 0;
uint16_t tick = 0;
float delta_pwm = 0.0;
float pwm = 0.0;
uint16_t start_pwm = 0;
uint16_t ziel_pwm = 0;
}; };
dimmer_ldr_t dimmer_ldr; dimmer_t dimmer_stufen;
dimmer_t dimmer_ldr;
// initialize with i2c-Address 0, use Wire Library // initialize with i2c-Address 0, use Wire Library
PCA9685 pwmController; PCA9685 pwmController;
@ -77,11 +76,11 @@ private:
}; };
/* DIMM */ /* DIMM */
bool dimm_stufe(uint8_t stufe); // bool dimmer(dimmer_t* dimmer, bool dim_type);
bool dimm_treppe(); bool dimmer_tick(dimmer_t* dimmer, bool dim_type);
void anim_tick(); void start_animation(dimmer_t* dimmer, bool dim_type,
void start_animation(); uint16_t on_pwm, uint16_t off_pwm);
void berechne_dimmer(); // void berechne_dimmer(dimmer_t* dimmer, bool dim_type);
void print_state_on_change(); void print_state_on_change();
/* LDR */ /* LDR */
@ -91,7 +90,6 @@ private:
public: public:
Treppe(uint8_t _stufen) : stufen(_stufen){ Treppe(uint8_t _stufen) : stufen(_stufen){
FSMTreppe_Obj.initialize(); FSMTreppe_Obj.initialize();
berechne_dimmer();
} }
~Treppe() { ~Treppe() {
FSMTreppe_Obj.terminate(); FSMTreppe_Obj.terminate();
@ -103,7 +101,6 @@ public:
// Parameter section // Parameter section
void set_idle_prozent(int prozent); void set_idle_prozent(int prozent);
void set_idle_pwm_max(const uint16_t new_pwm); void set_idle_pwm_max(const uint16_t new_pwm);
void activate_idle_pwm(bool active);
void set_active_pwm(uint16_t _active_pwm); void set_active_pwm(uint16_t _active_pwm);
void set_time_per_stair(uint16_t _time_per_stair); void set_time_per_stair(uint16_t _time_per_stair);
}; };