Browse Source

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)

tags/v1.0.0
Simon Schmidt 2 years ago
parent
commit
7643961ed2
2 changed files with 114 additions and 155 deletions
  1. 94
    132
      lib/treppe/treppe.cpp
  2. 20
    23
      lib/treppe/treppe.h

+ 94
- 132
lib/treppe/treppe.cpp View File

@@ -2,100 +2,94 @@
// #define DEBUG_TIMING

/*
- dimmt stufe (0 - 15, PCA9685 outputs) mit linearen ticks
von idle bis active pwm
- return false solange gedimmt wird
- return true bei nächster stufe
- dimmer_tick: increment pwm jeden tick, bis anim beendet
- return: fsm_pend.anim_beendet
*/
bool Treppe::dimm_stufe(uint8_t stufe)
bool Treppe::dimmer_tick(dimmer_t* dimmer, bool dim_type)
{
if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN)
dimmer_stufe.pwm += dimmer_stufe.delta_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->pwm += dimmer->delta_pwm;
Serial.printf("%.0f", dimmer->pwm);

if(dim_type == DIM_STUFEN) {
pwmController.setChannelPWM(dimmer->stufe, static_cast<uint16_t>(dimmer->pwm));
} else { // DIM_LDR
pwmController.setAllChannelsPWM(static_cast<uint16_t>(dimmer->pwm));
}

dimmer_stufe.tick++;
if (dimmer_stufe.tick >= dimmer_stufe.ticks)
dimmer->tick++;
if (dimmer->tick < dimmer->ticks)
{
Serial.println("");
Serial.print("-");
return false;
}
Serial.print(" - ");
return true;
}


/*
- dimmt treppe (all PCA9685 outputs) mit linearen ticks
von idle bis active brightness
- return false solange gedimmt wird
- return true bei ende
*/
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.println("");
if(dim_type == DIM_LDR) {
Serial.printf("DIM_LDR: start: %d, ziel: %d\n",
dimmer->start_pwm, dimmer->ziel_pwm);
return true;
}
else // DIM_STUFEN
{
// Serial.printf("anim_tick(): stufe: %d, start: %d, ziel: %d, current %f\n",
// stufe, start_pwm, ziel_pwm, current_pwm);
Serial.printf("DIM_STUFEN: stufe: %d, start: %d, ziel: %d\n",
dimmer->stufe, dimmer->start_pwm, dimmer->ziel_pwm);

if (fsm_outputs.laufrichtung == LR_HOCH)
{
if (dimmer_stufe.stufe >= stufen - 1)
{
anim_beendet = true;
return;
}
dimmer_stufe.stufe++;
if (dimmer->stufe >= stufen - 1)
return true;
dimmer->stufe++;
}
else
else // LR_RUNTER
{
if (dimmer_stufe.stufe <= 0)
{
anim_beendet = true;
return;
}
dimmer_stufe.stufe--;
if (dimmer->stufe <= 0)
return true;
dimmer->stufe--;
}
dimmer_stufe.tick = 0;
dimmer_stufe.pwm = dimmer_stufe.start_pwm;
dimmer->tick = 0;
dimmer->pwm = dimmer->start_pwm;
}
return false;
}

// 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)
dimmer_stufe.stufe = 0;
else
dimmer_stufe.stufe = stufen - 1;
if(dim_type == DIM_STUFEN) {
if (fsm_outputs.laufrichtung == LR_HOCH)
dimmer->stufe = 0;
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)
{
dimmer_stufe.start_pwm = idle_pwm_ist;
dimmer_stufe.ziel_pwm = active_pwm;
dimmer->start_pwm = off_pwm;
dimmer->ziel_pwm = on_pwm;
dimmer->delta_pwm = (float)(on_pwm - off_pwm)
/ (float)dimmer->ticks;
}
else
{
dimmer_stufe.start_pwm = active_pwm;
dimmer_stufe.ziel_pwm = idle_pwm_ist;
dimmer->start_pwm = on_pwm;
dimmer->ziel_pwm = off_pwm;
dimmer->delta_pwm = (float)(off_pwm - on_pwm)
/ (float)dimmer->ticks;
}

dimmer_stufe.tick = 0;
dimmer_stufe.pwm = dimmer_stufe.start_pwm;
dimmer->tick = 0;
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()
@@ -210,17 +204,11 @@ bool Treppe::check_ldr()
float ldr = read_ldr();

