Compare commits
188
Commits
caff8a7e56
..
v1.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1686b9ea2a | ||
|
|
8c45c65d00 | ||
|
|
6bd0844927 | ||
|
|
b309c0b207 | ||
|
|
767df957cc | ||
|
|
0d6f0b28e2 | ||
|
|
937f7f09e7 | ||
|
|
6ae3f5690f | ||
|
|
7c770a7802 | ||
|
|
6807d0f0af | ||
|
|
770c2436fd | ||
|
|
3145949020 | ||
|
|
ca938ef3dd | ||
|
|
f8fac7acfb | ||
|
|
9ed1b24316 | ||
|
|
125b39a418 | ||
|
|
e47cae30a8 | ||
|
|
b2ff66d44c | ||
|
|
c23b9f2bc6 | ||
|
|
31c268487c | ||
|
|
ad21d73fbb | ||
|
|
42a927e383 | ||
|
|
13db3da082 | ||
|
|
9518c06fd9 | ||
|
|
2820869e14 | ||
|
|
6e810fad59 | ||
|
|
79a9eecaad | ||
|
|
1189b7c3a4 | ||
|
|
7643961ed2 | ||
|
|
6cc52dc460 | ||
|
|
d3ed19e639 | ||
|
|
d55da4e6d7 | ||
|
|
f677f18681 | ||
|
|
f027478e2e | ||
|
|
5986beb10c | ||
|
|
f57e875a17 | ||
|
|
d16f3823b8 | ||
|
|
a5ac7d358b | ||
|
|
0cd46a3c9f | ||
|
|
3a93b8a002 | ||
|
|
0e5085c008 | ||
|
|
7177472ea6 | ||
|
|
03d0cfedd1 | ||
|
|
66d220cdb0 | ||
|
|
2754bd5247 | ||
|
|
f62a18fe66 | ||
|
|
2139ff5943 | ||
|
|
6a04a4d1c9 | ||
|
|
630250da78 | ||
|
|
35ba3e7573 | ||
|
|
53efb0c309 | ||
|
|
c1e24d633b | ||
|
|
5e36ef55df | ||
|
|
6b5cabb1f4 | ||
|
|
37380cbebc | ||
|
|
8c507083a7 | ||
|
|
2f6502ce20 | ||
|
|
278179fa6e | ||
|
|
f38ef0ed0e | ||
|
|
f2a9ed2888 | ||
|
|
1662079547 | ||
|
|
1e8d24dc40 | ||
|
|
af40298378 | ||
|
|
8351a6430c | ||
|
|
b2ddc978b6 | ||
|
|
22f141e2cd | ||
|
|
f5d6e376c6 | ||
|
|
eeac10c66f | ||
|
|
e9d16a80d4 | ||
|
|
dcae074b55 | ||
|
|
472eba7977 | ||
|
|
6a398d9ba0 | ||
|
|
f28aa2df8b | ||
|
|
754da9f931 | ||
|
|
df2a8fa1e3 | ||
|
|
dc159a35d0 | ||
|
|
2378ca80b9 | ||
|
|
79ff1f0d33 | ||
|
|
6a36971406 | ||
|
|
714fcb4b18 | ||
|
|
712acf3541 | ||
|
|
df89c9716c | ||
|
|
66e8ddb2d9 | ||
|
|
5b197288bc | ||
|
|
a9f098097c | ||
|
|
a0f6a5aec3 | ||
|
|
633b99f818 | ||
|
|
5d32392844 | ||
|
|
50e714e5f8 | ||
|
|
e0bc75826f | ||
|
|
3d13e761f4 | ||
|
|
3c824bfc92 | ||
|
|
9ea541a1b4 | ||
|
|
b89604edc3 | ||
|
|
4e6445fea8 | ||
|
|
10b57ca516 | ||
|
|
e8329f2587 | ||
|
|
014aa028d7 | ||
|
|
b47f778fc1 | ||
|
|
c7eaffda00 | ||
|
|
69e1e869a5 | ||
|
|
1a284080e8 | ||
|
|
3490e7ba44 | ||
|
|
d059c3d72d | ||
|
|
33499beb32 | ||
|
|
38c81ae182 | ||
|
|
a8ceb258b8 | ||
|
|
7e5a6fac9f | ||
|
|
b7ba521c59 | ||
|
|
55ebd21975 | ||
|
|
2b2a135bd5 | ||
|
|
a400b0464d | ||
|
|
2d9be85b09 | ||
|
|
33b9f0150e | ||
|
|
48d0dc50f7 | ||
|
|
cdb34a3cbf | ||
|
|
1b34714d27 | ||
|
|
90a9213a3c | ||
|
|
7976f5258f | ||
|
|
bb3a735d37 | ||
|
|
3c186771fe | ||
|
|
c40e7f80e5 | ||
|
|
9d1105cb80 | ||
|
|
4130b64370 | ||
|
|
bff8cdbeb7 | ||
|
|
d8343ea91f | ||
|
|
78f09b3a3b | ||
|
|
bd0e364d22 | ||
|
|
32266b5f37 | ||
|
|
b62f4f9f95 | ||
|
|
a8af7543ba | ||
|
|
85f8da3476 | ||
|
|
f323bd4cf9 | ||
|
|
708bb2cda4 | ||
|
|
a4196bb579 | ||
|
|
908c4298be | ||
|
|
6e885673b8 | ||
|
|
93cc958800 | ||
|
|
9d30423ca3 | ||
|
|
b3b11d0818 | ||
|
|
51bdd6210e | ||
|
|
d51bb4c95c | ||
|
|
2659e366ec | ||
|
|
4951ca46c1 | ||
|
|
97a6076864 | ||
|
|
ff6b82867c | ||
|
|
a3dc7a5fba | ||
|
|
c13b0adc82 | ||
|
|
da20f74db8 | ||
|
|
d5b9827543 | ||
|
|
3c6889854e | ||
|
|
8d8ffe4173 | ||
|
|
006404fccf | ||
|
|
d17091651f | ||
|
|
4b608c42ca | ||
|
|
278f746b33 | ||
|
|
642ee7d0a6 | ||
|
|
6596346d3d | ||
|
|
b696703d45 | ||
|
|
baecaf02da | ||
|
|
1d7f2f368b | ||
|
|
c8938f4b36 | ||
|
|
cd80b9b7ba | ||
|
|
657f77e73d | ||
|
|
b51cce709a | ||
|
|
09aff91b31 | ||
|
|
36fd363d67 | ||
|
|
ee72092a3a | ||
|
|
a66ab2b1d0 | ||
|
|
6a7f2e6a4e | ||
|
|
49f9c9c217 | ||
|
|
61d6cde899 | ||
|
|
65e922b090 | ||
|
|
461c887ddf | ||
|
|
e7cf45c45e | ||
|
|
055a6193df | ||
|
|
c6e288280e | ||
|
|
d0b824963b | ||
|
|
407581451b | ||
|
|
5443800b40 | ||
|
|
769e132baa | ||
|
|
b5a5257a37 | ||
|
|
f317600d03 | ||
|
|
306d9721c4 | ||
|
|
71e5c47852 | ||
|
|
29e130b837 | ||
|
|
36fb748f6d | ||
|
|
d4584f57e8 |
No files matched your search
+7
-5
@@ -1,7 +1,9 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
include/wifi_credentials.h
|
||||
.vscode
|
||||
.vscode/*
|
||||
.vscode/**
|
||||
compress
|
||||
data_gz
|
||||
platformio.ini
|
||||
include/wifi_credentials.h
|
||||
include/*.gz.h
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/PCA9685-Arduino"]
|
||||
path = lib/PCA9685-Arduino
|
||||
url = https://github.com/NachtRaveVL/PCA9685-Arduino
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"random": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -17,5 +17,23 @@ https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html
|
||||
```
|
||||
|
||||
##### platformio.ini
|
||||
change IP of esp8266 accordingly
|
||||
IP gets printed on Serial Monitor after first Upload
|
||||
see templ_platformio_ini
|
||||
|
||||
```ini
|
||||
[env:<BOARD>]
|
||||
platform = espressif8266
|
||||
board = <BOARD>
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
|
||||
extra_scripts = pre:extra_script.py
|
||||
|
||||
; stuff for OTA
|
||||
; https://docs.platformio.org/en/latest/platforms/espressif8266.html#over-the-air-ota-update
|
||||
upload_protocol = espota
|
||||
upload_port = <IPADRESS>
|
||||
upload_flags =
|
||||
--port=8266
|
||||
--auth=admin
|
||||
```
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os, gzip
|
||||
# https://www.mischianti.org/2020/10/26/web-server-with-esp8266-and-esp32-byte-array-gzipped-pages-and-spiffs-2/
|
||||
@@ -27,8 +28,11 @@ def convert_to_gzip(src, out, f):
|
||||
f_out.write(top.encode(encoding='utf-8'))
|
||||
|
||||
|
||||
src='include/http/'
|
||||
out='include/'
|
||||
src='data/'
|
||||
out='compress/'
|
||||
|
||||
if not 'compress' in os.listdir():
|
||||
os.mkdir('compress')
|
||||
|
||||
for f in os.listdir(src):
|
||||
convert_to_gzip(src, out, f)
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os, gzip
|
||||
# https://stackoverflow.com/questions/8156707/gzip-a-file-in-python
|
||||
|
||||
src_dir='data'
|
||||
out_dir='data_gz'
|
||||
|
||||
if not 'data_gz' in os.listdir():
|
||||
os.mkdir('data_gz')
|
||||
|
||||
for f in os.listdir(src_dir):
|
||||
with open(f'{src_dir}/{f}', 'rb') as f_in:
|
||||
with gzip.open(f'{out_dir}/{f}.gz', 'wb') as f_out:
|
||||
f_out.writelines(f_in)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 531 B |
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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">
|
||||
<link href="/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<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" 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" 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">
|
||||
<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" data-output="out_tim_ldr" min="0" max="5000" value="500">
|
||||
</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="1000" value="50">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="terminal">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<script src="/input.js"></script>
|
||||
|
||||
</html>
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
let rangeValues = {};
|
||||
let xhrUpd = new XMLHttpRequest();
|
||||
|
||||
xhrUpd.onreadystatechange = function () {
|
||||
if (xhrUpd.readyState == 4) {
|
||||
if (xhrUpd.status == 200) {
|
||||
console.log("xhrUpd: ", xhrUpd.responseText);
|
||||
}
|
||||
else {
|
||||
console.log("xhrUpd: status=", xhrUpd.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reloadRangeValues() {
|
||||
let url = "/update";
|
||||
// if there are scheduled updates, send them
|
||||
if (Object.keys(rangeValues).length > 0) {
|
||||
let params = [];
|
||||
for (let p in rangeValues)
|
||||
params.push(encodeURIComponent(p) + "=" + encodeURIComponent(rangeValues[p]));
|
||||
params = params.join("&");
|
||||
|
||||
xhrUpd.open("POST", url, true);
|
||||
xhrUpd.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhrUpd.send(params);
|
||||
|
||||
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));
|
||||
};
|
||||
|
||||
function updateParameters() {
|
||||
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 = '';
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
html {
|
||||
font-size: 16px;
|
||||
font-family: sans-serif, Arial, Helvetica;
|
||||
background-color: #ffffff;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
border-radius: 3;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: 10px;
|
||||
background-color: #585858;
|
||||
color: white;
|
||||
font-size: xx-large;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.param_block{
|
||||
padding: 1em;
|
||||
color: #000000;
|
||||
border: 1px solid darkred;
|
||||
font-size: x-large;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.val_range {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.regler {
|
||||
/* -webkit-appearance: none; */
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
border-radius: 20px;
|
||||
outline: black;
|
||||
background-color: rgb(176, 188, 228);
|
||||
}
|
||||
|
||||
#note {
|
||||
font-size: medium;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* .regler::-webkit-slider-thumb{
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 5%;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(107, 122, 192);
|
||||
cursor:pointer;
|
||||
} */
|
||||
/* input[type=range]::-webkit-slider-thumb{
|
||||
-webkit-appearance: none;
|
||||
border:none;
|
||||
height: 30px;
|
||||
width: 4%;
|
||||
border-radius: 30px;
|
||||
} */
|
||||
|
||||
.slider {
|
||||
margin: 1%;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------*/
|
||||
/*Switch:
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
Hide default HTML checkbox
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
*/
|
||||
/* The slider */
|
||||
|
||||
|
||||
/*input:checked + .slider {
|
||||
background-color: #04AA6D;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px #04AA6D;
|
||||
}*/
|
||||
/*
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
*/
|
||||
|
||||
.terminal {
|
||||
margin:5%;
|
||||
padding: 1%;
|
||||
width: 80%;
|
||||
border: 1px solid black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#term {
|
||||
font-size: large;
|
||||
width: 100%;
|
||||
height: 20em;
|
||||
}
|
||||
|
||||
#clear_term {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
input:invalid+span:after {
|
||||
content: '✖';
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
input:valid+span:after {
|
||||
content: '✓';
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
Hardware Timer didnt work https://github.com/khoih-prog/ESP8266TimerInterrupt#why-using-isr-based-hardware-timer-interrupt-is-better
|
||||
|
||||
=> Software Timer https://ullisroboterseite.de/esp8266-timing.html#timer
|
||||
|
||||
|
||||
|
||||
|
||||
### __Zum aktivieren von GDBStub:__
|
||||
```c
|
||||
#include <GDBStub.h>
|
||||
|
||||
...
|
||||
|
||||
void setup() {
|
||||
Serial.begin(460800);
|
||||
gdbstub_init();
|
||||
```
|
||||
|
||||
### __Achtung !__
|
||||
GDB muss dafür compiled werden
|
||||
GDB-Version aus Arduino Toolchain hat Support
|
||||
|
||||
```sh
|
||||
$ ./start_xtensa_gdb_stub.sh
|
||||
```
|
||||
|
||||
### __Achtung !__
|
||||
Don`t forget __\r__
|
||||
|
||||
ESP-OTA wird von ufw oder Defender geblockt.
|
||||
- Windows -> Python needs to be granted with rights
|
||||
- Linux -> open udp port in ufw ->
|
||||
|
||||
```sh
|
||||
platform.ini
|
||||
upload_flags =
|
||||
--host-port <PORT>
|
||||
...
|
||||
$ sudo ufw allow tcp/<PORT>
|
||||
```
|
||||
|
||||
|
||||
```c++
|
||||
server.streamFile(f, mime::getContentType(SRH::_path), requestMethod);
|
||||
|
||||
=====>
|
||||
|
||||
const String& p = SRH::_path;
|
||||
if(p.endsWith(".gzip")) {
|
||||
server.sendHeader("Content-Encoding", "gzip");
|
||||
server.streamFile(f, mime::getContentType(p.substring(0, p.length()-5)), requestMethod);
|
||||
}
|
||||
else
|
||||
server.streamFile(f, mime::getContentType(SRH::_path), requestMethod);
|
||||
```
|
||||
|
||||
### HW issues
|
||||
- GPIO2 used as input -> must be high during startup
|
||||
- PCB Solution: cut trace to GPIO2, solder bridge to GPIO16
|
||||
- -> disadvantage: GPIO16 is not interrupt capable
|
||||
|
||||
|
||||
### FSM 2 - to do
|
||||
- stairway light switches off after timeout
|
||||
- switches concurrently on again if sensor is still high
|
||||
- desired behavior? Defective Sensor would cause continuos animation
|
||||
- edge detection / interrupts as solution ?
|
||||
|
||||
|
||||
### LED_sequence_v1:
|
||||
TODO:
|
||||
- disable led stripes after defined time (webserver paramter?)
|
||||
- define what to do if people enter stairs from different directions
|
||||
- CAUTION: Sensor-Deadtime at LEAST 8 seconds
|
||||
- --> switch off with person leaving stairs might not be possible
|
||||
|
||||
### Webserver on v0.3.0 now working with LittleFS
|
||||
TODO:
|
||||
- check dir for files automatic
|
||||
- move handleNotFound to httpserver.h
|
||||
- maybe compress files ?
|
||||
|
||||
|
||||
### LED Flickering issue
|
||||
https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15
|
||||
PlatformIO Library veraltet !!
|
||||
|
||||
|
||||
### TIMER in OTA unterbrechen !!!!!
|
||||
|
||||
|
||||
|
||||
### further improvments
|
||||
with streamFile gzip encoded Files can be sent
|
||||
this reduces space on fs !
|
||||
new easier script needed to just convert to .gz
|
||||
maybe measure timings on ESP
|
||||
|
||||
__=> use serveStatic because way simpler !__
|
||||
__=> serverStatic("/") works wonders__
|
||||
|
||||
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARHRRHRGH
|
||||
Two implementations of FSM are not that good,
|
||||
linker puts them together ?!?
|
||||
:):):):):):):)
|
||||
=> maybe investigate for doc
|
||||
|
||||
### TODO Treppe
|
||||
- dynamic lighting with ldr
|
||||
- http control over active pwm ... => set_active_pwm()
|
||||
-> is implemntiert, kann mit % oder abs eingestellt werden
|
||||
- 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 ?
|
||||
-> wird hochgedimmt beim einschalten von 0
|
||||
- on/off switch http
|
||||
- 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?
|
||||
-> currently ignored, second persons walks in darkness
|
||||
-> animation from both sides?
|
||||
-> problem: person 1 leaving stairway might pass the sensor right after person 2 -> person 1 leaving not detected
|
||||
|
||||
- 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?
|
||||
|
||||
|
||||
- active brightness can be lower than idle in the moment
|
||||
- change idle to precentage of active !!
|
||||
|
||||
- Webpage needs to load settings from eeprom !!
|
||||
File diff suppressed because it is too large.
Load diff
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB |
@@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>My test page</title>
|
||||
<link href="http://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
|
||||
<link href="styles/style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Mozilla is cool</h1>
|
||||
<p>At Mozilla, we’re a global community of</p>
|
||||
|
||||
<ul> <!-- changed to list in the tutorial -->
|
||||
<li>technologists</li>
|
||||
<li>thinkers</li>
|
||||
<li>builders</li>
|
||||
</ul>
|
||||
|
||||
<p>working together to keep the Internet alive and accessible, so people worldwide can be informed contributors and creators of the Web. We believe this act of human collaboration across an open platform is essential to individual growth and our collective future.</p>
|
||||
|
||||
<p>Read the <a href="https://www.mozilla.org/en-US/about/manifesto/">Mozilla Manifesto</a> to learn even more about the values and principles that guide the pursuit of our mission.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
html {
|
||||
font-size: 10px;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
|
||||
h1 {
|
||||
font-size: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p, li {
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
|
||||
html {
|
||||
background-color: #00539F;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #FF9500;
|
||||
padding: 0 20px 20px 20px;
|
||||
border: 5px solid black;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding: 20px 0;
|
||||
color: #00539F;
|
||||
text-shadow: 3px 3px 1px black;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
// filename: index.html.gz.h
|
||||
#define index_html_gz_len 573
|
||||
const char index_html_gz[] = {
|
||||
0x1F, 0x8B, 0x08, 0x00, 0xB4, 0x6E, 0xC7, 0x60, 0x02, 0xFF,
|
||||
0x8D, 0x53, 0xCB, 0x8E, 0xD4, 0x30, 0x10, 0xBC, 0x23, 0xF1,
|
||||
0x0F, 0xBD, 0xB9, 0xB2, 0x13, 0x6B, 0x6F, 0x08, 0x65, 0x82,
|
||||
0x10, 0x70, 0xE0, 0x30, 0x5A, 0xC4, 0x82, 0x10, 0x47, 0xC7,
|
||||
0xE9, 0x24, 0xD6, 0x38, 0x6E, 0xCB, 0x6E, 0x6F, 0x18, 0x4E,
|
||||
0xFC, 0x06, 0xBF, 0xC7, 0x97, 0xD0, 0xCE, 0x64, 0x16, 0x56,
|
||||
0x70, 0xE0, 0x92, 0x87, 0xAB, 0x1F, 0x55, 0xD5, 0xED, 0xE6,
|
||||
0xEA, 0xCD, 0xED, 0xEB, 0x8F, 0x5F, 0xDE, 0xBF, 0x85, 0x89,
|
||||
0x67, 0xD7, 0x3E, 0x7D, 0xD2, 0x6C, 0x6F, 0x80, 0x66, 0x42,
|
||||
0xDD, 0xAF, 0x5F, 0xF2, 0x3D, 0x23, 0x6B, 0x30, 0x93, 0x8E,
|
||||
0x09, 0x79, 0x5F, 0x65, 0x1E, 0x76, 0xCF, 0xAB, 0x0B, 0xC6,
|
||||
0x96, 0x1D, 0xB6, 0x87, 0x13, 0x30, 0x26, 0x86, 0xA0, 0x47,
|
||||
0x6C, 0xD4, 0xF9, 0x6C, 0x0B, 0x70, 0xD6, 0x1F, 0x61, 0x8A,
|
||||
0x38, 0xEC, 0xAB, 0x89, 0x39, 0xBC, 0x50, 0x6A, 0x20, 0xCF,
|
||||
0xA9, 0x1E, 0x89, 0x46, 0x87, 0x3A, 0xD8, 0x54, 0x1B, 0x9A,
|
||||
0x95, 0x49, 0xE9, 0xE5, 0xA0, 0x67, 0xEB, 0x4E, 0xFB, 0xDB,
|
||||
0x80, 0xFE, 0xD9, 0x9D, 0xF6, 0xA9, 0x82, 0x88, 0x6E, 0x5F,
|
||||
0x25, 0x3E, 0x39, 0x4C, 0x13, 0x22, 0x57, 0xC0, 0xA7, 0x80,
|
||||
0xFB, 0x8A, 0xF1, 0x2B, 0x97, 0x8C, 0xEA, 0x1F, 0x4D, 0xCE,
|
||||
0xD1, 0x6A, 0x7D, 0xD5, 0x25, 0xE6, 0xFF, 0x8A, 0x34, 0xEA,
|
||||
0x41, 0x71, 0xD3, 0x51, 0x7F, 0xBA, 0x54, 0x9E, 0x6E, 0xDA,
|
||||
0x03, 0x7D, 0xB3, 0xCE, 0x69, 0xB0, 0x09, 0x0C, 0x91, 0x93,
|
||||
0xC8, 0x9B, 0x0B, 0x1A, 0xDA, 0x57, 0x0C, 0x1B, 0x7E, 0x0D,
|
||||
0x0B, 0xFE, 0xFC, 0xFE, 0x23, 0x22, 0x68, 0x18, 0x1D, 0x75,
|
||||
0xDA, 0x49, 0xF8, 0x3C, 0x67, 0x6F, 0xF9, 0x04, 0x34, 0x34,
|
||||
0x2A, 0x48, 0xD6, 0x96, 0x97, 0x5D, 0x0B, 0xCD, 0xD5, 0x6E,
|
||||
0x57, 0x5C, 0xF5, 0x23, 0xF6, 0xC0, 0x04, 0xCE, 0x8A, 0x81,
|
||||
0xD6, 0x03, 0x4F, 0x08, 0x9C, 0x99, 0xA2, 0x95, 0x0A, 0xBB,
|
||||
0xDD, 0xD6, 0x6A, 0x15, 0xD9, 0x32, 0x9A, 0xC9, 0x93, 0xA3,
|
||||
0x51, 0x62, 0x53, 0xA3, 0xE4, 0xE4, 0x11, 0x3A, 0x89, 0x0D,
|
||||
0x18, 0xFF, 0x06, 0xBA, 0x6C, 0x5D, 0xFF, 0x18, 0x68, 0x54,
|
||||
0x76, 0xBF, 0xF9, 0x84, 0x76, 0xA1, 0x78, 0xB4, 0x7E, 0x14,
|
||||
0x22, 0x23, 0x0A, 0x83, 0x58, 0x18, 0x1D, 0x11, 0xC3, 0x4A,
|
||||
0xE7, 0x9D, 0x67, 0x8C, 0x1E, 0x19, 0xB4, 0xB3, 0xF7, 0xA2,
|
||||
0xCF, 0xF7, 0xA0, 0x8D, 0xC1, 0x94, 0x6C, 0xE7, 0xF0, 0x1A,
|
||||
0x12, 0x41, 0x40, 0x0A, 0x0E, 0x41, 0xAA, 0xB8, 0x7E, 0xB1,
|
||||
0x3D, 0x82, 0xD1, 0x1E, 0x3A, 0x14, 0x3D, 0x03, 0xC5, 0x59,
|
||||
0x04, 0x1A, 0x19, 0x7A, 0xB4, 0x5D, 0xD1, 0x95, 0xD6, 0x02,
|
||||
0x26, 0xA2, 0x5E, 0x7F, 0x68, 0x58, 0x7B, 0x7C, 0xC6, 0xAE,
|
||||
0x96, 0x87, 0x24, 0x39, 0x8B, 0xD2, 0x44, 0xC4, 0x48, 0xA0,
|
||||
0xE1, 0x82, 0x4F, 0x79, 0x96, 0x72, 0x86, 0xC4, 0xE5, 0x8E,
|
||||
0xA2, 0x66, 0x4B, 0x5E, 0xA0, 0x48, 0xA9, 0x94, 0x02, 0x92,
|
||||
0x7D, 0x81, 0xE0, 0x34, 0x97, 0x56, 0x65, 0x4A, 0x42, 0x0C,
|
||||
0x3D, 0x17, 0xFB, 0x44, 0x84, 0xF5, 0xBD, 0xBD, 0xB7, 0x7D,
|
||||
0x96, 0xBF, 0x31, 0xD2, 0xC2, 0xD3, 0xDA, 0x9D, 0x72, 0x5C,
|
||||
0xEB, 0xA1, 0xE1, 0xA2, 0x68, 0xC8, 0x9C, 0x23, 0xD6, 0x8F,
|
||||
0x66, 0x14, 0xDA, 0x0F, 0xB2, 0x11, 0x2B, 0xB7, 0x46, 0xFF,
|
||||
0xB1, 0xC1, 0x49, 0x56, 0x78, 0x59, 0x96, 0x7A, 0x3E, 0x8F,
|
||||
0xBD, 0xA6, 0x38, 0x2A, 0xF4, 0xBB, 0x4F, 0x77, 0x4A, 0xC8,
|
||||
0x65, 0x56, 0x42, 0xD5, 0x0E, 0x72, 0x19, 0x48, 0x55, 0x0F,
|
||||
0xAB, 0x73, 0xB8, 0x9C, 0x35, 0x4A, 0xB7, 0xEB, 0xB0, 0x51,
|
||||
0x47, 0x0F, 0xA2, 0xD3, 0xC3, 0x4C, 0x65, 0x65, 0x4A, 0xEA,
|
||||
0xDA, 0xEB, 0x5E, 0xBB, 0x8C, 0x67, 0x8B, 0x42, 0xB4, 0xDE,
|
||||
0x58, 0xF1, 0x35, 0x09, 0xA2, 0x19, 0xC6, 0x5C, 0x9C, 0x2D,
|
||||
0x41, 0x21, 0xC7, 0x94, 0xED, 0xEA, 0x4D, 0x51, 0x32, 0x5B,
|
||||
0x19, 0x05, 0xF9, 0x8D, 0x7F, 0x19, 0xEE, 0xB6, 0xC2, 0xB2,
|
||||
0xAB, 0xE7, 0x1B, 0xFD, 0x0B, 0xD0, 0xF5, 0x7E, 0xB7, 0xEB,
|
||||
0x03, 0x00, 0x00};
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef __OTA_H
|
||||
#define __OTA_H
|
||||
|
||||
#include <ArduinoOTA.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
void ota_setup() {
|
||||
ArduinoOTA.setPort(8266);
|
||||
ArduinoOTA.setHostname("ESP_Treppenlicht");
|
||||
ArduinoOTA.setPassword("admin");
|
||||
// Password can be set with it's md5 value as well
|
||||
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
||||
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
||||
|
||||
ArduinoOTA.onStart([]() {
|
||||
String type;
|
||||
if (ArduinoOTA.getCommand() == U_FLASH) {
|
||||
type = "sketch";
|
||||
} else { // U_FS
|
||||
type = "filesystem";
|
||||
}
|
||||
|
||||
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
|
||||
Serial.println("Start updating " + type);
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) {
|
||||
Serial.println("Auth Failed");
|
||||
} else if (error == OTA_BEGIN_ERROR) {
|
||||
Serial.println("Begin Failed");
|
||||
} else if (error == OTA_CONNECT_ERROR) {
|
||||
Serial.println("Connect Failed");
|
||||
} else if (error == OTA_RECEIVE_ERROR) {
|
||||
Serial.println("Receive Failed");
|
||||
} else if (error == OTA_END_ERROR) {
|
||||
Serial.println("End Failed");
|
||||
}
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
|
||||
}
|
||||
|
||||
#endif // __OTA_H
|
||||
@@ -1,32 +0,0 @@
|
||||
// filename: style.css.gz.h
|
||||
#define style_css_gz_len 283
|
||||
const char style_css_gz[] = {
|
||||
0x1F, 0x8B, 0x08, 0x00, 0xB4, 0x6E, 0xC7, 0x60, 0x02, 0xFF,
|
||||
0x75, 0x51, 0xC1, 0x8A, 0xC3, 0x20, 0x10, 0xBD, 0x17, 0xFA,
|
||||
0x0F, 0x03, 0x7B, 0xE8, 0xA5, 0x82, 0x6D, 0x49, 0xA1, 0xF6,
|
||||
0x9E, 0x6B, 0x0F, 0xFB, 0x05, 0x26, 0x1A, 0x33, 0xAC, 0xD1,
|
||||
0xA0, 0x96, 0xB6, 0xBB, 0xEC, 0xBF, 0xEF, 0x24, 0xA9, 0x59,
|
||||
0x4A, 0x76, 0x11, 0x15, 0x9E, 0xEF, 0xBD, 0x79, 0x33, 0xB6,
|
||||
0xA9, 0xB3, 0xF0, 0xB5, 0x5E, 0x01, 0x34, 0xDE, 0x25, 0x16,
|
||||
0xF1, 0x53, 0x0B, 0xD8, 0xF1, 0xFE, 0x7E, 0x9E, 0xB1, 0x46,
|
||||
0x76, 0x68, 0x1F, 0x02, 0x36, 0x97, 0x5E, 0x3B, 0x78, 0x97,
|
||||
0x2E, 0x6E, 0xB6, 0x10, 0xE9, 0x62, 0x51, 0x07, 0x6C, 0x88,
|
||||
0xF8, 0xBD, 0x5E, 0x0D, 0xAB, 0xDD, 0x2D, 0x9C, 0x8E, 0xD9,
|
||||
0x29, 0xE9, 0x7B, 0x62, 0xD2, 0xA2, 0x71, 0x02, 0x6A, 0xED,
|
||||
0x92, 0x0E, 0x59, 0xD7, 0x6F, 0xC1, 0xE2, 0x32, 0xC2, 0xF1,
|
||||
0x29, 0xB4, 0xE8, 0x34, 0x6B, 0x35, 0x9A, 0x36, 0x09, 0xD8,
|
||||
0x4F, 0x90, 0x4E, 0xA4, 0x67, 0xB1, 0x97, 0x35, 0x3A, 0x43,
|
||||
0xDC, 0x91, 0x9A, 0x43, 0xCC, 0x0D, 0x55, 0xB2, 0xFE, 0x30,
|
||||
0xC1, 0x5F, 0x9D, 0x62, 0xB5, 0xB7, 0x3E, 0x08, 0x78, 0xE3,
|
||||
0xBC, 0x38, 0x9C, 0xCA, 0x4C, 0xAE, 0xBC, 0x7A, 0x4C, 0xD4,
|
||||
0x1B, 0xAA, 0xD4, 0x0E, 0x69, 0x73, 0xDC, 0x4E, 0x06, 0x83,
|
||||
0x14, 0x95, 0x83, 0xBC, 0x26, 0x7F, 0xFE, 0xC7, 0xAE, 0x2C,
|
||||
0x4F, 0x05, 0xE7, 0xE3, 0x6B, 0x2F, 0x95, 0x1A, 0xC3, 0x70,
|
||||
0xD8, 0x93, 0xC9, 0xEF, 0x31, 0x69, 0x7D, 0x50, 0x9A, 0x14,
|
||||
0x05, 0x81, 0xD1, 0x5B, 0x54, 0x50, 0x59, 0xB2, 0xCB, 0x41,
|
||||
0xF2, 0xE0, 0xE6, 0xAA, 0xAF, 0x96, 0xA3, 0xD7, 0x84, 0x2D,
|
||||
0x1A, 0x79, 0x4E, 0x36, 0xB6, 0x52, 0xF9, 0x9B, 0x80, 0x03,
|
||||
0x31, 0x87, 0x4D, 0x23, 0x79, 0x2D, 0x81, 0x9D, 0x99, 0x6A,
|
||||
0x28, 0x8C, 0xBD, 0x95, 0xF4, 0x9D, 0x95, 0xF5, 0xE3, 0xF3,
|
||||
0x1F, 0xCD, 0x92, 0xE2, 0x07, 0x5A, 0x7D, 0xE2, 0xF6, 0x18,
|
||||
0x02, 0x00, 0x00};
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
// filename: include/http/index.html.gz.h
|
||||
// uncompressed: index.html, gzip: 622
|
||||
#define index_html_gz 622
|
||||
const char index_html_gz[] = {
|
||||
0x1F, 0x8B, 0x08, 0x00, 0x22, 0x7E, 0xC2, 0x60, 0x02, 0xFF, 0x8D, 0x54, 0xCD, 0x6E, 0xD4, 0x30,
|
||||
0x10, 0xBE, 0xF3, 0x14, 0x43, 0xAE, 0x74, 0x63, 0xF5, 0x86, 0xAA, 0x6C, 0x10, 0x82, 0x22, 0x71,
|
||||
0xA8, 0x8A, 0x68, 0x11, 0xE2, 0xE8, 0x38, 0x93, 0xC4, 0xAA, 0xE3, 0xB1, 0xEC, 0x71, 0xB7, 0xCB,
|
||||
0x89, 0xD7, 0xE0, 0xF5, 0x78, 0x12, 0xC6, 0xCE, 0xB6, 0x2A, 0xEA, 0x85, 0x4B, 0x12, 0xCF, 0xDF,
|
||||
0xF7, 0x7D, 0x33, 0xE3, 0x74, 0xAF, 0x3F, 0x5E, 0x7F, 0xB8, 0xFD, 0xF1, 0xE5, 0x12, 0x16, 0x5E,
|
||||
0x5D, 0xFF, 0xAA, 0xDB, 0x5E, 0x00, 0xDD, 0x82, 0x7A, 0x2C, 0x1F, 0xF2, 0xB9, 0x22, 0x6B, 0x30,
|
||||
0x8B, 0x8E, 0x09, 0x79, 0xDF, 0x64, 0x9E, 0x76, 0x6F, 0x9B, 0x93, 0x8B, 0x2D, 0x3B, 0xEC, 0xAF,
|
||||
0x8E, 0xC0, 0x98, 0x18, 0x82, 0x9E, 0xB1, 0x53, 0x9B, 0x6D, 0xF3, 0x3B, 0xEB, 0xEF, 0x60, 0x89,
|
||||
0x38, 0xED, 0x9B, 0x85, 0x39, 0x5C, 0x28, 0x35, 0x91, 0xE7, 0xD4, 0xCE, 0x44, 0xB3, 0x43, 0x1D,
|
||||
0x6C, 0x6A, 0x0D, 0xAD, 0xCA, 0xA4, 0xF4, 0x6E, 0xD2, 0xAB, 0x75, 0xC7, 0xFD, 0x75, 0x40, 0xFF,
|
||||
0xE6, 0x46, 0xFB, 0xD4, 0x40, 0x44, 0xB7, 0x6F, 0x12, 0x1F, 0x1D, 0xA6, 0x05, 0x91, 0x1B, 0xE0,
|
||||
0x63, 0xC0, 0x7D, 0xC3, 0xF8, 0xC0, 0x25, 0xA3, 0x79, 0x89, 0xB1, 0x05, 0xAB, 0xFA, 0x6A, 0x4B,
|
||||
0xC8, 0x7F, 0xD5, 0xE8, 0xD4, 0xA3, 0xD8, 0x6E, 0xA0, 0xF1, 0x78, 0x2A, 0xBB, 0x9C, 0xF7, 0x57,
|
||||
0xF4, 0xD3, 0x3A, 0xA7, 0xC1, 0x26, 0x30, 0x44, 0x4E, 0xE2, 0xCE, 0x4F, 0x4E, 0xBB, 0xCE, 0x90,
|
||||
0xA2, 0xD9, 0x37, 0x76, 0x15, 0xCD, 0x49, 0x4D, 0x56, 0xF0, 0xE9, 0xA1, 0x0D, 0x7E, 0x6E, 0x40,
|
||||
0x3B, 0x69, 0xD3, 0xED, 0x82, 0xF0, 0x69, 0xB3, 0x82, 0xA3, 0x99, 0x2E, 0x40, 0xC3, 0xE4, 0x44,
|
||||
0xA3, 0x9F, 0xA1, 0xD8, 0x52, 0x8E, 0x91, 0xB2, 0x1F, 0xCB, 0x99, 0x25, 0xF6, 0x52, 0x47, 0x5E,
|
||||
0x5A, 0xE1, 0xB3, 0x01, 0x84, 0xFE, 0x3D, 0xC3, 0x09, 0xFF, 0x0C, 0x0E, 0xF8, 0xE7, 0xD7, 0xEF,
|
||||
0x88, 0x52, 0x62, 0x76, 0x34, 0x68, 0x27, 0x74, 0xD6, 0x35, 0x7B, 0xCB, 0x47, 0xA0, 0xA9, 0x53,
|
||||
0xE1, 0x31, 0x2B, 0xBB, 0x1E, 0xBA, 0xD7, 0xBB, 0x5D, 0x99, 0x96, 0x9F, 0x71, 0x04, 0x26, 0x70,
|
||||
0x56, 0x26, 0x63, 0x7D, 0x05, 0xE1, 0xCC, 0x14, 0xAD, 0xE4, 0xEF, 0x76, 0x9B, 0x90, 0xDA, 0xBE,
|
||||
0x9E, 0xD1, 0x2C, 0x9E, 0x84, 0xA5, 0x84, 0xA6, 0x4E, 0x89, 0xE5, 0xB9, 0x73, 0x91, 0xFE, 0x62,
|
||||
0x7C, 0x61, 0x1F, 0xB2, 0x75, 0xE3, 0x3F, 0xF6, 0x4E, 0x09, 0xFE, 0x13, 0xFF, 0x03, 0xC5, 0xBB,
|
||||
0x2A, 0x8E, 0x66, 0x14, 0xEC, 0x58, 0xB8, 0xDC, 0x21, 0x86, 0x4A, 0xE4, 0xB3, 0x67, 0x8C, 0x1E,
|
||||
0x59, 0x7A, 0x65, 0xEF, 0x45, 0x97, 0x1F, 0x41, 0x1B, 0x83, 0x29, 0xD9, 0xC1, 0xE1, 0x19, 0x24,
|
||||
0x82, 0x80, 0x14, 0x1C, 0x82, 0x54, 0x71, 0xE3, 0xC1, 0x8E, 0x08, 0x46, 0x7B, 0x18, 0x50, 0x94,
|
||||
0x4C, 0x14, 0x57, 0x91, 0x66, 0x64, 0x91, 0xA2, 0x1D, 0x8A, 0xA2, 0x54, 0x0B, 0x98, 0x88, 0xBA,
|
||||
0x1E, 0x68, 0xAA, 0x18, 0xDF, 0x71, 0x68, 0xE5, 0x21, 0x49, 0xCE, 0xA2, 0x80, 0x88, 0x10, 0x09,
|
||||
0x34, 0x5C, 0xFC, 0x4B, 0x5E, 0xA5, 0x9C, 0x21, 0xE9, 0xEE, 0x40, 0x51, 0xB3, 0x25, 0x2F, 0xAE,
|
||||
0x48, 0xA9, 0x94, 0x02, 0x92, 0x1D, 0x84, 0xE0, 0x34, 0x17, 0xA8, 0x32, 0x7D, 0x21, 0x86, 0x9E,
|
||||
0x4B, 0xE3, 0x44, 0x84, 0x95, 0xA1, 0xDD, 0xDB, 0x31, 0xCB, 0x69, 0x8E, 0x74, 0xE0, 0xA5, 0xA2,
|
||||
0x53, 0x8E, 0xB5, 0x1E, 0x1A, 0x2E, 0x8A, 0xA6, 0xCC, 0x39, 0x62, 0xFB, 0x6C, 0x36, 0xA1, 0xFF,
|
||||
0x2A, 0x5B, 0x56, 0x99, 0x75, 0xFA, 0xD9, 0x9D, 0x48, 0x72, 0x29, 0x0E, 0x87, 0x43, 0xBB, 0x6E,
|
||||
0xC3, 0x6E, 0x29, 0xCE, 0x0A, 0xFD, 0xEE, 0xDB, 0x8D, 0x12, 0x6A, 0x99, 0x95, 0x10, 0xB5, 0x93,
|
||||
0xDC, 0x2E, 0x52, 0xCD, 0xD3, 0x42, 0x5E, 0x3D, 0xDA, 0x3A, 0xA5, 0xFB, 0x3A, 0x64, 0xD4, 0xD1,
|
||||
0x83, 0xA8, 0xF4, 0xB0, 0x52, 0x59, 0x94, 0x92, 0x5A, 0xB1, 0xEE, 0xB5, 0xCB, 0xB8, 0x35, 0x28,
|
||||
0x44, 0xEB, 0x8D, 0x95, 0xAE, 0x26, 0xF1, 0x68, 0x86, 0x39, 0x97, 0xBE, 0x96, 0xA0, 0x90, 0x63,
|
||||
0xCA, 0xB6, 0x76, 0xA6, 0xE8, 0x58, 0xAD, 0x0C, 0x82, 0xFC, 0xC6, 0xBE, 0xCC, 0x75, 0xBB, 0x16,
|
||||
0xB2, 0xFF, 0xF5, 0xEF, 0xF0, 0x17, 0x2C, 0x3C, 0x3D, 0x28, 0x35, 0x04, 0x00, 0x00};
|
||||
Submodule
+1
Submodule lib/PCA9685-Arduino added at a70be39257.
-46
@@ -1,46 +0,0 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
@@ -0,0 +1,124 @@
|
||||
#include "filesys.h"
|
||||
|
||||
FSInfo fsinfo;
|
||||
|
||||
auto mount_fs() -> bool {
|
||||
if(!LittleFS.begin()) {
|
||||
Serial.println("[ERROR] LittleFS.info(), reset ...");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!LittleFS.info(fsinfo)) {
|
||||
Serial.println("[ERROR] LittleFS.info(), reset ...");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("Filesystem opened:\n\r");
|
||||
printf("\ttotalBytes:\t%d\n\r", fsinfo.totalBytes);
|
||||
printf("\tusedBytes:\t%d\n\r", fsinfo.usedBytes);
|
||||
printf("\tblockSize:\t%d\n\r", fsinfo.blockSize);
|
||||
printf("\tpageSize:\t%d\n\r", fsinfo.pageSize);
|
||||
printf("\tmaxOpenFiles:\t%d\n\r", fsinfo.maxOpenFiles);
|
||||
printf("\tmaxPathLength:\t%d\n\r", fsinfo.maxPathLength);
|
||||
printf("\n\r");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto format_fs() -> bool {
|
||||
printf("Formatting FS ! \n\r");
|
||||
return LittleFS.format();
|
||||
}
|
||||
|
||||
void ls(const char * dirname) {
|
||||
Serial.printf("ls -l %s\n\r", dirname);
|
||||
Dir root = LittleFS.openDir(dirname);
|
||||
|
||||
while (root.next()) {
|
||||
File file = root.openFile("r");
|
||||
|
||||
time_t lw = file.getLastWrite();
|
||||
struct tm * tmstruct = localtime(&lw);
|
||||
Serial.printf("%8d %02d %02d %02d:%02d %s\n\r",
|
||||
file.size(),
|
||||
tmstruct->tm_mon + 1,
|
||||
tmstruct->tm_mday,
|
||||
tmstruct->tm_hour,
|
||||
tmstruct->tm_min,
|
||||
root.fileName().c_str());
|
||||
file.close();
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
File open(const char * path) {
|
||||
return LittleFS.open(path, "r");
|
||||
}
|
||||
|
||||
|
||||
void printFile(const char * path) {
|
||||
Serial.printf("Reading file: %s\n\r", path);
|
||||
|
||||
File file = LittleFS.open(path, "r");
|
||||
if (!file) {
|
||||
Serial.println("Failed to open file for reading");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Read from file: ");
|
||||
while (file.available()) {
|
||||
Serial.write(file.read());
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void writeFile(const char * path, const char * message) {
|
||||
Serial.printf("Writing file: %s\n\r", path);
|
||||
|
||||
File file = LittleFS.open(path, "w");
|
||||
if (!file) {
|
||||
Serial.println("Failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
if (file.print(message)) {
|
||||
Serial.println("File written");
|
||||
} else {
|
||||
Serial.println("Write failed");
|
||||
}
|
||||
delay(2000); // Make sure the CREATE and LASTWRITE times are different
|
||||
file.close();
|
||||
}
|
||||
|
||||
void appendFile(const char * path, const char * message) {
|
||||
Serial.printf("Appending to file: %s\n\r", path);
|
||||
|
||||
File file = LittleFS.open(path, "a");
|
||||
if (!file) {
|
||||
Serial.println("Failed to open file for appending");
|
||||
return;
|
||||
}
|
||||
if(file.print(message)) {
|
||||
Serial.println("Message appended");
|
||||
} else {
|
||||
Serial.println("Append failed");
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void renameFile(const char * path1, const char * path2) {
|
||||
Serial.printf("Renaming file %s to %s\n\r", path1, path2);
|
||||
if (LittleFS.rename(path1, path2)) {
|
||||
Serial.println("File renamed");
|
||||
} else {
|
||||
Serial.println("Rename failed");
|
||||
}
|
||||
}
|
||||
|
||||
void deleteFile(const char * path) {
|
||||
Serial.printf("Deleting file: %s\n\r", path);
|
||||
if (LittleFS.remove(path)) {
|
||||
Serial.println("File deleted");
|
||||
} else {
|
||||
Serial.println("Delete failed");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <LittleFS.h>
|
||||
|
||||
// some usefull wrappers for Filesystem
|
||||
bool mount_fs();
|
||||
bool format_fs();
|
||||
|
||||
File open(const char * path);
|
||||
|
||||
void ls(const char * dirname);
|
||||
void printFile(const char * path);
|
||||
void writeFile(const char * path, const char * message);
|
||||
void appendFile(const char * path, const char * message);
|
||||
void renameFile(const char * path1, const char * path2);
|
||||
void deleteFile(const char * path);
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "httpserver.h"
|
||||
|
||||
auto HTTPServer::start() -> bool {
|
||||
if (!mount_fs()) {
|
||||
logf("cant mount filesystem, EXIT !\n\r");
|
||||
return false;
|
||||
}
|
||||
|
||||
logf("LittleFS mounted !\n\r");
|
||||
logf("root:\n\r");
|
||||
this->listRoot();
|
||||
logf("\n\r");
|
||||
|
||||
// default handler
|
||||
this->onNotFound([this]() {
|
||||
String message = "File Not Found\n\n";
|
||||
message += "URI: ";
|
||||
message += uri();
|
||||
message += "\nMethod: ";
|
||||
message += (method() == HTTP_GET) ? "GET" : "POST";
|
||||
message += "\nArguments: ";
|
||||
message += args();
|
||||
message += "\n";
|
||||
|
||||
for (uint8_t i = 0; i < args(); i++) {
|
||||
message += " " + argName(i) + ": " + arg(i) + "\n";
|
||||
}
|
||||
send(404, "text/plain", message);
|
||||
});
|
||||
|
||||
// add static root file handler for http
|
||||
this->serveStatic("/", LittleFS, "/");
|
||||
this->begin();
|
||||
logf("Server active on Port 80 !\n\r");
|
||||
return true;
|
||||
}
|
||||
|
||||
void HTTPServer::start_apps() {
|
||||
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++) {
|
||||
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);
|
||||
logt("set_active_pwm = %d %\n", arg(i).toInt());
|
||||
}
|
||||
else if (argName(i).equals("range_idl_pwm")) {
|
||||
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")) {
|
||||
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_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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
send(200, "text/plain", "accepted");
|
||||
});
|
||||
|
||||
this->on("/terminal", HTTP_POST, [this]() {
|
||||
// logf("got /terminal\n");
|
||||
if (tbuf_head) {
|
||||
send(200, "text/plain", tbuf);
|
||||
tbuf_head = 0;
|
||||
} else {
|
||||
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>
|
||||
void HTTPServer::logf(const char *format, Args... args) const {
|
||||
Serial.print(log_prefix);
|
||||
Serial.printf(format, args...);
|
||||
}
|
||||
|
||||
void HTTPServer::logt(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
// append logging string to local buffer
|
||||
if (tbuf_head < TBUF_LEN) {
|
||||
tbuf_head +=
|
||||
vsnprintf(tbuf + tbuf_head, TBUF_LEN - tbuf_head, format, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef __HTTPSERVER_H
|
||||
#define __HTTPSERVER_H
|
||||
// Wrapper for ESP8266WebServer with Filesystem as HTTP source
|
||||
|
||||
#include "filesys.h"
|
||||
#include "treppe.h"
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// debug log <ESP8266WebServer.h>
|
||||
// #define DEBUGV(f,...) do { Serial.printf(PSTR(f), ##__VA_ARGS__); } while (0)
|
||||
|
||||
#define TBUF_LEN 256
|
||||
|
||||
class HTTPServer : public ESP8266WebServer {
|
||||
|
||||
private:
|
||||
const char *rootDir = "/";
|
||||
const char *log_prefix = "[HTTPServer] ";
|
||||
|
||||
size_t tbuf_head = 0;
|
||||
char tbuf[TBUF_LEN];
|
||||
|
||||
void listRoot() { ls(rootDir); }
|
||||
Treppe *treppe;
|
||||
|
||||
public:
|
||||
HTTPServer(const int _port, const char *_rootDir, Treppe *_treppe)
|
||||
: ESP8266WebServer(_port), rootDir(_rootDir), treppe(_treppe) {}
|
||||
~HTTPServer() { Serial.printf("[HTTPServer] shut down ...\n\r"); }
|
||||
|
||||
bool start();
|
||||
void start_apps();
|
||||
|
||||
template <class... Args>
|
||||
void logf(const char *format, Args... args) const;
|
||||
void logt(const char *format, ...);
|
||||
};
|
||||
|
||||
#endif // __HTTPSERVER_H
|
||||
@@ -0,0 +1,276 @@
|
||||
//
|
||||
// Academic License - for use in teaching, academic research, and meeting
|
||||
// course requirements at degree granting institutions only. Not for
|
||||
// government, commercial, or other organizational use.
|
||||
//
|
||||
// File: FSMTreppe.cpp
|
||||
//
|
||||
// Code generated for Simulink model 'FSMTreppe'.
|
||||
//
|
||||
// Model version : 1.51
|
||||
// Simulink Coder version : 9.5 (R2021a) 14-Nov-2020
|
||||
// C/C++ source code generated on : Wed Jul 7 18:54:01 2021
|
||||
//
|
||||
// Target selection: ert.tlc
|
||||
// Embedded hardware selection: ARM Compatible->ARM Cortex-M
|
||||
// Code generation objectives: Unspecified
|
||||
// Validation result: Not run
|
||||
//
|
||||
#include "FSMTreppe3.h"
|
||||
|
||||
// Named constants for Chart: '<Root>/FSMTreppe'
|
||||
const uint32_t FSMTreppe_IN_abdimmen_hoch = 1U;
|
||||
const uint32_t FSMTreppe_IN_abdimmen_ldr = 2U;
|
||||
const uint32_t FSMTreppe_IN_abdimmen_runter = 3U;
|
||||
const uint32_t FSMTreppe_IN_aufdimmen_hoch = 4U;
|
||||
const uint32_t FSMTreppe_IN_aufdimmen_ldr = 5U;
|
||||
const uint32_t FSMTreppe_IN_aufdimmen_runter = 6U;
|
||||
const uint32_t FSMTreppe_IN_inaktiv = 7U;
|
||||
const uint32_t FSMTreppe_IN_ruhezustand = 8U;
|
||||
const uint32_t FSMTreppe_IN_warten_hoch = 9U;
|
||||
const uint32_t FSMTreppe_IN_warten_runter = 10U;
|
||||
|
||||
// Model step function
|
||||
void FSMTreppeModelClass::step()
|
||||
{
|
||||
// Chart: '<Root>/FSMTreppe' incorporates:
|
||||
// Inport: '<Root>/anim_beendet'
|
||||
// Inport: '<Root>/ldr_schwelle'
|
||||
// Inport: '<Root>/sensor_oben'
|
||||
// Inport: '<Root>/sensor_unten'
|
||||
|
||||
if (FSMTreppe_DW.temporalCounter_i1 < 511U) {
|
||||
FSMTreppe_DW.temporalCounter_i1 = static_cast<uint16_t>
|
||||
(FSMTreppe_DW.temporalCounter_i1 + 1U);
|
||||
}
|
||||
|
||||
if (FSMTreppe_DW.is_active_c3_FSMTreppe == 0U) {
|
||||
FSMTreppe_DW.is_active_c3_FSMTreppe = 1U;
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_inaktiv;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 0U;
|
||||
} else {
|
||||
switch (FSMTreppe_DW.is_c3_FSMTreppe) {
|
||||
case FSMTreppe_IN_abdimmen_hoch:
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 6U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_ruhezustand;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 3U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_abdimmen_ldr:
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 2U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_inaktiv;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_abdimmen_runter:
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 9U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_ruhezustand;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 3U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_aufdimmen_hoch:
|
||||
// Outport: '<Root>/laufrichtung'
|
||||
FSMTreppe_Y.laufrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 4U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_warten_hoch;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 5U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_aufdimmen_ldr:
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 1U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_ruhezustand;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 3U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_aufdimmen_runter:
|
||||
// Outport: '<Root>/laufrichtung'
|
||||
FSMTreppe_Y.laufrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 7U;
|
||||
if ((FSMTreppe_U.anim_beendet == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_warten_runter;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 8U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_inaktiv:
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 0U;
|
||||
if (FSMTreppe_U.ldr_schwelle == 1U) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_aufdimmen_ldr;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 1U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_ruhezustand:
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 3U;
|
||||
if (FSMTreppe_U.sensor_unten == 1U) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_aufdimmen_hoch;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/laufrichtung'
|
||||
FSMTreppe_Y.laufrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 4U;
|
||||
} else if (FSMTreppe_U.sensor_oben == 1U) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_aufdimmen_runter;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/laufrichtung'
|
||||
FSMTreppe_Y.laufrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 1U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 7U;
|
||||
} else if (FSMTreppe_U.ldr_schwelle == 0U) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_abdimmen_ldr;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 2U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
}
|
||||
break;
|
||||
|
||||
case FSMTreppe_IN_warten_hoch:
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 5U;
|
||||
if ((FSMTreppe_U.sensor_oben == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_abdimmen_hoch;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 6U;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Outport: '<Root>/status'
|
||||
// case IN_warten_runter:
|
||||
FSMTreppe_Y.status = 8U;
|
||||
if ((FSMTreppe_U.sensor_unten == 1U) || (FSMTreppe_DW.temporalCounter_i1 >=
|
||||
500U)) {
|
||||
FSMTreppe_DW.is_c3_FSMTreppe = FSMTreppe_IN_abdimmen_runter;
|
||||
FSMTreppe_DW.temporalCounter_i1 = 0U;
|
||||
|
||||
// Outport: '<Root>/dimmrichtung'
|
||||
FSMTreppe_Y.dimmrichtung = 0U;
|
||||
|
||||
// Outport: '<Root>/status'
|
||||
FSMTreppe_Y.status = 9U;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End of Chart: '<Root>/FSMTreppe'
|
||||
}
|
||||
|
||||
// Model initialize function
|
||||
void FSMTreppeModelClass::initialize()
|
||||
{
|
||||
// (no initialization code required)
|
||||
}
|
||||
|
||||
// Model terminate function
|
||||
void FSMTreppeModelClass::terminate()
|
||||
{
|
||||
// (no terminate code required)
|
||||
}
|
||||
|
||||
// Constructor
|
||||
FSMTreppeModelClass::FSMTreppeModelClass() :
|
||||
FSMTreppe_DW(),
|
||||
FSMTreppe_U(),
|
||||
FSMTreppe_Y()
|
||||
{
|
||||
// Currently there is no constructor body generated.
|
||||
}
|
||||
|
||||
// Destructor
|
||||
FSMTreppeModelClass::~FSMTreppeModelClass()
|
||||
{
|
||||
// Currently there is no destructor body generated.
|
||||
}
|
||||
|
||||
//
|
||||
// File trailer for generated code.
|
||||
//
|
||||
// [EOF]
|
||||
//
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// Academic License - for use in teaching, academic research, and meeting
|
||||
// course requirements at degree granting institutions only. Not for
|
||||
// government, commercial, or other organizational use.
|
||||
//
|
||||
// File: FSMTreppe.h
|
||||
//
|
||||
// Code generated for Simulink model 'FSMTreppe'.
|
||||
//
|
||||
// Model version : 1.51
|
||||
// Simulink Coder version : 9.5 (R2021a) 14-Nov-2020
|
||||
// C/C++ source code generated on : Wed Jul 7 18:54:01 2021
|
||||
//
|
||||
// Target selection: ert.tlc
|
||||
// Embedded hardware selection: ARM Compatible->ARM Cortex-M
|
||||
// Code generation objectives: Unspecified
|
||||
// Validation result: Not run
|
||||
//
|
||||
#ifndef RTW_HEADER_FSMTreppe_h_
|
||||
#define RTW_HEADER_FSMTreppe_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Class declaration for model FSMTreppe
|
||||
class FSMTreppeModelClass {
|
||||
// public data and function members
|
||||
public:
|
||||
// Block states (default storage) for system '<Root>'
|
||||
struct DW_FSMTreppe_T {
|
||||
uint16_t temporalCounter_i1=0; // '<Root>/FSMTreppe'
|
||||
uint8_t is_active_c3_FSMTreppe=0; // '<Root>/FSMTreppe'
|
||||
uint8_t is_c3_FSMTreppe=0; // '<Root>/FSMTreppe'
|
||||
};
|
||||
|
||||
// External inputs (root inport signals with default storage)
|
||||
struct ExtU_FSMTreppe_T {
|
||||
uint32_t sensor_unten=0; // '<Root>/sensor_unten'
|
||||
uint32_t sensor_oben=0; // '<Root>/sensor_oben'
|
||||
uint32_t anim_beendet=0; // '<Root>/anim_beendet'
|
||||
uint32_t ldr_schwelle=0; // '<Root>/ldr_schwelle'
|
||||
};
|
||||
|
||||
// External outputs (root outports fed by signals with default storage)
|
||||
struct ExtY_FSMTreppe_T {
|
||||
uint32_t laufrichtung=0; // '<Root>/laufrichtung'
|
||||
uint32_t status=0; // '<Root>/status'
|
||||
uint32_t dimmrichtung=0; // '<Root>/dimmrichtung'
|
||||
};
|
||||
|
||||
// model initialize function
|
||||
void initialize();
|
||||
|
||||
// model step function
|
||||
void step();
|
||||
|
||||
// model terminate function
|
||||
void terminate();
|
||||
|
||||
// Constructor
|
||||
FSMTreppeModelClass();
|
||||
|
||||
// Destructor
|
||||
~FSMTreppeModelClass();
|
||||
|
||||
// Root-level structure-based inputs set method
|
||||
|
||||
// Root inports set method
|
||||
void setExternalInputs(const ExtU_FSMTreppe_T* pExtU_FSMTreppe_T)
|
||||
{
|
||||
FSMTreppe_U.anim_beendet = pExtU_FSMTreppe_T->anim_beendet;
|
||||
FSMTreppe_U.ldr_schwelle = pExtU_FSMTreppe_T->ldr_schwelle;
|
||||
FSMTreppe_U.sensor_oben = pExtU_FSMTreppe_T->sensor_oben;
|
||||
FSMTreppe_U.sensor_unten = pExtU_FSMTreppe_T->sensor_unten;
|
||||
}
|
||||
|
||||
// Root-level structure-based outputs get method
|
||||
|
||||
// Root outports get method
|
||||
const FSMTreppeModelClass::ExtY_FSMTreppe_T getExternalOutputs() const
|
||||
{
|
||||
return FSMTreppe_Y;
|
||||
}
|
||||
|
||||
// private data and function members
|
||||
private:
|
||||
// Block states
|
||||
DW_FSMTreppe_T FSMTreppe_DW;
|
||||
|
||||
// External inputs
|
||||
ExtU_FSMTreppe_T FSMTreppe_U;
|
||||
|
||||
// External outputs
|
||||
ExtY_FSMTreppe_T FSMTreppe_Y;
|
||||
};
|
||||
|
||||
//-
|
||||
// The generated code includes comments that allow you to trace directly
|
||||
// back to the appropriate location in the model. The basic format
|
||||
// is <system>/block_name, where system is the system number (uniquely
|
||||
// assigned by Simulink) and block_name is the name of the block.
|
||||
//
|
||||
// Note that this particular code originates from a subsystem build,
|
||||
// and has its own system numbers different from the parent model.
|
||||
// Refer to the system hierarchy for this subsystem below, and use the
|
||||
// MATLAB hilite_system command to trace the generated code back
|
||||
// to the parent model. For example,
|
||||
//
|
||||
// hilite_system('FSM_Treppenlicht/FSMTreppe') - opens subsystem FSM_Treppenlicht/FSMTreppe
|
||||
// hilite_system('FSM_Treppenlicht/FSMTreppe/Kp') - opens and selects block Kp
|
||||
//
|
||||
// Here is the system hierarchy for this model
|
||||
//
|
||||
// '<Root>' : 'FSM_Treppenlicht'
|
||||
// '<S1>' : 'FSM_Treppenlicht/FSMTreppe'
|
||||
|
||||
#endif // RTW_HEADER_FSMTreppe_h_
|
||||
|
||||
//
|
||||
// File trailer for generated code.
|
||||
//
|
||||
// [EOF]
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,401 @@
|
||||
#include "treppe.h"
|
||||
// #define DEBUG_TIMING
|
||||
|
||||
/*
|
||||
- dimmer_tick: increment pwm jeden tick, bis anim beendet
|
||||
- return: fsm_pend.anim_beendet
|
||||
*/
|
||||
bool Treppe::dimmer_tick(dimmer_t *dimmer, bool dim_type) {
|
||||
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->tick++;
|
||||
if (dimmer->tick < dimmer->ticks) {
|
||||
Serial.print("-");
|
||||
return false;
|
||||
}
|
||||
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("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 >= stufen - 1)
|
||||
return true;
|
||||
dimmer->stufe++;
|
||||
} else { // LR_RUNTER
|
||||
if (dimmer->stufe <= 0)
|
||||
return true;
|
||||
dimmer->stufe--;
|
||||
}
|
||||
dimmer->tick = 0;
|
||||
dimmer->pwm = dimmer->start_pwm;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// startbedingunen für animation
|
||||
void Treppe::start_animation(dimmer_t *dimmer, bool dim_type, uint16_t on_pwm,
|
||||
uint16_t off_pwm) {
|
||||
fsm_pend.anim_beendet = false;
|
||||
|
||||
if (dim_type == DIM_STUFEN) {
|
||||
if (fsm_outputs.laufrichtung == LR_HOCH)
|
||||
dimmer->stufe = 0;
|
||||
else
|
||||
dimmer->stufe = stufen - 1;
|
||||
|
||||
dimmer->ticks = param.time_per_stair / INT_TIME; // [ms]
|
||||
} else { // DIM_LDR
|
||||
dimmer->ticks = param.time_ldr / INT_TIME; // [ms]
|
||||
}
|
||||
|
||||
if (fsm_outputs.dimmrichtung == DR_AUFDIMMEN) {
|
||||
dimmer->start_pwm = off_pwm;
|
||||
dimmer->ziel_pwm = on_pwm;
|
||||
dimmer->delta_pwm = (float)(on_pwm - off_pwm) / (float)dimmer->ticks;
|
||||
} else {
|
||||
dimmer->start_pwm = on_pwm;
|
||||
dimmer->ziel_pwm = off_pwm;
|
||||
dimmer->delta_pwm = (float)(off_pwm - on_pwm) / (float)dimmer->ticks;
|
||||
}
|
||||
|
||||
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() {
|
||||
static FSMTreppeModelClass::ExtU_FSMTreppe_T last_in;
|
||||
static FSMTreppeModelClass::ExtY_FSMTreppe_T last_out;
|
||||
if (fsm_inputs.anim_beendet != last_in.anim_beendet ||
|
||||
fsm_inputs.sensor_oben != last_in.sensor_oben ||
|
||||
fsm_inputs.sensor_unten != last_in.sensor_unten ||
|
||||
fsm_inputs.ldr_schwelle != last_in.ldr_schwelle ||
|
||||
fsm_outputs.dimmrichtung != last_out.dimmrichtung ||
|
||||
fsm_outputs.laufrichtung != last_out.laufrichtung ||
|
||||
fsm_outputs.status != last_out.status) {
|
||||
last_in.anim_beendet = fsm_inputs.anim_beendet;
|
||||
last_in.sensor_oben = fsm_inputs.sensor_oben;
|
||||
last_in.sensor_unten = fsm_inputs.sensor_unten;
|
||||
last_in.ldr_schwelle = fsm_inputs.ldr_schwelle;
|
||||
last_out.dimmrichtung = fsm_outputs.dimmrichtung;
|
||||
last_out.laufrichtung = fsm_outputs.laufrichtung;
|
||||
last_out.status = fsm_outputs.status;
|
||||
|
||||
Serial.printf("FSM IN: s_u: %d, s_o: %d, a_b: %d, l_s: %d => ",
|
||||
fsm_inputs.sensor_oben, fsm_inputs.sensor_unten,
|
||||
fsm_inputs.anim_beendet, fsm_inputs.ldr_schwelle);
|
||||
Serial.printf("OUT: LR: %d DR: %d ST: %d\n", fsm_outputs.laufrichtung,
|
||||
fsm_outputs.dimmrichtung, fsm_outputs.status);
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
const bool s_oben = digitalRead(SENSOR_OBEN);
|
||||
const bool s_unten = digitalRead(SENSOR_UNTEN);
|
||||
|
||||
fsm_pend.sensor_oben = false;
|
||||
fsm_pend.sensor_unten = false;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
float Treppe::read_ldr() {
|
||||
/*
|
||||
Reads Illuminance in Lux
|
||||
|
||||
FUTURE USE : show current Illuminance on Webserver in order to calibrate
|
||||
|
||||
Voltage Divider 1 (R13, R14):
|
||||
R13 = 220k, R14 = 82k
|
||||
V(ADC) = V(in1) * R14/(R13+R14)
|
||||
-> V(in1) = V(ADC) * (R13+R14)/R14
|
||||
V(ADC) = analogRead(A0)/1023.00
|
||||
-> V(in1) = analogRead(A0)/1023.00 * (R13+R14)/R14
|
||||
= analogRead(A0) * (R13+R14)/(R14*1023.00)
|
||||
= analogRead(A0) * (220k+82k)/(82k*1023.00)
|
||||
= analogRead(A0) * 0.0036
|
||||
|
||||
Voltage Divider 2 (LDR, R1 || (R13+R14))
|
||||
R1 = 47k, R13+R14 = 302k -> R1||(R13+R14) = 40,67k
|
||||
Vcc/V(in1) = R(LDR) / (R1||(R13+R14))
|
||||
-> R(LDR) = Vcc/V(in1) * (R1||(R13+R14))
|
||||
R(LDR) = 3.3V * 40.67k / V(in1)
|
||||
|
||||
Join formulas:
|
||||
|
||||
R(LDR) = 3.3V * 40.67k / (0.0036 * analogRead(A0))
|
||||
= 37280.00/analogRead(A0)
|
||||
ldr_ohm = R(LDR)
|
||||
|
||||
E(LDR) = 6526.5 * R(LDR)^-2 (see Excel Regression)
|
||||
E(LDR) = 6526.5 / (R(LDR)^2)
|
||||
ldr_value = E(LDR)
|
||||
*/
|
||||
// float ldr_ohm = 37280.00 / analogRead(A0);
|
||||
float vol_adc = analogRead(A0) * 0.0036;
|
||||
if(vol_adc > 3.29)
|
||||
vol_adc = 3.29;
|
||||
|
||||
float ldr_ohm = 40.67 * (3.3 - vol_adc) / vol_adc;
|
||||
|
||||
float ldr_value = 6526.6 / (ldr_ohm * ldr_ohm);
|
||||
#ifdef LDRDEBUG
|
||||
Serial.printf("vol_adc: %f Ohm: %f lux: %f Comp: %d\n", vol_adc, ldr_ohm, ldr_value,
|
||||
param.ldr_schwelle);
|
||||
#endif
|
||||
return ldr_value;
|
||||
}
|
||||
|
||||
bool Treppe::check_ldr() {
|
||||
static uint8_t active = 0;
|
||||
|
||||
// follow up: averaging over many samples?
|
||||
float ldr = read_ldr();
|
||||
|
||||
if (ldr < param.ldr_schwelle) {
|
||||
active = 1;
|
||||
}
|
||||
if (ldr > param.ldr_schwelle + LDR_HYS) {
|
||||
active = 0;
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
void Treppe::task() {
|
||||
#ifdef DEBUG_TIMING
|
||||
uint32_t m = micros();
|
||||
#endif
|
||||
|
||||
// TODO wenn LDR geändert => idle_pwm_soll anpassen
|
||||
// fsm_pend.ldr_changed = true;
|
||||
fsm_inputs.ldr_schwelle = check_ldr();
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
Serial.print("1:");
|
||||
Serial.println(micros() - m);
|
||||
m = micros();
|
||||
#endif
|
||||
|
||||
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
|
||||
Serial.print("2:");
|
||||
Serial.println(micros() - m);
|
||||
m = micros();
|
||||
#endif
|
||||
|
||||
FSMTreppe_Obj.setExternalInputs(&fsm_inputs);
|
||||
FSMTreppe_Obj.step();
|
||||
fsm_outputs = FSMTreppe_Obj.getExternalOutputs();
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
Serial.print("3:");
|
||||
Serial.println(micros() - m);
|
||||
m = micros();
|
||||
#endif
|
||||
|
||||
print_state_on_change();
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
Serial.print("4:");
|
||||
Serial.println(micros() - m);
|
||||
m = micros();
|
||||
#endif
|
||||
|
||||
if (fsm_outputs.status == ST_AUFDIMMEN_HOCH ||
|
||||
fsm_outputs.status == ST_ABDIMMEN_HOCH ||
|
||||
fsm_outputs.status == ST_AUFDIMMEN_RUNTER ||
|
||||
fsm_outputs.status == ST_ABDIMMEN_RUNTER) {
|
||||
if (fsm_pend.anim_beendet)
|
||||
start_animation(&dimmer_stufen, DIM_STUFEN, param.active_pwm,
|
||||
idle_pwm_ist);
|
||||
else
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Serial.print("5:");
|
||||
Serial.println(micros() - m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Treppe::setup() {
|
||||
pwmController.resetDevices();
|
||||
// Deactive PCA9685 Phase Balancer due to LED Flickering
|
||||
// https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15
|
||||
// see also lib/PCA9685-Arduin/PCA9685.h:204
|
||||
pwmController.init(PCA9685_PhaseBalancer_None);
|
||||
// pwmController.init(PCA9685_PhaseBalancer_Linear);
|
||||
pwmController.setPWMFrequency(100);
|
||||
// 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(0, OUTPUT);
|
||||
digitalWrite(13, HIGH);
|
||||
digitalWrite(0, HIGH);
|
||||
|
||||
pinMode(A0, INPUT);
|
||||
pinMode(SENSOR_OBEN, INPUT);
|
||||
pinMode(SENSOR_UNTEN, INPUT);
|
||||
pinMode(OE, OUTPUT);
|
||||
digitalWrite(OE, 0);
|
||||
|
||||
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,
|
||||
const vorgabe_typ_t vorgabe_typ) {
|
||||
if (vorgabe_typ == VORGABE_PROZENT) {
|
||||
param_pend.idle_pwm_max = param_pend.active_pwm * value / 100;
|
||||
} else if (vorgabe_typ == VORGABE_12BIT) {
|
||||
param_pend.idle_pwm_max = value;
|
||||
}
|
||||
|
||||
if (param_pend.idle_pwm_max > param_pend.active_pwm) {
|
||||
param_pend.idle_pwm_max = param_pend.active_pwm;
|
||||
}
|
||||
param_changed = true;
|
||||
|
||||
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) {
|
||||
param_pend.active_pwm = 4095 * value / 100;
|
||||
} else if (vorgabe_typ == VORGABE_12BIT) {
|
||||
param_pend.active_pwm = value;
|
||||
}
|
||||
|
||||
if (param_pend.active_pwm > 4095) {
|
||||
param_pend.idle_pwm_max = 4095;
|
||||
}
|
||||
param_changed = true;
|
||||
|
||||
Serial.printf("Treppe: param_pend.active_pwm=%d\n", param_pend.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(const uint16_t value) {
|
||||
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", 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);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef __TREPPE_H
|
||||
#define __TREPPE_H
|
||||
|
||||
#include "FSMTreppe3/FSMTreppe3.h"
|
||||
#include "PCA9685.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#define LDRDEBUG // comment in to override LDR measurement
|
||||
#define LDR_HYS 100 // Hysteresis for switching off FSM [lux]
|
||||
|
||||
#define SENSOR_OBEN 16
|
||||
#define SENSOR_UNTEN 12
|
||||
#define OE 14
|
||||
|
||||
#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 };
|
||||
|
||||
#define EEP_START_ADDR 100 // define Start Address for "EEPROM" storage -> depends on size of "wifi_data"!
|
||||
|
||||
class Treppe {
|
||||
private:
|
||||
const uint8_t stufen;
|
||||
|
||||
struct stairway_param_t {
|
||||
uint16_t time_ldr = 500;
|
||||
uint16_t time_per_stair = 300; // dimmtime per stair [ms]
|
||||
uint16_t idle_pwm_max = 100;
|
||||
uint16_t active_pwm = 2000;
|
||||
uint16_t ldr_schwelle = 30; // activation value for FSM [lx]
|
||||
};
|
||||
stairway_param_t param;
|
||||
stairway_param_t param_pend; // zwischenspeicher änderungen
|
||||
bool param_changed = false;
|
||||
|
||||
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;
|
||||
|
||||
struct dimmer_t {
|
||||
uint8_t stufe = 0;
|
||||
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_t dimmer_stufen;
|
||||
dimmer_t dimmer_ldr;
|
||||
|
||||
// initialize with i2c-Address 0, use Wire Library
|
||||
PCA9685 pwmController;
|
||||
FSMTreppeModelClass FSMTreppe_Obj;
|
||||
FSMTreppeModelClass::ExtU_FSMTreppe_T fsm_inputs;
|
||||
FSMTreppeModelClass::ExtY_FSMTreppe_T fsm_outputs;
|
||||
enum fsm_status_t {
|
||||
ST_INAKTIV_LDR = 0,
|
||||
ST_AUFDIMMEN_LDR = 1,
|
||||
ST_ABDIMMEN_LDR = 2,
|
||||
ST_RUHEZUSTAND = 3,
|
||||
ST_AUFDIMMEN_HOCH = 4,
|
||||
ST_WARTEN_HOCH = 5,
|
||||
ST_ABDIMMEN_HOCH = 6,
|
||||
ST_AUFDIMMEN_RUNTER = 7,
|
||||
ST_WARTEN_RUNTER = 8,
|
||||
ST_ABDIMMEN_RUNTER = 9
|
||||
};
|
||||
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_tick(dimmer_t *dimmer, bool dim_type);
|
||||
void start_animation(dimmer_t *dimmer, bool dim_type, uint16_t on_pwm,
|
||||
uint16_t off_pwm);
|
||||
|
||||
/* LDR */
|
||||
bool read_sensor(int sensor);
|
||||
float read_ldr();
|
||||
bool check_ldr();
|
||||
|
||||
public:
|
||||
Treppe(uint8_t _stufen) : stufen(_stufen) { FSMTreppe_Obj.initialize(); }
|
||||
~Treppe() { FSMTreppe_Obj.terminate(); }
|
||||
|
||||
void setup();
|
||||
void task(); // call periodically
|
||||
|
||||
// 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_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
|
||||
Binary file not shown.
@@ -1,30 +0,0 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp01_1m]
|
||||
platform = espressif8266
|
||||
board = esp01_1m
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
|
||||
extra_scripts = pre:extra_script.py
|
||||
|
||||
; stuff for OTA
|
||||
; https://docs.platformio.org/en/latest/platforms/espressif8266.html#over-the-air-ota-update
|
||||
upload_protocol = espota
|
||||
upload_port = 192.168.10.94
|
||||
upload_flags =
|
||||
--port=8266
|
||||
--auth=admin
|
||||
|
||||
lib_deps =
|
||||
|
||||
# The exact version
|
||||
ottowinter/PCA9685 16-Channel PWM Driver Module Library @ 1.2.9
|
||||
@@ -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 /dev/ttyUSB0
|
||||
thb loop
|
||||
@@ -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
|
||||
+95
-141
@@ -1,71 +1,97 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include "wifi_credentials.h"
|
||||
#ifdef WITH_DEBUGGING_ON
|
||||
#include <GDBStub.h> // debugging support via GDBStub over UART
|
||||
#endif
|
||||
|
||||
#include "PCA9685.h"
|
||||
|
||||
// Änderung
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
// OTA & WEB
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include "httpserver.h"
|
||||
#include "ota.h"
|
||||
#include "wifi_credentials.h"
|
||||
#include <EEPROM.h>
|
||||
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <WiFiClient.h> // evtl weghauen ?
|
||||
// BOARD
|
||||
#define ESP12_LED 2
|
||||
// #define NODEMCU_LED 16
|
||||
|
||||
#include "index.html.gz.h"
|
||||
#include "style.css.gz.h"
|
||||
// images are possible
|
||||
// maybe check out FS <- SPIFFS
|
||||
// PWM
|
||||
#include "treppe.h"
|
||||
os_timer_t timer1;
|
||||
uint8_t timer_flag = 0;
|
||||
Treppe stairs(16);
|
||||
|
||||
const char* ssid = STASSID;
|
||||
const char* password = STAPSK;
|
||||
// WIFI
|
||||
const char *ssid = STASSID;
|
||||
const char *password = STAPSK;
|
||||
|
||||
const int led = 13;
|
||||
ESP8266WebServer server(80);
|
||||
// port 80, root directory of server '/'
|
||||
HTTPServer httpServer(80, "/", &stairs);
|
||||
|
||||
void handleRootGz() {
|
||||
const char* dataType = "text/html";
|
||||
server.sendHeader(F("Content-Encoding"), F("gzip"));
|
||||
server.send(200, dataType, (const char*)index_html_gz, index_html_gz_len);
|
||||
}
|
||||
|
||||
void handleCssGz() {
|
||||
const char* dataType = "text/css";
|
||||
server.sendHeader(F("Content-Encoding"), F("gzip"));
|
||||
server.send(200, dataType, (const char*)style_css_gz, style_css_gz_len);
|
||||
}
|
||||
|
||||
|
||||
void handleNotFound() {
|
||||
digitalWrite(led, 1);
|
||||
String message = "File Not Found\n\n";
|
||||
message += "URI: ";
|
||||
message += server.uri();
|
||||
message += "\nMethod: ";
|
||||
message += (server.method() == HTTP_GET) ? "GET" : "POST";
|
||||
message += "\nArguments: ";
|
||||
message += server.args();
|
||||
message += "\n";
|
||||
|
||||
for (uint8_t i = 0; i < server.args(); i++) {
|
||||
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
|
||||
uint32_t _t = 0;
|
||||
#define SP_US(_str, _a) \
|
||||
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); \
|
||||
}
|
||||
|
||||
server.send(404, "text/plain", message);
|
||||
digitalWrite(led, 0);
|
||||
struct { // Struct for wifi-data, 40 Bytes each SSID and PW
|
||||
char SSID[40] = "";
|
||||
char PW[40] = "";
|
||||
} wifi_data;
|
||||
|
||||
void timerCallback(void *pArg) {
|
||||
*(static_cast<int *>(pArg)) += 1;
|
||||
stairs.task();
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
uint8_t inter = 0;
|
||||
ICACHE_RAM_ATTR void int_test() { inter = 1; }
|
||||
|
||||
void setup_webserver() {
|
||||
pinMode(led, OUTPUT);
|
||||
digitalWrite(led, 0);
|
||||
Serial.println("");
|
||||
void setup() {
|
||||
#ifdef WITH_DEBUGGING_ON
|
||||
Serial.begin(460800);
|
||||
gdbstub_init();
|
||||
#else
|
||||
Serial.begin(76800);
|
||||
#endif
|
||||
Serial.println("Booting ....");
|
||||
pinMode(ESP12_LED, OUTPUT);
|
||||
|
||||
// Wait for connection
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
EEPROM.begin(512); // init virtual "EEPROM" with size 512 Bytes
|
||||
|
||||
// strncpy(wifi_data.SSID, "donotconnect", 40);
|
||||
// strncpy(wifi_data.PW, "unsafe lol", 40);
|
||||
|
||||
EEPROM.get(0, wifi_data);
|
||||
// EEPROM.commit();
|
||||
|
||||
Wire.begin(); // Wire must be started first
|
||||
Wire.setClock(
|
||||
1000000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz
|
||||
stairs.setup();
|
||||
Serial.println("PCA9685 connected !");
|
||||
// attachInterrupt(digitalPinToInterrupt(2), int_test, RISING);
|
||||
// attachInterrupt(digitalPinToInterrupt(12), int_test, RISING);
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("Connection Failed! Rebooting...");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
@@ -74,97 +100,25 @@ void setup_webserver() {
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
//server.on("/", handleRoot);
|
||||
server.on("/", handleRootGz);
|
||||
server.on("/styles/style.css", handleCssGz);
|
||||
server.onNotFound(handleNotFound);
|
||||
ota_setup();
|
||||
|
||||
server.begin();
|
||||
Serial.println("HTTP server started");
|
||||
httpServer.start();
|
||||
httpServer.start_apps();
|
||||
Serial.println("HTTP server started !");
|
||||
|
||||
os_timer_setfn(&timer1, timerCallback, &timer_flag);
|
||||
os_timer_arm(&timer1, 20, true);
|
||||
|
||||
Serial.println("SSID: " + String(wifi_data.SSID) +
|
||||
" PW: " + String(wifi_data.PW));
|
||||
}
|
||||
|
||||
|
||||
|
||||
PCA9685 pwmController;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("Booting");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
Wire.begin(); // Wire must be started first
|
||||
Wire.setClock(400000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz
|
||||
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("Connection Failed! Rebooting...");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
// setup OTA
|
||||
ArduinoOTA.setPort(8266);
|
||||
ArduinoOTA.setHostname("ESP_Treppenlicht");
|
||||
ArduinoOTA.setPassword("admin");
|
||||
// Password can be set with it's md5 value as well
|
||||
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
||||
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
||||
|
||||
ArduinoOTA.onStart([]() {
|
||||
String type;
|
||||
if (ArduinoOTA.getCommand() == U_FLASH) {
|
||||
type = "sketch";
|
||||
} else { // U_FS
|
||||
type = "filesystem";
|
||||
}
|
||||
|
||||
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
|
||||
Serial.println("Start updating " + type);
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) {
|
||||
Serial.println("Auth Failed");
|
||||
} else if (error == OTA_BEGIN_ERROR) {
|
||||
Serial.println("Begin Failed");
|
||||
} else if (error == OTA_CONNECT_ERROR) {
|
||||
Serial.println("Connect Failed");
|
||||
} else if (error == OTA_RECEIVE_ERROR) {
|
||||
Serial.println("Receive Failed");
|
||||
} else if (error == OTA_END_ERROR) {
|
||||
Serial.println("End Failed");
|
||||
}
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
Serial.println("Ready");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
setup_webserver();
|
||||
|
||||
pwmController.resetDevices(); // Software resets all PCA9685 devices on Wire line
|
||||
|
||||
pwmController.init(B000000); // Address pins A5-A0 set to B000000
|
||||
pwmController.setPWMFrequency(200); // Default is 200Hz, supports 24Hz to 1526Hz
|
||||
|
||||
pwmController.setChannelPWM(0, 128 << 4); // Set PWM to 128/255, but in 4096 land
|
||||
|
||||
Serial.println(pwmController.getChannelPWM(0)); // Should output 2048, which is 128 << 4
|
||||
|
||||
}
|
||||
|
||||
uint32_t t;
|
||||
#define SP_US(_str,_a) Serial.print(_str); Serial.print(" took: "); Serial.print(_a); Serial.println("µs")
|
||||
#define TIMEIF_US(_str,_f, _l) t=micros(); _f; t=micros()-t; if(t > _l) { SP_US(_str, t); }
|
||||
|
||||
void loop() {
|
||||
TIMEIF_US("OTA", ArduinoOTA.handle(), 20000);
|
||||
if (inter != 0u) {
|
||||
Serial.printf("interrupt\n");
|
||||
inter = 0;
|
||||
}
|
||||
|
||||
TIMEIF_US("HTTP", server.handleClient(), 20000);
|
||||
TIMEIF_US(ArduinoOTA.handle(), 10000, "OTA");
|
||||
TIMEIF_US(httpServer.handleClient(), 10000, "HTTP");
|
||||
}
|
||||
@@ -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"
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/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
|
||||
|
||||
echo "Starting gdb"
|
||||
$GDB_PATH -x scripts/gdboptions
|
||||
@@ -0,0 +1,97 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
description = ESP8266 Treppenlicht Steuerung
|
||||
default_envs = ota
|
||||
; test_dir = test
|
||||
data_dir = data_gz
|
||||
|
||||
[env:hardware]
|
||||
platform = espressif8266
|
||||
; board = nodemcuv2
|
||||
board = huzzah
|
||||
framework = arduino
|
||||
; build_unflags = -Os
|
||||
; build_flags = -O2
|
||||
|
||||
board_build.filesystem = littlefs
|
||||
board_build.ldscript = eagle.flash.4m1m.ld
|
||||
extra_scripts = pre:create_gz_files.py
|
||||
|
||||
[env:serial]
|
||||
extends = env:hardware
|
||||
upload_protocol = esptool
|
||||
upload_speed = 921600
|
||||
upload_port = COM23
|
||||
monitor_port = COM23
|
||||
monitor_speed = 76800
|
||||
|
||||
[env:ota]
|
||||
extends = env:hardware
|
||||
; OTA => https://docs.platformio.org/en/latest/platforms/espressif8266.html#over-the-air-ota-update
|
||||
upload_protocol = espota
|
||||
upload_port = <!! IP ADDRESS !!>
|
||||
upload_flags =
|
||||
--port=8266
|
||||
--host_port=<!! PORT !!>
|
||||
--auth=admin
|
||||
|
||||
|
||||
[env:debug]
|
||||
extends = env:hardware
|
||||
; look at doku.md
|
||||
build_flags = -DWITH_DEBUGGING_ON -Os -g3 -ggdb3
|
||||
upload_protocol = esptool
|
||||
upload_speed = 921600
|
||||
upload_port = COM23
|
||||
|
||||
; for pio check
|
||||
; check_tool = cppcheck
|
||||
check_tool = clangtidy
|
||||
check_flags =
|
||||
clangtidy: --fix-errors lib/httpserver/*
|
||||
; clangtidy: lib/httpserver/* lib/treppe/* lib/treppe/FSMTreppe3/* lib/PCA9685-Arduino/*
|
||||
check_skip_packages = yes
|
||||
|
||||
# This file is used compile and run tests located in the `unit` directory.
|
||||
# For more info, see:
|
||||
# https://docs.platformio.org/en/latest/plus/unit-testing.html
|
||||
# https://github.com/ThrowTheSwitch/Unity
|
||||
# https://github.com/ThrowTheSwitch/Unity/blob/master/docs/UnityAssertionsReference.md
|
||||
|
||||
|
||||
|
||||
# To prepare coverage data for lcov, add ${coverage.build_flags} to env:test build flags
|
||||
# To actually generate coverage report:
|
||||
# $ `pio test` / run the test `program` manually
|
||||
# $ lcov --include (readlink -f ../espurna)'/*' --capture --directory .pio/build/test/ --output-file test.info
|
||||
# $ genhtml --ignore-errors source test.info --output-directory out
|
||||
|
||||
[coverage]
|
||||
build_flags = -lgcov -fprofile-arcs -ftest-coverage
|
||||
|
||||
[env:test]
|
||||
extends = env:hardware
|
||||
|
||||
|
||||
[env:native]
|
||||
platform = native
|
||||
test_build_project_src = true
|
||||
build_flags =
|
||||
-DMANUFACTURER="PLATFORMIO"
|
||||
-DDEVICE="TEST"
|
||||
-std=gnu++11
|
||||
-g
|
||||
-Os
|
||||
-I lib/treppe
|
||||
-I lib/PCA9685-Arduino
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// #include <Arduino.h>
|
||||
// #include <unity.h>
|
||||
|
||||
// String STR_TO_TEST;
|
||||
|
||||
// // void setUp(void) {
|
||||
// // // set stuff up here
|
||||
// // STR_TO_TEST = "Hello, world!";
|
||||
// // }
|
||||
|
||||
// // void tearDown(void) {
|
||||
// // // clean stuff up here
|
||||
// // STR_TO_TEST = "";
|
||||
// // }
|
||||
|
||||
// void test_led_builtin_pin_number(void) {
|
||||
// TEST_ASSERT_EQUAL(2, LED_BUILTIN);
|
||||
// }
|
||||
|
||||
// void test_string_concat(void) {
|
||||
// String hello = "Hello, ";
|
||||
// String world = "world!";
|
||||
// TEST_ASSERT_EQUAL_STRING(STR_TO_TEST.c_str(), (hello + world).c_str());
|
||||
// }
|
||||
|
||||
|
||||
// void setup()
|
||||
// {
|
||||
// delay(2000); // service delay
|
||||
// UNITY_BEGIN();
|
||||
|
||||
// RUN_TEST(test_led_builtin_pin_number);
|
||||
// RUN_TEST(test_string_concat);
|
||||
|
||||
// UNITY_END(); // stop unit testing
|
||||
// }
|
||||
|
||||
// void loop()
|
||||
// {
|
||||
// }
|
||||
@@ -0,0 +1,47 @@
|
||||
// #include <Arduino.h>
|
||||
#include "treppe.h"
|
||||
#include <unity.h>
|
||||
|
||||
Treppe stairs(10);
|
||||
|
||||
void setUp(void) {
|
||||
// run before each test
|
||||
// set stuff up here
|
||||
stairs.setup();
|
||||
Serial.println("Treppe initialized !");
|
||||
Serial.println("PCA9685 connected !");
|
||||
}
|
||||
|
||||
void tearDown(void) {
|
||||
// clean stuff up here
|
||||
}
|
||||
|
||||
void test_set_state(void) {
|
||||
stairs.setState(1);
|
||||
TEST_ASSERT_EQUAL(1, stairs.getState());
|
||||
stairs.setState(0);
|
||||
TEST_ASSERT_EQUAL(0, stairs.getState());
|
||||
}
|
||||
|
||||
|
||||
void test_set_direction(void) {
|
||||
stairs.setDirection(1);
|
||||
TEST_ASSERT_EQUAL(1, stairs.getDirection());
|
||||
stairs.setDirection(0);
|
||||
TEST_ASSERT_EQUAL(0, stairs.getDirection());
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
delay(2000); // service delay
|
||||
UNITY_BEGIN();
|
||||
|
||||
RUN_TEST(test_set_state);
|
||||
RUN_TEST(test_set_direction);
|
||||
|
||||
UNITY_END(); // stop unit testing
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
CD .\data
|
||||
py.exe -m http.server
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
cd data
|
||||
python3 -m http.server
|
||||
Reference in new issue
Block a user