18 Commits
Author SHA1 Message Date
schmidtsi76327 6bd0844927 got parameter fetch working beta only 2021-09-06 00:41:11 +02:00
schmidtsi76327 b309c0b207 formatting 2021-09-04 10:29:09 +02:00
bartschdo76253 767df957cc ldr schwelle [lx], parameter change when inactive 2021-07-25 17:38:12 +02:00
bartschdo76253 0d6f0b28e2 Merge branch 'master' of https://git.efi.th-nuernberg.de/gitea/schmidtsi76327/ESP8266_Treppenlicht 2021-07-25 17:05:20 +02:00
bartschdo76253 937f7f09e7 new ldr algo 2021-07-25 17:05:14 +02:00
schmidtsi76327 6ae3f5690f add to TODO 2021-07-22 21:50:01 +02:00
schmidtsi76327 7c770a7802 change terminal reload to fetch API, use promises, DOMContentLoaded etc. 2021-07-22 21:49:22 +02:00
schmidtsi76327 6807d0f0af add pending settings buffer, gets written in RUHEZUSTAND, add TODO point ! 2021-07-22 21:25:24 +02:00
schmidtsi76327 770c2436fd change read sensors, trigger via web possible, modify js to fetch with HTTP_POST 2021-07-22 21:08:23 +02:00
schmidtsi76327 3145949020 use fetch and update js and add some buttons for webpage 2021-07-22 03:42:51 +02:00
schmidtsi76327 ca938ef3dd TODO update 2021-07-19 12:36:24 +02:00
schmidtsi76327 f8fac7acfb added win debug script 2021-07-19 12:34:06 +02:00
bartschdo76253 9ed1b24316 variable viewport -> besser usability on phones 2021-07-19 12:22:45 +02:00
schmidtsi76327 125b39a418 added log messages 2021-07-19 12:01:20 +02:00
schmidtsi76327 e47cae30a8 merge conflicts 2021-07-19 11:57:12 +02:00
schmidtsi76327 b2ff66d44c updates to change other parameters from http 2021-07-19 11:54:37 +02:00
bartschdo76253 c23b9f2bc6 Merge branch 'master' of https://git.efi.th-nuernberg.de/gitea/schmidtsi76327/ESP8266_Treppenlicht 2021-07-19 11:44:05 +02:00
bartschdo76253 31c268487c EEP implementation 2021-07-19 11:31:32 +02:00
12 changed files with 357 additions and 146 deletions

No files matched your search