if (ldr < ldr_schwelle) {
idle_pwm_soll = idle_pwm_max;
active = true;
active = 1;
}
if (ldr > ldr_schwelle + LDR_HYS) {
idle_pwm_soll = 0;
active = false;
active = 0;
}

if (idle_pwm_soll != idle_pwm_ist) {
}
activate_idle_pwm(active);
return active;
}

@@ -240,7 +228,7 @@ void Treppe::task()

fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN);
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
Serial.print("2:");
@@ -271,44 +259,39 @@ void Treppe::task()
fsm_outputs.status == ST_AUFDIMMEN_RUNTER ||
fsm_outputs.status == ST_ABDIMMEN_RUNTER )
{
if(anim_beendet)
start_animation();
if(fsm_pend.anim_beendet)
start_animation(&dimmer_stufen, DIM_STUFEN, active_pwm, idle_pwm_ist);
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
Serial.print("5:");
Serial.println(micros()-m);
m=micros();
#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.print("5:");
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()
{
pwmController.resetDevices();
@@ -326,8 +309,7 @@ void Treppe::setup()
pinMode(OE, OUTPUT);
digitalWrite(OE, 0);

Serial.printf("dimmer_stufe.delta_pwm %f\n", dimmer_stufe.delta_pwm);
Serial.printf("Treppe: initial parameters: stufen=%d\n", stufen);
Serial.printf("Treppe: stufen=%d\n", stufen);
}

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)
{
if(new_pwm > active_pwm) {
idle_pwm_max = active_pwm;
idle_pwm_soll = active_pwm;
} else {
idle_pwm_max = new_pwm;
idle_pwm_soll = new_pwm;
}

Serial.printf("Treppe: idle_pwm_max=%d\n", idle_pwm_max);
berechne_dimmer();
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;
}
}
Serial.printf("Treppe: idle_pwm_soll=%d\n", idle_pwm_soll);
fsm_pend.ldr_changed = true;
}

void Treppe::set_active_pwm(uint16_t _active_pwm)
{
active_pwm = _active_pwm;
berechne_dimmer();
Serial.printf("Treppe: active_pwm=%d\n", active_pwm);
}
void Treppe::set_time_per_stair(uint16_t _time_per_stair)
{
time_per_stair = _time_per_stair;
berechne_dimmer();
Serial.printf("Treppe: time_per_stair=%d\n", time_per_stair);
}

+ 20
- 23
lib/treppe/treppe.h View File

@@ -16,18 +16,23 @@
class Treppe {
private:
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 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 active_pwm = 700;

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_stufe_t {
struct dimmer_t {
uint8_t stufe = 0;
uint16_t ticks = 0;
uint16_t tick = 0;
@@ -37,18 +42,12 @@ private:
uint16_t start_pwm = 0;
uint16_t ziel_pwm = 0;
};
dimmer_stufe_t dimmer_stufe;

struct dimmer_ldr_t {
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;
enum dimmer_type_t {
DIM_STUFEN=0,
DIM_LDR=1
};
dimmer_ldr_t dimmer_ldr;
dimmer_t dimmer_stufen;
dimmer_t dimmer_ldr;
// initialize with i2c-Address 0, use Wire Library
PCA9685 pwmController;
@@ -77,11 +76,11 @@ private:
};

/* DIMM */
bool dimm_stufe(uint8_t stufe);
bool dimm_treppe();
void anim_tick();
void start_animation();
void berechne_dimmer();
// bool dimmer(dimmer_t* dimmer, bool dim_type);
bool dimmer_tick(dimmer_t* dimmer, bool dim_type);
void start_animation(dimmer_t* dimmer, bool dim_type,
uint16_t on_pwm, uint16_t off_pwm);
// void berechne_dimmer(dimmer_t* dimmer, bool dim_type);
void print_state_on_change();

/* LDR */
@@ -91,7 +90,6 @@ private:
public:
Treppe(uint8_t _stufen) : stufen(_stufen){
FSMTreppe_Obj.initialize();
berechne_dimmer();
}
~Treppe() {
FSMTreppe_Obj.terminate();
@@ -103,7 +101,6 @@ public:
// Parameter section
void set_idle_prozent(int prozent);
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_time_per_stair(uint16_t _time_per_stair);
};

Loading…
Cancel
Save