@@ -1,6 +1,7 @@ | |||
<!DOCTYPE html> | |||
<html> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
<head> | |||
<title>ESP8266 Treppenlicht</title> | |||
<link href="/favicon.png" rel="icon" type="image/png" sizes="10x10"> | |||
@@ -10,19 +11,24 @@ | |||
<body> | |||
<div class="topbar">Treppenlicht</div> | |||
<div class="param_block"> | |||
<input type="button" class="control" data-action="s_oben" value="sensor_oben"> | |||
<input type="button" class="control" data-action="s_unten" value="sensor_unten"> | |||
<input type="button" class="control" data-action="on_off" value="on_off"> | |||
</div> | |||
<div class="param_block"> | |||
Active Brightness: <output id="out_act_pwm" class="val_range">50</output> % | |||
<div class="slider"> | |||
<input type="range" class="regler" id="range_act_pwm" min="0" max="100" value="50"> | |||
<input type="range" class="regler" id="range_act_pwm" data-output="out_act_pwm" min="0" max="100" value="50"> | |||
</div> | |||
</div> | |||
<div class="param_block"> | |||
Idle Brightness Maximum: <output id="out_idl_pwm" class="val_range">50</output> % | |||
<label id="note">[100% == Active Brightness]</label> | |||
<div class="slider"> | |||
<input type="range" class="regler" id="range_idl_pwm" min="0" max="100" value="50"> | |||
<input type="range" class="regler" id="range_idl_pwm" data-output="out_idl_pwm" min="0" max="100" value="50"> | |||
</div> | |||
<label id="note">idle brightness gets controlled via LDR measurments</label> | |||
</div> | |||
@@ -31,27 +37,27 @@ | |||
Time per stair [ms]: <output id="out_tim_sta" class="val_range">300</output> ms | |||
<div class="slider"> | |||
<input type="range" class="regler" id="range_tim_sta" min="0" max="5000" value="300"> | |||
<input type="range" class="regler" id="range_tim_sta" data-output="out_tim_sta" min="0" max="5000" value="300"> | |||
</div> | |||
</div> | |||
<div class="param_block"> | |||
Time LDR [ms]: <output id="out_tim_ldr" class="val_range">500</output> ms | |||
<div class="slider"> | |||
<input type="range" class="regler" id="range_tim_ldr" min="0" max="5000" value="500"> | |||
<input type="range" class="regler" id="range_tim_ldr" data-output="out_tim_ldr" min="0" max="5000" value="500"> | |||
</div> | |||
</div> | |||
<div class="param_block"> | |||
LDR Schwelle [%]: <output id="out_ldr_shw" class="val_range">50</output> % | |||
<div class="slider"> | |||
<input type="range" class="regler" id="range_ldr_shw" min="0" max="100" value="50"> | |||
<input type="range" class="regler" id="range_ldr_shw" data-output="out_ldr_shw" min="0" max="100" value="50"> | |||
</div> | |||
</div> | |||
<div class="terminal"> | |||
<input type="button" id="clear_term" value="clear" onclick="clearTerminal();"> | |||
<input type="button" id="clear_term" value="clear"> | |||
<input type="checkbox" id="scroll" name="scroll" value="scroll" checked> | |||
<label for="scroll"> autoscroll </label> | |||
<textarea id="term">waiting for log messages ... </textarea> |
@@ -1,13 +1,13 @@ | |||
let rangeValues = {}; | |||
let xhrUpd = new XMLHttpRequest(); | |||
xhrUpd.onreadystatechange = function(){ | |||
if(xhrUpd.readyState == 4) { | |||
if (xhrUpd.status == 200){ | |||
console.log(xhrUpd.responseText); | |||
xhrUpd.onreadystatechange = function () { | |||
if (xhrUpd.readyState == 4) { | |||
if (xhrUpd.status == 200) { | |||
console.log("xhrUpd: ", xhrUpd.responseText); | |||
} | |||
else { | |||
console.log("status:", xhrUpd.status); | |||
console.log("xhrUpd: status=", xhrUpd.status); | |||
} | |||
} | |||
} | |||
@@ -15,9 +15,9 @@ xhrUpd.onreadystatechange = function(){ | |||
function reloadRangeValues() { | |||
let url = "/update"; | |||
// if there are scheduled updates, send them | |||
if(Object.keys(rangeValues).length > 0) { | |||
if (Object.keys(rangeValues).length > 0) { | |||
let params = []; | |||
for(let p in rangeValues) | |||
for (let p in rangeValues) | |||
params.push(encodeURIComponent(p) + "=" + encodeURIComponent(rangeValues[p])); | |||
params = params.join("&"); | |||
@@ -28,52 +28,61 @@ function reloadRangeValues() { | |||
rangeValues = {}; | |||
} | |||
setTimeout(reloadRangeValues, 1000); | |||
}; | |||
reloadRangeValues(); | |||
function sendRangeValue(range, val) { | |||
rangeValues[range] = val; | |||
console.log(rangeValues); | |||
function reloadTerminal() { | |||
const terminal = document.querySelector("#term"); | |||
const autoscroll = document.querySelector("#scroll"); | |||
fetch(`/terminal`, { | |||
method: 'POST', | |||
headers: { | |||
'Content-Type': 'application/x-www-form-urlencoded', | |||
}, | |||
body: '' | |||
}) | |||
.then(response => response.text()) | |||
.then(data => { | |||
if(data.length > 0) { | |||
terminal.innerHTML += data; | |||
if (autoscroll.checked) | |||
terminal.scrollTop = terminal.scrollHeight; | |||
} | |||
}) | |||
.catch(error => console.log('Error:', error)); | |||
}; | |||
// connect actions to range inputs | |||
function rangeToOutput(range, output) { | |||
document.getElementById(range).oninput = function() { | |||
document.getElementById(output).innerHTML = this.value; | |||
sendRangeValue(this.id, this.value); | |||
} | |||
} | |||
document.addEventListener('DOMContentLoaded', () => { | |||
setInterval(reloadTerminal, 1000); | |||
setInterval(reloadRangeValues, 1000); | |||
rangeToOutput("range_act_pwm", "out_act_pwm"); | |||
rangeToOutput("range_idl_pwm", "out_idl_pwm"); | |||
rangeToOutput("range_tim_sta", "out_tim_sta"); | |||
rangeToOutput("range_tim_ldr", "out_tim_ldr"); | |||
rangeToOutput("range_ldr_shw", "out_ldr_shw"); | |||
let xhr = new XMLHttpRequest(); | |||
xhr.onreadystatechange = function(){ | |||
if(xhr.readyState == 4) { | |||
if (xhr.status == 200){ | |||
console.log(xhr.responseText); | |||
terminal = document.getElementById("term"); | |||
autoscroll = document.getElementById("scroll"); | |||
terminal.innerHTML += xhr.responseText; | |||
if(autoscroll.checked) | |||
terminal.scrollTop = terminal.scrollHeight; | |||
// use data- attributes for action | |||
document.querySelectorAll('.control').forEach((button) => { | |||
button.onclick = () => { | |||
fetch(`/action`, { | |||
method: 'POST', | |||
headers: { | |||
'Content-Type': 'application/x-www-form-urlencoded', | |||
}, | |||
body: `control=${button.dataset.action}` | |||
}) | |||
.then(response => console.log(response)) | |||
.catch(error => console.log('Error:', error)); | |||
} | |||
else { | |||
console.log("status:", xhr.status); | |||
}); | |||
document.querySelectorAll('.regler').forEach((regler) => { | |||
regler.oninput = () => { | |||
document.querySelector(`#${regler.dataset.output}`).innerHTML = regler.value; | |||
rangeValues[regler.id] = regler.value; | |||
} | |||
} | |||
} | |||
function reloadTerminal() { | |||
xhr.open("POST", "/terminal", true); | |||
xhr.send(); | |||
setTimeout(reloadTerminal, 1000); | |||
}; | |||
reloadTerminal(); | |||
function clearTerminal() { | |||
document.getElementById("term").innerHTML = ''; | |||
} | |||
}); | |||
document.querySelector('#clear_term').onclick = () => { | |||
document.querySelector("#term").innerHTML = ''; | |||
}; | |||
}); | |||
@@ -113,8 +113,10 @@ linker puts them together ?!? | |||
- testing if dimming crashes when two animations | |||
-> ldr does not interrupt animation, animation get's finished and stairs fade out -> FSM works without collisions | |||
- interrupt to pending from sensors | |||
-> rising edge trigger implemented, via pending input | |||
- settings struct | |||
-> implemented with EEPROM | |||
-> adapted to only change on ruhezustand | |||
- script for gdb on windows | |||
-> [implemented](start_xtensa_gdb_stub.cmd) | |||
- welcome animation ? | |||
@@ -130,4 +132,10 @@ linker puts them together ?!? | |||
- behavior when someone enters stairway from opposite direction after animation finished but person 1 is still on stairway? | |||
-> currently stairs fade off from direction 1 | |||
-> additional wait-state between "warten hoch/runter" and "abdimmen hoch/runter" after sensor detected person? | |||
-> additional wait-state between "warten hoch/runter" and "abdimmen hoch/runter" after sensor detected person? | |||
- active brightness can be lower than idle in the moment | |||
- change idle to precentage of active !! | |||
- Webpage needs to load settings from eeprom !! |
@@ -31,17 +31,33 @@ auto HTTPServer::start() -> bool { | |||
// add static root file handler for http | |||
this->serveStatic("/", LittleFS, "/"); | |||
this->begin(); | |||
Serial.printf("Server active on Port 80 !\n\r"); | |||
logf("Server active on Port 80 !\n\r"); | |||
return true; | |||
} | |||
void HTTPServer::start_apps() { | |||
// application handler | |||
this->on("/action", HTTP_POST, [this]() { | |||
if (args()) { | |||
logf("%s=%s\n", argName(0).c_str(), arg(0).c_str()); | |||
if (argName(0).equals("control")) { | |||
if (arg(0).equals("s_oben")) { | |||
treppe->overwrite_sensors(true, false); | |||
logt("control => s_oben !\n"); | |||
} | |||
else if (arg(0).equals("s_unten")) { | |||
treppe->overwrite_sensors(false, true); | |||
logt("control => s_unten !\n"); | |||
} | |||
} | |||
} | |||
send(200, "text/plain", "accepted"); | |||
}); | |||
this->on("/update", HTTP_POST, [this]() { | |||
if (args()) { | |||
for (int i = 0; i < args() - 1; i++) { | |||
Serial.printf("%s=%s\n", argName(i).c_str(), arg(i).c_str()); | |||
logf("%s=%s\n", argName(i).c_str(), arg(i).c_str()); | |||
if (argName(i).equals("range_act_pwm")) { | |||
treppe->set_active_pwm(arg(i).toInt(), VORGABE_PROZENT); | |||
@@ -70,7 +86,7 @@ void HTTPServer::start_apps() { | |||
}); | |||
this->on("/terminal", HTTP_POST, [this]() { | |||
// Serial.printf("got /terminal\n"); | |||
// logf("got /terminal\n"); | |||
if (tbuf_head) { | |||
send(200, "text/plain", tbuf); | |||
tbuf_head = 0; |
@@ -27,8 +27,7 @@ bool Treppe::dimmer_tick(dimmer_t *dimmer, bool dim_type) { | |||
Serial.printf("DIM_LDR: start: %d, ziel: %d\n", dimmer->start_pwm, | |||
dimmer->ziel_pwm); | |||
return true; | |||
} else // DIM_STUFEN | |||
{ | |||
} else { // DIM_STUFEN | |||
Serial.printf("DIM_STUFEN: stufe: %d, start: %d, ziel: %d\n", | |||
dimmer->stufe, dimmer->start_pwm, dimmer->ziel_pwm); | |||
@@ -36,8 +35,7 @@ bool Treppe::dimmer_tick(dimmer_t *dimmer, bool dim_type) { | |||
if (dimmer->stufe >= stufen - 1) | |||
return true; | |||
dimmer->stufe++; | |||
} else // LR_RUNTER | |||
{ | |||
} else { // LR_RUNTER | |||
if (dimmer->stufe <= 0) | |||
return true; | |||
dimmer->stufe--; | |||
@@ -59,9 +57,9 @@ void Treppe::start_animation(dimmer_t *dimmer, bool dim_type, uint16_t on_pwm, | |||
else | |||
dimmer->stufe = stufen - 1; | |||
dimmer->ticks = parameters.time_per_stair / INT_TIME; // [ms] | |||
dimmer->ticks = param.time_per_stair / INT_TIME; // [ms] | |||
} else { // DIM_LDR | |||
dimmer->ticks = parameters.time_ldr / INT_TIME; // [ms] | |||
dimmer->ticks = param.time_ldr / INT_TIME; // [ms] | |||
} | |||
if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN) { | |||
@@ -108,33 +106,38 @@ void Treppe::print_state_on_change() { | |||
} | |||
} | |||
bool Treppe::read_sensor(int sensor) { | |||
void Treppe::overwrite_sensors(bool s_oben, bool s_unten) { | |||
fsm_pend.web_ctrl_s_oben = s_oben; | |||
fsm_pend.web_ctrl_s_unten = s_unten; | |||
} | |||
/* | |||
reads sensors with edge detection | |||
void Treppe::read_sensors() { | |||
const bool s_oben = digitalRead(SENSOR_OBEN); | |||
const bool s_unten = digitalRead(SENSOR_UNTEN); | |||
returns true if motion was detected | |||
returns false if no motion was detected | |||
returns false if motion was detected, but state did not change back to not | |||
detected | |||
*/ | |||
uint8_t pegel = digitalRead(sensor); | |||
static uint8_t pegel_alt[2] = {0, 0}; | |||
fsm_pend.sensor_oben = false; | |||
fsm_pend.sensor_unten = false; | |||
uint8_t index = 0; | |||
if (sensor == SENSOR_OBEN) | |||
index = 0; | |||
else | |||
index = 1; | |||
// rising trigger => 1 cycle true ! | |||
if (s_oben && !fsm_pend.last_s_oben) { | |||
fsm_pend.sensor_oben = true; | |||
} | |||
if (s_unten && !fsm_pend.last_s_unten) { | |||
fsm_pend.sensor_unten = true; | |||
} | |||
if (pegel == 1 && pegel_alt[index] == 0) { | |||
pegel_alt[index] = pegel; | |||
return true; | |||
} else { | |||
pegel_alt[index] = pegel; | |||
return false; | |||
fsm_pend.last_s_oben = s_oben; | |||
fsm_pend.last_s_unten = s_unten; | |||
// check for manipulation over webserver | |||
if (fsm_pend.web_ctrl_s_oben) { | |||
fsm_pend.sensor_oben = true; | |||
fsm_pend.web_ctrl_s_oben = false; | |||
} | |||
if (fsm_pend.web_ctrl_s_unten) { | |||
fsm_pend.sensor_unten = true; | |||
fsm_pend.web_ctrl_s_unten = false; | |||
} | |||
// return static_cast<bool>(pegel); | |||
} | |||
float Treppe::read_ldr() { | |||
@@ -190,10 +193,10 @@ bool Treppe::check_ldr() { | |||
// follow up: averaging over many samples? | |||
float ldr = read_ldr(); | |||
if (ldr < parameters.ldr_schwelle) { | |||
if (ldr < param.ldr_schwelle) { | |||
active = 1; | |||
} | |||
if (ldr > parameters.ldr_schwelle + LDR_HYS) { | |||
if (ldr > param.ldr_schwelle + LDR_HYS) { | |||
active = 0; | |||
} | |||
return active; | |||
@@ -206,7 +209,6 @@ void Treppe::task() { | |||
// TODO wenn LDR geändert => idle_pwm_soll anpassen | |||
// fsm_pend.ldr_changed = true; | |||
fsm_inputs.ldr_schwelle = check_ldr(); | |||
#ifdef DEBUG_TIMING | |||
@@ -215,8 +217,10 @@ void Treppe::task() { | |||
m = micros(); | |||
#endif | |||
fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN); | |||
fsm_inputs.sensor_unten = read_sensor(SENSOR_UNTEN); | |||
read_sensors(); | |||
fsm_inputs.sensor_oben = fsm_pend.sensor_oben; | |||
fsm_inputs.sensor_unten = fsm_pend.sensor_unten; | |||
fsm_inputs.anim_beendet = fsm_pend.anim_beendet; | |||
#ifdef DEBUG_TIMING | |||
@@ -248,7 +252,7 @@ void Treppe::task() { | |||
fsm_outputs.status == ST_AUFDIMMEN_RUNTER || | |||
fsm_outputs.status == ST_ABDIMMEN_RUNTER) { | |||
if (fsm_pend.anim_beendet) | |||
start_animation(&dimmer_stufen, DIM_STUFEN, parameters.active_pwm, | |||
start_animation(&dimmer_stufen, DIM_STUFEN, param.active_pwm, | |||
idle_pwm_ist); | |||
else | |||
fsm_pend.anim_beendet = dimmer_tick(&dimmer_stufen, DIM_STUFEN); | |||
@@ -268,6 +272,12 @@ void Treppe::task() { | |||
if (!fsm_pend.anim_beendet) { | |||
fsm_pend.anim_beendet = dimmer_tick(&dimmer_ldr, DIM_LDR); | |||
} | |||
if (param_changed) { | |||
param_changed = false; | |||
param = param_pend; | |||
save_param_to_eeprom(); | |||
} | |||
} | |||
#ifdef DEBUG_TIMING | |||
@@ -288,7 +298,7 @@ void Treppe::setup() { | |||
// WARNING: before getting Parameters of Flash, make sure plausible parameters | |||
// are written in flash! | |||
EEPROM.get(EEP_START_ADDR, parameters); // get Parameters of flash | |||
EEPROM.get(EEP_START_ADDR, param); // get Parameters of flash | |||
pinMode(13, OUTPUT); | |||
pinMode(0, OUTPUT); | |||
@@ -304,73 +314,73 @@ void Treppe::setup() { | |||
Serial.printf("Treppe: stufen=%d\n", stufen); | |||
} | |||
void Treppe::saveParam() { | |||
void Treppe::save_param_to_eeprom() { | |||
EEPROM.put(EEP_START_ADDR, | |||
parameters); // copy Parameters so "EEPROM"-section in RAM | |||
param); // copy Parameters so "EEPROM"-section in RAM | |||
EEPROM.commit(); // write "EEPROM"-section to flash | |||
} | |||
void Treppe::set_idle_pwm_max(const uint16_t value, | |||
const vorgabe_typ_t vorgabe_typ) { | |||
if (vorgabe_typ == VORGABE_PROZENT) { | |||
parameters.idle_pwm_max = parameters.active_pwm * value / 100; | |||
param_pend.idle_pwm_max = param_pend.active_pwm * value / 100; | |||
} else if (vorgabe_typ == VORGABE_12BIT) { | |||
parameters.idle_pwm_max = value; | |||
param_pend.idle_pwm_max = value; | |||
} | |||
if (parameters.idle_pwm_max > parameters.active_pwm) { | |||
parameters.idle_pwm_max = parameters.active_pwm; | |||
if (param_pend.idle_pwm_max > param_pend.active_pwm) { | |||
param_pend.idle_pwm_max = param_pend.active_pwm; | |||
} | |||
saveParam(); | |||
param_changed = true; | |||
Serial.printf("Treppe: parameters.idle_pwm_max=%d\n", | |||
parameters.idle_pwm_max); | |||
Serial.printf("Treppe: param_pend.idle_pwm_max=%d\n", | |||
param_pend.idle_pwm_max); | |||
} | |||
void Treppe::set_active_pwm(const uint16_t value, | |||
const vorgabe_typ_t vorgabe_typ) { | |||
if (vorgabe_typ == VORGABE_PROZENT) { | |||
parameters.active_pwm = 4095 * value / 100; | |||
param_pend.active_pwm = 4095 * value / 100; | |||
} else if (vorgabe_typ == VORGABE_12BIT) { | |||
parameters.active_pwm = value; | |||
param_pend.active_pwm = value; | |||
} | |||
if (parameters.active_pwm > 4095) { | |||
parameters.idle_pwm_max = 4095; | |||
if (param_pend.active_pwm > 4095) { | |||
param_pend.idle_pwm_max = 4095; | |||
} | |||
saveParam(); | |||
param_changed = true; | |||
Serial.printf("Treppe: parameters.active_pwm=%d\n", parameters.active_pwm); | |||
Serial.printf("Treppe: param_pend.active_pwm=%d\n", param_pend.active_pwm); | |||
} | |||
void Treppe::set_time_ldr(const uint16_t value) { | |||
parameters.time_ldr = value; | |||
if (parameters.time_ldr > TIME_MS_MAX) | |||
parameters.time_ldr = TIME_MS_MAX; | |||
saveParam(); | |||
param_pend.time_ldr = value; | |||
if (param_pend.time_ldr > TIME_MS_MAX) | |||
param_pend.time_ldr = TIME_MS_MAX; | |||
param_changed = true; | |||
Serial.printf("Treppe: time_ldr=%d\n", parameters.time_ldr); | |||
Serial.printf("Treppe: time_ldr=%d\n", param_pend.time_ldr); | |||
} | |||
void Treppe::set_time_per_stair(const uint16_t value) { | |||
parameters.time_per_stair = value; | |||
if (parameters.time_per_stair > TIME_MS_MAX) | |||
parameters.time_per_stair = TIME_MS_MAX; | |||
saveParam(); | |||
param_pend.time_per_stair = value; | |||
if (param_pend.time_per_stair > TIME_MS_MAX) | |||
param_pend.time_per_stair = TIME_MS_MAX; | |||
param_changed = true; | |||
Serial.printf("Treppe: time_per_stair=%d\n", parameters.time_per_stair); | |||
Serial.printf("Treppe: time_per_stair=%d\n", param_pend.time_per_stair); | |||
} | |||
void Treppe::set_ldr_schwelle(const uint16_t value, | |||
const vorgabe_typ_t vorgabe_typ) { | |||
if (vorgabe_typ == VORGABE_PROZENT) { | |||
// ?! | |||
parameters.ldr_schwelle = 10 * value / 100; | |||
param_pend.ldr_schwelle = 10 * value / 100; | |||
} else if (vorgabe_typ == VORGABE_12BIT) { | |||
// parameters.ldr_schwelle = value; | |||
// param_pend.ldr_schwelle = value; | |||
} | |||
saveParam(); | |||
param_changed = true; | |||
Serial.printf("Treppe: ldr_schwelle=%d\n", parameters.ldr_schwelle); | |||
Serial.printf("Treppe: ldr_schwelle=%d\n", param_pend.ldr_schwelle); | |||
} |
@@ -30,15 +30,21 @@ private: | |||
uint16_t active_pwm = 2000; | |||
uint16_t ldr_schwelle = 2; // activation value for FSM [lx] | |||
}; | |||
stairway_param_t parameters; | |||
stairway_param_t param; | |||
stairway_param_t param_pend; // zwischenspeicher änderungen | |||
bool param_changed = false; | |||
uint16_t idle_pwm_ist = parameters.idle_pwm_max; | |||
uint16_t idle_pwm_ist = param.idle_pwm_max; | |||
uint16_t idle_pwm_soll = 0; | |||
struct fsm_pending_inputs_t { | |||
bool anim_beendet = true; | |||
bool sensor_unten = false; | |||
bool last_s_unten = false; | |||
bool web_ctrl_s_unten = false; | |||
bool sensor_oben = false; | |||
bool last_s_oben = false; | |||
bool web_ctrl_s_oben = false; | |||
bool ldr_changed = false; | |||
}; | |||
fsm_pending_inputs_t fsm_pend; | |||
@@ -77,13 +83,13 @@ private: | |||
enum fsm_laufrichtung_t { LR_RUNTER = 0, LR_HOCH = 1 }; | |||
enum fsm_dimmrichtung_t { DR_ABDIMMEN = 0, DR_AUFDIMMEN = 1 }; | |||
void read_sensors(); | |||
void print_state_on_change(); | |||
/* DIMM */ | |||
// 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 */ | |||
bool read_sensor(int sensor); | |||
@@ -98,13 +104,15 @@ public: | |||
void task(); // call periodically | |||
// Parameter section | |||
void saveParam(); | |||
void save_param_to_eeprom(); | |||
void set_idle_pwm_max(const uint16_t value, const vorgabe_typ_t vorgabe_typ); | |||
void set_active_pwm(const uint16_t value, const vorgabe_typ_t vorgabe_typ); | |||
void set_time_ldr(const uint16_t value); | |||
void set_time_per_stair(const uint16_t value); | |||
void set_ldr_schwelle(const uint16_t value, const vorgabe_typ_t vorgabe_typ); | |||
void overwrite_sensors(bool s_oben, bool s_unten); | |||
}; | |||
#endif // __TREPPE_H |