+28 -15
View File
@@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head> <head>
<title>ESP8266 Treppenlicht</title> <title>ESP8266 Treppenlicht</title>
@@ -10,41 +11,53 @@
<body> <body>
<div class="topbar">Treppenlicht</div> <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"> <div class="param_block">
Active Brightness: <output id="out_act_pwm" class="val_range">50</output> % Active Brightness: <output id="out_act_pwm" class="val_range">50</output> %
<div class="slider"> <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: <output id="out_idl_pwm" class="val_range">50</output> %
<div class="slider">
<input type="range" class="regler" id="range_idl_pwm" min="0" max="100" value="50">
</div> </div>
</div> </div>
<div class="param_block"> <div class="param_block">
Time per stair: <output id="out_tim_sta" class="val_range">50</output> % 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" data-output="out_idl_pwm" min="0" max="100" value="50">
</div>
<label id="note">idle brightness gets controlled via LDR measurments</label>
</div>
<div class="param_block">
Time per stair [ms]: <output id="out_tim_sta" class="val_range">300</output> ms
<div class="slider"> <div class="slider">
<input type="range" class="regler" id="range_tim_sta" min="0" max="100" value="50"> <input type="range" class="regler" id="range_tim_sta" data-output="out_tim_sta" min="0" max="5000" value="300">
</div> </div>
</div> </div>
<div class="param_block"> <div class="param_block">
On Time: <output id="out_tim_on" class="val_range">50</output> % Time LDR [ms]: <output id="out_tim_ldr" class="val_range">500</output> ms
<div class="slider"> <div class="slider">
<input type="range" class="regler" id="range_tim_on" min="0" max="100" value="50"> <input type="range" class="regler" id="range_tim_ldr" data-output="out_tim_ldr" min="0" max="5000" value="500">
</div>
</div> </div>
<div class="param_block">
LDR Schwelle [lx]: <output id="out_ldr_shw" class="val_range">50</output> lx
<div class="slider">
<input type="range" class="regler" id="range_ldr_shw" data-output="out_ldr_shw" min="0" max="100" value="50">
</div>
</div> </div>
<div class="terminal"> <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> <input type="checkbox" id="scroll" name="scroll" value="scroll" checked>
<label for="scroll"> autoscroll </label> <label for="scroll"> autoscroll </label>
<textarea id="term">waiting for log messages ...&#10;</textarea> <textarea id="term">waiting for log messages ...&#10;</textarea>
+84 -43
View File
@@ -4,10 +4,10 @@ let xhrUpd = new XMLHttpRequest();
xhrUpd.onreadystatechange = function () { xhrUpd.onreadystatechange = function () {
if (xhrUpd.readyState == 4) { if (xhrUpd.readyState == 4) {
if (xhrUpd.status == 200) { if (xhrUpd.status == 200) {
console.log(xhrUpd.responseText); console.log("xhrUpd: ", xhrUpd.responseText);
} }
else { else {
console.log("status:", xhrUpd.status); console.log("xhrUpd: status=", xhrUpd.status);
} }
} }
} }
@@ -28,52 +28,93 @@ function reloadRangeValues() {
rangeValues = {}; rangeValues = {};
} }
setTimeout(reloadRangeValues, 1000);
};
reloadRangeValues();
function sendRangeValue(range, val) {
rangeValues[range] = val;
console.log(rangeValues);
}; };
// connect actions to range inputs function reloadTerminal() {
function rangeToOutput(range, output) { const terminal = document.querySelector("#term");
document.getElementById(range).oninput = function() { const autoscroll = document.querySelector("#scroll");
document.getElementById(output).innerHTML = this.value;
sendRangeValue(this.id, this.value);
}
}
rangeToOutput("range_act_pwm", "out_act_pwm"); fetch('/terminal', {
rangeToOutput("range_idl_pwm", "out_idl_pwm"); method: 'POST',
rangeToOutput("range_tim_sta", "out_tim_sta"); headers: {
rangeToOutput("range_tim_on", "out_tim_on"); 'Content-Type': 'application/x-www-form-urlencoded',
},
body: ''
let xhr = new XMLHttpRequest(); })
.then(response => response.text())
xhr.onreadystatechange = function(){ .then(data => {
if(xhr.readyState == 4) { if(data.length > 0) {
if (xhr.status == 200){ terminal.innerHTML += data;
console.log(xhr.responseText);
terminal = document.getElementById("term");
autoscroll = document.getElementById("scroll");
terminal.innerHTML += xhr.responseText;
if (autoscroll.checked) if (autoscroll.checked)
terminal.scrollTop = terminal.scrollHeight; terminal.scrollTop = terminal.scrollHeight;
} }
else { })
console.log("status:", xhr.status); .catch(error => console.log('Error:', error));
}
}
}
function reloadTerminal() {
xhr.open("POST", "/terminal", true);
xhr.send();
setTimeout(reloadTerminal, 1000);
}; };
reloadTerminal();
function clearTerminal() { function updateParameters() {
document.getElementById("term").innerHTML = ''; fetch('/parameters', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: ''
})
.then(response => response.json())
.then(json_str => {
const active_pwm = Math.round(json_str.active_pwm / 4095 * 100);
document.querySelector('#range_act_pwm').value = active_pwm;
document.querySelector('#out_act_pwm').value = active_pwm;
const idle_pwm_max = Math.round(json_str.idle_pwm_max / json_str.active_pwm * 100);
document.querySelector('#range_idl_pwm').value = idle_pwm_max;
document.querySelector('#out_idl_pwm').value = idle_pwm_max;
document.querySelector('#range_tim_sta').value = json_str.time_per_stair;
document.querySelector('#out_tim_sta').value = json_str.time_per_stair;
document.querySelector('#range_tim_ldr').value = json_str.time_ldr;
document.querySelector('#out_tim_ldr').value = json_str.time_ldr;
document.querySelector('#range_ldr_shw').value = json_str.ldr_schwelle;
document.querySelector('#out_ldr_shw').value = json_str.ldr_schwelle;
})
.catch(error => console.log('Error:', error));
};
document.addEventListener('DOMContentLoaded', () => {
setInterval(reloadTerminal, 1000);
setInterval(reloadRangeValues, 1000);
updateParameters();
// 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));
} }
});
document.querySelectorAll('.regler').forEach((regler) => {
regler.oninput = () => {
document.querySelector(`#${regler.dataset.output}`).innerHTML = regler.value;
rangeValues[regler.id] = regler.value;
}
});
document.querySelector('#clear_term').onclick = () => {
document.querySelector("#term").innerHTML = '';
};
});
+6 -2
View File
@@ -38,6 +38,12 @@ body {
outline: black; outline: black;
background-color: rgb(176, 188, 228); background-color: rgb(176, 188, 228);
} }
#note {
font-size: medium;
font-style: italic;
}
/* .regler::-webkit-slider-thumb{ /* .regler::-webkit-slider-thumb{
-webkit-appearance: none; -webkit-appearance: none;
appearance: none; appearance: none;
@@ -112,8 +118,6 @@ input:checked + .slider:before {
margin: 2px; margin: 2px;
} }
input[type="number"] { input[type="number"] {
width: 100px; width: 100px;
} }
+14 -2
View File
@@ -109,15 +109,21 @@ linker puts them together ?!?
### TODO Treppe ### TODO Treppe
- dynamic lighting with ldr - dynamic lighting with ldr
- http control over active pwm ... => set_active_pwm() - http control over active pwm ... => set_active_pwm()
-> is implemntiert, kann mit % oder abs eingestellt werden
- testing if dimming crashes when two animations - testing if dimming crashes when two animations
-> ldr does not interrupt animation, animation get's finished and stairs fade out -> FSM works without collisions -> ldr does not interrupt animation, animation get's finished and stairs fade out -> FSM works without collisions
- interrupt to pending from sensors - interrupt to pending from sensors
-> rising edge trigger implemented, via pending input
- settings struct - settings struct
-> implemented with EEPROM
-> adapted to only change on ruhezustand
- script for gdb on windows - script for gdb on windows
- dynamic time for dimming => set_time_per_stair() -> [implemented](start_xtensa_gdb_stub.cmd)
- welcome animation ? - welcome animation ?
-> wird hochgedimmt beim einschalten von 0
- on/off switch http - on/off switch http
- use logging to serial http monitor with httpserver.logt(); - use logging to serial http monitor with httpserver.logt()
-> is used for some status updates
- behavior when someone enters stairway from opposite direction while animation is running? - behavior when someone enters stairway from opposite direction while animation is running?
-> currently ignored, second persons walks in darkness -> currently ignored, second persons walks in darkness
@@ -127,3 +133,9 @@ linker puts them together ?!?
- behavior when someone enters stairway from opposite direction after animation finished but person 1 is still on stairway? - 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 -> 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 !!
+39 -6
View File
@@ -31,28 +31,53 @@ auto HTTPServer::start() -> bool {
// add static root file handler for http // add static root file handler for http
this->serveStatic("/", LittleFS, "/"); this->serveStatic("/", LittleFS, "/");
this->begin(); this->begin();
Serial.printf("Server active on Port 80 !\n\r"); logf("Server active on Port 80 !\n\r");
return true; return true;
} }
void HTTPServer::start_apps() { 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]() { this->on("/update", HTTP_POST, [this]() {
if (args()) { if (args()) {
for (int i = 0; i < args() - 1; i++) { 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")) { if (argName(i).equals("range_act_pwm")) {
treppe->set_active_pwm(arg(i).toInt(), VORGABE_PROZENT); treppe->set_active_pwm(arg(i).toInt(), VORGABE_PROZENT);
logt("set_active_pwm = %d %\n", arg(i).toInt());
} }
else if (argName(i).equals("range_idl_pwm")) { else if (argName(i).equals("range_idl_pwm")) {
treppe->set_idle_pwm_max(arg(i).toInt(), VORGABE_PROZENT); treppe->set_idle_pwm_max(arg(i).toInt(), VORGABE_PROZENT);
logt("set_idle_pwm_max = %d %\n", arg(i).toInt());
} }
else if (argName(i).equals("range_tim_sta")) { else if (argName(i).equals("range_tim_sta")) {
treppe->set_time_per_stair(arg(i).toInt());
logt("set_time_per_stair = %d\n", arg(i).toInt());
} }
else if (argName(i).equals("range_tim_on")) { else if (argName(i).equals("range_tim_ldr")) {
treppe->set_time_ldr(arg(i).toInt());
logt("set_time_ldr = %d\n", arg(i).toInt());
}
else if (argName(i).equals("range_ldr_shw")) {
treppe->set_ldr_schwelle(arg(i).toInt(), VORGABE_12BIT);
logt("set_ldr_schwelle = %d %\n", arg(i).toInt());
} }
} }
@@ -61,7 +86,7 @@ void HTTPServer::start_apps() {
}); });
this->on("/terminal", HTTP_POST, [this]() { this->on("/terminal", HTTP_POST, [this]() {
// Serial.printf("got /terminal\n"); // logf("got /terminal\n");
if (tbuf_head) { if (tbuf_head) {
send(200, "text/plain", tbuf); send(200, "text/plain", tbuf);
tbuf_head = 0; tbuf_head = 0;
@@ -69,6 +94,14 @@ void HTTPServer::start_apps() {
send(202, "text/plain", ""); send(202, "text/plain", "");
} }
}); });
this->on("/parameters", HTTP_POST, [this]() {
logt("got /parameters\n");
char json_str[255];
treppe->param_to_json(json_str, 255);
logt("%s\n", json_str);
send(200, "application/json", json_str);
});
} }
template <class... Args> template <class... Args>
+119 -51
View File
@@ -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, Serial.printf("DIM_LDR: start: %d, ziel: %d\n", dimmer->start_pwm,
dimmer->ziel_pwm); dimmer->ziel_pwm);
return true; return true;
} else // DIM_STUFEN } else { // DIM_STUFEN
{
Serial.printf("DIM_STUFEN: stufe: %d, start: %d, ziel: %d\n", Serial.printf("DIM_STUFEN: stufe: %d, start: %d, ziel: %d\n",
dimmer->stufe, dimmer->start_pwm, dimmer->ziel_pwm); 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) if (dimmer->stufe >= stufen - 1)
return true; return true;
dimmer->stufe++; dimmer->stufe++;
} else // LR_RUNTER } else { // LR_RUNTER
{
if (dimmer->stufe <= 0) if (dimmer->stufe <= 0)
return true; return true;
dimmer->stufe--; dimmer->stufe--;
@@ -59,9 +57,9 @@ void Treppe::start_animation(dimmer_t *dimmer, bool dim_type, uint16_t on_pwm,
else else
dimmer->stufe = stufen - 1; 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 } 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) { 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;
}
/* void Treppe::read_sensors() {
reads sensors with edge detection const bool s_oben = digitalRead(SENSOR_OBEN);
const bool s_unten = digitalRead(SENSOR_UNTEN);
returns true if motion was detected fsm_pend.sensor_oben = false;
returns false if no motion was detected fsm_pend.sensor_unten = false;
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};
uint8_t index = 0; // rising trigger => 1 cycle true !
if (sensor == SENSOR_OBEN) if (s_oben && !fsm_pend.last_s_oben) {
index = 0; fsm_pend.sensor_oben = true;
else }
index = 1; if (s_unten && !fsm_pend.last_s_unten) {
fsm_pend.sensor_unten = true;
}
if (pegel == 1 && pegel_alt[index] == 0) { fsm_pend.last_s_oben = s_oben;
pegel_alt[index] = pegel; fsm_pend.last_s_unten = s_unten;
return true;
} else { // check for manipulation over webserver
pegel_alt[index] = pegel; if (fsm_pend.web_ctrl_s_oben) {
return false; 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() { float Treppe::read_ldr() {
@@ -169,8 +172,14 @@ float Treppe::read_ldr() {
E(LDR) = 6526.5 / (R(LDR)^2) E(LDR) = 6526.5 / (R(LDR)^2)
ldr_value = E(LDR) ldr_value = E(LDR)
*/ */
float ldr_ohm = 37280.00 / analogRead(A0); // float ldr_ohm = 37280.00 / analogRead(A0);
float voltage = analogRead(A0) * 0.0036;
float ldr_ohm = 40.57 * (3.3 - voltage) / voltage;
float ldr_value = 6526.6 / (ldr_ohm * ldr_ohm); float ldr_value = 6526.6 / (ldr_ohm * ldr_ohm);
#ifdef LDRDEBUG
Serial.printf("Ohm: %f lux: %f Comp: %d\n", ldr_ohm, ldr_value,
param.ldr_schwelle);
#endif
return ldr_value; return ldr_value;
} }
@@ -178,17 +187,16 @@ bool Treppe::check_ldr() {
static uint8_t active = 0; static uint8_t active = 0;
#ifdef LDRDEBUG #ifdef LDRDEBUG
Serial.printf("R(LDR) = %f kOhm %f lux\n", ldr_value, lux); // return true;
return true;
#endif #endif
// follow up: averaging over many samples? // follow up: averaging over many samples?
float ldr = read_ldr(); float ldr = read_ldr();
if (ldr < parameters.ldr_schwelle) { if (ldr < param.ldr_schwelle) {
active = 1; active = 1;
} }
if (ldr > parameters.ldr_schwelle + LDR_HYS) { if (ldr > param.ldr_schwelle + LDR_HYS) {
active = 0; active = 0;
} }
return active; return active;
@@ -201,7 +209,6 @@ void Treppe::task() {
// TODO wenn LDR geändert => idle_pwm_soll anpassen // TODO wenn LDR geändert => idle_pwm_soll anpassen
// fsm_pend.ldr_changed = true; // fsm_pend.ldr_changed = true;
fsm_inputs.ldr_schwelle = check_ldr(); fsm_inputs.ldr_schwelle = check_ldr();
#ifdef DEBUG_TIMING #ifdef DEBUG_TIMING
@@ -210,8 +217,10 @@ void Treppe::task() {
m = micros(); m = micros();
#endif #endif
fsm_inputs.sensor_oben = read_sensor(SENSOR_OBEN); read_sensors();
fsm_inputs.sensor_unten = read_sensor(SENSOR_UNTEN); fsm_inputs.sensor_oben = fsm_pend.sensor_oben;
fsm_inputs.sensor_unten = fsm_pend.sensor_unten;
fsm_inputs.anim_beendet = fsm_pend.anim_beendet; fsm_inputs.anim_beendet = fsm_pend.anim_beendet;
#ifdef DEBUG_TIMING #ifdef DEBUG_TIMING
@@ -243,7 +252,7 @@ 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 (fsm_pend.anim_beendet) 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); idle_pwm_ist);
else else
fsm_pend.anim_beendet = dimmer_tick(&dimmer_stufen, DIM_STUFEN); fsm_pend.anim_beendet = dimmer_tick(&dimmer_stufen, DIM_STUFEN);
@@ -265,6 +274,16 @@ void Treppe::task() {
} }
} }
if (fsm_outputs.status == ST_RUHEZUSTAND ||
fsm_outputs.status == ST_INAKTIV_LDR) {
if (param_changed) {
param_changed = false;
param = param_pend;
save_param_to_eeprom();
Serial.printf("Parameter Change applied!\n");
}
}
#ifdef DEBUG_TIMING #ifdef DEBUG_TIMING
Serial.print("5:"); Serial.print("5:");
Serial.println(micros() - m); Serial.println(micros() - m);
@@ -281,6 +300,10 @@ void Treppe::setup() {
pwmController.setPWMFrequency(100); pwmController.setPWMFrequency(100);
// pwmController.setAllChannelsPWM(idle_pwm); // pwmController.setAllChannelsPWM(idle_pwm);
// WARNING: before getting Parameters of Flash, make sure plausible parameters
// are written in flash!
EEPROM.get(EEP_START_ADDR, param); // get Parameters of flash
pinMode(13, OUTPUT); pinMode(13, OUTPUT);
pinMode(0, OUTPUT); pinMode(0, OUTPUT);
digitalWrite(13, HIGH); digitalWrite(13, HIGH);
@@ -295,39 +318,84 @@ void Treppe::setup() {
Serial.printf("Treppe: stufen=%d\n", stufen); Serial.printf("Treppe: stufen=%d\n", stufen);
} }
void Treppe::save_param_to_eeprom() {
EEPROM.put(EEP_START_ADDR,
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, void Treppe::set_idle_pwm_max(const uint16_t value,
const vorgabe_typ_t vorgabe_typ) { const vorgabe_typ_t vorgabe_typ) {
if (vorgabe_typ == VORGABE_PROZENT) { 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) { } 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) { if (param_pend.idle_pwm_max > param_pend.active_pwm) {
parameters.idle_pwm_max = parameters.active_pwm; param_pend.idle_pwm_max = param_pend.active_pwm;
} }
param_changed = true;
Serial.printf("Treppe: parameters.idle_pwm_max=%d\n", Serial.printf("Treppe: param_pend.idle_pwm_max=%d\n",
parameters.idle_pwm_max); param_pend.idle_pwm_max);
} }
void Treppe::set_active_pwm(const uint16_t value, void Treppe::set_active_pwm(const uint16_t value,
const vorgabe_typ_t vorgabe_typ) { const vorgabe_typ_t vorgabe_typ) {
if (vorgabe_typ == VORGABE_PROZENT) { if (vorgabe_typ == VORGABE_PROZENT) {
parameters.active_pwm = 4095 * value / 100; param_pend.active_pwm = 4095 * value / 100;
} else if (vorgabe_typ == VORGABE_12BIT) { } else if (vorgabe_typ == VORGABE_12BIT) {
parameters.active_pwm = value; param_pend.active_pwm = value;
} }
if (parameters.active_pwm > 4095) { if (param_pend.active_pwm > 4095) {
parameters.idle_pwm_max = 4095; param_pend.idle_pwm_max = 4095;
}
param_changed = true;
Serial.printf("Treppe: param_pend.active_pwm=%d\n", param_pend.active_pwm);
} }
Serial.printf("Treppe: parameters.active_pwm=%d\n", parameters.active_pwm); void Treppe::set_time_ldr(const uint16_t value) {
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", param_pend.time_ldr);
} }
void Treppe::set_time_per_stair(uint16_t _time_per_stair) { void Treppe::set_time_per_stair(const uint16_t value) {
parameters.time_per_stair = _time_per_stair; param_pend.time_per_stair = value;
Serial.printf("Treppe: time_per_stair=%d\n", parameters.time_per_stair); 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", 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) {
// ?!
param_pend.ldr_schwelle = 10 * value / 100;
} else if (vorgabe_typ == VORGABE_12BIT) {
param_pend.ldr_schwelle = value;
}
param_changed = true;
Serial.printf("Treppe: ldr_schwelle=%d\n", param_pend.ldr_schwelle);
}
void Treppe::param_to_json(char *json_str, size_t sz) {
snprintf(json_str, sz, "{\n\
\"time_ldr\": %d,\n\
\"time_per_stair\": %d,\n\
\"idle_pwm_max\": %d,\n\
\"active_pwm\": %d,\n\
\"ldr_schwelle\": %d\n}\n",
param.time_ldr, param.time_per_stair, param.idle_pwm_max,
param.active_pwm, param.ldr_schwelle);
} }
+26 -8
View File
@@ -3,18 +3,22 @@
#include "FSMTreppe3/FSMTreppe3.h" #include "FSMTreppe3/FSMTreppe3.h"
#include "PCA9685.h" #include "PCA9685.h"
#include <EEPROM.h>
//#define LDRDEBUG // comment in to override LDR measurement //#define LDRDEBUG // comment in to override LDR measurement
#define LDR_HYS 1 // Hysteresis for switching off FSM [lux] #define LDR_HYS 8 // Hysteresis for switching off FSM [lux]
#define SENSOR_OBEN 16 #define SENSOR_OBEN 16
#define SENSOR_UNTEN 12 #define SENSOR_UNTEN 12
#define OE 14 #define OE 14
#define INT_TIME 20 // interrupt intervall [ms] #define INT_TIME 20 // interrupt intervall [ms]
#define TIME_MS_MAX 5000 // maximum time for animation [ms]
enum vorgabe_typ_t { VORGABE_PROZENT = 0, VORGABE_12BIT = 1 }; enum vorgabe_typ_t { VORGABE_PROZENT = 0, VORGABE_12BIT = 1 };
#define EEP_START_ADDR 100 // define Start Address for "EEPROM" storage -> depends on size of "wifi_data"!
class Treppe { class Treppe {
private: private:
const uint8_t stufen; const uint8_t stufen;
@@ -24,17 +28,23 @@ private:
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 active_pwm = 2000; uint16_t active_pwm = 2000;
uint16_t ldr_schwelle = 2; // activation value for FSM [lx] uint16_t ldr_schwelle = 30; // 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; uint16_t idle_pwm_soll = 0;
struct fsm_pending_inputs_t { struct fsm_pending_inputs_t {
bool anim_beendet = true; bool anim_beendet = true;
bool sensor_unten = false; bool sensor_unten = false;
bool last_s_unten = false;
bool web_ctrl_s_unten = false;
bool sensor_oben = false; bool sensor_oben = false;
bool last_s_oben = false;
bool web_ctrl_s_oben = false;
bool ldr_changed = false; bool ldr_changed = false;
}; };
fsm_pending_inputs_t fsm_pend; fsm_pending_inputs_t fsm_pend;
@@ -73,13 +83,13 @@ private:
enum fsm_laufrichtung_t { LR_RUNTER = 0, LR_HOCH = 1 }; enum fsm_laufrichtung_t { LR_RUNTER = 0, LR_HOCH = 1 };
enum fsm_dimmrichtung_t { DR_ABDIMMEN = 0, DR_AUFDIMMEN = 1 }; enum fsm_dimmrichtung_t { DR_ABDIMMEN = 0, DR_AUFDIMMEN = 1 };
void read_sensors();
void print_state_on_change();
/* DIMM */ /* DIMM */
// bool dimmer(dimmer_t* dimmer, bool dim_type);
bool dimmer_tick(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, void start_animation(dimmer_t *dimmer, bool dim_type, uint16_t on_pwm,
uint16_t off_pwm); uint16_t off_pwm);
// void berechne_dimmer(dimmer_t* dimmer, bool dim_type);
void print_state_on_change();
/* LDR */ /* LDR */
bool read_sensor(int sensor); bool read_sensor(int sensor);
@@ -94,9 +104,17 @@ public:
void task(); // call periodically void task(); // call periodically
// Parameter section // Parameter section
void save_param_to_eeprom();
void param_to_json(char* json_str, size_t sz);
void set_idle_pwm_max(const uint16_t value, const vorgabe_typ_t vorgabe_typ); 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_active_pwm(const uint16_t value, const vorgabe_typ_t vorgabe_typ);
void set_time_per_stair(uint16_t _time_per_stair);
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 #endif // __TREPPE_H
+1 -1
View File
@@ -13,5 +13,5 @@ mem 0x60000000 0x60001fff rw
set serial baud 460800 set serial baud 460800
file .pio/build/debug/firmware.elf file .pio/build/debug/firmware.elf
target remote \\.\COM23 target remote /dev/ttyUSB0
thb loop thb loop
+17
View File
@@ -0,0 +1,17 @@
set remote hardware-breakpoint-limit 1
set remote hardware-watchpoint-limit 1
set remote interrupt-on-connect on
set remote kill-packet off
set remote symbol-lookup-packet off
set remote verbose-resume-packet off
mem 0x20000000 0x3fefffff ro cache
mem 0x3ff00000 0x3fffffff rw
mem 0x40000000 0x400fffff ro cache
mem 0x40100000 0x4013ffff rw cache
mem 0x40140000 0x5fffffff ro cache
mem 0x60000000 0x60001fff rw
set serial baud 460800
file .pio/build/debug/firmware.elf
target remote \\.\COM23
thb loop
+18 -17
View File
@@ -32,26 +32,32 @@ const char* password = STAPSK;
HTTPServer httpServer(80, "/", &stairs); HTTPServer httpServer(80, "/", &stairs);
uint32_t _t = 0; uint32_t _t = 0;
#define SP_US(_str,_a) Serial.print(_str); Serial.print(" took: "); Serial.print(_a); Serial.println("us") #define SP_US(_str, _a) \
#define TIMEIF_US(_f, _l, _str) _t=micros(); _f; _t=micros()-_t; if(_t > (_l)) { SP_US(_str, _t); } Serial.print(_str); \
Serial.print(" took: "); \
Serial.print(_a); \
Serial.println("us")
#define TIMEIF_US(_f, _l, _str) \
_t = micros(); \
_f; \
_t = micros() - _t; \
if (_t > (_l)) { \
SP_US(_str, _t); \
}
struct { // Struct for wifi-data, 40 Bytes each SSID and PW struct { // Struct for wifi-data, 40 Bytes each SSID and PW
char SSID[40] = ""; char SSID[40] = "";
char PW[40] = ""; char PW[40] = "";
} wifi_data; } wifi_data;
void timerCallback(void *pArg) {
void timerCallback(void *pArg)
{
*(static_cast<int *>(pArg)) += 1; *(static_cast<int *>(pArg)) += 1;
stairs.task(); stairs.task();
} }
// =============================================== // ===============================================
uint8_t inter = 0; uint8_t inter = 0;
ICACHE_RAM_ATTR void int_test(){ ICACHE_RAM_ATTR void int_test() { inter = 1; }
inter = 1;
}
void setup() { void setup() {
#ifdef WITH_DEBUGGING_ON #ifdef WITH_DEBUGGING_ON
@@ -72,7 +78,8 @@ void setup() {
// EEPROM.commit(); // EEPROM.commit();
Wire.begin(); // Wire must be started first Wire.begin(); // Wire must be started first
Wire.setClock(1000000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz Wire.setClock(
1000000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz
stairs.setup(); stairs.setup();
Serial.println("PCA9685 connected !"); Serial.println("PCA9685 connected !");
// attachInterrupt(digitalPinToInterrupt(2), int_test, RISING); // attachInterrupt(digitalPinToInterrupt(2), int_test, RISING);
@@ -102,20 +109,14 @@ void setup() {
os_timer_setfn(&timer1, timerCallback, &timer_flag); os_timer_setfn(&timer1, timerCallback, &timer_flag);
os_timer_arm(&timer1, 20, true); os_timer_arm(&timer1, 20, true);
Serial.println("SSID: " + String(wifi_data.SSID) + " PW: " + String(wifi_data.PW)); Serial.println("SSID: " + String(wifi_data.SSID) +
" PW: " + String(wifi_data.PW));
} }
uint32_t c = 0;
void loop() { void loop() {
if (inter != 0u) { if (inter != 0u) {
Serial.printf("interrupt\n"); Serial.printf("interrupt\n");
inter = 0; inter = 0;
}
if(c++%1000000 == 0) { { {
httpServer.logt("[%d] starting :)\n", c);
}
}
} }
TIMEIF_US(ArduinoOTA.handle(), 10000, "OTA"); TIMEIF_US(ArduinoOTA.handle(), 10000, "OTA");
+5
View File
@@ -0,0 +1,5 @@
SET GDB_PATH=C:\Users\simon\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\bin\xtensa-lx106-elf-gdb.exe
echo "Starting gdb"
echo %GDB_PATH%
%GDB_PATH% -x ".\scripts\gdboptions_win"
-1
View File
@@ -1,6 +1,5 @@
#!/bin/bash #!/bin/bash
GDB_PATH=~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/bin/xtensa-lx106-elf-gdb GDB_PATH=~/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/bin/xtensa-lx106-elf-gdb
cd ..
echo "Starting gdb" echo "Starting gdb"
$GDB_PATH -x scripts/gdboptions $GDB_PATH -x scripts/gdboptions