35 Commits

Author SHA1 Message Date
e6f1283aae final fixes before Release for DE XI 2023-04-30 10:05:41 +02:00
a92b1edfd9 reformated points-table on WebUI 2023-04-18 20:07:52 +02:00
4cce7c1c86 fixed show setting in WebUI 2023-04-18 20:07:38 +02:00
0a1625e9b8 made Faction-Names configurable 2023-04-18 20:06:57 +02:00
c24829ed70 added Device-ID to SystemInfo 2023-04-18 13:00:34 +02:00
a102405596 reverted calculation-order of checksum and store 2023-04-18 12:53:27 +02:00
1b7157dbdc read back EEPROM after Format to Maintain DTC 2023-04-18 12:50:26 +02:00
cad34d6b84 swapped migration of Persistance and Config 2023-04-18 12:47:04 +02:00
701bf9f457 fixed another warning and bug in Logoutput 2023-04-18 12:30:14 +02:00
0a895a00b9 fixed warning 2023-04-18 12:29:55 +02:00
22a62e3d1e refactoring 2023-04-18 12:28:11 +02:00
f48b5a09ed renamed eeprom-files and added migrator 2023-04-18 12:27:04 +02:00
7f6c486eab fixed config if checkbox not set 2023-04-17 23:14:46 +02:00
3e77f89538 propely handle sysstart and display Startup 2023-04-17 23:12:13 +02:00
f33076a0a3 fixed typo 2023-04-17 22:57:43 +02:00
7e58db489d made active faction recovery configurable 2023-04-17 22:55:16 +02:00
eb771d07d3 fixed copy&paste-error 2023-04-17 22:29:19 +02:00
e2059cb587 reworked DisplayOverride 2023-04-17 22:28:16 +02:00
6702154ef5 made dot blink if faction active 2023-04-17 22:27:26 +02:00
a899cf4dcf Log-Output Format fix 2023-04-17 22:27:01 +02:00
ea230bcee7 bumped Version 2023-04-17 22:02:37 +02:00
c059d7d085 more Sysinfo on WebUI 2023-04-17 22:00:06 +02:00
b8c79955a8 fixed warning 2023-04-17 21:54:46 +02:00
44240aa7bf extended DTC-output by DebugVal 2023-04-17 21:54:36 +02:00
6bc523b2a8 fixed Display of current SysStatus 2023-04-17 21:53:52 +02:00
97cdd7fad1 changed Reset via Buttons during Startup 2023-04-17 21:52:49 +02:00
ec62eeee1e corrected ColorScheme on WebUI 2023-04-17 21:51:27 +02:00
7b166caf84 points and reset-function on webUI 2023-04-17 21:51:13 +02:00
62a7cd1b9c correct EEPROM-Type 2023-04-17 20:23:17 +02:00
7e047c0c09 some Wifi-defines renamed for consistency 2023-04-17 20:23:05 +02:00
8c2d553dfb switched Factions 2023-04-13 21:04:29 +02:00
ca9409e328 more fixes 2023-04-13 01:28:41 +02:00
5a6dc524ad removed Artifacts from other Project 2023-04-13 00:56:35 +02:00
41b27c02dd fixed DTC-Numbering 2023-04-13 00:55:55 +02:00
e344977b8f fixed WiFi-Client Feature 2023-04-13 00:48:43 +02:00
22 changed files with 526 additions and 183 deletions

View File

@@ -73,6 +73,35 @@
<input class="form-control" type="text" placeholder="%SYSTEM_STATUS%" readonly> <input class="form-control" type="text" placeholder="%SYSTEM_STATUS%" readonly>
</p> </p>
<!-- Div Group current Mode --> <!-- Div Group current Mode -->
<!-- Div Group Faction Points -->
<hr />
<p>
<h4>aktueller Punktestand</h4>
<div class="container-fluid">
<div class="row">
<div class="col text-center %FACTION_1_ACTIVE% text-white p-3">%NAME_FAC_1%</div>
<div class="col text-center %FACTION_2_ACTIVE% text-white p-3">%NAME_FAC_2%</div>
<div class="col text-center %FACTION_3_ACTIVE% text-white p-3">%NAME_FAC_3%</div>
</div>
<div class="row">
<div class="col bg-dark text-white p-3"><img src="static/img/logo_fac1.png"
class="rounded mx-auto img-fluid d-block" alt="...">
</div>
<div class="col bg-dark text-white p-3"><img src="static/img/logo_fac2.png"
class="rounded mx-auto img-fluid d-block" alt="...">
</div>
<div class="col bg-dark text-white p-3"><img src="static/img/logo_fac3.png"
class="rounded mx-auto img-fluid d-block" alt="...">
</div>
</div>
<div class="row">
<div class="col text-center bg-secondary text-white p-3">%POINTS_FAC_1%</div>
<div class="col text-center bg-secondary text-white p-3">%POINTS_FAC_2%</div>
<div class="col text-center bg-secondary text-white p-3">%POINTS_FAC_3%</div>
</div>
</div>
</p>
<!-- Div GroupFaction Points -->
<!-- Div Group DTC Table --> <!-- Div Group DTC Table -->
<div %SHOW_DTC_TABLE%> <div %SHOW_DTC_TABLE%>
<hr /> <hr />
@@ -98,6 +127,19 @@
<!-- Div Tab Maintenance --> <!-- Div Tab Maintenance -->
<div id="tab_maintenance" class="tab-pane fade" role="tabpanel"> <div id="tab_maintenance" class="tab-pane fade" role="tabpanel">
<h3>Wartung</h3> <h3>Wartung</h3>
<!-- Div Group Reset Timers -->
<hr />
<p>
<h4>Punkte zur&uuml;cksetzen</h4>
<form action="post.htm" method="POST" class="form-horizontal">
<div class="form-group row">
<div class="col text-center">
<button name="resetpoints" type="submit" class="btn btn-outline-primary">Reset</button>
</div>
</div>
</form>
</p>
<!-- Div Group Reset Timers -->
<!-- Div Group EEPROM formatting --> <!-- Div Group EEPROM formatting -->
<hr /> <hr />
<p> <p>
@@ -153,26 +195,79 @@
<!-- Div Group Device Reboot --> <!-- Div Group Device Reboot -->
</div> </div>
<!-- Div Tab Maintenance --> <!-- Div Tab Maintenance -->
<!-- Div Tab Settings--> <!-- Div Tab Settings-->
<div id="tab_source" class="tab-pane fade" role="tabpanel"> <div id="tab_source" class="tab-pane fade" role="tabpanel">
<h3>Einstellungen</h3> <h3>Einstellungen</h3>
<!-- Div Group Battery Type --> <!-- Div Group Battery Type -->
<hr /> <hr />
<p> <p>
<h4>Akku-Variante</h4>
<form action="post.htm" method="POST" class="form-horizontal"> <form action="post.htm" method="POST" class="form-horizontal">
<h4>Akku-Variante</h4>
<div class="form-group row"> <div class="form-group row">
<label for="sourceselect" class="control-label col-4">Akku</label> <label for="battery_select" class="control-label col-4">Akku</label>
<div class="col-8"> <div class="col-8">
<select id="sourceselect" name="sourceselect" class="select form-control"> <select id="battery_select" name="battery_select" class="select form-control">
%BATTERY_SELECT_OPTIONS% %BATTERY_SELECT_OPTIONS%
</select> </select>
</div> </div>
</div> </div>
<h4>Timer-Einstellungen</h4>
<div class="form-group row">
<label for="factionreboot_cont" class="control-label col-4">active Faction Recovery</label>
<div class="col-8">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="factionreboot_cont" id="factionreboot_cont"
%FACTIONREBOOT_CHECKED%>
<label class="form-check-label" for="factionreboot_cont">
aktive Faktion beim booten wiederherstellen ?
</label>
</div>
</div>
</div>
<h4>Faktionsbezeichnungen</h4>
<div class="alert alert-primary alert-dismissable show fade" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong>Achtung!</strong><br>
Faktionsbezeichnungen können nur aus ASCII-Zeichen bestehen, also A-Z, a-z und 0-9
</div>
<div class="form-group row">
<label for="faction_1_name" class="control-label col-4">Faktion 1</label>
<div class="col-8">
<div class="input-group">
<input id="faction_1_name" name="faction_1_name" value="%NAME_FAC_1%" type="text" class="form-control" pattern="[A-Za-z0-9 _-]{1,32}">
<div class="input-group-append">
<span class="input-group-text">max 32 Zeichen</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="faction_2_name" class="control-label col-4">Faktion 2</label>
<div class="col-8">
<div class="input-group">
<input id="faction_2_name" name="faction_2_name" value="%NAME_FAC_2%" type="text" class="form-control" pattern="[A-Za-z0-9 _-]{1,32}">
<div class="input-group-append">
<span class="input-group-text">max 32 Zeichen</span>
</div>
</div>
</div>
</div>
<div class="form-group row">
<label for="faction_3_name" class="control-label col-4">Faktion 3</label>
<div class="col-8">
<div class="input-group">
<input id="faction_3_name" name="faction_3_name" value="%NAME_FAC_3%" type="text" class="form-control" pattern="[A-Za-z0-9 _-]{1,32}">
<div class="input-group-append">
<span class="input-group-text">max 32 Zeichen</span>
</div>
</div>
</div>
</div>
<div class="form-group row"> <div class="form-group row">
<div class="col text-center"> <div class="col text-center">
<button name="sourcesave" type="submit" class="btn btn-outline-primary">&Uuml;bernehmen</button> <button name="settingssave" type="submit" class="btn btn-outline-primary">&Uuml;bernehmen</button>
</div> </div>
</div> </div>
</form> </form>
@@ -198,6 +293,18 @@
<td>Hostname</td> <td>Hostname</td>
<td>%HOSTNAME%</td> <td>%HOSTNAME%</td>
</tr> </tr>
<tr>
<td>Device-ID</td>
<td>%DEVICENAME_ID%</td>
</tr>
<tr>
<td>Battery Voltage</td>
<td>%BAT_VOLTAGE%V</td>
</tr>
<tr>
<td>Battery Remain</td>
<td>%BAT_REMAIN_CAPACITY%&#37;</td>
</tr>
</table> </table>
</p> </p>
<!-- Div Group Sysinfo:Geraeteinfo --> <!-- Div Group Sysinfo:Geraeteinfo -->
@@ -215,6 +322,10 @@
<td>Battery_type</td> <td>Battery_type</td>
<td>%BATTERY_TYPE%</td> <td>%BATTERY_TYPE%</td>
</tr> </tr>
<tr>
<td>Faction_recovery</td>
<td>%FACTION_RECOVERY%</td>
</tr>
<tr> <tr>
<td>EEPROM Version</td> <td>EEPROM Version</td>
<td>%EEPROM_VERSION%</td> <td>%EEPROM_VERSION%</td>
@@ -251,15 +362,15 @@
</tr> </tr>
<tr> <tr>
<td>faction_1_timer</td> <td>faction_1_timer</td>
<td>%FACTION_1_TIMER%</td> <td>%POINTS_FAC_1%</td>
</tr> </tr>
<tr> <tr>
<td>faction_2_timer</td> <td>faction_2_timer</td>
<td>%FACTION_2_TIMER%</td> <td>%POINTS_FAC_2%</td>
</tr> </tr>
<tr> <tr>
<td>faction_3_timer</td> <td>faction_3_timer</td>
<td>%FACTION_3_TIMER%</td> <td>%POINTS_FAC_3%</td>
</tr> </tr>
<tr> <tr>
<td>checksum</td> <td>checksum</td>
@@ -378,7 +489,7 @@
<div class="container-fluid text-center"> <div class="container-fluid text-center">
<div class="footer-copyright text-center py-3"> <div class="footer-copyright text-center py-3">
<span class="text-muted">© 2023 - <span class="text-muted">© 2023 -
<a class="text-reset fw-bold" href="https://hiabuto.de/">Hiabuto Defence Systems</a></span> <a class="text-reset fw-bold" href="https://hiabuto.de/">Hiabuto Defense Systems</a></span>
</div> </div>
</div> </div>
</footer> </footer>

