Compare commits
4 Commits
eaf2ad4933
...
f52f4103f6
Author | SHA1 | Date | |
---|---|---|---|
f52f4103f6 | |||
62cc2bf982 | |||
e375fab048 | |||
16d6aee420 |
@ -12,7 +12,7 @@
|
||||
<script src="static/js/bootstrap.min.js"></script>
|
||||
<script src="static/js/websocket.js"></script>
|
||||
<script src="static/js/dtc_table.js"></script>
|
||||
<script src="static/js/script.js" type="text/javascript"></script>
|
||||
<script src="static/js/script.js"></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="static/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="static/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="static/img/favicon-16x16.png">
|
||||
@ -37,7 +37,6 @@
|
||||
<li class="nav-item"><a class="nav-link active" role="tab" data-toggle="tab" href="#tab_home">Home</a></li>
|
||||
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_maintenance">Wartung</a></li>
|
||||
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_source">Einstellungen</a></li>
|
||||
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_sysinfo">Systeminfo</a></li>
|
||||
<li class="nav-item"><a class="nav-link" role="tab" data-toggle="tab" href="#tab_fwupdate">Update</a></li>
|
||||
|
||||
</ul>
|
||||
@ -61,9 +60,9 @@
|
||||
<p>
|
||||
<h4>Tankinhalt verbleibend</h4>
|
||||
<div class="progress">
|
||||
<div class="progress-bar text-light" role="progressbar" aria-valuenow="%TANK_REMAIN_CAPACITY%"
|
||||
aria-valuemin="0" aria-valuemax="100" style="width: %TANK_REMAIN_CAPACITY%%">
|
||||
%TANK_REMAIN_CAPACITY%%
|
||||
<div id="tankremain" class="progress-bar text-light" role="progressbar" aria-valuenow="0"
|
||||
aria-valuemin="0" aria-valuemax="100" style="width: 0%">
|
||||
0
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
@ -159,7 +158,7 @@
|
||||
<label for="measuredpulses" class="control-label col-4">erfasste Pulse</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="measuredpulses" name="measuredpulses" value="%MEASURED_PULSES%" type="text" readonly
|
||||
<input id="measuredpulses" name="measuredpulses" value="0" type="text" readonly
|
||||
class="form-control">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">Pulse</span>
|
||||
@ -169,7 +168,7 @@
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col text-center">
|
||||
<button name="measurestartstop" type="submit" class="btn btn-outline-primary">%MEASURE_BTN%</button>
|
||||
<button name="measurestartstop" type="submit" class="btn btn-outline-primary">Start</button>
|
||||
<button name="measurereset" type="submit" class="btn btn-outline-primary ml-2">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -217,6 +216,21 @@
|
||||
</form>
|
||||
</p>
|
||||
<!-- Div Group EEPROM formatting -->
|
||||
<!-- Div Group LiveDebug -->
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Live Debug</h4>
|
||||
<div class="form-group row">
|
||||
<textarea class="form-control" spellcheck="false" id="livedebug-out" rows="3" readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col text-center">
|
||||
<button id="btn-ws-start" class="btn btn-outline-primary">Start</button>
|
||||
<button id="btn-ws-stop" class="btn btn-outline-primary ml-2">Stop</button>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
<!-- Div Group LiveDebug -->
|
||||
<!-- Div Group Device Reboot -->
|
||||
<hr />
|
||||
<p>
|
||||
@ -244,8 +258,7 @@
|
||||
<div class="form-group row">
|
||||
<label for="sourceselect" class="control-label col-4">Schnittstelle</label>
|
||||
<div class="col-8">
|
||||
<select id="sourceselect" name="sourceselect" class="select form-control">
|
||||
%SOURCE_SELECT_OPTIONS%
|
||||
<select id="sourceselect" name="sourceselect" class="select form-control">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -266,7 +279,7 @@
|
||||
</p>
|
||||
<!-- Div Group Signal Source -->
|
||||
<!-- Div Group Source:Impulse Settings-->
|
||||
<div %SHOW_IMPULSE_SETTINGS%>
|
||||
<div id="showimpulse" class="removeable">
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Einstellungen Impulseingang</h4>
|
||||
@ -276,8 +289,7 @@
|
||||
<label for="tirewidth" class="control-label col-4">Reifenbreite</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="tirewidth" name="tirewidth" type="text" required="required" class="form-control"
|
||||
value="%TIRE_WIDTH_MM%">
|
||||
<input id="tirewidth" name="tirewidth" type="text" required="required" class="form-control">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">mm</span>
|
||||
</div>
|
||||
@ -289,8 +301,7 @@
|
||||
<label for="tireratio" class="control-label col-4">Höhe/Breite-Verhältniss</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="tireratio" name="tireratio" type="text" required="required" class="form-control"
|
||||
value="%TIRE_RATIO%">
|
||||
<input id="tireratio" name="tireratio" type="text" required="required" class="form-control">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">mm</span>
|
||||
</div>
|
||||
@ -301,8 +312,7 @@
|
||||
<label for="tiredia" class="control-label col-4">Felgendurchmesser</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="tiredia" name="tiredia" type="text" required="required" class="form-control"
|
||||
value="%RIM_DIAMETER%">
|
||||
<input id="tiredia" name="tiredia" type="text" required="required" class="form-control">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">"</span>
|
||||
</div>
|
||||
@ -313,8 +323,7 @@
|
||||
<label for="pulserev" class="control-label col-4">Pulse pro Umdrehung</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="pulserev" name="pulserev" type="text" required="required" class="form-control"
|
||||
value="%PULSE_PER_REV%">
|
||||
<input id="pulserev" name="pulserev" type="text" required="required" class="form-control">
|
||||
<div class="input-group-addon"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -329,7 +338,7 @@
|
||||
</div>
|
||||
<!-- Div Group Source:Impulse Settings-->
|
||||
<!-- Div Group Source:CAN Settings-->
|
||||
<div %SHOW_CAN_SETTINGS%>
|
||||
<div id="showcan" class="removeable">
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Einstellungen CAN-Bus</h4>
|
||||
@ -338,7 +347,6 @@
|
||||
<label for="cansource" class="control-label col-4">Model</label>
|
||||
<div class="col-8">
|
||||
<select id="cansource" name="cansource" class="select form-control">
|
||||
%CANSOURCE_SELECT_OPTIONS%
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -352,7 +360,7 @@
|
||||
</div>
|
||||
<!-- Div Group Source:CAN Settings-->
|
||||
<!-- Div Group Source:GPS Settings-->
|
||||
<div %SHOW_GPS_SETTINGS%>
|
||||
<div id="showgps" class="removeable">
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Einstellungen GPS</h4>
|
||||
@ -361,7 +369,6 @@
|
||||
<label for="gpsbaud" class="control-label col-4">Baudrate</label>
|
||||
<div class="col-8">
|
||||
<select id="gpsbaud" name="gpsbaud" class="select form-control">
|
||||
%GPSBAUD_SELECT_OPTIONS%
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -383,7 +390,7 @@
|
||||
<label for="lubedistancenormal" class="control-label col-4">Normal (grün)</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="lubedistancenormal" name="lubedistancenormal" value="%LUBE_DISTANCE_NORMAL%" type="text"
|
||||
<input id="lubedistancenormal" name="lubedistancenormal" type="text"
|
||||
class="form-control" required="required">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">m</span>
|
||||
@ -395,7 +402,7 @@
|
||||
<label for="lubedistancerain" class="control-label col-4">Regen (blau)</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="lubedistancerain" name="lubedistancerain" value="%LUBE_DISTANCE_RAIN%" type="text"
|
||||
<input id="lubedistancerain" name="lubedistancerain" type="text"
|
||||
class="form-control" required="required">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">m</span>
|
||||
@ -420,7 +427,7 @@
|
||||
<label for="tankcap" class="control-label col-4">Tankkapazität</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="tankcap" name="tankcap" value="%TANK_CAPACITY%" type="text" class="form-control"
|
||||
<input id="tankcap" name="tankcap" type="text" class="form-control"
|
||||
required="required">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">ml</span>
|
||||
@ -432,7 +439,7 @@
|
||||
<label for="tankwarn" class="control-label col-4">Leer-Warnung</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="tankwarn" name="tankwarn" value="%TANK_REMIND%" type="text" class="form-control"
|
||||
<input id="tankwarn" name="tankwarn" type="text" class="form-control"
|
||||
required="required">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%</span>
|
||||
@ -444,7 +451,7 @@
|
||||
<label for="pumppulse" class="control-label col-4">Menge pro Puls</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="pumppulse" name="pumppulse" value="%AMOUNT_PER_DOSE%" type="text" class="form-control"
|
||||
<input id="pumppulse" name="pumppulse" type="text" class="form-control"
|
||||
required="required">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">µl</span>
|
||||
@ -469,7 +476,7 @@
|
||||
<label for="ledmodeflash" class="control-label col-4">LED Modus blinken</label>
|
||||
<div class="col-8">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="ledmodeflash" id="ledmodeflash" %LEDFLASHCHECKED%>
|
||||
<input class="form-check-input" type="checkbox" name="ledmodeflash" id="ledmodeflash">
|
||||
<label class="form-check-label" for="ledmodeflash">
|
||||
LED blinken
|
||||
</label>
|
||||
@ -480,7 +487,7 @@
|
||||
<label for="ledmaxbrightness" class="control-label col-4">Max Helligkeit</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="ledmaxbrightness" name="ledmaxbrightness" value="%LED_MAX_BRIGHTNESS%" type="text"
|
||||
<input id="ledmaxbrightness" name="ledmaxbrightness" type="text"
|
||||
class="form-control" required="required">
|
||||
</div>
|
||||
</div>
|
||||
@ -489,7 +496,7 @@
|
||||
<label for="ledminbrightness" class="control-label col-4">Min Helligkeit</label>
|
||||
<div class="col-8">
|
||||
<div class="input-group">
|
||||
<input id="ledminbrightness" name="ledminbrightness" value="%LED_MIN_BRIGHTNESS%" type="text"
|
||||
<input id="ledminbrightness" name="ledminbrightness" type="text"
|
||||
class="form-control" required="required">
|
||||
</div>
|
||||
</div>
|
||||
@ -505,171 +512,6 @@
|
||||
</div>
|
||||
<!-- Div Tab Settings -->
|
||||
|
||||
<!-- Div Tab SystemInfo -->
|
||||
<div id="tab_sysinfo" class="tab-pane fade" role="tabpanel">
|
||||
<h3>Systeminfo</h3>
|
||||
<!-- Div Group Sysinfo:Geraeteinfo -->
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Gerät</h4>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="col-7" scope="col">Parameter</td>
|
||||
<th class="col-5" scope="col">Value</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hostname</td>
|
||||
<td>%HOSTNAME%</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<!-- Div Group Sysinfo:Geraeteinfo -->
|
||||
<!-- Div Group Sysinfo:Settings -->
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Einstellungen</h4>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="col-7" scope="col">Parameter</td>
|
||||
<th class="col-5" scope="col">Value</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DistancePerLube_Default</td>
|
||||
<td>%LUBE_DISTANCE_NORMAL%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DistancePerLube_Rain</td>
|
||||
<td>%LUBE_DISTANCE_RAIN%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tankCapacity_ml</td>
|
||||
<td>%TANK_CAPACITY%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>amountPerDose_µl</td>
|
||||
<td>%AMOUNT_PER_DOSE%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TankRemindAtPercentage</td>
|
||||
<td>%TANK_REMIND%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PulsePerRevolution</td>
|
||||
<td>%PULSE_PER_REV%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TireWidth_mm</td>
|
||||
<td>%TIRE_WIDTH_MM%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TireWidthHeight_Ratio</td>
|
||||
<td>%TIRE_RATIO%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RimDiameter_Inch</td>
|
||||
<td>%RIM_DIAMETER%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DistancePerRevolution_mm</td>
|
||||
<td>%DISTANCE_PER_REV%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BleedingPulses</td>
|
||||
<td>%BLEEDING_PULSES%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SpeedSource</td>
|
||||
<td>%SPEED_SOURCE%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GPSBaudRate</td>
|
||||
<td>%GPS_BAUD%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CANSource</td>
|
||||
<td>%CAN_SOURCE%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LED Mode Flash</td>
|
||||
<td>%LED_MODE_FLASH%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LED Max Brightness</td>
|
||||
<td>%LED_MAX_BRIGHTNESS%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LED Min Brightness</td>
|
||||
<td>%LED_MIN_BRIGHTNESS%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EEPROM Version</td>
|
||||
<td>%EEPROM_VERSION%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Checksum</td>
|
||||
<td>%CONFIG_CHECKSUM%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
<!-- Div Group Sysinfo:Settings -->
|
||||
<!-- Div Group Sysinfo:Persistance -->
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Betriebsdaten</h4>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="col-7" scope="col">Parameter</td>
|
||||
<th class="col-5" scope="col">Value</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>writeCycleCounter</td>
|
||||
<td>%WRITE_CYCLE_COUNT%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>PersistenceMarker</td>
|
||||
<td>%PERSISTENCE_MARKER%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>tankRemain_µl</td>
|
||||
<td>%TANK_REMAIN_UL%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TravelDistance_highRes</td>
|
||||
<td>%TRAVEL_DISTANCE_HIGHRES%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Odometer</td>
|
||||
<td>%ODOMETER%,%ODOMETER_M%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>checksum</td>
|
||||
<td>%PERSISTANCE_CHECKSUM%</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<!-- Div Group Sysinfo:Persistance -->
|
||||
<!-- Div Group LiveDebug -->
|
||||
<hr />
|
||||
<p>
|
||||
<h4>Live Debug</h4>
|
||||
<div class="form-group row">
|
||||
<textarea class="form-control" spellcheck="false" id="livedebug-out" rows="3" readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col text-center">
|
||||
<button id="btn-ws-start" class="btn btn-outline-primary">Start</button>
|
||||
<button id="btn-ws-stop" class="btn btn-outline-primary ml-2">Stop</button>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
<!-- Div Group LiveDebug -->
|
||||
</div>
|
||||
<!-- Div Tab SystemInfo -->
|
||||
|
||||
<!-- Div Tab Firmware Update-->
|
||||
<div id="tab_fwupdate" class="tab-pane fade" role="tabpanel">
|
||||
<h3>Firmware</h3>
|
||||
|
@ -71,7 +71,7 @@ function onMessage(event) {
|
||||
const result = processDataString(data_sliced, statusMapping);
|
||||
console.log("STATUS:");
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
fillValuestoHTML(result);
|
||||
fillValuesToHTML(result);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ function onMessage(event) {
|
||||
const result = processDataString(data_sliced, staticMapping);
|
||||
console.log("STATIC:");
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
fillValuestoHTML(result);
|
||||
fillValuesToHTML(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -139,11 +139,47 @@ function do_resize(textbox) {
|
||||
else textbox.rows = rows;
|
||||
}
|
||||
|
||||
function fillValuestoHTML(dataset) {
|
||||
function fillValuesToHTML(dataset) {
|
||||
for (var key in dataset) {
|
||||
var inputElement = document.getElementById(key);
|
||||
if (inputElement) {
|
||||
inputElement.value = dataset[key];
|
||||
var element = document.getElementById(key);
|
||||
|
||||
if (element) {
|
||||
if (element.type === "checkbox") {
|
||||
// Wenn das Element ein Kontrollkästchen ist
|
||||
element.checked = dataset[key] == 1 ? true : false;
|
||||
} else if (element.tagName === "SELECT") {
|
||||
// Wenn das Element ein Dropdown ist
|
||||
setDropdownValue(element, dataset[key]);
|
||||
} else if (element.classList.contains("progress-bar")) {
|
||||
// Wenn das Element eine Fortschrittsleiste ist
|
||||
updateProgressBar(element, dataset[key]);
|
||||
} else if (element.classList.contains("removeable")) {
|
||||
// Wenn das Element ein Settingsabschnitt-div ist
|
||||
if (dataset[key] == 0) element.remove();
|
||||
} else {
|
||||
// Standardmäßig für Textfelder und andere Elemente
|
||||
element.value = dataset[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Setzen des ausgewählten Werts für Dropdowns
|
||||
function setDropdownValue(selectElement, value) {
|
||||
for (var i = 0; i < selectElement.options.length; i++) {
|
||||
if (selectElement.options[i].value === value) {
|
||||
selectElement.selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Aktualisieren der Fortschrittsleiste
|
||||
function updateProgressBar(progressBar, value) {
|
||||
// Wert in das aria-valuenow-Attribut einfügen
|
||||
progressBar.setAttribute("aria-valuenow", value);
|
||||
|
||||
// Breite des Fortschrittsbalkens und inneren Text aktualisieren
|
||||
progressBar.style.width = value + "%";
|
||||
progressBar.textContent = value + "%";
|
||||
}
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file can.h
|
||||
*
|
||||
* @brief Header file for Controller Area Network (CAN) functionality in the ChainLube application.
|
||||
*
|
||||
* This file provides functions and structures related to Controller Area Network (CAN)
|
||||
* communication for the ChainLube project. It includes functions for initializing CAN,
|
||||
* processing CAN messages, and retrieving wheel speed from CAN data.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _CAN_H_
|
||||
#define _CAN_H_
|
||||
|
||||
@ -9,6 +22,7 @@
|
||||
#include "dtc.h"
|
||||
#include "debugger.h"
|
||||
|
||||
// CAN frame structure definition
|
||||
struct can_frame
|
||||
{
|
||||
unsigned long can_id;
|
||||
@ -16,8 +30,9 @@ struct can_frame
|
||||
uint8_t data[8] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
// Function prototypes
|
||||
void Init_CAN();
|
||||
void CAN_Process();
|
||||
uint32_t Process_CAN_WheelSpeed();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file common.h
|
||||
*
|
||||
* @brief Header file for common definitions and macros in the ChainLube application.
|
||||
*
|
||||
* This file defines common macros, GPIO configurations, and other shared constants
|
||||
* for the ChainLube project. It includes definitions for GPIO pins, OTA delays, pulse lengths,
|
||||
* and other common settings used across the project.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
@ -5,6 +18,7 @@
|
||||
#define QUOTE(x) Q(x)
|
||||
#define SET_BIT(value, bitPosition) ((value) |= (1U << (bitPosition)))
|
||||
|
||||
// Conditional compilation based on PCB revision
|
||||
#if PCB_REV == 1
|
||||
#define GPIO_BUTTON D7
|
||||
#define GPIO_LED D8
|
||||
@ -40,17 +54,17 @@
|
||||
#define LUBE_PULSE_LENGHT_MS 160
|
||||
#define LUBE_PULSE_PAUSE_MS 340
|
||||
|
||||
// Pump pulse parameters
|
||||
// -> 2Hz PumpPulse
|
||||
// -> 49,7cc / h @ 2Hz
|
||||
// -> 49,7 ml / h @ 2Hz
|
||||
// -> 828,4µl / min @ 2Hz
|
||||
// -> 828,3µl / 60s
|
||||
// -> 13,81µl / 1s
|
||||
// -> 6,90µl / Pulse
|
||||
|
||||
// -> 49.7cc / h @ 2Hz
|
||||
// -> 49.7 ml / h @ 2Hz
|
||||
// -> 828.4µl / min @ 2Hz
|
||||
// -> 828.3µl / 60s
|
||||
// -> 13.81µl / 1s
|
||||
// -> 6.90µl / Pulse
|
||||
#define DEFAULT_PUMP_DOSE 7
|
||||
|
||||
#define STARTUP_DELAY 5000
|
||||
#define SHUTDOWN_DELAY_MS 5000
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,3 +1,17 @@
|
||||
/**
|
||||
* @file config.h
|
||||
*
|
||||
* @brief Header file for configuration settings and EEPROM operations in the ChainLube application.
|
||||
*
|
||||
* This file defines configuration settings for the ChainLube project, including default values,
|
||||
* EEPROM structures, and functions for EEPROM operations. It also defines enums for different sources
|
||||
* of speed input, GPS baud rates, and CAN bus sources. Additionally, it includes functions for EEPROM handling
|
||||
* such as storing, retrieving, and formatting configuration data.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
@ -14,6 +28,7 @@
|
||||
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC256
|
||||
#endif
|
||||
|
||||
// Enum for different sources of speed input
|
||||
typedef enum SpeedSource_e
|
||||
{
|
||||
#ifdef FEATURE_ENABLE_TIMER
|
||||
@ -24,6 +39,7 @@ typedef enum SpeedSource_e
|
||||
SOURCE_CAN
|
||||
} SpeedSource_t;
|
||||
|
||||
// String representation of SpeedSource enum
|
||||
const char SpeedSourceString[][8] = {
|
||||
#ifdef FEATURE_ENABLE_TIMER
|
||||
"Timer",
|
||||
@ -33,32 +49,37 @@ const char SpeedSourceString[][8] = {
|
||||
"CAN-Bus"
|
||||
};
|
||||
|
||||
const size_t SpeedSourceString_Elements = sizeof(SpeedSourceString) / sizeof(SpeedSourceString[0]);
|
||||
|
||||
// Enum for GPS baud rates
|
||||
typedef enum GPSBaudRate_e
|
||||
{
|
||||
BAUD_9600,
|
||||
BAUD_115200
|
||||
} GPSBaudRate_t;
|
||||
|
||||
// String representation of GPSBaudRate enum
|
||||
const char GPSBaudRateString[][7] = {
|
||||
"9600",
|
||||
"115200"};
|
||||
|
||||
const size_t GPSBaudRateString_Elements = sizeof(GPSBaudRateString) / sizeof(GPSBaudRateString[0]);
|
||||
|
||||
// Enum for CAN bus sources
|
||||
typedef enum CANSource_e
|
||||
{
|
||||
KTM_890_ADV_R_2021,
|
||||
KTM_1290_SD_R_2023
|
||||
} CANSource_t;
|
||||
|
||||
// String representation of CANSource enum
|
||||
const char CANSourceString[][30] = {
|
||||
"KTM 890 Adventure R (2021)",
|
||||
"KTM 1290 Superduke R (2023)"};
|
||||
|
||||
const size_t CANSourceString_Elements = sizeof(CANSourceString) / sizeof(CANSourceString[0]);
|
||||
|
||||
const size_t SpeedSourceString_Elements = sizeof(SpeedSourceString) / sizeof(SpeedSourceString[0]);
|
||||
|
||||
// Structure for persistence data stored in EEPROM
|
||||
typedef struct
|
||||
{
|
||||
uint16_t writeCycleCounter = 0;
|
||||
@ -69,6 +90,7 @@ typedef struct
|
||||
uint32_t checksum = 0;
|
||||
} persistenceData_t;
|
||||
|
||||
// Structure for configuration settings stored in EEPROM
|
||||
typedef struct
|
||||
{
|
||||
uint8_t EEPROM_Version = 0;
|
||||
@ -92,6 +114,7 @@ typedef struct
|
||||
uint32_t checksum = 0;
|
||||
} LubeConfig_t;
|
||||
|
||||
// Default configuration settings
|
||||
const LubeConfig_t LubeConfig_defaults = {
|
||||
0, 8000, 4000, 320, DEFAULT_PUMP_DOSE, 30, 1, 150, 70, 18, 2000, 25, SOURCE_IMPULSE,
|
||||
BAUD_115200,
|
||||
@ -117,4 +140,4 @@ uint32_t ConfigSanityCheck(bool autocorrect = false);
|
||||
extern LubeConfig_t LubeConfig;
|
||||
extern persistenceData_t PersistenceData;
|
||||
extern uint16_t eePersistenceMarker;
|
||||
#endif // _CONFIG_H_
|
||||
#endif // _CONFIG_H_
|
||||
|
@ -1,9 +1,21 @@
|
||||
/**
|
||||
* @file debugger.h
|
||||
*
|
||||
* @brief Header file for debugging functions and status in the ChainLube application.
|
||||
*
|
||||
* This file declares functions and status definitions for debugging purposes in the ChainLube project.
|
||||
* It includes functions to print system information, WiFi information, format EEPROM data,
|
||||
* handle debug messages, and manage the status of different debug ports.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _DEBUGGER_H_
|
||||
#define _DEBUGGER_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "webui.h"
|
||||
|
||||
const char PROGMEM helpCmd[] = "sysinfo - System Info\n"
|
||||
"netinfo - WiFi Info\n"
|
||||
"formatPDS - Format Persistence EEPROM Data\n"
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file dtc.h
|
||||
*
|
||||
* @brief Header file for handling Diagnostic Trouble Codes (DTC) in the ChainLube application.
|
||||
*
|
||||
* This file provides definitions and functions for handling Diagnostic Trouble Codes (DTC)
|
||||
* in the ChainLube project. It includes structures for DTC entries, severity levels,
|
||||
* and functions for DTC maintenance and processing. DTCs are used to track system errors and issues.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _DTC_H_
|
||||
#define _DTC_H_
|
||||
|
||||
|
@ -1,4 +1,18 @@
|
||||
// Auto-generated by script on 2023-12-04 02:10:49
|
||||
/**
|
||||
* @file dtc_defs.h
|
||||
*
|
||||
* @brief Header file for Diagnostic Trouble Code (DTC) definitions in the ChainLube application.
|
||||
*
|
||||
* This file contains definitions for Diagnostic Trouble Codes (DTC) in the ChainLube project.
|
||||
* It includes enums for DTC active status, severity levels, and specific DTC codes.
|
||||
* The file also defines an array of DTC definitions and a timestamp indicating the generation time.
|
||||
*
|
||||
* @note This file is auto-generated by a script on 2024-01-09 12:08:43.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef DTC_DEFS_H
|
||||
#define DTC_DEFS_H
|
||||
|
||||
@ -66,6 +80,6 @@ const DTC_t dtc_definitions[] = {
|
||||
{ DTC_LAST_DTC , DTC_NONE } // Last Error
|
||||
};
|
||||
|
||||
const uint32_t dtc_generation_timestamp = 1701652249;
|
||||
const uint32_t dtc_generation_timestamp = 1704798523;
|
||||
|
||||
#endif // DTC_DEFS_H
|
@ -1,4 +1,18 @@
|
||||
// Auto-generated by script on {{ timestamp }}
|
||||
/**
|
||||
* @file dtc_defs.h
|
||||
*
|
||||
* @brief Header file for Diagnostic Trouble Code (DTC) definitions in the ChainLube application.
|
||||
*
|
||||
* This file contains definitions for Diagnostic Trouble Codes (DTC) in the ChainLube project.
|
||||
* It includes enums for DTC active status, severity levels, and specific DTC codes.
|
||||
* The file also defines an array of DTC definitions and a timestamp indicating the generation time.
|
||||
*
|
||||
* @note This file is auto-generated by a script on {{ timestamp }}.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef DTC_DEFS_H
|
||||
#define DTC_DEFS_H
|
||||
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file globals.h
|
||||
*
|
||||
* @brief Header file for global variables and enums in the ChainLube application.
|
||||
*
|
||||
* This file contains declarations for global variables and enums used in the ChainLube application.
|
||||
* It includes enums for system status and EEPROM-related requests, as well as a struct for global variables.
|
||||
* The file also defines a struct for constants and initializes it with firmware and required flash version information.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _GLOBALS_H_
|
||||
#define _GLOBALS_H_
|
||||
|
||||
@ -29,29 +42,29 @@ typedef enum eEERequest
|
||||
|
||||
typedef struct Globals_s
|
||||
{
|
||||
tSystem_Status systemStatus = sysStat_Startup;
|
||||
tSystem_Status resumeStatus = sysStat_Startup;
|
||||
char systemStatustxt[16] = "";
|
||||
uint16_t purgePulses = 0;
|
||||
eEERequest requestEEAction = EE_IDLE;
|
||||
char DeviceName[33];
|
||||
char FlashVersion[10];
|
||||
uint16_t eePersistanceAdress;
|
||||
uint8_t TankPercentage;
|
||||
bool hasDTC;
|
||||
bool measurementActive;
|
||||
uint32_t measuredPulses;
|
||||
tSystem_Status systemStatus = sysStat_Startup; /**< Current system status */
|
||||
tSystem_Status resumeStatus = sysStat_Startup; /**< Status to resume after rain mode */
|
||||
char systemStatustxt[16] = ""; /**< Text representation of system status */
|
||||
uint16_t purgePulses = 0; /**< Number of purge pulses */
|
||||
eEERequest requestEEAction = EE_IDLE;; /**< EEPROM-related request */
|
||||
char DeviceName[33]; /**< Device name */
|
||||
char FlashVersion[10]; /**< Flash version */
|
||||
uint16_t eePersistanceAdress; /**< EEPROM persistence address */
|
||||
uint8_t TankPercentage; /**< Tank percentage */
|
||||
bool hasDTC; /**< Flag indicating the presence of Diagnostic Trouble Codes (DTC) */
|
||||
bool measurementActive; /**< Flag indicating active measurement */
|
||||
uint32_t measuredPulses; /**< Number of measured pulses */
|
||||
} Globals_t;
|
||||
|
||||
extern Globals_t globals;
|
||||
extern Globals_t globals; /**< Global variable struct */
|
||||
|
||||
typedef struct Constants_s
|
||||
{
|
||||
uint8_t FW_Version_major;
|
||||
uint8_t FW_Version_minor;
|
||||
uint8_t Required_Flash_Version_major;
|
||||
uint8_t Required_Flash_Version_minor;
|
||||
char GitHash[11];
|
||||
uint8_t FW_Version_major; /**< Firmware version major number */
|
||||
uint8_t FW_Version_minor; /**< Firmware version minor number */
|
||||
uint8_t Required_Flash_Version_major; /**< Required flash version major number */
|
||||
uint8_t Required_Flash_Version_minor; /**< Required flash version minor number */
|
||||
char GitHash[11]; /**< Git hash string */
|
||||
} Constants_t;
|
||||
|
||||
const Constants_t constants PROGMEM = {
|
||||
@ -60,6 +73,9 @@ const Constants_t constants PROGMEM = {
|
||||
GIT_REV // Git-Hash-String
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initializes global variables.
|
||||
*/
|
||||
void initGlobals();
|
||||
|
||||
#endif
|
||||
#endif // _GLOBALS_H_
|
||||
|
@ -1,3 +1,17 @@
|
||||
/**
|
||||
* @file gps.h
|
||||
*
|
||||
* @brief Header file for GPS-related functions in the ChainLube application.
|
||||
*
|
||||
* This file contains declarations for functions related to GPS (Global Positioning System) functionality
|
||||
* within the ChainLube application. It includes the initialization of the GPS module and processing of GPS
|
||||
* data to calculate wheel speed. Additionally, it references other necessary header files for configuration,
|
||||
* common definitions, diagnostics, and debugging.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _GPS_H_
|
||||
#define _GPS_H_
|
||||
|
||||
@ -7,7 +21,16 @@
|
||||
#include "dtc.h"
|
||||
#include "debugger.h"
|
||||
|
||||
/**
|
||||
* @brief Initializes the GPS module.
|
||||
*/
|
||||
void Init_GPS();
|
||||
|
||||
/**
|
||||
* @brief Processes GPS data to calculate wheel speed.
|
||||
*
|
||||
* @return Calculated wheel speed in millimeters per second.
|
||||
*/
|
||||
uint32_t Process_GPS_WheelSpeed();
|
||||
|
||||
#endif
|
||||
#endif // _GPS_H_
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file led_colors.h
|
||||
*
|
||||
* @brief Header file defining color values for LEDs in the ChainLube application.
|
||||
*
|
||||
* This file contains color definitions in hexadecimal format for various states and events of LEDs
|
||||
* used in the ChainLube application. It provides a convenient way to reference specific colors for
|
||||
* different visual indications in the system.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _LED_COLORS_H_
|
||||
#define _LED_COLORS_H_
|
||||
|
||||
@ -19,17 +32,14 @@
|
||||
#define COLOR_AMBER 0xFF6400
|
||||
#define COLOR_WARM_WHITE 0xFDF5E6
|
||||
|
||||
|
||||
#define LED_DEFAULT_COLOR COLOR_WARM_WHITE
|
||||
#define LED_STARTUP_NORMAL COLOR_WARM_WHITE
|
||||
#define LED_STARTUP_TANKWARN COLOR_AMBER
|
||||
#define LED_NORMAL_COLOR COLOR_GREEN
|
||||
#define LED_RAIN_COLOR COLOR_BLUE
|
||||
#define LED_NORMAL_COLOR COLOR_GREEN
|
||||
#define LED_RAIN_COLOR COLOR_BLUE
|
||||
#define LED_WIFI_BLINK COLOR_YELLOW
|
||||
#define LED_PURGE_COLOR COLOR_MAGENTA
|
||||
#define LED_ERROR_BLINK COLOR_RED
|
||||
#define LED_SHUTDOWN_BLINK COLOR_CYAN
|
||||
|
||||
|
||||
|
||||
#endif /* _LED_COLORS_H_ */
|
||||
|
@ -1,3 +1,15 @@
|
||||
/**
|
||||
* @file lubeapp.h
|
||||
*
|
||||
* @brief Header file for the ChainLube application functions.
|
||||
*
|
||||
* This file contains function declarations related to the main functionality of the ChainLube
|
||||
* application. It includes functions for running the application and generating lubrication pulses.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _LUBEAPP_H_
|
||||
#define _LUBEAPP_H_
|
||||
|
||||
@ -12,4 +24,4 @@
|
||||
void RunLubeApp(uint32_t add_milimeters);
|
||||
void LubePulse();
|
||||
|
||||
#endif
|
||||
#endif /* _LUBEAPP_H_ */
|
||||
|
@ -1,3 +1,15 @@
|
||||
/**
|
||||
* @file sanitycheck.h
|
||||
*
|
||||
* @brief Header file for sanity checks and configuration validation in the ChainLube application.
|
||||
*
|
||||
* This file contains checks and validations to ensure that the configuration and features of the
|
||||
* ChainLube application are compatible with the selected PCB revision and defined parameters.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _SANITYCHECK_H_
|
||||
#define _SANITYCHECK_H_
|
||||
|
||||
@ -34,4 +46,4 @@
|
||||
#error "You must define an WIFI_AP_PASSWORD for Standalone AP-Mode"
|
||||
#endif
|
||||
|
||||
#endif //_SANITYCHECK_H_
|
||||
#endif // _SANITYCHECK_H_
|
||||
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file webui.h
|
||||
*
|
||||
* @brief Header file for the web-based user interface (WebUI) in the ChainLube application.
|
||||
*
|
||||
* This file contains declarations for functions related to the initialization and processing of the
|
||||
* web-based user interface (WebUI). It includes the necessary libraries and dependencies for handling
|
||||
* web server functionality, asynchronous JSON operations, and live debugging through WebSockets.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#ifndef _WEBUI_H_
|
||||
#define _WEBUI_H_
|
||||
|
||||
@ -22,4 +35,4 @@ void Webserver_Process();
|
||||
|
||||
void Websocket_PushLiveDebug(String Message);
|
||||
|
||||
#endif
|
||||
#endif // _WEBUI_H_
|
||||
|
@ -1,3 +1,17 @@
|
||||
/**
|
||||
* @file can.cpp
|
||||
*
|
||||
* @brief Implementation file for CAN-related functions in the ChainLube application.
|
||||
*
|
||||
* This file contains the implementation of functions related to CAN (Controller Area Network)
|
||||
* communication within the ChainLube application. It includes the initialization of the CAN module,
|
||||
* setup of masks and filters, and processing of CAN messages. Additionally, a debug message function
|
||||
* is included if CAN debugging is enabled.
|
||||
*
|
||||
* @author Your Name
|
||||
* @date Date
|
||||
*/
|
||||
|
||||
#include "can.h"
|
||||
|
||||
MCP_CAN CAN0(GPIO_CS_CAN);
|
||||
@ -6,9 +20,14 @@ MCP_CAN CAN0(GPIO_CS_CAN);
|
||||
void sendCANDebugMessage();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initializes the CAN module, sets masks, and filters based on the configured CAN source.
|
||||
*
|
||||
* This function initializes the CAN module, sets masks and filters based on the configured CAN source
|
||||
* in the application settings, and sets the CAN module in normal mode for communication.
|
||||
*/
|
||||
void Init_CAN()
|
||||
{
|
||||
|
||||
if (CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ) != CAN_OK)
|
||||
MaintainDTC(DTC_CAN_TRANSCEIVER_FAILED, true);
|
||||
|
||||
@ -30,6 +49,11 @@ void Init_CAN()
|
||||
CAN0.setMode(MCP_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes CAN messages and sends a CAN debug message periodically.
|
||||
*
|
||||
* This function processes CAN messages and sends a CAN debug message periodically based on a time interval.
|
||||
*/
|
||||
void CAN_Process()
|
||||
{
|
||||
static uint32_t previousMillis = 0;
|
||||
@ -40,7 +64,15 @@ void CAN_Process()
|
||||
previousMillis = millis();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes CAN messages to determine the wheel speed based on the configured CAN source.
|
||||
*
|
||||
* This function reads incoming CAN messages and extracts the rear wheel speed information.
|
||||
* The wheel speed is then converted to millimeters per second based on the configured CAN source.
|
||||
* The function also monitors the CAN signal for potential issues and triggers diagnostic trouble codes (DTCs).
|
||||
*
|
||||
* @return The calculated distance traveled in millimeters since the last call.
|
||||
*/
|
||||
uint32_t Process_CAN_WheelSpeed()
|
||||
{
|
||||
#define FACTOR_RWP_KMH_890ADV 18 // Divider to convert Raw Data to km/h
|
||||
@ -87,6 +119,13 @@ uint32_t Process_CAN_WheelSpeed()
|
||||
}
|
||||
|
||||
#ifdef CAN_DEBUG_MESSAGE
|
||||
/**
|
||||
* @brief Sends periodic CAN debug messages for monitoring and diagnostics.
|
||||
*
|
||||
* This function sends periodic CAN debug messages containing various system information for monitoring and diagnostics.
|
||||
* The information includes system status, timestamps, tank percentage, DTC flags, and other relevant data.
|
||||
* The debug messages are sent with a configurable multiplexer to broadcast different types of information in each cycle.
|
||||
*/
|
||||
void sendCANDebugMessage()
|
||||
{
|
||||
#define MAX_DEBUG_MULTIPLEXER 6
|
||||
|
@ -1,24 +1,51 @@
|
||||
/**
|
||||
* @file config.cpp
|
||||
* @brief Implementation of EEPROM and configuration-related functions.
|
||||
*
|
||||
* This file contains functions for managing EEPROM storage and handling configuration data.
|
||||
* It includes the definitions of configuration structures, EEPROM access, and utility functions.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "debugger.h"
|
||||
|
||||
// Instance of I2C_eeprom for EEPROM access
|
||||
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES);
|
||||
|
||||
// Configuration and persistence data structures
|
||||
LubeConfig_t LubeConfig;
|
||||
persistenceData_t PersistenceData;
|
||||
const uint16_t eeVersion = 2; // inc
|
||||
|
||||
// EEPROM version identifier
|
||||
const uint16_t eeVersion = 2; // Increment this version when changing EEPROM structures
|
||||
|
||||
// Flag indicating whether EEPROM is available
|
||||
boolean eeAvailable = false;
|
||||
|
||||
// Offsets within EEPROM for LubeConfig and PersistenceData
|
||||
const uint16_t startofLubeConfig = 16;
|
||||
const uint16_t startofPersistence = 16 + sizeof(LubeConfig) + (sizeof(LubeConfig) % 16);
|
||||
|
||||
// Function prototype to check EEPROM availability
|
||||
boolean checkEEPROMavailable();
|
||||
|
||||
/**
|
||||
* @brief Initializes EEPROM and checks its availability.
|
||||
*
|
||||
* This function initializes the EEPROM using the I2C_eeprom instance and checks if it's available.
|
||||
*/
|
||||
void InitEEPROM()
|
||||
{
|
||||
ee.begin();
|
||||
checkEEPROMavailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes EEPROM actions based on the request from the global state.
|
||||
*
|
||||
* This function processes EEPROM actions based on the request from the global state.
|
||||
* It performs actions such as saving, loading, and formatting EEPROM data for both configuration and persistence.
|
||||
*/
|
||||
void EEPROM_Process()
|
||||
{
|
||||
switch (globals.requestEEAction)
|
||||
@ -37,7 +64,7 @@ void EEPROM_Process()
|
||||
FormatConfig_EEPROM();
|
||||
globals.requestEEAction = EE_IDLE;
|
||||
GetConfig_EEPROM();
|
||||
Debug_pushMessage("Formated EEPROM CFG\n");
|
||||
Debug_pushMessage("Formatted EEPROM CFG\n");
|
||||
break;
|
||||
case EE_PDS_SAVE:
|
||||
StorePersistence_EEPROM();
|
||||
@ -53,7 +80,7 @@ void EEPROM_Process()
|
||||
FormatPersistence_EEPROM();
|
||||
globals.requestEEAction = EE_IDLE;
|
||||
GetPersistence_EEPROM();
|
||||
Debug_pushMessage("Formated EEPROM PDS\n");
|
||||
Debug_pushMessage("Formatted EEPROM PDS\n");
|
||||
break;
|
||||
case EE_FORMAT_ALL:
|
||||
FormatConfig_EEPROM();
|
||||
@ -61,7 +88,7 @@ void EEPROM_Process()
|
||||
GetConfig_EEPROM();
|
||||
GetPersistence_EEPROM();
|
||||
globals.requestEEAction = EE_IDLE;
|
||||
Debug_pushMessage("Formated EEPROM ALL\n");
|
||||
Debug_pushMessage("Formatted EEPROM ALL\n");
|
||||
break;
|
||||
case EE_ALL_SAVE:
|
||||
StorePersistence_EEPROM();
|
||||
@ -75,22 +102,36 @@ void EEPROM_Process()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the configuration data in EEPROM.
|
||||
*
|
||||
* This function calculates the checksum for the configuration data, updates it, and stores it in EEPROM.
|
||||
* It also performs a sanity check on the configuration and raises a diagnostic trouble code (DTC) if needed.
|
||||
*/
|
||||
void StoreConfig_EEPROM()
|
||||
{
|
||||
LubeConfig.checksum = 0;
|
||||
LubeConfig.checksum = Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig));
|
||||
|
||||
if (!checkEEPROMavailable())
|
||||
return;
|
||||
|
||||
ee.updateBlock(startofLubeConfig, (uint8_t *)&LubeConfig, sizeof(LubeConfig));
|
||||
|
||||
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
|
||||
|
||||
if (ConfigSanityCheckResult > 0)
|
||||
{
|
||||
MaintainDTC(DTC_EEPROM_CFG_SANITY, true, ConfigSanityCheckResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the configuration data from EEPROM.
|
||||
*
|
||||
* This function reads the configuration data from EEPROM, performs a checksum validation,
|
||||
* and conducts a sanity check on the configuration. It raises a diagnostic trouble code (DTC) if needed.
|
||||
*/
|
||||
void GetConfig_EEPROM()
|
||||
{
|
||||
if (!checkEEPROMavailable())
|
||||
@ -105,15 +146,23 @@ void GetConfig_EEPROM()
|
||||
{
|
||||
MaintainDTC(DTC_EEPROM_CFG_BAD, true);
|
||||
}
|
||||
|
||||
LubeConfig.checksum = checksum;
|
||||
|
||||
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
|
||||
|
||||
if (ConfigSanityCheckResult > 0)
|
||||
{
|
||||
MaintainDTC(DTC_EEPROM_CFG_SANITY, true, ConfigSanityCheckResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the persistence data in EEPROM.
|
||||
*
|
||||
* This function increments the write cycle counter, performs a checksum calculation on the persistence data,
|
||||
* and stores it in EEPROM. It also handles EEPROM page movement when needed.
|
||||
*/
|
||||
void StorePersistence_EEPROM()
|
||||
{
|
||||
if (PersistenceData.writeCycleCounter >= 0xFFF0)
|
||||
@ -130,6 +179,13 @@ void StorePersistence_EEPROM()
|
||||
ee.updateBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the persistence data from EEPROM.
|
||||
*
|
||||
* This function reads the EEPROM to get the start address of the persistence data.
|
||||
* If the start address is out of range, it resets and stores defaults. Otherwise,
|
||||
* it reads from EEPROM and checks if the data is correct.
|
||||
*/
|
||||
void GetPersistence_EEPROM()
|
||||
{
|
||||
if (!checkEEPROMavailable())
|
||||
@ -159,6 +215,11 @@ void GetPersistence_EEPROM()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Formats the configuration partition in EEPROM.
|
||||
*
|
||||
* This function resets the configuration data to defaults and stores it in EEPROM.
|
||||
*/
|
||||
void FormatConfig_EEPROM()
|
||||
{
|
||||
Debug_pushMessage("Formatting Config-Partition\n");
|
||||
@ -167,6 +228,11 @@ void FormatConfig_EEPROM()
|
||||
StoreConfig_EEPROM();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Formats the persistence partition in EEPROM.
|
||||
*
|
||||
* This function resets the persistence data to defaults and stores it in EEPROM.
|
||||
*/
|
||||
void FormatPersistence_EEPROM()
|
||||
{
|
||||
Debug_pushMessage("Formatting Persistance-Partition\n");
|
||||
@ -174,16 +240,22 @@ void FormatPersistence_EEPROM()
|
||||
// memset(&PersistenceData, 0, sizeof(PersistenceData));
|
||||
StorePersistence_EEPROM();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Moves the persistence page in EEPROM.
|
||||
*
|
||||
* This function adjusts the persistence page address and resets the write cycle counter.
|
||||
*
|
||||
* @param reset If true, the function resets the persistence page address to the start of the partition.
|
||||
*/
|
||||
void MovePersistencePage_EEPROM(boolean reset)
|
||||
{
|
||||
if (!checkEEPROMavailable())
|
||||
return;
|
||||
|
||||
globals.eePersistanceAdress = +sizeof(PersistenceData);
|
||||
globals.eePersistanceAdress += sizeof(PersistenceData);
|
||||
PersistenceData.writeCycleCounter = 0;
|
||||
|
||||
// check if we reached the End of the EEPROM and Startover at the beginning
|
||||
// Check if we reached the end of the EEPROM and start over at the beginning
|
||||
if ((globals.eePersistanceAdress + sizeof(PersistenceData)) > ee.getDeviceSize() || reset)
|
||||
{
|
||||
globals.eePersistanceAdress = startofPersistence;
|
||||
@ -192,25 +264,45 @@ void MovePersistencePage_EEPROM(boolean reset)
|
||||
ee.updateBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate CRC-32 checksum for a block of data.
|
||||
*
|
||||
* This function implements the CRC-32 algorithm.
|
||||
*
|
||||
* @param data Pointer to the data block.
|
||||
* @param len Length of the data block in bytes.
|
||||
* @return CRC-32 checksum.
|
||||
*/
|
||||
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
|
||||
{
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
uint32_t crc, mask;
|
||||
crc = 0xFFFFFFFF;
|
||||
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
uint32_t mask;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
crc ^= *data++;
|
||||
|
||||
for (uint8_t k = 0; k < 8; k++)
|
||||
{
|
||||
mask = -(crc & 1);
|
||||
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
||||
}
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dump a portion of EEPROM contents for debugging.
|
||||
*
|
||||
* This function prints the contents of a specified portion of EEPROM in a formatted way.
|
||||
*
|
||||
* @param memoryAddress Starting address in EEPROM.
|
||||
* @param length Number of bytes to dump.
|
||||
*/
|
||||
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
{
|
||||
#define BLOCK_TO_LENGTH 16
|
||||
@ -220,42 +312,79 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
||||
|
||||
char ascii_buf[BLOCK_TO_LENGTH + 1];
|
||||
sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII");
|
||||
|
||||
// Print column headers
|
||||
Debug_pushMessage(PSTR("\nAddress "));
|
||||
for (int x = 0; x < BLOCK_TO_LENGTH; x++)
|
||||
Debug_pushMessage("%3d", x);
|
||||
|
||||
// Align address and length to BLOCK_TO_LENGTH boundaries
|
||||
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
||||
|
||||
// Iterate through the specified portion of EEPROM
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
{
|
||||
int blockpoint = memoryAddress % BLOCK_TO_LENGTH;
|
||||
|
||||
// Print ASCII representation header for each block
|
||||
if (blockpoint == 0)
|
||||
{
|
||||
ascii_buf[BLOCK_TO_LENGTH] = 0;
|
||||
Debug_pushMessage(" %s", ascii_buf);
|
||||
Debug_pushMessage("\n0x%05X:", memoryAddress);
|
||||
}
|
||||
|
||||
// Read and print each byte
|
||||
ascii_buf[blockpoint] = ee.readByte(memoryAddress);
|
||||
Debug_pushMessage(" %02X", ascii_buf[blockpoint]);
|
||||
|
||||
// Replace non-printable characters with dots in ASCII representation
|
||||
if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E)
|
||||
ascii_buf[blockpoint] = '.';
|
||||
|
||||
memoryAddress++;
|
||||
}
|
||||
|
||||
// Print a new line at the end of the dump
|
||||
Debug_pushMessage("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if EEPROM is available and connected.
|
||||
*
|
||||
* This function checks if the EEPROM is available and connected. If not, it triggers
|
||||
* a diagnostic trouble code (DTC) indicating the absence of EEPROM.
|
||||
*
|
||||
* @return true if EEPROM is available, false otherwise.
|
||||
*/
|
||||
boolean checkEEPROMavailable()
|
||||
{
|
||||
// Check if EEPROM is connected
|
||||
if (!ee.isConnected())
|
||||
{
|
||||
// Trigger DTC for no EEPROM found
|
||||
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear DTC for no EEPROM found since it's available now
|
||||
MaintainDTC(DTC_NO_EEPROM_FOUND, false);
|
||||
|
||||
// EEPROM is available
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform sanity check on configuration settings.
|
||||
*
|
||||
* This function checks the validity of various configuration settings and returns a bitmask
|
||||
* indicating which settings need to be reset. If autocorrect is enabled, it resets the settings
|
||||
* to their default values.
|
||||
*
|
||||
* @param autocorrect If true, automatically correct invalid settings by resetting to defaults.
|
||||
* @return A bitmask indicating which settings need to be reset.
|
||||
*/
|
||||
uint32_t ConfigSanityCheck(bool autocorrect)
|
||||
{
|
||||
uint32_t setting_reset_bits = 0;
|
||||
@ -332,7 +461,7 @@ uint32_t ConfigSanityCheck(bool autocorrect)
|
||||
LubeConfig.DistancePerRevolution_mm = LubeConfig_defaults.DistancePerRevolution_mm;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(LubeConfig.BleedingPulses > 0) || !(LubeConfig.BleedingPulses < 1001))
|
||||
{
|
||||
SET_BIT(setting_reset_bits, 10);
|
||||
@ -360,5 +489,6 @@ uint32_t ConfigSanityCheck(bool autocorrect)
|
||||
if (autocorrect)
|
||||
LubeConfig.CANSource = LubeConfig_defaults.CANSource;
|
||||
}
|
||||
// Return the bitmask indicating which settings need to be reset
|
||||
return setting_reset_bits;
|
||||
}
|
@ -1,3 +1,16 @@
|
||||
/**
|
||||
* @file debugger.cpp
|
||||
* @brief Implementation of debugging functions for monitoring and diagnostics.
|
||||
*
|
||||
* This file contains the implementation of various debugging functions to monitor
|
||||
* and diagnose the system. It includes functions to print system information, WiFi
|
||||
* details, EEPROM status, dump configuration settings, dump persistence data, show
|
||||
* Diagnostic Trouble Codes (DTCs), and more.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.04.2024
|
||||
*/
|
||||
|
||||
#include "debugger.h"
|
||||
|
||||
DebugStatus_t DebuggerStatus[dbg_cntElements];
|
||||
@ -15,32 +28,45 @@ void Debug_ShowDTCs();
|
||||
void Debug_dumpGlobals();
|
||||
void Debug_printHelp();
|
||||
|
||||
/**
|
||||
* @brief Initializes the debugger by setting the initial status for different debug ports.
|
||||
* Serial debug output is turned off.
|
||||
*/
|
||||
void initDebugger()
|
||||
{
|
||||
// Set the initial status of debug ports
|
||||
DebuggerStatus[dbg_Serial] = disabled;
|
||||
DebuggerStatus[dbg_Webui] = disabled;
|
||||
|
||||
// Disable serial debug output
|
||||
Serial.setDebugOutput(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes incoming debug commands from the Serial interface.
|
||||
* It reads characters from Serial and interprets them as commands.
|
||||
* The recognized commands are processed accordingly.
|
||||
*/
|
||||
void Debug_Process()
|
||||
{
|
||||
// Enumeration for tracking the state of input processing
|
||||
typedef enum InputProcessed_e
|
||||
{
|
||||
IDLE,
|
||||
CMD_COMPLETE,
|
||||
CMD_ABORT,
|
||||
CMD_OVERFLOW
|
||||
IDLE, ///< No command processing is in progress
|
||||
CMD_COMPLETE, ///< Received a complete command
|
||||
CMD_ABORT, ///< Received an abort command (Esc)
|
||||
CMD_OVERFLOW ///< Input buffer overflow occurred
|
||||
} InputProcessed_t;
|
||||
|
||||
static unsigned int inputCnt = 0;
|
||||
static char inputBuffer[32];
|
||||
InputProcessed_t InputProcessed = IDLE;
|
||||
static unsigned int inputCnt = 0; ///< Counter for characters in the input buffer
|
||||
static char inputBuffer[32]; ///< Buffer to store the received characters
|
||||
InputProcessed_t InputProcessed = IDLE; ///< State variable for input processing
|
||||
|
||||
// Check if there are characters available in the Serial input buffer
|
||||
if (Serial.available())
|
||||
{
|
||||
char inputChar = Serial.read();
|
||||
|
||||
// Process the received character based on its value
|
||||
switch (inputChar)
|
||||
{
|
||||
case '\n':
|
||||
@ -55,7 +81,7 @@ void Debug_Process()
|
||||
InputProcessed = CMD_ABORT;
|
||||
break;
|
||||
|
||||
case 0x21 ... 0x7E: // its a real letter or sign and not some control-chars
|
||||
case 0x21 ... 0x7E: // it's a real letter or sign and not some control-chars
|
||||
inputBuffer[inputCnt] = inputChar;
|
||||
inputCnt++;
|
||||
break;
|
||||
@ -64,6 +90,7 @@ void Debug_Process()
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for input buffer overflow
|
||||
if (inputCnt > sizeof(inputBuffer))
|
||||
{
|
||||
inputCnt = 0;
|
||||
@ -72,6 +99,7 @@ void Debug_Process()
|
||||
}
|
||||
}
|
||||
|
||||
// Process the command based on the detected state of input processing
|
||||
switch (InputProcessed)
|
||||
{
|
||||
case CMD_ABORT:
|
||||
@ -83,7 +111,7 @@ void Debug_Process()
|
||||
break;
|
||||
|
||||
case CMD_OVERFLOW:
|
||||
Debug_pushMessage("input Buffer overflow\n");
|
||||
Debug_pushMessage("Input buffer overflow\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -91,32 +119,53 @@ void Debug_Process()
|
||||
}
|
||||
InputProcessed = IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the status of a specific debug port (Serial or WebUI).
|
||||
* Updates the status in the DebuggerStatus array and provides debug messages.
|
||||
*
|
||||
* @param port The debug port to set the status for (dbg_Serial or dbg_Webui).
|
||||
* @param status The status to set (enabled or disabled).
|
||||
*/
|
||||
void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status)
|
||||
{
|
||||
// Display a debug message based on the provided status
|
||||
if (status == disabled)
|
||||
Debug_pushMessage("disable DebugPort %s\n", sDebugPorts[port]);
|
||||
Debug_pushMessage("Disable DebugPort %s\n", sDebugPorts[port]);
|
||||
|
||||
// Update the status in the DebuggerStatus array
|
||||
DebuggerStatus[port] = status;
|
||||
|
||||
// Display a debug message based on the updated status
|
||||
if (status == enabled)
|
||||
Debug_pushMessage("enabled DebugPort %s\n", sDebugPorts[port]);
|
||||
Debug_pushMessage("Enabled DebugPort %s\n", sDebugPorts[port]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes a formatted debug message to the enabled debug ports (Serial or WebUI).
|
||||
*
|
||||
* @param format The format string for the debug message.
|
||||
* @param ... Additional arguments for formatting the message.
|
||||
*/
|
||||
void Debug_pushMessage(const char *format, ...)
|
||||
{
|
||||
// Check if either the Serial or WebUI debug port is enabled
|
||||
if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
|
||||
{
|
||||
char buff[64];
|
||||
va_list arg;
|
||||
char buff[64]; // Buffer to hold the formatted message
|
||||
va_list arg; // Variable argument list for vsnprintf
|
||||
va_start(arg, format);
|
||||
|
||||
// Format the message and store it in the buffer
|
||||
vsnprintf(buff, sizeof(buff), format, arg);
|
||||
va_end(arg);
|
||||
|
||||
// Send the message to the Serial debug port if enabled
|
||||
if (DebuggerStatus[dbg_Serial] == enabled)
|
||||
{
|
||||
Serial.print(buff);
|
||||
}
|
||||
|
||||
// Push the message to the WebUI debug port if enabled
|
||||
if (DebuggerStatus[dbg_Webui] == enabled)
|
||||
{
|
||||
Websocket_PushLiveDebug(String(buff));
|
||||
@ -124,12 +173,22 @@ void Debug_pushMessage(const char *format, ...)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes a formatted CAN debug message to the enabled debug ports (Serial or WebUI).
|
||||
*
|
||||
* @param id CAN message ID.
|
||||
* @param dlc Data Length Code of the CAN message.
|
||||
* @param data Pointer to the data array of the CAN message.
|
||||
*/
|
||||
void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
|
||||
{
|
||||
// Check if either the Serial or WebUI debug port is enabled
|
||||
if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
|
||||
{
|
||||
char buff[100];
|
||||
char *p = buff;
|
||||
char buff[100]; // Buffer to hold the formatted message
|
||||
char *p = buff; // Pointer to navigate the buffer
|
||||
|
||||
// Format the CAN message information into the buffer
|
||||
p += snprintf(p, sizeof(buff), "CAN: 0x%08X | %d | ", id, dlc);
|
||||
for (int i = 0; i < dlc; i++)
|
||||
{
|
||||
@ -138,10 +197,13 @@ void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
|
||||
*(p++) = '\n';
|
||||
*p = '\0';
|
||||
|
||||
// Send the formatted CAN message to the Serial debug port if enabled
|
||||
if (DebuggerStatus[dbg_Serial] == enabled)
|
||||
{
|
||||
Serial.print(buff);
|
||||
}
|
||||
|
||||
// Push the formatted CAN message to the WebUI debug port if enabled
|
||||
if (DebuggerStatus[dbg_Webui] == enabled)
|
||||
{
|
||||
Websocket_PushLiveDebug(String(buff));
|
||||
@ -149,8 +211,14 @@ void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes a debug command and performs corresponding actions.
|
||||
*
|
||||
* @param command The debug command to be processed.
|
||||
*/
|
||||
void processCmdDebug(String command)
|
||||
{
|
||||
// Check the received command and execute corresponding actions
|
||||
if (command == "help")
|
||||
Debug_printHelp();
|
||||
else if (command == "sysinfo")
|
||||
@ -193,18 +261,29 @@ void processCmdDebug(String command)
|
||||
Debug_pushMessage("unknown Command\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Formats the Config-EEPROM and resets it to default values.
|
||||
* Prints a debug message after formatting.
|
||||
*/
|
||||
void Debug_formatCFG()
|
||||
{
|
||||
Debug_pushMessage("Formatting Config-EEPROM and reseting to default\n");
|
||||
Debug_pushMessage("Formatting Config-EEPROM and resetting to default\n");
|
||||
FormatConfig_EEPROM();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Formats the Persistence-EEPROM and resets it to default values.
|
||||
* Prints a debug message after formatting.
|
||||
*/
|
||||
void Debug_formatPersistence()
|
||||
{
|
||||
Debug_pushMessage("Formatting Persistence-EEPROM and reseting to default\n");
|
||||
Debug_pushMessage("Formatting Persistence-EEPROM and resetting to default\n");
|
||||
FormatPersistence_EEPROM();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints system information and status to the debug output.
|
||||
*/
|
||||
void Debug_printSystemInfo()
|
||||
{
|
||||
Debug_pushMessage("Souko's ChainOiler Mk1\n");
|
||||
@ -224,10 +303,13 @@ void Debug_printSystemInfo()
|
||||
: ideMode == FM_DOUT ? "DOUT"
|
||||
: "UNKNOWN"));
|
||||
Debug_pushMessage("OTA-Pass: %s\n", QUOTE(ADMIN_PASSWORD));
|
||||
Debug_pushMessage("Git-Revison: %s\n", constants.GitHash);
|
||||
Debug_pushMessage("Git-Revision: %s\n", constants.GitHash);
|
||||
Debug_pushMessage("Sw-Version: %d.%02d\n", constants.FW_Version_major, constants.FW_Version_minor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dumps the current configuration parameters to the debug output.
|
||||
*/
|
||||
void Debug_dumpConfig()
|
||||
{
|
||||
Debug_pushMessage("DistancePerLube_Default: %d\n", LubeConfig.DistancePerLube_Default);
|
||||
@ -237,7 +319,7 @@ void Debug_dumpConfig()
|
||||
Debug_pushMessage("TankRemindAtPercentage: %d\n", LubeConfig.TankRemindAtPercentage);
|
||||
Debug_pushMessage("PulsePerRevolution: %d\n", LubeConfig.PulsePerRevolution);
|
||||
Debug_pushMessage("TireWidth_mm: %d\n", LubeConfig.TireWidth_mm);
|
||||
Debug_pushMessage("TireWidthHeight_Ratio: %d\n", LubeConfig.TireWidth_mm);
|
||||
Debug_pushMessage("TireWidthHeight_Ratio: %d\n", LubeConfig.TireWidthHeight_Ratio);
|
||||
Debug_pushMessage("RimDiameter_Inch: %d\n", LubeConfig.RimDiameter_Inch);
|
||||
Debug_pushMessage("DistancePerRevolution_mm: %d\n", LubeConfig.DistancePerRevolution_mm);
|
||||
Debug_pushMessage("BleedingPulses: %d\n", LubeConfig.BleedingPulses);
|
||||
@ -247,6 +329,9 @@ void Debug_dumpConfig()
|
||||
Debug_pushMessage("checksum: 0x%08X\n", LubeConfig.checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dumps the global variables and their values to the debug output.
|
||||
*/
|
||||
void Debug_dumpGlobals()
|
||||
{
|
||||
Debug_pushMessage("systemStatus: %d\n", globals.systemStatus);
|
||||
@ -261,6 +346,9 @@ void Debug_dumpGlobals()
|
||||
Debug_pushMessage("hasDTC: %d\n", globals.hasDTC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dumps the persistence data variables and their values to the debug output.
|
||||
*/
|
||||
void Debug_dumpPersistance()
|
||||
{
|
||||
Debug_pushMessage("writeCycleCounter: %d\n", PersistenceData.writeCycleCounter);
|
||||
@ -270,12 +358,21 @@ void Debug_dumpPersistance()
|
||||
Debug_pushMessage("PSD Adress: 0x%04X\n", globals.eePersistanceAdress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints information related to WiFi to the debug output.
|
||||
*/
|
||||
void Debug_printWifiInfo()
|
||||
{
|
||||
// Add relevant code here if needed
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the EEPROM data integrity by calculating and comparing checksums.
|
||||
* Prints the result to the debug output.
|
||||
*/
|
||||
void Debug_CheckEEPOM()
|
||||
{
|
||||
// Check PersistenceData EEPROM checksum
|
||||
uint32_t checksum = PersistenceData.checksum;
|
||||
PersistenceData.checksum = 0;
|
||||
|
||||
@ -290,6 +387,7 @@ void Debug_CheckEEPOM()
|
||||
|
||||
PersistenceData.checksum = checksum;
|
||||
|
||||
// Check LubeConfig EEPROM checksum
|
||||
checksum = LubeConfig.checksum;
|
||||
LubeConfig.checksum = 0;
|
||||
|
||||
@ -304,24 +402,32 @@ void Debug_CheckEEPOM()
|
||||
LubeConfig.checksum = checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Displays Diagnostic Trouble Codes (DTCs) along with their timestamps,
|
||||
* status, and severity in a formatted manner.
|
||||
*/
|
||||
void Debug_ShowDTCs()
|
||||
{
|
||||
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
|
||||
char buff_active[9];
|
||||
|
||||
// Header for the DTC display
|
||||
Debug_pushMessage("\n timestamp | DTC-Nr. | status | severity\n");
|
||||
|
||||
// Iterate through DTCStorage and display each entry
|
||||
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
{
|
||||
if (DTCStorage[i].Number < DTC_LAST_DTC)
|
||||
{
|
||||
// Format timestamp
|
||||
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
|
||||
DTCStorage[i].timestamp / 86400000, // Days
|
||||
DTCStorage[i].timestamp / 360000 % 24, // Hours
|
||||
DTCStorage[i].timestamp / 60000 % 60, // Minutes
|
||||
DTCStorage[i].timestamp / 1000 % 60, // Seconds
|
||||
DTCStorage[i].timestamp % 1000); // milliseconds
|
||||
DTCStorage[i].timestamp % 1000); // Milliseconds
|
||||
|
||||
// Determine DTC status
|
||||
if (DTCStorage[i].active == DTC_ACTIVE)
|
||||
strcpy(buff_active, "active");
|
||||
else if (DTCStorage[i].active == DTC_PREVIOUS)
|
||||
@ -329,19 +435,28 @@ void Debug_ShowDTCs()
|
||||
else
|
||||
strcpy(buff_active, "none");
|
||||
|
||||
// Display DTC information
|
||||
Debug_pushMessage("%s %7d %8s %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Displays the help commands for debugging through Serial or WebUI.
|
||||
* Each command is printed individually in a formatted manner.
|
||||
*/
|
||||
void Debug_printHelp()
|
||||
{
|
||||
char buff[64];
|
||||
|
||||
for (unsigned int i = sizeof(helpCmd) / 63; i < sizeof(helpCmd) / 63; i++)
|
||||
// Iterate through helpCmd and display each command
|
||||
for (unsigned int i = 0; i < sizeof(helpCmd) / 63; i++)
|
||||
{
|
||||
// Copy a portion of helpCmd to buff for display
|
||||
memcpy_P(buff, (helpCmd + (i * 63)), 63);
|
||||
buff[63] = 0;
|
||||
|
||||
// Display the help command
|
||||
Debug_pushMessage(buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,37 @@
|
||||
/**
|
||||
* @file dtc.cpp
|
||||
* @brief Implementation of functions related to Diagnostic Trouble Codes (DTCs).
|
||||
*
|
||||
* This file contains the implementation of functions that manage the status
|
||||
* and registration of Diagnostic Trouble Codes in the system.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
#include "dtc.h"
|
||||
#include "debugger.h"
|
||||
|
||||
DTCEntry_t DTCStorage[MAX_DTC_STORAGE];
|
||||
|
||||
// Function implementations...
|
||||
|
||||
/**
|
||||
* @brief Maintains the status of Diagnostic Trouble Codes (DTCs) in the DTCStorage array.
|
||||
* Updates the status of existing DTCs or adds new ones based on their activity.
|
||||
*
|
||||
* @param DTC_no The number of the Diagnostic Trouble Code.
|
||||
* @param active Indicates whether the DTC is active (true) or inactive (false).
|
||||
* @param DebugValue Additional debugging information associated with the DTC.
|
||||
*/
|
||||
void MaintainDTC(DTCNum_t DTC_no, boolean active, uint32_t DebugValue)
|
||||
{
|
||||
// Iterate through the existing DTCs in the storage
|
||||
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
{
|
||||
// Check if the DTC with the specified number exists
|
||||
if (DTCStorage[i].Number == DTC_no)
|
||||
{
|
||||
// If the DTC is active and was not active before, update its status
|
||||
if (active && DTCStorage[i].active != DTC_ACTIVE)
|
||||
{
|
||||
Debug_pushMessage("DTC gone active: %d, DebugVal: %d\n", DTC_no, DebugValue);
|
||||
@ -16,21 +39,23 @@ void MaintainDTC(DTCNum_t DTC_no, boolean active, uint32_t DebugValue)
|
||||
DTCStorage[i].active = DTC_ACTIVE;
|
||||
DTCStorage[i].debugVal = DebugValue;
|
||||
}
|
||||
// If the DTC is not active anymore, update its status to previous
|
||||
if (!active && DTCStorage[i].active == DTC_ACTIVE)
|
||||
{
|
||||
Debug_pushMessage("DTC gone previous: %d\n", DTC_no);
|
||||
DTCStorage[i].active = DTC_PREVIOUS;
|
||||
}
|
||||
return;
|
||||
return; // DTC found and processed, exit the function
|
||||
}
|
||||
}
|
||||
|
||||
// DTC was not found with upper iteration, but is active
|
||||
// so we need to look for free space to store DTC
|
||||
// DTC was not found in the existing storage, but it is active,
|
||||
// so look for free space to store the new DTC
|
||||
if (active == true)
|
||||
{
|
||||
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
{
|
||||
// Check for an empty slot in the storage
|
||||
if (DTCStorage[i].Number == DTC_LAST_DTC)
|
||||
{
|
||||
Debug_pushMessage("new DTC registered: %d, DebugVal: %d\n", DTC_no, DebugValue);
|
||||
@ -38,12 +63,20 @@ void MaintainDTC(DTCNum_t DTC_no, boolean active, uint32_t DebugValue)
|
||||
DTCStorage[i].timestamp = millis();
|
||||
DTCStorage[i].active = DTC_ACTIVE;
|
||||
DTCStorage[i].debugVal = DebugValue;
|
||||
return;
|
||||
return; // New DTC registered, exit the function
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears a specific Diagnostic Trouble Code (DTC) entry.
|
||||
*
|
||||
* This function clears the information related to a specific DTC entry,
|
||||
* setting its status to inactive and timestamp to zero.
|
||||
*
|
||||
* @param DTC_no The Diagnostic Trouble Code number to be cleared.
|
||||
*/
|
||||
void ClearDTC(DTCNum_t DTC_no)
|
||||
{
|
||||
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
@ -57,6 +90,12 @@ void ClearDTC(DTCNum_t DTC_no)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears all Diagnostic Trouble Code (DTC) entries.
|
||||
*
|
||||
* This function clears all DTC entries, setting their status to inactive and
|
||||
* timestamps to zero.
|
||||
*/
|
||||
void ClearAllDTC()
|
||||
{
|
||||
for (int i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
@ -67,6 +106,15 @@ void ClearAllDTC()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the last recorded Diagnostic Trouble Code (DTC) number.
|
||||
*
|
||||
* This function retrieves the DTC number of the last recorded DTC based on the
|
||||
* timestamp. Optionally, it can filter only active DTCs.
|
||||
*
|
||||
* @param only_active If true, considers only active DTCs; otherwise, considers all.
|
||||
* @return The DTC number of the last recorded DTC or DTC_LAST_DTC if none found.
|
||||
*/
|
||||
DTCNum_t getlastDTC(boolean only_active)
|
||||
{
|
||||
int8_t pointer = -1;
|
||||
@ -87,6 +135,15 @@ DTCNum_t getlastDTC(boolean only_active)
|
||||
return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the severity level for a specific Diagnostic Trouble Code (DTC).
|
||||
*
|
||||
* This function looks up the severity level associated with the provided DTC code
|
||||
* from the predefined list of DTC definitions.
|
||||
*
|
||||
* @param targetCode The DTC code for which to retrieve the severity.
|
||||
* @return The severity level of the specified DTC or DTC_NONE if not found.
|
||||
*/
|
||||
DTCSeverity_t getSeverityForDTC(DTCNum_t targetCode)
|
||||
{
|
||||
for (int i = 0; i < DTC_LAST_DTC; i++)
|
||||
@ -99,6 +156,16 @@ DTCSeverity_t getSeverityForDTC(DTCNum_t targetCode)
|
||||
return DTC_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes Diagnostic Trouble Codes (DTCs) and updates system status accordingly.
|
||||
*
|
||||
* This function checks for the presence of active DTCs and adjusts the system status
|
||||
* based on the severity of the most critical DTC. If a critical DTC is detected,
|
||||
* the system status is set to sysStat_Error, potentially triggering a system shutdown.
|
||||
*
|
||||
* @note The function also preserves the original system status when transitioning to an error state
|
||||
* and restores it when all DTCs are cleared.
|
||||
*/
|
||||
void DTC_Process()
|
||||
{
|
||||
static tSystem_Status preserverSysStatusError;
|
||||
@ -120,10 +187,10 @@ void DTC_Process()
|
||||
else
|
||||
{
|
||||
globals.hasDTC = false;
|
||||
|
||||
|
||||
if (globals.systemStatus == sysStat_Error)
|
||||
{
|
||||
globals.systemStatus = preserverSysStatusError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,23 @@
|
||||
/**
|
||||
* @file globals.cpp
|
||||
* @brief Implementation of global variables and initialization functions.
|
||||
*
|
||||
* This file defines and initializes the global variables used throughout the project.
|
||||
* The global variables are encapsulated in the Globals_t structure. The initGlobals function
|
||||
* is responsible for initializing these variables to their default values during system startup.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
// Global instance of the Globals_t structure
|
||||
Globals_t globals;
|
||||
|
||||
/**
|
||||
* @brief Initializes global variables to default values during system startup.
|
||||
*
|
||||
* This function sets the initial values for various global variables, ensuring proper
|
||||
* initialization of system-wide parameters.
|
||||
*/
|
||||
void initGlobals()
|
||||
{
|
||||
globals.purgePulses = 0;
|
||||
|
@ -1,7 +1,26 @@
|
||||
/**
|
||||
* @file gps.cpp
|
||||
*
|
||||
* @brief Implementation file for GPS-related functions in the ChainLube application.
|
||||
*
|
||||
* This file contains the implementation of functions related to GPS functionality within the ChainLube
|
||||
* application. It includes the initialization of the GPS module, processing GPS data for wheel speed,
|
||||
* and maintaining Diagnostic Trouble Codes (DTCs) based on GPS communication status.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#include "gps.h"
|
||||
|
||||
TinyGPSPlus gps;
|
||||
|
||||
/**
|
||||
* @brief Initializes the GPS module with the specified baud rate.
|
||||
*
|
||||
* This function initializes the GPS module with the baud rate configured in the application settings.
|
||||
* It also prints a debug message indicating the initialization status.
|
||||
*/
|
||||
void Init_GPS()
|
||||
{
|
||||
uint32_t baudrate;
|
||||
@ -22,6 +41,15 @@ void Init_GPS()
|
||||
Serial.begin(baudrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes GPS data to calculate rear wheel speed and returns the distance traveled.
|
||||
*
|
||||
* This function processes GPS data received from the GPS module, calculates the rear wheel speed in
|
||||
* kilometers per hour, and returns the distance traveled based on the speed and time elapsed since
|
||||
* the last valid speed measurement.
|
||||
*
|
||||
* @return The distance traveled in millimeters since the last GPS speed measurement.
|
||||
*/
|
||||
uint32_t Process_GPS_WheelSpeed()
|
||||
{
|
||||
static uint32_t lastRecTimestamp;
|
||||
@ -49,7 +77,9 @@ uint32_t Process_GPS_WheelSpeed()
|
||||
lastRecTimestamp = millis();
|
||||
}
|
||||
}
|
||||
|
||||
// Maintain DTC for no GPS data received within a certain time frame
|
||||
MaintainDTC(DTC_NO_GPS_SERIAL, (millis() > lastRecTimestamp + 10000));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,56 @@
|
||||
/**
|
||||
* @file lubeapp.cpp
|
||||
*
|
||||
* @brief Implementation file for the ChainLube application logic.
|
||||
*
|
||||
* This file contains the implementation of the ChainLube application logic, including functions
|
||||
* for running the main application, initiating lubrication pulses, and maintaining system status.
|
||||
* Global variables related to lubrication pulses are also defined in this file.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#include "lubeapp.h"
|
||||
|
||||
uint32_t lubePulseTimestamp = 0;
|
||||
|
||||
/**
|
||||
* @brief Runs the main logic of the ChainLube application based on the current system status.
|
||||
*
|
||||
* This function is responsible for executing the main logic of the ChainLube application. It calculates
|
||||
* the tank percentage, maintains Diagnostic Trouble Codes (DTCs) related to the tank level, updates travel
|
||||
* distances, triggers lubrication pulses, and handles the behavior based on the current system status
|
||||
* (Startup, Normal, Rain, Purge, Error, Shutdown). It also manages the pin state of the lube pump.
|
||||
*
|
||||
* @param add_milimeters The additional distance traveled in millimeters to be processed by the application.
|
||||
*/
|
||||
void RunLubeApp(uint32_t add_milimeters)
|
||||
{
|
||||
|
||||
// Calculate and update tank percentage
|
||||
globals.TankPercentage = PersistenceData.tankRemain_microL / (LubeConfig.tankCapacity_ml * 10);
|
||||
|
||||
// Maintain DTCs related to tank level
|
||||
MaintainDTC(DTC_TANK_EMPTY, (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL));
|
||||
MaintainDTC(DTC_TANK_LOW, (globals.TankPercentage < LubeConfig.TankRemindAtPercentage));
|
||||
|
||||
// Add traveled Distance in mm
|
||||
// Add traveled distance in millimeters
|
||||
PersistenceData.TravelDistance_highRes_mm += add_milimeters;
|
||||
PersistenceData.odometer_mm += add_milimeters;
|
||||
|
||||
// Update odometer if necessary
|
||||
if (PersistenceData.odometer_mm >= 1000000)
|
||||
{
|
||||
PersistenceData.odometer++;
|
||||
PersistenceData.odometer_mm = 0;
|
||||
}
|
||||
|
||||
// Handle different system statuses
|
||||
switch (globals.systemStatus)
|
||||
{
|
||||
case sysStat_Startup:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Startup"));
|
||||
// Transition to Normal status after startup delay
|
||||
if (millis() > STARTUP_DELAY)
|
||||
{
|
||||
globals.systemStatus = sysStat_Normal;
|
||||
@ -32,6 +60,7 @@ void RunLubeApp(uint32_t add_milimeters)
|
||||
|
||||
case sysStat_Normal:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Normal"));
|
||||
// Trigger lube pulse if traveled distance exceeds the configured limit
|
||||
if (PersistenceData.TravelDistance_highRes_mm / 1000 > LubeConfig.DistancePerLube_Default)
|
||||
{
|
||||
LubePulse();
|
||||
@ -41,16 +70,20 @@ void RunLubeApp(uint32_t add_milimeters)
|
||||
|
||||
case sysStat_Rain:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Rain"));
|
||||
// Trigger lube pulse if traveled distance exceeds the configured limit in Rain mode
|
||||
if (PersistenceData.TravelDistance_highRes_mm / 1000 > LubeConfig.DistancePerLube_Rain)
|
||||
{
|
||||
LubePulse();
|
||||
PersistenceData.TravelDistance_highRes_mm = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case sysStat_Purge:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Purge"));
|
||||
// Execute lube pulses during the Purge status
|
||||
if (globals.purgePulses > 0)
|
||||
{
|
||||
// Check if enough time has passed since the last lube pulse
|
||||
if (lubePulseTimestamp + LUBE_PULSE_PAUSE_MS < millis())
|
||||
{
|
||||
LubePulse();
|
||||
@ -60,35 +93,48 @@ void RunLubeApp(uint32_t add_milimeters)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transition back to the previous status after completing purge pulses
|
||||
globals.systemStatus = globals.resumeStatus;
|
||||
}
|
||||
break;
|
||||
|
||||
case sysStat_Error:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Error"));
|
||||
break;
|
||||
|
||||
case sysStat_Shutdown:
|
||||
strcpy_P(globals.systemStatustxt, PSTR("Shutdown"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// maintain Pin-State of Lube-Pump
|
||||
// Maintain Pin-State of Lube-Pump
|
||||
if (lubePulseTimestamp > millis())
|
||||
digitalWrite(GPIO_PUMP, HIGH);
|
||||
else
|
||||
digitalWrite(GPIO_PUMP, LOW);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiates a lubrication pulse if there is sufficient oil remaining in the tank.
|
||||
*
|
||||
* This function checks if there is enough oil remaining in the tank to perform a lubrication pulse.
|
||||
* If there is sufficient oil, it updates the lubePulseTimestamp to trigger the pulse and decreases
|
||||
* the tank oil level by the configured amount per dose (LubeConfig.amountPerDose_microL).
|
||||
*/
|
||||
void LubePulse()
|
||||
{
|
||||
if (PersistenceData.tankRemain_microL > 0) // Only Lube if theres Oil remaining!
|
||||
// Only initiate a lubrication pulse if there is oil remaining in the tank
|
||||
if (PersistenceData.tankRemain_microL > 0)
|
||||
{
|
||||
lubePulseTimestamp = millis() + LUBE_PULSE_LENGHT_MS;
|
||||
|
||||
if (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL) // Prevent underrun and shiftover
|
||||
// Prevent underrun and shift over by adjusting the tank oil level
|
||||
if (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL)
|
||||
PersistenceData.tankRemain_microL = 0;
|
||||
else
|
||||
PersistenceData.tankRemain_microL = PersistenceData.tankRemain_microL - LubeConfig.amountPerDose_microL;
|
||||
PersistenceData.tankRemain_microL -= LubeConfig.amountPerDose_microL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,18 @@
|
||||
/**
|
||||
* @file main.cpp
|
||||
*
|
||||
* @brief Main source file for the Souko's ChainLube Mk1 ESP8266 project.
|
||||
*
|
||||
* This file includes necessary libraries, defines configuration options, and declares global variables
|
||||
* and function prototypes. It sets up essential components, initializes peripherals, and defines
|
||||
* callbacks for interrupt service routines (ISRs) and timers. The main setup function configures the
|
||||
* project, and the loop function handles the main execution loop, performing various tasks based on
|
||||
* the configured options.
|
||||
*
|
||||
* @author Marcel Peterkau
|
||||
* @date 09.01.2024
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#ifdef FEATURE_ENABLE_OLED
|
||||
@ -46,8 +61,8 @@ U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(-1);
|
||||
void Display_Process();
|
||||
#endif
|
||||
void Button_Process();
|
||||
void toggleWiFiAP(boolean shutdown = false);
|
||||
void SystemShutdown();
|
||||
void toggleWiFiAP(bool shutdown = false);
|
||||
void SystemShutdown(bool restart = false);
|
||||
uint32_t Process_Impulse_WheelSpeed();
|
||||
void EEPROMCyclicPDS_callback();
|
||||
|
||||
@ -57,28 +72,49 @@ Ticker WiFiMaintainConnectionTicker(wifiMaintainConnectionTicker_callback, 1000,
|
||||
#endif
|
||||
Ticker EEPROMCyclicPDSTicker(EEPROMCyclicPDS_callback, 60000, 0, MILLIS);
|
||||
|
||||
/**
|
||||
* @brief Initializes the ESP8266 project, configuring various components and setting up required services.
|
||||
*
|
||||
* This setup function is responsible for initializing the ESP8266 project, including setting the CPU frequency,
|
||||
* configuring WiFi settings, initializing DTC storage, handling WiFi client functionality (if enabled),
|
||||
* initializing the Serial communication, setting up an OLED display (if enabled), initializing EEPROM,
|
||||
* loading configuration and persistence data from EEPROM, initializing LEDs, setting up the chosen speed source
|
||||
* (CAN, GPS, Impulse), configuring GPIO pins, setting up Over-The-Air (OTA) updates, initializing the web user interface,
|
||||
* initializing global variables, starting cyclic EEPROM updates for Persistence Data Structure (PDS), and printing
|
||||
* initialization status messages to Serial.
|
||||
*/
|
||||
void setup()
|
||||
{
|
||||
// Set CPU frequency to 80MHz
|
||||
system_update_cpu_freq(SYS_CPU_80MHZ);
|
||||
|
||||
// Generate a unique device name based on ESP chip ID
|
||||
snprintf(globals.DeviceName, 32, HOST_NAME, ESP.getChipId());
|
||||
|
||||
// Disable WiFi persistent storage
|
||||
WiFi.persistent(false);
|
||||
|
||||
ClearAllDTC(); // Init DTC-Storage
|
||||
// Initialize and clear Diagnostic Trouble Code (DTC) storage
|
||||
ClearAllDTC();
|
||||
|
||||
#ifdef FEATURE_ENABLE_WIFI_CLIENT
|
||||
// Configure WiFi settings for client mode if enabled
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setHostname(globals.DeviceName);
|
||||
wifiMulti.addAP(QUOTE(WIFI_SSID_CLIENT), QUOTE(WIFI_PASSWORD_CLIENT));
|
||||
WiFiMaintainConnectionTicker.start();
|
||||
#else
|
||||
// Disable WiFi if WiFi client feature is not enabled
|
||||
WiFi.mode(WIFI_OFF);
|
||||
#endif
|
||||
|
||||
// Initialize Serial communication
|
||||
Serial.begin(115200);
|
||||
Serial.print("\n\nSouko's ChainLube Mk1\n");
|
||||
Serial.print(globals.DeviceName);
|
||||
|
||||
#ifdef FEATURE_ENABLE_OLED
|
||||
// Initialize OLED display if enabled
|
||||
u8x8.begin();
|
||||
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||
u8x8.clearDisplay();
|
||||
@ -87,14 +123,17 @@ void setup()
|
||||
Serial.print("\nDisplay-Init done");
|
||||
#endif
|
||||
|
||||
// Initialize EEPROM, load configuration, and persistence data from EEPROM
|
||||
InitEEPROM();
|
||||
GetConfig_EEPROM();
|
||||
GetPersistence_EEPROM();
|
||||
Serial.print("\nEE-Init done");
|
||||
|
||||
// Initialize LEDs
|
||||
leds.begin();
|
||||
Serial.print("\nLED-Init done");
|
||||
|
||||
// Initialize based on the chosen speed source (CAN, GPS, Impulse)
|
||||
switch (LubeConfig.SpeedSource)
|
||||
{
|
||||
case SOURCE_CAN:
|
||||
@ -115,13 +154,18 @@ void setup()
|
||||
}
|
||||
|
||||
Serial.print("\nSource-Init done");
|
||||
|
||||
// Configure GPIO pins for button and pump control
|
||||
pinMode(GPIO_BUTTON, INPUT_PULLUP);
|
||||
pinMode(GPIO_PUMP, OUTPUT);
|
||||
|
||||
// Set up OTA updates
|
||||
ArduinoOTA.setPort(8266);
|
||||
ArduinoOTA.setHostname(globals.DeviceName);
|
||||
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
|
||||
|
||||
#ifdef FEATURE_ENABLE_OLED
|
||||
// Set up OTA callbacks for OLED display if enabled
|
||||
ArduinoOTA.onStart([]()
|
||||
{
|
||||
u8x8.clearDisplay();
|
||||
@ -148,20 +192,40 @@ void setup()
|
||||
u8x8.drawString(0, 0, "OTA-Restart");
|
||||
u8x8.refreshDisplay(); });
|
||||
#endif
|
||||
|
||||
// Begin OTA updates
|
||||
ArduinoOTA.begin();
|
||||
Serial.print("\nOTA-Init done");
|
||||
|
||||
// Initialize the web user interface
|
||||
initWebUI();
|
||||
Serial.print("\nWebUI-Init done");
|
||||
|
||||
// Initialize global variables
|
||||
initGlobals();
|
||||
Serial.print("\nglobals-Init done");
|
||||
|
||||
// Start cyclic EEPROM updates for Persistence Data Structure (PDS)
|
||||
EEPROMCyclicPDSTicker.start();
|
||||
Serial.print("\nSetup Done\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main execution loop for the ESP8266 project, performing various tasks based on configuration.
|
||||
*
|
||||
* This loop function handles different tasks based on the configured source of speed data (impulse, CAN, time, GPS).
|
||||
* It calculates wheel distance, runs the lubrication application, updates the OLED display (if enabled),
|
||||
* processes CAN messages, handles button input, manages LED behavior, performs EEPROM-related tasks, handles
|
||||
* webserver operations, processes Diagnostic Trouble Codes (DTC), and manages debugging. Additionally, it
|
||||
* integrates functionalities such as Over-The-Air (OTA) updates, cyclic EEPROM updates for Persistence Data
|
||||
* Structure (PDS), WiFi connection maintenance, and system shutdown handling.
|
||||
*/
|
||||
void loop()
|
||||
{
|
||||
// Variable to store calculated wheel distance
|
||||
uint32_t wheelDistance = 0;
|
||||
|
||||
// Switch based on the configured speed source
|
||||
switch (LubeConfig.SpeedSource)
|
||||
{
|
||||
case SOURCE_IMPULSE:
|
||||
@ -180,14 +244,22 @@ void loop()
|
||||
break;
|
||||
}
|
||||
|
||||
// Run lubrication application with the calculated wheel distance
|
||||
RunLubeApp(wheelDistance);
|
||||
|
||||
#ifdef FEATURE_ENABLE_OLED
|
||||
// Update OLED display if enabled
|
||||
Display_Process();
|
||||
#endif
|
||||
|
||||
// Process CAN messages if the speed source is not impulse
|
||||
if (LubeConfig.SpeedSource != SOURCE_IMPULSE)
|
||||
{
|
||||
CAN_Process();
|
||||
}
|
||||
|
||||
// Process button input, manage LED behavior, perform EEPROM tasks, handle webserver operations,
|
||||
// process Diagnostic Trouble Codes (DTC), and manage debugging
|
||||
Button_Process();
|
||||
LED_Process();
|
||||
EEPROM_Process();
|
||||
@ -195,18 +267,35 @@ void loop()
|
||||
DTC_Process();
|
||||
Debug_Process();
|
||||
|
||||
// Handle OTA updates and update cyclic EEPROM tasks for Persistence Data Structure (PDS)
|
||||
ArduinoOTA.handle();
|
||||
EEPROMCyclicPDSTicker.update();
|
||||
|
||||
#ifdef FEATURE_ENABLE_WIFI_CLIENT
|
||||
// Update WiFi connection maintenance ticker if WiFi client feature is enabled
|
||||
WiFiMaintainConnectionTicker.update();
|
||||
#endif
|
||||
|
||||
// Perform system shutdown if the status is set to shutdown
|
||||
if (globals.systemStatus == sysStat_Shutdown)
|
||||
SystemShutdown();
|
||||
SystemShutdown(false);
|
||||
|
||||
// Yield to allow other tasks to run
|
||||
yield();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts an IPAddress object to a String representation.
|
||||
*
|
||||
* This function takes an IPAddress object and converts it into a String representing
|
||||
* the IPv4 address. Each octet of the address is separated by a dot.
|
||||
*
|
||||
* @param ipAddress The IPAddress object to be converted.
|
||||
* @return A String representing the IPv4 address.
|
||||
*/
|
||||
String IpAddress2String(const IPAddress &ipAddress)
|
||||
{
|
||||
// Concatenate each octet of the IPAddress with dots in between
|
||||
return String(ipAddress[0]) + String(".") +
|
||||
String(ipAddress[1]) + String(".") +
|
||||
String(ipAddress[2]) + String(".") +
|
||||
@ -214,42 +303,80 @@ String IpAddress2String(const IPAddress &ipAddress)
|
||||
}
|
||||
|
||||
#ifdef FEATURE_ENABLE_WIFI_CLIENT
|
||||
/**
|
||||
* @brief Callback function for maintaining WiFi connection and handling connection failures.
|
||||
*
|
||||
* This callback function is used by a ticker to periodically check the WiFi connection status.
|
||||
* If the device is not connected to WiFi, it counts connection failures. If the number of failures
|
||||
* exceeds a defined threshold, the function triggers the initiation of an Access Point (AP) mode
|
||||
* using the `toggleWiFiAP` function.
|
||||
*/
|
||||
void wifiMaintainConnectionTicker_callback()
|
||||
{
|
||||
// Static variables to track WiFi connection failure count and maximum allowed failures
|
||||
static uint32_t WiFiFailCount = 0;
|
||||
const uint32_t WiFiFailMax = 20;
|
||||
|
||||
// Check if the device is connected to WiFi
|
||||
if (wifiMulti.run(connectTimeoutMs) == WL_CONNECTED)
|
||||
{
|
||||
return;
|
||||
return; // Exit if connected
|
||||
}
|
||||
else
|
||||
{
|
||||
// Increment WiFi connection failure count
|
||||
if (WiFiFailCount < WiFiFailMax)
|
||||
{
|
||||
WiFiFailCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trigger AP mode if the maximum failures are reached
|
||||
Debug_pushMessage("WiFi not connected! - Start AP");
|
||||
toggleWiFiAP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Callback function for cyclically storing Persistence Data Structure (PDS) to EEPROM.
|
||||
*
|
||||
* This callback function is invoked periodically to store the Persistence Data Structure (PDS)
|
||||
* to the EEPROM. It ensures that essential data is saved persistently, allowing the system to
|
||||
* recover its state after power cycles or resets.
|
||||
*/
|
||||
void EEPROMCyclicPDS_callback()
|
||||
{
|
||||
StorePersistence_EEPROM();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interrupt Service Routine (ISR) triggered by wheel speed sensor pulses.
|
||||
*
|
||||
* This ISR is called whenever a pulse is detected from the wheel speed sensor. It increments
|
||||
* the `wheel_pulse` variable, which is used to track the number of pulses received.
|
||||
*/
|
||||
void trigger_ISR()
|
||||
{
|
||||
wheel_pulse++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Manages LED behavior based on the current system status and user overrides.
|
||||
*
|
||||
* This function handles LED behavior, including startup animations, confirmation animations for
|
||||
* normal and rain modes, indication for purge, error, shutdown, and normal operation. It supports
|
||||
* user overrides to set a specific LED color. The LED status is determined by the current system
|
||||
* status, and specific LED patterns are displayed accordingly.
|
||||
*
|
||||
* @param override Flag indicating whether to override the LED behavior (0: No override, 1: Override, 2: Resume previous state).
|
||||
* @param SetColor The color to set when overriding the LED behavior.
|
||||
*/
|
||||
void LED_Process(uint8_t override, uint32_t SetColor)
|
||||
{
|
||||
// Enumeration to represent LED status
|
||||
typedef enum
|
||||
{
|
||||
LED_Startup,
|
||||
@ -263,17 +390,20 @@ void LED_Process(uint8_t override, uint32_t SetColor)
|
||||
LED_Override
|
||||
} tLED_Status;
|
||||
|
||||
// Static variables to track LED status, system status, override color, and previous LED status
|
||||
static tSystem_Status oldSysStatus = sysStat_Startup;
|
||||
static tLED_Status LED_Status = LED_Startup;
|
||||
static uint32_t LED_override_color = 0;
|
||||
static tLED_Status LED_ResumeOverrideStatus = LED_Startup;
|
||||
|
||||
// Variables for managing LED animation timing
|
||||
uint8_t color = 0;
|
||||
uint32_t timer = 0;
|
||||
uint32_t animtimer = 0;
|
||||
static uint32_t timestamp = 0;
|
||||
timer = millis();
|
||||
|
||||
// Handle LED overrides
|
||||
if (override == 1)
|
||||
{
|
||||
if (LED_Status != LED_Override)
|
||||
@ -294,6 +424,7 @@ void LED_Process(uint8_t override, uint32_t SetColor)
|
||||
}
|
||||
}
|
||||
|
||||
// Update LED status when system status changes
|
||||
if (oldSysStatus != globals.systemStatus)
|
||||
{
|
||||
switch (globals.systemStatus)
|
||||
@ -330,6 +461,7 @@ void LED_Process(uint8_t override, uint32_t SetColor)
|
||||
oldSysStatus = globals.systemStatus;
|
||||
}
|
||||
|
||||
// Handle different LED statuses
|
||||
switch (LED_Status)
|
||||
{
|
||||
case LED_Startup:
|
||||
@ -433,28 +565,47 @@ void LED_Process(uint8_t override, uint32_t SetColor)
|
||||
}
|
||||
leds.show();
|
||||
}
|
||||
|
||||
#ifdef FEATURE_ENABLE_OLED
|
||||
/**
|
||||
* @brief Manages the display content based on the current system status and updates the OLED display.
|
||||
*
|
||||
* This function handles the content to be displayed on the OLED screen, taking into account the
|
||||
* current system status. It clears the display and prints relevant information such as system mode,
|
||||
* remaining lubrication distance, tank level, WiFi status, speed source, and IP address. Additionally,
|
||||
* it refreshes the OLED display with the updated content.
|
||||
*/
|
||||
void Display_Process()
|
||||
{
|
||||
// Static variable to track the previous system status
|
||||
static tSystem_Status oldSysStatus = sysStat_Startup;
|
||||
|
||||
// Check if the system status has changed since the last update
|
||||
if (oldSysStatus != globals.systemStatus)
|
||||
{
|
||||
// Clear the display and print the system title when the status changes
|
||||
u8x8.clearDisplay();
|
||||
u8x8.drawString(0, 0, "KTM ChainLube V1");
|
||||
oldSysStatus = globals.systemStatus;
|
||||
}
|
||||
|
||||
// Set the cursor position for displaying information on the OLED screen
|
||||
u8x8.setCursor(0, 1);
|
||||
|
||||
// Calculate remaining lubrication distance based on system mode
|
||||
uint32_t DistRemain = globals.systemStatus == sysStat_Normal ? LubeConfig.DistancePerLube_Default : LubeConfig.DistancePerLube_Rain;
|
||||
DistRemain = DistRemain - (PersistenceData.TravelDistance_highRes_mm / 1000);
|
||||
|
||||
// Display relevant information on the OLED screen based on system status
|
||||
u8x8.printf(PSTR("Mode: %10s\n"), globals.systemStatustxt);
|
||||
if (globals.systemStatus == sysStat_Error)
|
||||
{
|
||||
// Display the last Diagnostic Trouble Code (DTC) in case of an error
|
||||
u8x8.printf(PSTR("last DTC: %6d\n"), getlastDTC(false));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display information such as next lubrication distance, tank level, WiFi status, speed source, and IP address
|
||||
u8x8.printf(PSTR("next Lube: %4dm\n"), DistRemain);
|
||||
u8x8.printf(PSTR("Tank: %8dml\n"), PersistenceData.tankRemain_microL / 1000);
|
||||
u8x8.printf(PSTR("WiFi: %10s\n"), (WiFi.getMode() == WIFI_AP ? "AP" : WiFi.getMode() == WIFI_OFF ? "OFF"
|
||||
@ -463,18 +614,29 @@ void Display_Process()
|
||||
u8x8.printf(PSTR("Source: %8s\n"), SpeedSourceString[LubeConfig.SpeedSource]);
|
||||
u8x8.printf("%s\n", WiFi.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
// Refresh the OLED display with the updated content
|
||||
u8x8.refreshDisplay();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Processes the button input and performs corresponding actions based on button state and timing.
|
||||
*
|
||||
* This function handles the button input, detecting button presses and executing actions based on
|
||||
* predefined time delays. Actions include toggling WiFi, starting purge, toggling operating modes,
|
||||
* and displaying feedback through LEDs. The function utilizes an enumeration to track button actions
|
||||
* and manages the timing for different actions.
|
||||
*/
|
||||
void Button_Process()
|
||||
{
|
||||
|
||||
// Time delays for different button actions
|
||||
#define BUTTON_ACTION_DELAY_TOGGLEMODE 500
|
||||
#define BUTTON_ACTION_DELAY_PURGE 3500
|
||||
#define BUTTON_ACTION_DELAY_WIFI 6500
|
||||
#define BUTTON_ACTION_DELAY_NOTHING 9500
|
||||
|
||||
// Enumeration to represent button actions
|
||||
typedef enum buttonAction_e
|
||||
{
|
||||
BTN_INACTIVE,
|
||||
@ -484,15 +646,18 @@ void Button_Process()
|
||||
BTN_STARTPURGE
|
||||
} buttonAction_t;
|
||||
|
||||
// Static variables to track button state and timing
|
||||
static uint32_t buttonTimestamp = 0;
|
||||
static buttonAction_t buttonAction = BTN_INACTIVE;
|
||||
|
||||
// Check if button is pressed (LOW)
|
||||
if (digitalRead(GPIO_BUTTON) == LOW)
|
||||
{
|
||||
|
||||
// Update button timestamp on the first button press
|
||||
if (buttonTimestamp == 0)
|
||||
buttonTimestamp = millis();
|
||||
|
||||
// Check and execute actions based on predefined time delays
|
||||
if (buttonTimestamp + BUTTON_ACTION_DELAY_NOTHING < millis())
|
||||
{
|
||||
LED_Process(1, COLOR_WARM_WHITE);
|
||||
@ -515,8 +680,9 @@ void Button_Process()
|
||||
buttonAction = BTN_TOGGLEMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
else // Button is released
|
||||
{
|
||||
// Execute corresponding actions based on the detected button action
|
||||
if (buttonAction != BTN_INACTIVE)
|
||||
{
|
||||
switch (buttonAction)
|
||||
@ -544,6 +710,7 @@ void Button_Process()
|
||||
globals.systemStatus = sysStat_Normal;
|
||||
globals.resumeStatus = sysStat_Normal;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -555,28 +722,49 @@ void Button_Process()
|
||||
Debug_pushMessage("Nothing or invalid\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// Display feedback through LEDs
|
||||
LED_Process(2);
|
||||
}
|
||||
|
||||
// Reset button state and timestamp
|
||||
buttonAction = BTN_INACTIVE;
|
||||
buttonTimestamp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void toggleWiFiAP(boolean shutdown)
|
||||
/**
|
||||
* @brief Toggles the WiFi functionality based on the current status.
|
||||
*
|
||||
* This function manages the WiFi state, either turning it off or starting it as an Access Point (AP),
|
||||
* depending on the current mode. If the WiFi is turned off, it can be started in AP mode with the
|
||||
* device name and password configured. Additionally, it may stop certain operations related to WiFi
|
||||
* maintenance or display debug messages based on the defined features.
|
||||
*
|
||||
* @param shutdown Flag indicating whether the system is in a shutdown state.
|
||||
*/
|
||||
void toggleWiFiAP(bool shutdown)
|
||||
{
|
||||
// Check if WiFi is currently active
|
||||
if (WiFi.getMode() != WIFI_OFF)
|
||||
{
|
||||
// Turn off WiFi
|
||||
WiFi.mode(WIFI_OFF);
|
||||
Debug_pushMessage("WiFi turned off\n");
|
||||
|
||||
// Stop WiFi maintenance connection ticker if enabled
|
||||
#ifdef FEATURE_ENABLE_WIFI_CLIENT
|
||||
WiFiMaintainConnectionTicker.stop();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start WiFi in Access Point (AP) mode
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAPConfig(IPAddress(WIFI_AP_IP_GW), IPAddress(WIFI_AP_IP_GW), IPAddress(255, 255, 255, 0));
|
||||
WiFi.softAP(globals.DeviceName, QUOTE(WIFI_AP_PASSWORD));
|
||||
|
||||
// Stop WiFi maintenance connection ticker if enabled and display debug messages
|
||||
#ifdef FEATURE_ENABLE_WIFI_CLIENT
|
||||
WiFiMaintainConnectionTicker.stop();
|
||||
Debug_pushMessage("WiFi AP started, stopped Maintain-Timer\n");
|
||||
@ -586,23 +774,51 @@ void toggleWiFiAP(boolean shutdown)
|
||||
}
|
||||
}
|
||||
|
||||
void SystemShutdown()
|
||||
/**
|
||||
* @brief Performs necessary tasks before shutting down and optionally restarts the ESP.
|
||||
*
|
||||
* This function initiates a system shutdown, performing tasks such as storing configuration
|
||||
* and persistence data to EEPROM before shutting down. If a restart is requested, the ESP
|
||||
* will be restarted; otherwise, the system will enter an indefinite loop.
|
||||
*
|
||||
* @param restart Flag indicating whether to restart the ESP after shutdown (default: false).
|
||||
*/
|
||||
void SystemShutdown(bool restart)
|
||||
{
|
||||
static uint32_t shutdown_delay = 0;
|
||||
|
||||
// Initialize shutdown delay on the first call
|
||||
if (shutdown_delay == 0)
|
||||
{
|
||||
shutdown_delay = millis() + SHUTDOWN_DELAY_MS;
|
||||
Serial.printf("Shutdown requested - Restarting in %d seconds\n", SHUTDOWN_DELAY_MS / 1000);
|
||||
}
|
||||
|
||||
// Check if the shutdown delay has elapsed
|
||||
if (shutdown_delay < millis())
|
||||
{
|
||||
// Store configuration and persistence data to EEPROM
|
||||
StoreConfig_EEPROM();
|
||||
StorePersistence_EEPROM();
|
||||
ESP.restart();
|
||||
|
||||
// Perform restart if requested, otherwise enter an indefinite loop
|
||||
if (restart)
|
||||
ESP.restart();
|
||||
else
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the impulses from the wheel speed sensor and converts them into traveled distance.
|
||||
*
|
||||
* This function takes the pulse count from the wheel speed sensor and converts it into distance
|
||||
* traveled in millimeters. The conversion is based on the configured parameters such as the number
|
||||
* of pulses per revolution and the distance traveled per revolution.
|
||||
*
|
||||
* @return The calculated distance traveled in millimeters.
|
||||
*/
|
||||
uint32_t Process_Impulse_WheelSpeed()
|
||||
{
|
||||
uint32_t add_milimeters = 0;
|
||||
|
@ -7,7 +7,6 @@ const char *PARAM_MESSAGE = "message";
|
||||
String processor(const String &var);
|
||||
void WebserverPOST_Callback(AsyncWebServerRequest *request);
|
||||
void WebserverNotFound_Callback(AsyncWebServerRequest *request);
|
||||
void Webserver_Callback(AsyncWebServerRequest *request);
|
||||
void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void WebServerEEJSON_Callback(AsyncWebServerRequest *request);
|
||||
@ -46,11 +45,10 @@ void initWebUI()
|
||||
webServer.addHandler(&webSocket);
|
||||
|
||||
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
|
||||
webServer.serveStatic("/index.htm", LittleFS, "/index.htm").setCacheControl("max-age=360000");
|
||||
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
|
||||
{ request->redirect("/index.htm"); });
|
||||
webServer.onNotFound(WebserverNotFound_Callback);
|
||||
webServer.on("/index.htm", HTTP_GET, Webserver_Callback);
|
||||
webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback);
|
||||
webServer.on("/eejson", HTTP_GET, WebServerEEJSON_Callback);
|
||||
webServer.on(
|
||||
"/doUpdate", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverFirmwareUpdate_Callback);
|
||||
@ -74,147 +72,6 @@ void Webserver_Process()
|
||||
}
|
||||
}
|
||||
|
||||
String processor(const String &var)
|
||||
{
|
||||
if (var == "HOSTNAME")
|
||||
return String(globals.DeviceName);
|
||||
if (var == "TANK_REMAIN_CAPACITY")
|
||||
return String((PersistenceData.tankRemain_microL / 10) / LubeConfig.tankCapacity_ml);
|
||||
if (var == "LUBE_DISTANCE_NORMAL")
|
||||
return String(LubeConfig.DistancePerLube_Default);
|
||||
if (var == "LUBE_DISTANCE_RAIN")
|
||||
return String(LubeConfig.DistancePerLube_Rain);
|
||||
if (var == "TANK_CAPACITY")
|
||||
return String(LubeConfig.tankCapacity_ml);
|
||||
if (var == "AMOUNT_PER_DOSE")
|
||||
return String(LubeConfig.amountPerDose_microL);
|
||||
if (var == "TANK_REMIND")
|
||||
return String(LubeConfig.TankRemindAtPercentage);
|
||||
if (var == "PULSE_PER_REV")
|
||||
return String(LubeConfig.PulsePerRevolution);
|
||||
if (var == "TIRE_WIDTH_MM")
|
||||
return String(LubeConfig.TireWidth_mm);
|
||||
if (var == "TIRE_RATIO")
|
||||
return String(LubeConfig.TireWidthHeight_Ratio);
|
||||
if (var == "RIM_DIAMETER")
|
||||
return String(LubeConfig.RimDiameter_Inch);
|
||||
if (var == "DISTANCE_PER_REV")
|
||||
return String(LubeConfig.DistancePerRevolution_mm);
|
||||
if (var == "BLEEDING_PULSES")
|
||||
return String(LubeConfig.BleedingPulses);
|
||||
if (var == "SPEED_SOURCE")
|
||||
return String(SpeedSourceString[LubeConfig.SpeedSource]);
|
||||
if (var == "GPS_BAUD")
|
||||
return String(GPSBaudRateString[LubeConfig.GPSBaudRate]);
|
||||
if (var == "CAN_SOURCE")
|
||||
return String(CANSourceString[LubeConfig.CANSource]);
|
||||
if (var == "LED_MODE_FLASH")
|
||||
return String(LubeConfig.LED_Mode_Flash);
|
||||
if (var == "LEDFLASHCHECKED")
|
||||
return String(LubeConfig.LED_Mode_Flash == true ? "checked" : "");
|
||||
if (var == "LED_MAX_BRIGHTNESS")
|
||||
return String(LubeConfig.LED_Max_Brightness);
|
||||
if (var == "LED_MIN_BRIGHTNESS")
|
||||
return String(LubeConfig.LED_Min_Brightness);
|
||||
if (var == "EEPROM_VERSION")
|
||||
return String(LubeConfig.EEPROM_Version);
|
||||
if (var == "CONFIG_CHECKSUM")
|
||||
{
|
||||
char buffer[7];
|
||||
sprintf(buffer, "0x%04X", LubeConfig.checksum);
|
||||
return String(buffer);
|
||||
}
|
||||
if (var == "WRITE_CYCLE_COUNT")
|
||||
return String(PersistenceData.writeCycleCounter);
|
||||
if (var == "PERSISTENCE_MARKER")
|
||||
return String(globals.eePersistanceAdress);
|
||||
if (var == "TANK_REMAIN_UL")
|
||||
return String(PersistenceData.tankRemain_microL);
|
||||
if (var == "TRAVEL_DISTANCE_HIGHRES")
|
||||
return String(PersistenceData.TravelDistance_highRes_mm);
|
||||
if (var == "ODOMETER")
|
||||
return String(PersistenceData.odometer);
|
||||
if (var == "ODOMETER_M")
|
||||
return String(PersistenceData.odometer_mm / 1000);
|
||||
if (var == "PERSISTANCE_CHECKSUM")
|
||||
{
|
||||
char buffer[7];
|
||||
sprintf(buffer, "0x%04X", PersistenceData.checksum);
|
||||
return String(buffer);
|
||||
}
|
||||
if (var == "SHOW_IMPULSE_SETTINGS")
|
||||
return LubeConfig.SpeedSource == SOURCE_IMPULSE ? "" : "hidden";
|
||||
if (var == "SHOW_CAN_SETTINGS")
|
||||
return LubeConfig.SpeedSource == SOURCE_CAN ? "" : "hidden";
|
||||
if (var == "SHOW_GPS_SETTINGS")
|
||||
return LubeConfig.SpeedSource == SOURCE_GPS ? "" : "hidden";
|
||||
|
||||
if (var == "SOURCE_SELECT_OPTIONS")
|
||||
{
|
||||
String temp;
|
||||
for (uint32_t i = 0; i < SpeedSourceString_Elements; i++)
|
||||
{
|
||||
String selected = LubeConfig.SpeedSource == i ? " selected " : "";
|
||||
temp = temp + "<option value=\"" + i + "\"" + selected + ">" + SpeedSourceString[i] + "</option>";
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
if (var == "CANSOURCE_SELECT_OPTIONS")
|
||||
{
|
||||
String temp;
|
||||
for (uint32_t i = 0; i < CANSourceString_Elements; i++)
|
||||
{
|
||||
String selected = LubeConfig.CANSource == i ? " selected " : "";
|
||||
temp = temp + "<option value=\"" + i + "\"" + selected + ">" + CANSourceString[i] + "</option>";
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
if (var == "GPSBAUD_SELECT_OPTIONS")
|
||||
{
|
||||
String temp;
|
||||
for (uint32_t i = 0; i < GPSBaudRateString_Elements; i++)
|
||||
{
|
||||
String selected = LubeConfig.GPSBaudRate == i ? " selected " : "";
|
||||
temp = temp + "<option value=\"" + i + "\"" + selected + ">" + GPSBaudRateString[i] + "</option>";
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
if (var == "SYSTEM_STATUS")
|
||||
return String(globals.systemStatustxt);
|
||||
|
||||
if (var == "SW_VERSION")
|
||||
{
|
||||
char buffer[6];
|
||||
snprintf(buffer, sizeof(buffer), "%d.%02d", constants.FW_Version_major, constants.FW_Version_minor);
|
||||
return String(buffer);
|
||||
}
|
||||
|
||||
if (var == "FS_VERSION")
|
||||
return String(globals.FlashVersion);
|
||||
|
||||
if (var == "GIT_REV")
|
||||
return String(constants.GitHash);
|
||||
|
||||
if (var == "MEASURED_PULSES")
|
||||
return String(globals.measuredPulses);
|
||||
|
||||
if (var == "MEASURE_BTN")
|
||||
return String(globals.measurementActive == true ? "Stop" : "Start");
|
||||
|
||||
if (var == "PLACEHOLDER")
|
||||
return "placeholder";
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
void Webserver_Callback(AsyncWebServerRequest *request)
|
||||
{
|
||||
request->send(LittleFS, "/index.htm", "text/html", false, processor);
|
||||
}
|
||||
|
||||
void WebserverPOST_Callback(AsyncWebServerRequest *request)
|
||||
{
|
||||
request->send(LittleFS, "/post.htm", "text/html", false, processor);
|
||||
@ -647,13 +504,8 @@ void Websocket_RefreshClientData_Status(uint32_t client_id, bool send_mapping)
|
||||
{
|
||||
const char mapping[] = "MAPPING_STATUS:"
|
||||
"SystemStatus;"
|
||||
"TankRemain;"
|
||||
"TravelDistance_hr;"
|
||||
"Odometer;"
|
||||
"Odometer_mm;"
|
||||
"writeCycleCounter;"
|
||||
"BleedingPulses;"
|
||||
"TankPercent;";
|
||||
"tankremain;"
|
||||
"Odometer;";
|
||||
|
||||
if (client_id > 0)
|
||||
webSocket.text(client_id, mapping);
|
||||
@ -664,13 +516,8 @@ void Websocket_RefreshClientData_Status(uint32_t client_id, bool send_mapping)
|
||||
String temp = "STATUS:";
|
||||
|
||||
temp.concat(String(globals.systemStatustxt) + ";");
|
||||
temp.concat(String(PersistenceData.tankRemain_microL) + ";");
|
||||
temp.concat(String(PersistenceData.TravelDistance_highRes_mm) + ";");
|
||||
temp.concat(String(PersistenceData.odometer) + ";");
|
||||
temp.concat(String(PersistenceData.odometer_mm / 1000) + ";");
|
||||
temp.concat(String(PersistenceData.writeCycleCounter) + ";");
|
||||
temp.concat(String(LubeConfig.BleedingPulses) + ";");
|
||||
temp.concat(String((PersistenceData.tankRemain_microL / 10) / LubeConfig.tankCapacity_ml) + ";");
|
||||
temp.concat(String(PersistenceData.odometer + (PersistenceData.odometer_mm / 1000)) + ";");
|
||||
|
||||
if (client_id > 0)
|
||||
{
|
||||
@ -688,27 +535,26 @@ void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping)
|
||||
if (send_mapping)
|
||||
{
|
||||
const char mapping[] = "MAPPING_STATIC:"
|
||||
"DeviceName;"
|
||||
"EEPROM_Version;"
|
||||
"ConfigChecksum;"
|
||||
"DistanceDefault;"
|
||||
"DistanceRain;"
|
||||
"tankCapacity;"
|
||||
"amountPerDose;"
|
||||
"TankRemindAtPercentage;"
|
||||
"PulsePerRevolution;"
|
||||
"TireWidth_mm;"
|
||||
"TireWidthHeight_Ratio;"
|
||||
"RimDiameter_Inch;"
|
||||
"lubedistancenormal;"
|
||||
"lubedistancerain;"
|
||||
"tankcap;"
|
||||
"pumppulse;"
|
||||
"tankwarn;"
|
||||
"pulserev;"
|
||||
"tirewidth;"
|
||||
"tireratio;"
|
||||
"tiredia;"
|
||||
"DistancePerRevolution_mm;"
|
||||
"SpeedSourceString;"
|
||||
"GPSBaudRateString;"
|
||||
"CANSourceString;"
|
||||
"LED_Mode_Flash;"
|
||||
"LED_Max;"
|
||||
"LED_Min;"
|
||||
"eePersistanceAdress;"
|
||||
"PersisChecksum";
|
||||
"sourceselect;"
|
||||
"gpsbaud;"
|
||||
"cansource;"
|
||||
"ledmodeflash;"
|
||||
"ledmaxbrightness;"
|
||||
"ledminbrightness;"
|
||||
"showimpulse;"
|
||||
"showgps;"
|
||||
"showcan;"
|
||||
"BleedingPulses;";
|
||||
|
||||
if (client_id > 0)
|
||||
webSocket.text(client_id, mapping);
|
||||
@ -718,9 +564,6 @@ void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping)
|
||||
|
||||
String temp = "STATIC:";
|
||||
|
||||
temp.concat(String(globals.DeviceName) + ";");
|
||||
temp.concat(String(LubeConfig.EEPROM_Version) + ";");
|
||||
temp.concat(String(LubeConfig.checksum) + ";");
|
||||
temp.concat(String(LubeConfig.DistancePerLube_Default) + ";");
|
||||
temp.concat(String(LubeConfig.DistancePerLube_Rain) + ";");
|
||||
temp.concat(String(LubeConfig.tankCapacity_ml) + ";");
|
||||
@ -734,11 +577,13 @@ void Websocket_RefreshClientData_Static(uint32_t client_id, bool send_mapping)
|
||||
temp.concat(String(SpeedSourceString[LubeConfig.SpeedSource]) + ";");
|
||||
temp.concat(String(GPSBaudRateString[LubeConfig.GPSBaudRate]) + ";");
|
||||
temp.concat(String(CANSourceString[LubeConfig.CANSource]) + ";");
|
||||
temp.concat(String(LubeConfig.LED_Mode_Flash) + ";");
|
||||
temp.concat(String(LubeConfig.LED_Mode_Flash == true ? "1" : "0") + ";");
|
||||
temp.concat(String(LubeConfig.LED_Max_Brightness) + ";");
|
||||
temp.concat(String(LubeConfig.LED_Min_Brightness) + ";");
|
||||
temp.concat(String(globals.eePersistanceAdress) + ";");
|
||||
temp.concat(String(PersistenceData.checksum) + ";");
|
||||
temp.concat(String(LubeConfig.SpeedSource == SOURCE_IMPULSE ? "1" : "0") + ";");
|
||||
temp.concat(String(LubeConfig.SpeedSource == SOURCE_GPS ? "1" : "0") + ";");
|
||||
temp.concat(String(LubeConfig.SpeedSource == SOURCE_CAN ? "1" : "0") + ";");
|
||||
temp.concat(String(LubeConfig.BleedingPulses) + ";");
|
||||
|
||||
for (uint32_t i = 0; i < SpeedSourceString_Elements; i++)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user