View File

@@ -21,7 +21,7 @@
--white: #fff; --white: #fff;
--gray: #6c757d; --gray: #6c757d;
--gray-dark: #343a40; --gray-dark: #343a40;
--primary: #FF550B; --primary: #bb1515;
--secondary: #303030; --secondary: #303030;
--success: #015668; --success: #015668;
--info: #0F81C7; --info: #0F81C7;
@@ -1450,8 +1450,8 @@ fieldset:disabled a.btn {
.btn-primary { .btn-primary {
color: #fff; color: #fff;
background-color: #ff550b; background-color: #bb1515;
border-color: #ff550b; border-color: #bb1515;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075) box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075)
} }
@@ -1469,8 +1469,8 @@ fieldset:disabled a.btn {
.btn-primary.disabled, .btn-primary.disabled,
.btn-primary:disabled { .btn-primary:disabled {
color: #fff; color: #fff;
background-color: #ff550b; background-color: #bb1515;
border-color: #ff550b border-color: #bb1515
} }
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled).active,
@@ -1761,16 +1761,16 @@ fieldset:disabled a.btn {
} }
.btn-outline-primary { .btn-outline-primary {
color: #ff550b; color: #bb1515;
background-color: transparent; background-color: transparent;
background-image: none; background-image: none;
border-color: #ff550b border-color: #bb1515
} }
.btn-outline-primary:hover { .btn-outline-primary:hover {
color: #fff; color: #fff;
background-color: #ff550b; background-color: #bb1515;
border-color: #ff550b border-color: #bb1515
} }
.btn-outline-primary.focus, .btn-outline-primary.focus,
@@ -1780,7 +1780,7 @@ fieldset:disabled a.btn {
.btn-outline-primary.disabled, .btn-outline-primary.disabled,
.btn-outline-primary:disabled { .btn-outline-primary:disabled {
color: #ff550b; color: #bb1515;
background-color: transparent background-color: transparent
} }
@@ -1788,8 +1788,8 @@ fieldset:disabled a.btn {
.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled):active,
.show>.btn-outline-primary.dropdown-toggle { .show>.btn-outline-primary.dropdown-toggle {
color: #fff; color: #fff;
background-color: #ff550b; background-color: #bb1515;
border-color: #ff550b border-color: #bb1515
} }
.btn-outline-primary:not(:disabled):not(.disabled).active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,
@@ -2335,7 +2335,7 @@ input[type=submit].btn-block {
.dropdown-item:active { .dropdown-item:active {
color: #fff; color: #fff;
text-decoration: none; text-decoration: none;
background-color: #ff550b background-color: #bb1515
} }
.dropdown-item.disabled, .dropdown-item.disabled,
@@ -2661,7 +2661,7 @@ input[type=submit].btn-block {
.custom-control-input:checked~.custom-control-label::before { .custom-control-input:checked~.custom-control-label::before {
color: #fff; color: #fff;
background-color: #ff550b; background-color: #bb1515;
box-shadow: none box-shadow: none
} }
@@ -2720,7 +2720,7 @@ input[type=submit].btn-block {
} }
.custom-checkbox .custom-control-input:checked~.custom-control-label::before { .custom-checkbox .custom-control-input:checked~.custom-control-label::before {
background-color: #ff550b background-color: #bb1515
} }
.custom-checkbox .custom-control-input:checked~.custom-control-label::after { .custom-checkbox .custom-control-input:checked~.custom-control-label::after {
@@ -2728,7 +2728,7 @@ input[type=submit].btn-block {
} }
.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before { .custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before {
background-color: #ff550b; background-color: #bb1515;
box-shadow: none box-shadow: none
} }
@@ -2749,7 +2749,7 @@ input[type=submit].btn-block {
} }
.custom-radio .custom-control-input:checked~.custom-control-label::before { .custom-radio .custom-control-input:checked~.custom-control-label::before {
background-color: #ff550b background-color: #bb1515
} }
.custom-radio .custom-control-input:checked~.custom-control-label::after { .custom-radio .custom-control-input:checked~.custom-control-label::after {
@@ -2898,7 +2898,7 @@ input[type=submit].btn-block {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
margin-top: -.25rem; margin-top: -.25rem;
background-color: #ff550b; background-color: #bb1515;
border: 0; border: 0;
border-radius: 1rem; border-radius: 1rem;
box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1); box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1);
@@ -2928,7 +2928,7 @@ input[type=submit].btn-block {
.custom-range::-moz-range-thumb { .custom-range::-moz-range-thumb {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
background-color: #ff550b; background-color: #bb1515;
border: 0; border: 0;
border-radius: 1rem; border-radius: 1rem;
box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1); box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1);
@@ -2958,7 +2958,7 @@ input[type=submit].btn-block {
.custom-range::-ms-thumb { .custom-range::-ms-thumb {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
background-color: #ff550b; background-color: #bb1515;
border: 0; border: 0;
border-radius: 1rem; border-radius: 1rem;
box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1); box-shadow: 0 .1rem .25rem rgba(0, 0, 0, .1);
@@ -3063,7 +3063,7 @@ input[type=submit].btn-block {
.nav-pills .nav-link.active, .nav-pills .nav-link.active,
.nav-pills .show>.nav-link { .nav-pills .show>.nav-link {
color: #fff; color: #fff;
background-color: #ff550b background-color: #bb1515
} }
.nav-fill .nav-item { .nav-fill .nav-item {
@@ -3905,7 +3905,7 @@ input[type=submit].btn-block {
.badge-primary { .badge-primary {
color: #fff; color: #fff;
background-color: #ff550b background-color: #bb1515
} }
.badge-primary[href]:focus, .badge-primary[href]:focus,
@@ -4185,7 +4185,7 @@ input[type=submit].btn-block {
color: #6c757d; color: #6c757d;
text-align: center; text-align: center;
white-space: nowrap; white-space: nowrap;
background-color: #ff550b; background-color: #bb1515;
transition: width .6s ease transition: width .6s ease
} }
@@ -5184,7 +5184,7 @@ button.close {
} }
.bg-primary { .bg-primary {
background-color: #ff550b !important background-color: #bb1515 !important
} }
a.bg-primary:focus, a.bg-primary:focus,
@@ -5320,7 +5320,7 @@ button.bg-dark:hover {
} }
.border-primary { .border-primary {
border-color: #ff550b !important border-color: #bb1515 !important
} }
.border-secondary { .border-secondary {
@@ -8234,7 +8234,7 @@ button.bg-dark:hover {
} }
.text-primary { .text-primary {
color: #ff550b !important color: #bb1515 !important
} }
a.text-primary:focus, a.text-primary:focus,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,4 +1,4 @@
{ {
"title": "Akku-Spannung kritisch", "title": "Akku-Spannung kritisch",
"description": "Die Akkuspannung ist sehr niedrig. Bitte Akku umgehend ersetzen um eine schändliche Tiefentladung zu vermeiden!" "description": "Die Akkuspannung ist sehr niedrig. Bitte Akku umgehend ersetzen um eine schädliche Tiefentladung zu vermeiden!"
} }

View File

@@ -0,0 +1,4 @@
{
"title": "EEPROM-Migration failed",
"description": "Migration of EEPROM-Image from an other FW-Version failed - you need to reset everything manually!"
}

View File

@@ -1 +1 @@
1.1 1.02

View File

@@ -13,7 +13,7 @@
#define HOST_NAME "AirsoftTimer_%08X" #define HOST_NAME "AirsoftTimer_%08X"
#define SHUTDOWN_DELAY_MS 5000 #define SHUTDOWN_DELAY_MS 5000
#define RESETABLE_AFTER_STARTUP_MS 30000 #define STARTUP_DELAY_MS 20000
#define GPIO_LORA_TX D3 #define GPIO_LORA_TX D3
#define GPIO_LORA_RX D4 #define GPIO_LORA_RX D4

View File

@@ -3,11 +3,11 @@
#include <Arduino.h> #include <Arduino.h>
#define MAX_DTC_STORAGE 6 #define MAX_DTC_STORAGE 12
typedef enum DTCNums_e typedef enum DTCNums_e
{ {
DTC_NO_EEPROM_FOUND, DTC_NO_EEPROM_FOUND = 1,
DTC_EEPROM_CFG_BAD, DTC_EEPROM_CFG_BAD,
DTC_EEPROM_PDS_BAD, DTC_EEPROM_PDS_BAD,
DTC_EEPROM_PDSADRESS_BAD, DTC_EEPROM_PDSADRESS_BAD,
@@ -19,6 +19,7 @@ typedef enum DTCNums_e
DTC_NO_BATMNON_FOUND, DTC_NO_BATMNON_FOUND,
DTC_BAT_LOW, DTC_BAT_LOW,
DTC_BAT_CRITICAL, DTC_BAT_CRITICAL,
DTC_EEPROM_MIGRATE_FAILED,
DTC_LAST_DTC DTC_LAST_DTC
} DTCNums_t; } DTCNums_t;

View File

@@ -1,5 +1,5 @@
#ifndef _CONFIG_H_ #ifndef _EEPROM_H_
#define _CONFIG_H_ #define _EEPROM_H_
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h> #include <Wire.h>
@@ -8,8 +8,10 @@
#include "globals.h" #include "globals.h"
#include "dtc.h" #include "dtc.h"
#include "common.h" #include "common.h"
#include "debugger.h"
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC01 #define I2C_EE_ADDRESS 0x50
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC64
#define EEPROM_ENDURANCE 1000000 #define EEPROM_ENDURANCE 1000000
typedef enum typedef enum
@@ -30,6 +32,7 @@ typedef struct
uint32_t checksum = 0; uint32_t checksum = 0;
} persistenceData_t; } persistenceData_t;
extern persistenceData_t PersistenceData;
typedef enum typedef enum
{ {
BATTERY_UNDEFINED, BATTERY_UNDEFINED,
@@ -38,24 +41,38 @@ typedef enum
} batteryType_t; } batteryType_t;
const char BatteryString[][10]{ const char BatteryString[][10]{
"Undefined", "Undefined",
"LiPo 2S", "LiPo 2S",
"LiPo 3S" "LiPo 3S"};
};
const size_t BatteryString_Elements = sizeof(BatteryString) / sizeof(BatteryString[0]); const size_t BatteryString_Elements = sizeof(BatteryString) / sizeof(BatteryString[0]);
typedef struct typedef struct
{ {
uint8_t EEPROM_Version = 1; uint8_t EEPROM_Version;
batteryType_t batteryType = BATTERY_UNDEFINED; batteryType_t batteryType;
uint32_t checksum = 0; bool active_faction_on_reboot;
char Faction_1_Name[33];
char Faction_2_Name[33];
char Faction_3_Name[33];
uint32_t checksum;
} configData_t; } configData_t;
extern configData_t ConfigData;
const configData_t ConfigData_defaults = { const configData_t ConfigData_defaults = {
0, BATTERY_LIPO_3S, 0 2, // EEPROM_Version (incerease this if anything on Layout changes!)
BATTERY_LIPO_3S, // batteryType
false, // active_faction_on_reboot
"FACTION 1", // Faction_1_Name
"FACTION 2", // Faction_2_Name
"FACTION 3", // Faction_3_Name
0 // checksum
}; };
const uint16_t startofConfigData = 16;
const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16);
void InitEEPROM(); void InitEEPROM();
void EEPROM_Process(); void EEPROM_Process();
void StoreConfig_EEPROM(); void StoreConfig_EEPROM();
@@ -69,6 +86,4 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
void MovePersistencePage_EEPROM(boolean reset); void MovePersistencePage_EEPROM(boolean reset);
uint32_t ConfigSanityCheck(bool autocorrect = false); uint32_t ConfigSanityCheck(bool autocorrect = false);
extern configData_t ConfigData; #endif // _EEPROM_H_
extern persistenceData_t PersistenceData;
#endif // _CONFIG_H_

View File

@@ -5,12 +5,21 @@
typedef enum eSystem_Status typedef enum eSystem_Status
{ {
sysStat_null,
sysStat_Startup, sysStat_Startup,
sysStat_Normal, sysStat_Normal,
sysStat_Error, sysStat_Error,
sysStat_Shutdown sysStat_Shutdown
} tSystem_Status; } tSystem_Status;
const char sSystem_Status_txt[][9] = {
"Null",
"Startup",
"Normal",
"Error",
"Shutdown"
};
typedef enum eEERequest typedef enum eEERequest
{ {
EE_IDLE, EE_IDLE,
@@ -31,8 +40,6 @@ typedef struct Globals_s
char DeviceName_ID[43]; char DeviceName_ID[43];
char FlashVersion[10]; char FlashVersion[10];
tSystem_Status systemStatus = sysStat_Startup; tSystem_Status systemStatus = sysStat_Startup;
tSystem_Status resumeStatus = sysStat_Startup;
char systemStatustxt[16] = "";
eEERequest requestEEAction = EE_IDLE; eEERequest requestEEAction = EE_IDLE;
uint16_t eePersistanceAdress; uint16_t eePersistanceAdress;
bool hasDTC; bool hasDTC;
@@ -51,8 +58,8 @@ typedef struct Constants_s
} Constants_t; } Constants_t;
const Constants_t constants PROGMEM = { const Constants_t constants PROGMEM = {
1,1, // Firmware_Version 1,2, // Firmware_Version
1,1, // Required Flash Version 1,2, // Required Flash Version
GIT_REV // Git-Hash-String GIT_REV // Git-Hash-String
}; };

View File

@@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> #include <Adafruit_SSD1306.h>
#include "globals.h" #include "globals.h"
#include "config.h" #include "eeprom.h"
#define OLED_SDA 4 #define OLED_SDA 4
#define OLED_SCL 15 #define OLED_SCL 15

View File

@@ -2,20 +2,27 @@
#define _SANITYCHECK_H_ #define _SANITYCHECK_H_
#ifndef ADMIN_PASSWORD #ifndef ADMIN_PASSWORD
#error "You need to define ADMIN_PASSWORD for OTA-Update" #error "You need to define ADMIN_PASSWORD for OTA-Update"
#endif
#ifndef WIFI_PASSWORD
#error "You must define an WIFI_PASSWORD for OTA-Update"
#endif
#ifndef WIFI_SSID
#error "You must define an WIFI_SSID for OTA-Update"
#endif
#ifndef WIFI_AP_SSID
#warning "No WIFI_AP_SSID defined. Using DeviceName"
#define WIFI_AP_SSID DEVICE_NAME
#endif
#ifndef WIFI_AP_PASSWORD
#error "You must define an WIFI_AP_PASSWORD for Standalone AP-Mode"
#endif #endif
#ifndef WIFI_AP_SSID
#warning "No WIFI_AP_SSID defined. Using DeviceName"
#define WIFI_AP_SSID DEVICE_NAME
#endif
#ifndef WIFI_AP_PASSWORD
#error "You must define an WIFI_AP_PASSWORD for Standalone AP-Mode"
#endif
#ifdef FEATURE_ENABLE_WIFI_CLIENT
#ifndef WIFI_CLIENT_PASSWORD
#error "You must define an WIFI_PASSWORD for OTA-Update"
#endif
#ifndef WIFI_CLIENT_SSID
#error "You must define an WIFI_SSID for OTA-Update"
#endif
#endif
#endif //_SANITYCHECK_H_ #endif //_SANITYCHECK_H_

View File

@@ -11,7 +11,7 @@
#include <AsyncJson.h> #include <AsyncJson.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include "config.h" #include "eeprom.h"
#include "globals.h" #include "globals.h"
#include "dtc.h" #include "dtc.h"
#include "common.h" #include "common.h"

View File

@@ -30,16 +30,13 @@ build_flags=
;-DFEATURE_ENABLE_WIFI_CLIENT ;-DFEATURE_ENABLE_WIFI_CLIENT
;-DFEATURE_ENABLE_LORA ;-DFEATURE_ENABLE_LORA
;-DCAPTIVE ;-DCAPTIVE
-DWIFI_AP_IP_GW=10,0,1,1 -DWIFI_AP_IP_GW=10,0,0,1
-DADMIN_PASSWORD=${wifi_cred.admin_password} -DADMIN_PASSWORD=${wifi_cred.admin_password}
-DWIFI_SSID=${wifi_cred.wifi_ssid} -DWIFI_CLIENT_SSID=${wifi_cred.wifi_client_ssid}
-DWIFI_PASSWORD=${wifi_cred.wifi_password} -DWIFI_CLIENT_PASSWORD=${wifi_cred.wifi_client_password}
-DWIFI_AP_SSID=${wifi_cred.wifi_ap_ssid} -DWIFI_AP_SSID=${wifi_cred.wifi_ap_ssid}
-DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password} -DWIFI_AP_PASSWORD=${wifi_cred.wifi_ap_password}
-DDEVICE_NAME='"Dark Emergency Timer"' -DDEVICE_NAME='"Dark Emergency Timer"'
-DFACTION_1_NAME='"GOF"'
-DFACTION_2_NAME='"MILIZ"'
-DFACTION_3_NAME='"KGG"'
;build_type = debug ;build_type = debug

View File

@@ -33,7 +33,7 @@ void Debug_Process()
CMD_OVERFLOW CMD_OVERFLOW
} InputProcessed_t; } InputProcessed_t;
static int inputCnt = 0; static unsigned int inputCnt = 0;
static char inputBuffer[32]; static char inputBuffer[32];
InputProcessed_t InputProcessed = IDLE; InputProcessed_t InputProcessed = IDLE;
@@ -124,31 +124,6 @@ void Debug_pushMessage(const char *format, ...)
} }
} }
void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
{
if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
{
char buff[100];
char *p = buff;
p += snprintf(p, sizeof(buff), "CAN: 0x%08X | %d | ", id, dlc);
for (int i = 0; i < dlc; i++)
{
p += snprintf(p, sizeof(buff) - (p - buff), "%02X ", data[i]);
}
*(p++) = '\n';
*p = '\0';
if (DebuggerStatus[dbg_Serial] == enabled)
{
Serial.print(buff);
}
if (DebuggerStatus[dbg_Webui] == enabled)
{
Websocket_PushLiveDebug(String(buff));
}
}
}
void processCmdDebug(String command) void processCmdDebug(String command)
{ {
if (command == "help") if (command == "help")
@@ -199,7 +174,6 @@ void Debug_formatPersistence()
void Debug_printSystemInfo() void Debug_printSystemInfo()
{ {
Debug_pushMessage("Souko's ChainOiler Mk1\n");
Debug_pushMessage("Hostname: %s\n", globals.DeviceName); Debug_pushMessage("Hostname: %s\n", globals.DeviceName);
FlashMode_t ideMode = ESP.getFlashChipMode(); FlashMode_t ideMode = ESP.getFlashChipMode();
@@ -230,8 +204,6 @@ void Debug_dumpConfig()
void Debug_dumpGlobals() void Debug_dumpGlobals()
{ {
Debug_pushMessage("systemStatus: %d\n", globals.systemStatus); Debug_pushMessage("systemStatus: %d\n", globals.systemStatus);
Debug_pushMessage("resumeStatus: %d\n", globals.resumeStatus);
Debug_pushMessage("systemStatustxt: %s\n", globals.systemStatustxt);
Debug_pushMessage("battery_level: %d\n", globals.battery_level); Debug_pushMessage("battery_level: %d\n", globals.battery_level);
Debug_pushMessage("loadvoltage_mV: %d\n", globals.loadvoltage_mV); Debug_pushMessage("loadvoltage_mV: %d\n", globals.loadvoltage_mV);
Debug_pushMessage("requestEEAction: %d\n", globals.requestEEAction); Debug_pushMessage("requestEEAction: %d\n", globals.requestEEAction);
@@ -292,7 +264,7 @@ void Debug_ShowDTCs()
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
char buff_active[9]; char buff_active[9];
Debug_pushMessage("\n timestamp | DTC-Nr. | status | severity\n"); Debug_pushMessage("\n timestamp | DTC-Nr. | status | severity | debugVal\n");
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++) for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
{ {
@@ -312,7 +284,7 @@ void Debug_ShowDTCs()
else else
strcpy(buff_active, "none"); strcpy(buff_active, "none");
Debug_pushMessage("%s %7d %8s %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active, DTCStorage[i].severity); Debug_pushMessage("%s %7d %8s %8d %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active, DTCStorage[i].severity, DTCStorage[i].debugVal);
} }
} }
} }
@@ -321,7 +293,7 @@ void Debug_printHelp()
{ {
char buff[64]; char buff[64];
for (int i = sizeof(helpCmd) / 63; i < sizeof(helpCmd) / 63; i++) for (unsigned int i = sizeof(helpCmd) / 63; i < sizeof(helpCmd) / 63; i++)
{ {
memcpy_P(buff, (helpCmd + (i * 63)), 63); memcpy_P(buff, (helpCmd + (i * 63)), 63);
buff[63] = 0; buff[63] = 0;

View File

@@ -1,25 +1,28 @@
#include "config.h" #include "eeprom.h"
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES); I2C_eeprom ee(I2C_EE_ADDRESS, EEPROM_SIZE_BYTES);
configData_t ConfigData; configData_t ConfigData;
persistenceData_t PersistenceData; persistenceData_t PersistenceData;
const uint16_t eeVersion = 1; // inc bool eeAvailable = false;
boolean eeAvailable = false;
const uint16_t startofConfigData = 16; bool checkEEPROMavailable();
const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16); bool ValidateEEPROM_Version();
bool MigrateEEPROM(uint8_t fromVersion);
boolean checkEEPROMavailable();
void InitEEPROM() void InitEEPROM()
{ {
ee.begin(); ee.begin();
checkEEPROMavailable(); eeAvailable = checkEEPROMavailable();
eeAvailable = ValidateEEPROM_Version();
Serial.printf("Initialized EEPROM at Address 0x%02X\n", I2C_EE_ADDRESS);
} }
void EEPROM_Process() void EEPROM_Process()
{ {
if (eeAvailable == false)
return;
switch (globals.requestEEAction) switch (globals.requestEEAction)
{ {
case EE_CFG_SAVE: case EE_CFG_SAVE:
@@ -73,17 +76,18 @@ void EEPROM_Process()
void StoreConfig_EEPROM() void StoreConfig_EEPROM()
{ {
if (eeAvailable == false)
return;
ConfigData.checksum = 0; ConfigData.checksum = 0;
ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)); ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData));
if (!checkEEPROMavailable())
return;
ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
} }
void GetConfig_EEPROM() void GetConfig_EEPROM()
{ {
if (!checkEEPROMavailable()) if (eeAvailable == false)
return; return;
ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
@@ -108,6 +112,9 @@ void GetConfig_EEPROM()
void StorePersistence_EEPROM() void StorePersistence_EEPROM()
{ {
if (eeAvailable == false)
return;
if (PersistenceData.writeCycleCounter >= 0xFFF0) if (PersistenceData.writeCycleCounter >= 0xFFF0)
MovePersistencePage_EEPROM(false); MovePersistencePage_EEPROM(false);
else else
@@ -116,15 +123,12 @@ void StorePersistence_EEPROM()
PersistenceData.checksum = 0; PersistenceData.checksum = 0;
PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)); PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData));
if (!checkEEPROMavailable())
return;
ee.updateBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData)); ee.updateBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
} }
void GetPersistence_EEPROM() void GetPersistence_EEPROM()
{ {
if (!checkEEPROMavailable()) if (eeAvailable == false)
return; return;
ee.readBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress)); ee.readBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
@@ -153,22 +157,29 @@ void GetPersistence_EEPROM()
void FormatConfig_EEPROM() void FormatConfig_EEPROM()
{ {
if (eeAvailable == false)
return;
Serial.println("Formatting Config-Partition"); Serial.println("Formatting Config-Partition");
ConfigData = ConfigData_defaults; ConfigData = ConfigData_defaults;
ConfigData.EEPROM_Version = eeVersion;
StoreConfig_EEPROM(); StoreConfig_EEPROM();
GetConfig_EEPROM();
} }
void FormatPersistence_EEPROM() void FormatPersistence_EEPROM()
{ {
if (eeAvailable == false)
return;
Serial.println("Formatting Persistance-Partition"); Serial.println("Formatting Persistance-Partition");
memset(&PersistenceData, 0, sizeof(PersistenceData)); PersistenceData = {0};
StorePersistence_EEPROM(); StorePersistence_EEPROM();
GetPersistence_EEPROM();
} }
void MovePersistencePage_EEPROM(boolean reset) void MovePersistencePage_EEPROM(boolean reset)
{ {
if (!checkEEPROMavailable()) if (eeAvailable == false)
return; return;
globals.eePersistanceAdress = +sizeof(PersistenceData); globals.eePersistanceAdress = +sizeof(PersistenceData);
@@ -206,7 +217,7 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
{ {
#define BLOCK_TO_LENGTH 16 #define BLOCK_TO_LENGTH 16
if (!checkEEPROMavailable()) if (eeAvailable == false)
return; return;
char ascii_buf[BLOCK_TO_LENGTH + 1]; char ascii_buf[BLOCK_TO_LENGTH + 1];
@@ -236,15 +247,13 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
Serial.println(); Serial.println();
} }
boolean checkEEPROMavailable() bool checkEEPROMavailable()
{ {
if (!ee.isConnected()) if (!ee.isConnected())
{ {
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true); MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true);
globals.systemStatus = sysStat_Error;
return false; return false;
} }
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, false);
return true; return true;
} }
@@ -260,4 +269,90 @@ uint32_t ConfigSanityCheck(bool autocorrect)
} }
return setting_reset_bits; return setting_reset_bits;
}
bool ValidateEEPROM_Version()
{
if (eeAvailable == false)
return false;
uint8_t EEPROMVersionOnChip = ee.readByte(startofConfigData);
if (EEPROMVersionOnChip < ConfigData_defaults.EEPROM_Version)
{
Serial.printf("EEPROM Image Version is %d, but %d expected - trying to migrate\n", EEPROMVersionOnChip, ConfigData_defaults.EEPROM_Version);
if (!MigrateEEPROM(EEPROMVersionOnChip))
{
Serial.print("Error\n");
MaintainDTC(DTC_EEPROM_MIGRATE_FAILED, DTC_CRITICAL, true, EEPROMVersionOnChip);
return false;
}
else
{
Serial.print("Success\n");
}
}
return true;
}
bool MigrateEEPROM(uint8_t fromVersion)
{
uint16_t persistanceMarker_onChip;
switch (fromVersion)
{
// Version 1 EEPROM Layout: startAdress size (byte)
// const uint16_t startofConfigData = 16 16
// const uint16_t startofPersistence = 32 24
//
// typedef struct
// {
// uint8_t EEPROM_Version = 1; 16 1
// batteryType_t batteryType = BATTERY_UNDEFINED; 17 4
// bool active_faction_on_reboot = false; 21 1
// uint32_t checksum = 0; 22 4
// } configData_t;
//
// typedef struct offset
// {
// uint32_t writeCycleCounter = 0; 0 4
// uint32_t faction_1_timer = 0; 4 4
// uint32_t faction_2_timer = 0; 8 4
// uint32_t faction_3_timer = 0; 12 4
// factions_t activeFaction = NONE; 16 4
// uint32_t checksum = 0; 20 4
// } persistenceData_t;
case 1:
// Migrate Persistance-Data
ee.readBlock(0, (uint8_t *)&persistanceMarker_onChip, sizeof(uint16_t));
if (persistanceMarker_onChip < startofPersistence)
{
ee.readBlock(persistanceMarker_onChip + 0, (uint8_t *)&PersistenceData.writeCycleCounter, 4);
ee.readBlock(persistanceMarker_onChip + 4, (uint8_t *)&PersistenceData.faction_1_timer, 4);
ee.readBlock(persistanceMarker_onChip + 8, (uint8_t *)&PersistenceData.faction_2_timer, 4);
ee.readBlock(persistanceMarker_onChip + 12, (uint8_t *)&PersistenceData.faction_3_timer, 4);
ee.readBlock(persistanceMarker_onChip + 16, (uint8_t *)&PersistenceData.activeFaction, 4);
ee.readBlock(persistanceMarker_onChip + 20, (uint8_t *)&PersistenceData.checksum, 4);
MovePersistencePage_EEPROM(true);
StorePersistence_EEPROM();
}
// Migrate Config-Data and set defaults for Values which doesn't exists in this earlier Version
ConfigData.EEPROM_Version = ConfigData_defaults.EEPROM_Version;
strncpy(ConfigData.Faction_1_Name, ConfigData_defaults.Faction_1_Name, sizeof(ConfigData.Faction_1_Name));
strncpy(ConfigData.Faction_2_Name, ConfigData_defaults.Faction_2_Name, sizeof(ConfigData.Faction_2_Name));
strncpy(ConfigData.Faction_3_Name, ConfigData_defaults.Faction_3_Name, sizeof(ConfigData.Faction_3_Name));
ee.readBlock(17, (uint8_t *)&ConfigData.batteryType, 4);
ee.readBlock(21, (uint8_t *)&ConfigData.active_faction_on_reboot, 1);
StoreConfig_EEPROM();
return true;
break;
default:
return false;
break;
}
} }

View File

@@ -5,6 +5,5 @@ Globals_t globals;
void initGlobals() void initGlobals()
{ {
globals.systemStatus = sysStat_Startup; globals.systemStatus = sysStat_Startup;
globals.resumeStatus = sysStat_Normal;
globals.requestEEAction = EE_IDLE; globals.requestEEAction = EE_IDLE;
} }

View File

@@ -45,8 +45,9 @@ void toggleWiFiAP(boolean shutdown = false);
void SystemShutdown(); void SystemShutdown();
void SetBatteryType(batteryType_t type); void SetBatteryType(batteryType_t type);
void ProcessKeyCombos(bool *btnState); void ProcessKeyCombos(bool *btnState);
void OverrideDisplay(const uint8_t *message, uint32_t time); void OverrideDisplay(uint32_t time, const char *message1, const char *message2, const char *message3);
void initGlobals(); void initGlobals();
void maintainSysStat();
#ifdef FEATURE_ENABLE_LORA #ifdef FEATURE_ENABLE_LORA
void setMPins_Helper(int pin, int status); void setMPins_Helper(int pin, int status);
@@ -69,7 +70,7 @@ Ticker tmrWiFiMaintainConnection(tmrCallback_WiFiMaintainConnection, 1000, 0, MI
#endif #endif
uint32_t DisplayOverrideFlag = 0; uint32_t DisplayOverrideFlag = 0;
char DisplayOverrideValue[5] = {0}; char DisplayOverrideValue[3][5] = {0};
#ifdef FEATURE_ENABLE_LORA #ifdef FEATURE_ENABLE_LORA
void setMPins_Helper(int pin, int status) void setMPins_Helper(int pin, int status)
@@ -89,15 +90,15 @@ void setup()
Serial.begin(115200); Serial.begin(115200);
Serial.setDebugOutput(false); Serial.setDebugOutput(false);
Serial.println("\n\nDark Emergency Timer - by Hiabuto Defense"); Serial.print("\n\n-------------------START-------------------\n");
Serial.println(globals.DeviceName); Serial.print(globals.DeviceName);
Serial.print("\nby Hiabuto Defense\n");
ClearAllDTC(); // Init DTC-Storage ClearAllDTC(); // Init DTC-Storage
InitEEPROM(); InitEEPROM();
GetConfig_EEPROM(); GetConfig_EEPROM();
GetPersistence_EEPROM(); GetPersistence_EEPROM();
Serial.print("\nEE-Init done");
if (i2c_io.begin()) if (i2c_io.begin())
{ {
@@ -121,7 +122,7 @@ void setup()
#ifdef FEATURE_ENABLE_LORA #ifdef FEATURE_ENABLE_LORA
if (InitLoRa(&setMPins_Helper)) if (InitLoRa(&setMPins_Helper))
{ {
Serial.printf("Initialized LoRa_Transceiver"); Serial.print("Initialized LoRa_Transceiver\n");
tmrStatusSender.start(); tmrStatusSender.start();
} }
else else
@@ -133,8 +134,9 @@ void setup()
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFi.setHostname(globals.DeviceName); WiFi.setHostname(globals.DeviceName);
wifiMulti.addAP(QUOTE(WIFI_SSID_CLIENT), QUOTE(WIFI_PASSWORD_CLIENT)); wifiMulti.addAP(QUOTE(WIFI_CLIENT_SSID), QUOTE(WIFI_CLIENT_PASSWORD));
WiFiMaintainConnectionTicker.start(); tmrWiFiMaintainConnection.start();
Serial.print("WiFi-Client Initialized\n");
#else #else
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
#endif #endif
@@ -205,11 +207,15 @@ void setup()
tmrFactionTicker.start(); tmrFactionTicker.start();
tmrInputGetter.start(); tmrInputGetter.start();
if (ConfigData.active_faction_on_reboot == false)
PersistenceData.activeFaction = NONE;
Serial.print("\nSetup Done\n"); Serial.print("\nSetup Done\n");
} }
void loop() void loop()
{ {
maintainSysStat();
tmrEEPROMCyclicPDS.update(); tmrEEPROMCyclicPDS.update();
tmrFactionTicker.update(); tmrFactionTicker.update();
@@ -231,11 +237,9 @@ void loop()
#ifdef CAPTIVE #ifdef CAPTIVE
dnsServer.processNextRequest(); dnsServer.processNextRequest();
#endif #endif
#ifdef WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
tmrWiFiMaintainConnection.update(); tmrWiFiMaintainConnection.update();
#endif #endif
if (globals.systemStatus == sysStat_Shutdown)
SystemShutdown();
yield(); yield();
} }
@@ -257,9 +261,9 @@ void SevenSeg_Output()
disp_FAC_1.setBrightness(5); disp_FAC_1.setBrightness(5);
disp_FAC_2.setBrightness(5); disp_FAC_2.setBrightness(5);
disp_FAC_3.setBrightness(5); disp_FAC_3.setBrightness(5);
disp_FAC_1.display(String(DisplayOverrideValue)); disp_FAC_1.display(String(DisplayOverrideValue[0]));
disp_FAC_2.clearScreen(); disp_FAC_2.display(String(DisplayOverrideValue[1]));
disp_FAC_3.clearScreen(); disp_FAC_3.display(String(DisplayOverrideValue[2]));
} }
else else
{ {
@@ -285,16 +289,19 @@ void SevenSeg_Output()
disp_FAC_1.refresh(); disp_FAC_1.refresh();
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_1_timer / 60); snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_1_timer / 60);
disp_FAC_1.display(String(sevenSegBuff), false, false); disp_FAC_1.display(String(sevenSegBuff), false, false);
disp_FAC_1.setDp((PersistenceData.activeFaction == FACTION_1) && (millis() % 1000 > 500) ? 0x08 : 0x00);
disp_FAC_2.setBrightness(PersistenceData.activeFaction == FACTION_2 ? 5 : 1); disp_FAC_2.setBrightness(PersistenceData.activeFaction == FACTION_2 ? 5 : 1);
disp_FAC_2.refresh(); disp_FAC_2.refresh();
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_2_timer / 60); snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_2_timer / 60);
disp_FAC_2.display(String(sevenSegBuff), false, false); disp_FAC_2.display(String(sevenSegBuff), false, false);
disp_FAC_2.setDp((PersistenceData.activeFaction == FACTION_2) && (millis() % 1000 > 500) ? 0x08 : 0x00);
disp_FAC_3.setBrightness(PersistenceData.activeFaction == FACTION_3 ? 5 : 1); disp_FAC_3.setBrightness(PersistenceData.activeFaction == FACTION_3 ? 5 : 1);
disp_FAC_3.refresh(); disp_FAC_3.refresh();
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_3_timer / 60); snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", PersistenceData.faction_3_timer / 60);
disp_FAC_3.display(String(sevenSegBuff), false, false); disp_FAC_3.display(String(sevenSegBuff), false, false);
disp_FAC_3.setDp((PersistenceData.activeFaction == FACTION_3) && (millis() % 1000 > 500) ? 0x08 : 0x00);
} }
} }
} }
@@ -337,7 +344,7 @@ void tmrCallback_InputGetter()
if (keysPressed > 1) if (keysPressed > 1)
{ {
Serial.println("ERROR: More than one Flag active - setting no Faction active"); Debug_pushMessage("ERROR: More than one Flag active - setting no Faction active");
PersistenceData.activeFaction = NONE; PersistenceData.activeFaction = NONE;
return; return;
} }
@@ -346,7 +353,8 @@ void tmrCallback_InputGetter()
{ {
if (PersistenceData.activeFaction != FACTION_1) if (PersistenceData.activeFaction != FACTION_1)
{ {
Serial.println("Faction 1 captured !"); Debug_pushMessage("Faction 1 captured !");
globals.requestEEAction = EE_PDS_SAVE;
} }
PersistenceData.activeFaction = FACTION_1; PersistenceData.activeFaction = FACTION_1;
} }
@@ -355,7 +363,8 @@ void tmrCallback_InputGetter()
{ {
if (PersistenceData.activeFaction != FACTION_2) if (PersistenceData.activeFaction != FACTION_2)
{ {
Serial.println("Faction 2 captured !"); Debug_pushMessage("Faction 2 captured !");
globals.requestEEAction = EE_PDS_SAVE;
} }
PersistenceData.activeFaction = FACTION_2; PersistenceData.activeFaction = FACTION_2;
} }
@@ -364,7 +373,8 @@ void tmrCallback_InputGetter()
{ {
if (PersistenceData.activeFaction != FACTION_3) if (PersistenceData.activeFaction != FACTION_3)
{ {
Serial.println("Faction 3 captured !"); Debug_pushMessage("Faction 3 captured !");
globals.requestEEAction = EE_PDS_SAVE;
} }
PersistenceData.activeFaction = FACTION_3; PersistenceData.activeFaction = FACTION_3;
} }
@@ -412,8 +422,8 @@ void tmrCallback_PowerMonitor()
break; break;
} }
MaintainDTC(DTC_BAT_CRITICAL, DTC_CRITICAL, (battery_level < 5 ? true : false), battery_level);
MaintainDTC(DTC_BAT_LOW, DTC_WARN, (battery_level < 15 ? true : false), battery_level); MaintainDTC(DTC_BAT_LOW, DTC_WARN, (battery_level < 15 ? true : false), battery_level);
MaintainDTC(DTC_BAT_CRITICAL, DTC_CRITICAL, (battery_level < 5 ? true : false), battery_level);
// Serial.printf("Battery Level: %d %%\n", globals.battery_level); // Serial.printf("Battery Level: %d %%\n", globals.battery_level);
// Serial.printf("Bus Voltage: %f V\n", busvoltage); // Serial.printf("Bus Voltage: %f V\n", busvoltage);
@@ -446,7 +456,7 @@ void tmrCallback_WiFiMaintainConnection()
} }
else else
{ {
debugV("WiFi not connected! - Start AP"); Debug_pushMessage("WiFi not connected! - Start AP");
toggleWiFiAP(); toggleWiFiAP();
} }
} }
@@ -460,7 +470,7 @@ void toggleWiFiAP(boolean shutdown)
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
Serial.println("WiFi turned off"); Serial.println("WiFi turned off");
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFiMaintainConnectionTicker.stop(); tmrWiFiMaintainConnection.stop();
#endif #endif
} }
else else
@@ -469,7 +479,7 @@ void toggleWiFiAP(boolean shutdown)
WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0)); WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0));
WiFi.softAP(QUOTE(WIFI_AP_SSID), QUOTE(WIFI_AP_PASSWORD)); WiFi.softAP(QUOTE(WIFI_AP_SSID), QUOTE(WIFI_AP_PASSWORD));
#ifdef FEATURE_ENABLE_WIFI_CLIENT #ifdef FEATURE_ENABLE_WIFI_CLIENT
WiFiMaintainConnectionTicker.stop(); tmrWiFiMaintainConnection.stop();
Serial.println("WiFi AP started, stopped Maintain-Timer"); Serial.println("WiFi AP started, stopped Maintain-Timer");
#else #else
Serial.println("WiFi AP started"); Serial.println("WiFi AP started");
@@ -504,10 +514,12 @@ void SetBatteryType(batteryType_t type)
} }
} }
void OverrideDisplay(const char *message, uint32_t time) void OverrideDisplay(uint32_t time, const char *message1, const char *message2, const char *message3)
{ {
DisplayOverrideFlag = millis() + time; DisplayOverrideFlag = millis() + time;
strcpy(DisplayOverrideValue, message); strcpy(DisplayOverrideValue[0], message1);
strcpy(DisplayOverrideValue[1], message2);
strcpy(DisplayOverrideValue[2], message3);
} }
void ProcessKeyCombos(bool *btnState) void ProcessKeyCombos(bool *btnState)
@@ -552,20 +564,20 @@ void ProcessKeyCombos(bool *btnState)
if (btnState[0] != FAC_1_TRG_PRESSED && keyStatus_Fac1 == KEY_PRESSED) if (btnState[0] != FAC_1_TRG_PRESSED && keyStatus_Fac1 == KEY_PRESSED)
{ {
if (keyCount_Fac2 > 0 || keyCount_Fac3 > 0) if (keyCount_Fac2 > 0 || keyCount_Fac3 > 0)
Serial.printf("KeyCombo 2: %d | 3: %d\n", keyCount_Fac2, keyCount_Fac3); Debug_pushMessage("KeyCombo 2: %d | 3: %d\n", keyCount_Fac2, keyCount_Fac3);
if (keyCount_Fac2 == 2 && keyCount_Fac3 == 0) if (keyCount_Fac2 == 2 && keyCount_Fac3 == 0)
{ {
Serial.println("KeyCombo: WiFi AP ON"); Debug_pushMessage("KeyCombo: WiFi AP ON");
OverrideDisplay("NET ", 5000); OverrideDisplay(5000, "NET ", " ", " ");
toggleWiFiAP(false); toggleWiFiAP(false);
} }
else if (keyCount_Fac2 == 4 && keyCount_Fac3 == 0) else if (keyCount_Fac2 == 4 && keyCount_Fac3 == 0)
{ {
Serial.printf("KeyCombo: Reset Timer\n"); Debug_pushMessage("KeyCombo: Reset Timer\n");
if (millis() < RESETABLE_AFTER_STARTUP_MS) if (globals.systemStatus == sysStat_Startup)
{ {
OverrideDisplay("RST ", 5000); OverrideDisplay(5000, "RST ", " ", " ");
PersistenceData.faction_1_timer = 0; PersistenceData.faction_1_timer = 0;
PersistenceData.faction_2_timer = 0; PersistenceData.faction_2_timer = 0;
PersistenceData.faction_3_timer = 0; PersistenceData.faction_3_timer = 0;
@@ -574,8 +586,8 @@ void ProcessKeyCombos(bool *btnState)
} }
else else
{ {
OverrideDisplay("ERR ", 5000); OverrideDisplay(5000, "ERR ", " ", " ");
Serial.printf("ERROR: only %d seconds after Startup!\n", RESETABLE_AFTER_STARTUP_MS / 1000); Debug_pushMessage("ERROR: only %d seconds after Startup!\n", STARTUP_DELAY_MS / 1000);
} }
} }
@@ -585,4 +597,52 @@ void ProcessKeyCombos(bool *btnState)
keyStatus_Fac2 = KEY_RELEASED; keyStatus_Fac2 = KEY_RELEASED;
keyStatus_Fac3 = KEY_RELEASED; keyStatus_Fac3 = KEY_RELEASED;
} }
}
void maintainSysStat()
{
static tSystem_Status lastStat = sysStat_null;
// system Status Transistions
switch (globals.systemStatus)
{
case sysStat_Shutdown:
SystemShutdown();
break;
case sysStat_Startup:
if (millis() > STARTUP_DELAY_MS)
globals.systemStatus = sysStat_Normal;
break;
case sysStat_Error:
case sysStat_Normal:
case sysStat_null:
default:
break;
}
// system Status Changed Actions
if (lastStat != globals.systemStatus)
{
switch (globals.systemStatus)
{
case sysStat_Shutdown:
OverrideDisplay(SHUTDOWN_DELAY_MS, " re", "boot", " ");
break;
case sysStat_Startup:
OverrideDisplay(STARTUP_DELAY_MS, "star", "t up", " ");
break;
case sysStat_Error:
case sysStat_Normal:
case sysStat_null:
default:
break;
}
lastStat = globals.systemStatus;
}
} }

View File

@@ -33,10 +33,10 @@ void OLED_Process()
display.setCursor(0, 0); display.setCursor(0, 0);
display.printf("LiPo: %d%%\n", globals.battery_level); display.printf("LiPo: %d%%\n", globals.battery_level);
display.print(PersistenceData.activeFaction == FACTION_1 ? "> " : " "); display.print(PersistenceData.activeFaction == FACTION_1 ? "> " : " ");
display.printf("%-5s: %02d:%02d:%02d\n", FACTION_1_NAME, PersistenceData.faction_1_timer / 3600, (PersistenceData.faction_1_timer / 60) % 60, PersistenceData.faction_1_timer % 60); display.printf("%-5s: %02d:%02d:%02d\n", PersistenceData.faction_1_timer, PersistenceData.faction_1_timer / 3600, (PersistenceData.faction_1_timer / 60) % 60, PersistenceData.faction_1_timer % 60);
display.print(PersistenceData.activeFaction == FACTION_2 ? "> " : " "); display.print(PersistenceData.activeFaction == FACTION_2 ? "> " : " ");
display.printf("%-5s: %02d:%02d:%02d\n", FACTION_2_NAME, PersistenceData.faction_2_timer / 3600, (PersistenceData.faction_2_timer / 60) % 60, PersistenceData.faction_2_timer % 60); display.printf("%-5s: %02d:%02d:%02d\n", PersistenceData.faction_2_timer, PersistenceData.faction_2_timer / 3600, (PersistenceData.faction_2_timer / 60) % 60, PersistenceData.faction_2_timer % 60);
display.print(PersistenceData.activeFaction == FACTION_3 ? "> " : " "); display.print(PersistenceData.activeFaction == FACTION_3 ? "> " : " ");
display.printf("%-5s: %02d:%02d:%02d\n", FACTION_3_NAME, PersistenceData.faction_3_timer / 3600, (PersistenceData.faction_3_timer / 60) % 60, PersistenceData.faction_3_timer % 60); display.printf("%-5s: %02d:%02d:%02d\n", PersistenceData.faction_3_timer, PersistenceData.faction_3_timer / 3600, (PersistenceData.faction_3_timer / 60) % 60, PersistenceData.faction_3_timer % 60);
display.display(); display.display();
} }

View File

@@ -66,7 +66,7 @@ String processor(const String &var)
if (var == "HOSTNAME") if (var == "HOSTNAME")
return String(globals.DeviceName); return String(globals.DeviceName);
if (var == "SYSTEM_STATUS") if (var == "SYSTEM_STATUS")
return String(globals.systemStatustxt); return String(sSystem_Status_txt[globals.systemStatus]);
if (var == "SW_VERSION") if (var == "SW_VERSION")
{ {
char buffer[6]; char buffer[6];
@@ -84,6 +84,8 @@ String processor(const String &var)
return String(globals.battery_level); return String(globals.battery_level);
if (var == "DEVICENAME") if (var == "DEVICENAME")
return String(globals.DeviceName); return String(globals.DeviceName);
if (var == "DEVICENAME_ID")
return String(globals.DeviceName_ID);
if (var == "BATTERY_TYPE") if (var == "BATTERY_TYPE")
return String(ConfigData.batteryType); return String(ConfigData.batteryType);
if (var == "BAT_VOLTAGE") if (var == "BAT_VOLTAGE")
@@ -177,23 +179,24 @@ String processor(const String &var)
return String(buff); return String(buff);
} }
if (var == "STATUS_FAC_1") if (var == "ACTIVE_FACTION")
return PersistenceData.activeFaction == FACTION_1 ? "ACTIVE" : "INACTIVE"; return String(PersistenceData.activeFaction);
if (var == "STATUS_FAC_2") if (var == "FACTION_1_ACTIVE")
return PersistenceData.activeFaction == FACTION_2 ? "ACTIVE" : "INACTIVE"; return String(PersistenceData.activeFaction == FACTION_1 ? "bg-primary" : "bg-secondary");
if (var == "FACTION_2_ACTIVE")
if (var == "STATUS_FAC_3") return String(PersistenceData.activeFaction == FACTION_2 ? "bg-primary" : "bg-secondary");
return PersistenceData.activeFaction == FACTION_3 ? "ACTIVE" : "INACTIVE"; if (var == "FACTION_3_ACTIVE")
return String(PersistenceData.activeFaction == FACTION_3 ? "bg-primary" : "bg-secondary");
if (var == "NAME_FAC_1") if (var == "NAME_FAC_1")
return FACTION_1_NAME; return String(ConfigData.Faction_1_Name);
if (var == "NAME_FAC_2") if (var == "NAME_FAC_2")
return FACTION_2_NAME; return String(ConfigData.Faction_2_Name);
if (var == "NAME_FAC_3") if (var == "NAME_FAC_3")
return FACTION_3_NAME; return String(ConfigData.Faction_3_Name);
if (var == "BATTERY_SELECT_OPTIONS") if (var == "BATTERY_SELECT_OPTIONS")
{ {
@@ -206,6 +209,12 @@ String processor(const String &var)
return temp; return temp;
} }
if (var == "FACTIONREBOOT_CHECKED")
return String(ConfigData.active_faction_on_reboot == true ? "checked" : "");
if (var == "FACTION_RECOVERY")
return String(ConfigData.active_faction_on_reboot);
return String(); return String();
} }
@@ -225,8 +234,68 @@ void WebserverPOST_Callback(AsyncWebServerRequest *request)
AsyncWebParameter *p = request->getParam(i); AsyncWebParameter *p = request->getParam(i);
Debug_pushMessage("%s : %s\n", p->name().c_str(), p->value().c_str()); Debug_pushMessage("%s : %s\n", p->name().c_str(), p->value().c_str());
// begin: POST Form Maintenance
if (p->name() == "reset_ee_btn")
{
if (request->hasParam("reset_ee_pds", true))
{
AsyncWebParameter *param = request->getParam("reset_ee_pds", true);
if (param->value() == "on")
globals.requestEEAction = globals.requestEEAction == EE_CFG_FORMAT ? EE_FORMAT_ALL : EE_PDS_FORMAT;
}
if (request->hasParam("reset_ee_cfg", true))
{
AsyncWebParameter *param = request->getParam("reset_ee_cfg", true);
if (param->value() == "on")
globals.requestEEAction = globals.requestEEAction == EE_PDS_FORMAT ? EE_FORMAT_ALL : EE_CFG_FORMAT;
}
}
if (p->name() == "reboot")
{
globals.systemStatus = sysStat_Shutdown;
}
if (p->name() == "resetpoints")
{
PersistenceData.faction_1_timer = 0;
PersistenceData.faction_2_timer = 0;
PersistenceData.faction_3_timer = 0;
PersistenceData.activeFaction = NONE;
globals.requestEEAction == EE_PDS_SAVE;
}
// end: POST Form Maintenance
// begin: POST Form Settings // begin: POST Form Settings
if (p->name() == "cmdsubmit") if (p->name() == "battery_select")
{
batteryType_t temp = (batteryType_t)p->value().toInt();
ConfigData.batteryType = temp;
}
if (request->hasParam("factionreboot_cont", true))
{
AsyncWebParameter *param = request->getParam("factionreboot_cont", true);
if (param->value() == "on")
ConfigData.active_faction_on_reboot = true;
}
else
{
ConfigData.active_faction_on_reboot = false;
}
if (p->name() == "faction_1_name")
{
strncpy(ConfigData.Faction_1_Name, p->value().c_str(), sizeof(ConfigData.Faction_1_Name));
}
if (p->name() == "faction_2_name")
{
strncpy(ConfigData.Faction_2_Name, p->value().c_str(), sizeof(ConfigData.Faction_2_Name));
}
if (p->name() == "faction_3_name")
{
strncpy(ConfigData.Faction_3_Name, p->value().c_str(), sizeof(ConfigData.Faction_3_Name));
}
if (p->name() == "settingssave")
globals.requestEEAction = EE_CFG_SAVE; globals.requestEEAction = EE_CFG_SAVE;
// end: POST Form Settings // end: POST Form Settings
} }
@@ -338,6 +407,9 @@ void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &f
ConfigData.batteryType = (batteryType_t)doc["config"]["batteryType"].as<uint32_t>(); ConfigData.batteryType = (batteryType_t)doc["config"]["batteryType"].as<uint32_t>();
ConfigData.EEPROM_Version = doc["config"]["EEPROM_Version"].as<uint32_t>(); ConfigData.EEPROM_Version = doc["config"]["EEPROM_Version"].as<uint32_t>();
strncpy(ConfigData.Faction_1_Name, doc["config"]["Faction_1_Name"].as<String>().c_str(), sizeof(ConfigData.Faction_1_Name));
strncpy(ConfigData.Faction_2_Name, doc["config"]["Faction_2_Name"].as<String>().c_str(), sizeof(ConfigData.Faction_2_Name));
strncpy(ConfigData.Faction_3_Name, doc["config"]["Faction_3_Name"].as<String>().c_str(), sizeof(ConfigData.Faction_3_Name));
PersistenceData.writeCycleCounter = doc["persis"]["writeCycleCounter"].as<uint16_t>(); PersistenceData.writeCycleCounter = doc["persis"]["writeCycleCounter"].as<uint16_t>();
PersistenceData.activeFaction = (factions_t)doc["persis"]["activeFaction"].as<uint32_t>(); PersistenceData.activeFaction = (factions_t)doc["persis"]["activeFaction"].as<uint32_t>();
@@ -387,6 +459,9 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
config["EEPROM_Version"] = ConfigData.EEPROM_Version; config["EEPROM_Version"] = ConfigData.EEPROM_Version;
config["batteryType"] = ConfigData.batteryType; config["batteryType"] = ConfigData.batteryType;
config["Faction_1_Name"] = ConfigData.Faction_1_Name;
config["Faction_2_Name"] = ConfigData.Faction_2_Name;
config["Faction_3_Name"] = ConfigData.Faction_3_Name;
sprintf(buffer, "0x%08X", ConfigData.checksum); sprintf(buffer, "0x%08X", ConfigData.checksum);
config["checksum"] = buffer; config["checksum"] = buffer;