Fixed Filters, split file in html, script and css
This commit is contained in:
@@ -3,37 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>ESP32 Dashboard</title>
|
<title>ESP32 Dashboard</title>
|
||||||
<style>
|
<link rel="stylesheet" href="style.css">
|
||||||
body {
|
|
||||||
font-family: Arial;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
margin: auto;
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 900px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th, td {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 10px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background-color: #f4f4f4;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -44,6 +14,7 @@
|
|||||||
|
|
||||||
<div style="max-width: 900px; margin: 0 auto; text-align: left;">
|
<div style="max-width: 900px; margin: 0 auto; text-align: left;">
|
||||||
<p><strong>Timestamp:</strong> <span id="timestamp">-</span></p>
|
<p><strong>Timestamp:</strong> <span id="timestamp">-</span></p>
|
||||||
|
<p><strong>Data Valid:</strong> <span id="datavalid">-</span></p>
|
||||||
<p><strong>Generator voltage:</strong> <span id="volts_gen">-</span></p>
|
<p><strong>Generator voltage:</strong> <span id="volts_gen">-</span></p>
|
||||||
<p><strong>Engine RPM:</strong> <span id="eng_rpm">-</span></p>
|
<p><strong>Engine RPM:</strong> <span id="eng_rpm">-</span></p>
|
||||||
<p><strong>ADC read time:</strong> <span id="adc_read_time">-</span></p>
|
<p><strong>ADC read time:</strong> <span id="adc_read_time">-</span></p>
|
||||||
@@ -58,16 +29,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
|
||||||
<td>Trigger time</td>
|
|
||||||
<td id="coils12_trig_time">-</td>
|
|
||||||
<td id="coils34_trig_time">-</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Spark time</td>
|
|
||||||
<td id="coils12_spark_time">-</td>
|
|
||||||
<td id="coils34_spark_time">-</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Spark delay</td>
|
<td>Spark delay</td>
|
||||||
<td id="coils12_spark_delay">-</td>
|
<td id="coils12_spark_delay">-</td>
|
||||||
@@ -122,77 +83,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script src="script.js"></script>
|
||||||
let ws;
|
|
||||||
|
|
||||||
function connectWS() {
|
|
||||||
ws = new WebSocket("ws://" + location.host + "/ws");
|
|
||||||
|
|
||||||
ws.onopen = () => {
|
|
||||||
console.log("WebSocket connesso");
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = () => {
|
|
||||||
console.log("WebSocket disconnesso, retry...");
|
|
||||||
setTimeout(connectWS, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
let data;
|
|
||||||
|
|
||||||
try {
|
|
||||||
data = JSON.parse(event.data);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Invalid JSON received", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("timestamp").textContent = data.timestamp ?? "-";
|
|
||||||
document.getElementById("volts_gen").textContent = data.volts_gen ?? "-";
|
|
||||||
document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-";
|
|
||||||
document.getElementById("adc_read_time").textContent = data.adc_read_time ?? "-";
|
|
||||||
document.getElementById("n_queue_errors").textContent = data.n_queue_errors ?? "-";
|
|
||||||
|
|
||||||
const coils12 = data.coils12 || {};
|
|
||||||
const coils34 = data.coils34 || {};
|
|
||||||
|
|
||||||
document.getElementById("coils12_trig_time").textContent = coils12.trig_time ?? "-";
|
|
||||||
document.getElementById("coils34_trig_time").textContent = coils34.trig_time ?? "-";
|
|
||||||
document.getElementById("coils12_spark_time").textContent = coils12.spark_time ?? "-";
|
|
||||||
document.getElementById("coils34_spark_time").textContent = coils34.spark_time ?? "-";
|
|
||||||
document.getElementById("coils12_spark_delay").textContent = coils12.spark_delay ?? "-";
|
|
||||||
document.getElementById("coils34_spark_delay").textContent = coils34.spark_delay ?? "-";
|
|
||||||
document.getElementById("coils12_spark_status").textContent = coils12.spark_status ?? "-";
|
|
||||||
document.getElementById("coils34_spark_status").textContent = coils34.spark_status ?? "-";
|
|
||||||
document.getElementById("coils12_sstart_status").textContent = coils12.sstart_status ?? "-";
|
|
||||||
document.getElementById("coils34_sstart_status").textContent = coils34.sstart_status ?? "-";
|
|
||||||
document.getElementById("coils12_peak_p_in").textContent = coils12.peak_p_in ?? "-";
|
|
||||||
document.getElementById("coils34_peak_p_in").textContent = coils34.peak_p_in ?? "-";
|
|
||||||
document.getElementById("coils12_peak_n_in").textContent = coils12.peak_n_in ?? "-";
|
|
||||||
document.getElementById("coils34_peak_n_in").textContent = coils34.peak_n_in ?? "-";
|
|
||||||
document.getElementById("coils12_peak_p_out").textContent = coils12.peak_p_out ?? "-";
|
|
||||||
document.getElementById("coils34_peak_p_out").textContent = coils34.peak_p_out ?? "-";
|
|
||||||
document.getElementById("coils12_peak_n_out").textContent = coils12.peak_n_out ?? "-";
|
|
||||||
document.getElementById("coils34_peak_n_out").textContent = coils34.peak_n_out ?? "-";
|
|
||||||
document.getElementById("coils12_level_spark").textContent = coils12.level_spark ?? "-";
|
|
||||||
document.getElementById("coils34_level_spark").textContent = coils34.level_spark ?? "-";
|
|
||||||
document.getElementById("coils12_n_events").textContent = coils12.n_events ?? "-";
|
|
||||||
document.getElementById("coils34_n_events").textContent = coils34.n_events ?? "-";
|
|
||||||
document.getElementById("coils12_n_missed_firing").textContent = coils12.n_missed_firing ?? "-";
|
|
||||||
document.getElementById("coils34_n_missed_firing").textContent = coils34.n_missed_firing ?? "-";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
fetch("/start");
|
|
||||||
}
|
|
||||||
|
|
||||||
function stop() {
|
|
||||||
fetch("/stop");
|
|
||||||
}
|
|
||||||
|
|
||||||
connectWS();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
66
RotaxMonitor/data/script.js
Normal file
66
RotaxMonitor/data/script.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
let ws;
|
||||||
|
|
||||||
|
function connectWS() {
|
||||||
|
ws = new WebSocket("ws://" + location.host + "/ws");
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log("WebSocket connesso");
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log("WebSocket disconnesso, retry...");
|
||||||
|
setTimeout(connectWS, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
let data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = JSON.parse(event.data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Invalid JSON received", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("datavalid").textContent = data.datavalid ?? "-";
|
||||||
|
document.getElementById("timestamp").textContent = data.timestamp ?? "-";
|
||||||
|
document.getElementById("volts_gen").textContent = data.volts_gen ?? "-";
|
||||||
|
document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-";
|
||||||
|
document.getElementById("adc_read_time").textContent = data.adc_read_time ?? "-";
|
||||||
|
document.getElementById("n_queue_errors").textContent = data.n_queue_errors ?? "-";
|
||||||
|
|
||||||
|
const coils12 = data.coils12 || {};
|
||||||
|
const coils34 = data.coils34 || {};
|
||||||
|
|
||||||
|
document.getElementById("coils12_spark_delay").textContent = coils12.spark_delay ?? "-";
|
||||||
|
document.getElementById("coils34_spark_delay").textContent = coils34.spark_delay ?? "-";
|
||||||
|
document.getElementById("coils12_spark_status").textContent = coils12.spark_status ?? "-";
|
||||||
|
document.getElementById("coils34_spark_status").textContent = coils34.spark_status ?? "-";
|
||||||
|
document.getElementById("coils12_sstart_status").textContent = coils12.sstart_status ?? "-";
|
||||||
|
document.getElementById("coils34_sstart_status").textContent = coils34.sstart_status ?? "-";
|
||||||
|
document.getElementById("coils12_peak_p_in").textContent = coils12.peak_p_in ?? "-";
|
||||||
|
document.getElementById("coils34_peak_p_in").textContent = coils34.peak_p_in ?? "-";
|
||||||
|
document.getElementById("coils12_peak_n_in").textContent = coils12.peak_n_in ?? "-";
|
||||||
|
document.getElementById("coils34_peak_n_in").textContent = coils34.peak_n_in ?? "-";
|
||||||
|
document.getElementById("coils12_peak_p_out").textContent = coils12.peak_p_out ?? "-";
|
||||||
|
document.getElementById("coils34_peak_p_out").textContent = coils34.peak_p_out ?? "-";
|
||||||
|
document.getElementById("coils12_peak_n_out").textContent = coils12.peak_n_out ?? "-";
|
||||||
|
document.getElementById("coils34_peak_n_out").textContent = coils34.peak_n_out ?? "-";
|
||||||
|
document.getElementById("coils12_level_spark").textContent = coils12.level_spark ?? "-";
|
||||||
|
document.getElementById("coils34_level_spark").textContent = coils34.level_spark ?? "-";
|
||||||
|
document.getElementById("coils12_n_events").textContent = coils12.n_events ?? "-";
|
||||||
|
document.getElementById("coils34_n_events").textContent = coils34.n_events ?? "-";
|
||||||
|
document.getElementById("coils12_n_missed_firing").textContent = coils12.n_missed_firing ?? "-";
|
||||||
|
document.getElementById("coils34_n_missed_firing").textContent = coils34.n_missed_firing ?? "-";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
fetch("/start");
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
fetch("/stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
connectWS();
|
||||||
29
RotaxMonitor/data/style.css
Normal file
29
RotaxMonitor/data/style.css
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
@@ -1,7 +1,20 @@
|
|||||||
#include "datasave.h"
|
#include "datasave.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB)
|
static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB)
|
||||||
|
|
||||||
|
void ignitionBoxStatusAverage::filter(int32_t &old, const int32_t value, const uint32_t k)
|
||||||
|
{
|
||||||
|
float alpha = 1.0f / (float)k;
|
||||||
|
old = old + (int32_t)(alpha * (float)(value - old));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ignitionBoxStatusAverage::filter(float &old, const float value, const uint32_t k)
|
||||||
|
{
|
||||||
|
float alpha = 1.0f / (float)k;
|
||||||
|
old = old + (float)(alpha * (float)(value - old));
|
||||||
|
}
|
||||||
|
|
||||||
void ignitionBoxStatusAverage::reset()
|
void ignitionBoxStatusAverage::reset()
|
||||||
{
|
{
|
||||||
m_last = ignitionBoxStatus();
|
m_last = ignitionBoxStatus();
|
||||||
@@ -11,40 +24,37 @@ void ignitionBoxStatusAverage::reset()
|
|||||||
|
|
||||||
void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status)
|
void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status)
|
||||||
{
|
{
|
||||||
if (m_count == 0)
|
if (m_count == 0 && !m_data_valid)
|
||||||
{
|
{
|
||||||
m_last = new_status;
|
m_last = new_status;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// simple moving average calculation
|
|
||||||
m_last.timestamp = new_status.timestamp; // keep timestamp of latest status
|
|
||||||
|
|
||||||
m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging
|
|
||||||
m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging
|
|
||||||
m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status
|
|
||||||
m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status
|
|
||||||
m_last.coils12.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils12.spark_delay - m_last.coils12.spark_delay)); // incremental average calculation
|
|
||||||
m_last.coils12.peak_p_in += 1.0f / m_max_count * (new_status.coils12.peak_p_in - m_last.coils12.peak_p_in); // incremental average calculation
|
|
||||||
m_last.coils12.peak_n_in += 1.0f / m_max_count * (new_status.coils12.peak_n_in - m_last.coils12.peak_n_in); // incremental average calculation
|
|
||||||
m_last.coils12.peak_p_out += 1.0f / m_max_count * (new_status.coils12.peak_p_out - m_last.coils12.peak_p_out); // incremental average calculation
|
|
||||||
m_last.coils12.peak_n_out += 1.0f / m_max_count * (new_status.coils12.peak_n_out - m_last.coils12.peak_n_out); // incremental average calculation
|
|
||||||
|
|
||||||
m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging
|
|
||||||
m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging
|
|
||||||
m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status
|
|
||||||
m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status
|
|
||||||
m_last.coils34.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils34.spark_delay - m_last.coils34.spark_delay)); // incremental average calculation
|
|
||||||
m_last.coils34.peak_p_in += 1.0f / m_max_count * (new_status.coils34.peak_p_in - m_last.coils34.peak_p_in); // incremental average calculation
|
|
||||||
m_last.coils34.peak_n_in += 1.0f / m_max_count * (new_status.coils34.peak_n_in - m_last.coils34.peak_n_in); // incremental average calculation
|
|
||||||
m_last.coils34.peak_p_out += 1.0f / m_max_count * (new_status.coils34.peak_p_out - m_last.coils34.peak_p_out); // incremental average calculation
|
|
||||||
m_last.coils34.peak_n_out += 1.0f / m_max_count * (new_status.coils34.peak_n_out - m_last.coils34.peak_n_out); // incremental average calculation
|
|
||||||
|
|
||||||
m_last.eng_rpm += (uint32_t)(0.1f * (float)(new_status.eng_rpm - m_last.eng_rpm)); // incremental average calculation
|
|
||||||
m_last.adc_read_time += (uint32_t)(0.1f * (float)(new_status.adc_read_time - m_last.adc_read_time)); // incremental average calculation
|
|
||||||
m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value
|
|
||||||
}
|
|
||||||
m_count++;
|
m_count++;
|
||||||
|
// simple moving average calculation
|
||||||
|
m_last.timestamp = new_status.timestamp; // keep timestamp of latest status
|
||||||
|
|
||||||
|
m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging
|
||||||
|
m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging
|
||||||
|
m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status
|
||||||
|
m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status
|
||||||
|
filter(m_last.coils12.spark_delay, new_status.coils12.spark_delay, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils12.peak_p_in, new_status.coils12.peak_p_in, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils12.peak_n_in, new_status.coils12.peak_n_in, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation
|
||||||
|
|
||||||
|
m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging
|
||||||
|
m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging
|
||||||
|
m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status
|
||||||
|
m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status
|
||||||
|
filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation
|
||||||
|
filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation
|
||||||
|
filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation
|
||||||
|
m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value
|
||||||
|
|
||||||
if (m_count >= m_max_count)
|
if (m_count >= m_max_count)
|
||||||
{
|
{
|
||||||
m_count = 0; // reset count after reaching max samples to average
|
m_count = 0; // reset count after reaching max samples to average
|
||||||
@@ -67,6 +77,7 @@ const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const
|
|||||||
if (m_data_valid)
|
if (m_data_valid)
|
||||||
{
|
{
|
||||||
doc["timestamp"] = m_last.timestamp;
|
doc["timestamp"] = m_last.timestamp;
|
||||||
|
doc["datavalid"] = m_data_valid ? "TRUE" : "FALSE";
|
||||||
|
|
||||||
doc["coils12"]["n_events"] = m_last.coils12.n_events;
|
doc["coils12"]["n_events"] = m_last.coils12.n_events;
|
||||||
doc["coils12"]["n_missed_firing"] = m_last.coils12.n_missed_firing;
|
doc["coils12"]["n_missed_firing"] = m_last.coils12.n_missed_firing;
|
||||||
@@ -77,7 +88,7 @@ const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const
|
|||||||
doc["coils12"]["peak_p_out"] = m_last.coils12.peak_p_out;
|
doc["coils12"]["peak_p_out"] = m_last.coils12.peak_p_out;
|
||||||
doc["coils12"]["peak_n_out"] = m_last.coils12.peak_n_out;
|
doc["coils12"]["peak_n_out"] = m_last.coils12.peak_n_out;
|
||||||
doc["coils12"]["sstart_status"] = softStartStatusNames.at(m_last.coils12.sstart_status);
|
doc["coils12"]["sstart_status"] = softStartStatusNames.at(m_last.coils12.sstart_status);
|
||||||
|
|
||||||
doc["coils34"]["n_events"] = m_last.coils34.n_events;
|
doc["coils34"]["n_events"] = m_last.coils34.n_events;
|
||||||
doc["coils34"]["n_missed_firing"] = m_last.coils34.n_missed_firing;
|
doc["coils34"]["n_missed_firing"] = m_last.coils34.n_missed_firing;
|
||||||
doc["coils34"]["spark_delay"] = m_last.coils34.spark_delay;
|
doc["coils34"]["spark_delay"] = m_last.coils34.spark_delay;
|
||||||
@@ -113,8 +124,9 @@ void saveHistoryTask(void *pvParameters)
|
|||||||
void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path &file_name)
|
void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path &file_name)
|
||||||
{
|
{
|
||||||
// Initialize SPIFFS
|
// Initialize SPIFFS
|
||||||
if (!SAVE_HISTORY_TO_SPIFFS) return;
|
if (!SAVE_HISTORY_TO_SPIFFS)
|
||||||
//auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted
|
return;
|
||||||
|
// auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted
|
||||||
|
|
||||||
if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free) // check if at least 1MB is free for saving history
|
if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free) // check if at least 1MB is free for saving history
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,12 +53,19 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ignitionBoxStatusAverage() = default;
|
ignitionBoxStatusAverage() = default;
|
||||||
ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) {}
|
ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) {
|
||||||
|
m_data_valid = false;
|
||||||
|
m_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void update(const ignitionBoxStatus &new_status);
|
void update(const ignitionBoxStatus &new_status);
|
||||||
const bool get(ignitionBoxStatus &status) const;
|
const bool get(ignitionBoxStatus &status) const;
|
||||||
const ArduinoJson::JsonDocument toJson() const;
|
const ArduinoJson::JsonDocument toJson() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void filter(int32_t &old, const int32_t value, const uint32_t k);
|
||||||
|
void filter(float &old, const float value, const uint32_t k);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Task and function declarations
|
// Task and function declarations
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ struct coilsStatus
|
|||||||
{
|
{
|
||||||
int64_t trig_time = 0;
|
int64_t trig_time = 0;
|
||||||
int64_t spark_time = 0;
|
int64_t spark_time = 0;
|
||||||
uint32_t spark_delay = 0; // in microseconds
|
int32_t spark_delay = 0; // in microseconds
|
||||||
sparkStatus spark_status = sparkStatus::SPARK_POS_OK;
|
sparkStatus spark_status = sparkStatus::SPARK_POS_OK;
|
||||||
softStartStatus sstart_status = softStartStatus::NORMAL;
|
softStartStatus sstart_status = softStartStatus::NORMAL;
|
||||||
float peak_p_in = 0.0;
|
float peak_p_in = 0.0;
|
||||||
@@ -83,8 +83,8 @@ struct ignitionBoxStatus
|
|||||||
// voltage from generator
|
// voltage from generator
|
||||||
float volts_gen = 0.0;
|
float volts_gen = 0.0;
|
||||||
// enine rpm
|
// enine rpm
|
||||||
uint32_t eng_rpm = 0;
|
int32_t eng_rpm = 0;
|
||||||
// debug values
|
// debug values
|
||||||
uint32_t n_queue_errors = 0;
|
uint32_t n_queue_errors = 0;
|
||||||
uint32_t adc_read_time = 0;
|
int32_t adc_read_time = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ void loop()
|
|||||||
ignA_avg.update(ign_info); // update moving average with latest ignition status
|
ignA_avg.update(ign_info); // update moving average with latest ignition status
|
||||||
Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r');
|
Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r');
|
||||||
|
|
||||||
if (ws.count() > 0 && counter % max_queue == 0)
|
if (ws.count() > 0 && counter % 10 == 0) // send data every 10 samples
|
||||||
{
|
{
|
||||||
Serial.println();
|
Serial.println();
|
||||||
LOG_INFO("Sending average ignition status to websocket clients...");
|
LOG_INFO("Sending average ignition status to websocket clients...");
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
auto current_time = esp_timer_get_time();
|
auto current_time = esp_timer_get_time();
|
||||||
auto cycle_time = current_time - last_cycle_time;
|
auto cycle_time = current_time - last_cycle_time;
|
||||||
last_cycle_time = current_time;
|
last_cycle_time = current_time;
|
||||||
ign_box_sts.eng_rpm = (uint32_t)(60.0f / (cycle_time / 1000000.0f));
|
ign_box_sts.eng_rpm = (int32_t)(60.0f / (cycle_time / 1000000.0f));
|
||||||
}
|
}
|
||||||
case TRIG_FLAG_12N:
|
case TRIG_FLAG_12N:
|
||||||
coils = &ign_box_sts.coils12;
|
coils = &ign_box_sts.coils12;
|
||||||
@@ -177,7 +177,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED
|
// Timeout not occourred, expected POSITIVE edge spark OCCOURRED
|
||||||
if (spark_flag != SPARK_FLAG_TIMEOUT)
|
if (spark_flag != SPARK_FLAG_TIMEOUT)
|
||||||
{
|
{
|
||||||
coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time);
|
coils->spark_delay = (int32_t)(coils->spark_time - coils->trig_time);
|
||||||
coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge
|
coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge
|
||||||
coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
|
coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
// Timeout not occourred, expected NEGATIVE edge spark OCCOURRED
|
// Timeout not occourred, expected NEGATIVE edge spark OCCOURRED
|
||||||
if (spark_flag != SPARK_FLAG_TIMEOUT && expected_negative)
|
if (spark_flag != SPARK_FLAG_TIMEOUT && expected_negative)
|
||||||
{
|
{
|
||||||
coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time);
|
coils->spark_delay = (int32_t)(coils->spark_time - coils->trig_time);
|
||||||
coils->sstart_status = softStartStatus::SOFT_START;
|
coils->sstart_status = softStartStatus::SOFT_START;
|
||||||
coils->spark_status = sparkStatus::SPARK_NEG_OK;
|
coils->spark_status = sparkStatus::SPARK_NEG_OK;
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ void rtIgnitionTask(void *pvParameters)
|
|||||||
ign_box_sts.coils12.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_12N_OUT);
|
ign_box_sts.coils12.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_12N_OUT);
|
||||||
ign_box_sts.coils34.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_34P_OUT);
|
ign_box_sts.coils34.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_34P_OUT);
|
||||||
ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT);
|
ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT);
|
||||||
ign_box_sts.adc_read_time = (uint32_t)(esp_timer_get_time() - start_adc_read);
|
ign_box_sts.adc_read_time = (int32_t)(esp_timer_get_time() - start_adc_read);
|
||||||
}
|
}
|
||||||
else // simulate adc read timig
|
else // simulate adc read timig
|
||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ void setCursor(const uint8_t x, const uint8_t y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void printField(const char name[], const uint32_t val)
|
void printField(const char name[], const uint32_t val)
|
||||||
|
{
|
||||||
|
Serial.printf("%15s: %06u\n", name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printField(const char name[], const int32_t val)
|
||||||
{
|
{
|
||||||
Serial.printf("%15s: %06d\n", name, val);
|
Serial.printf("%15s: %06d\n", name, val);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
void clearScreen();
|
void clearScreen();
|
||||||
void setCursor(const uint8_t x, const uint8_t y);
|
void setCursor(const uint8_t x, const uint8_t y);
|
||||||
void printField(const char name[], const uint32_t val);
|
void printField(const char name[], const uint32_t val);
|
||||||
|
void printField(const char name[], const int32_t val);
|
||||||
void printField(const char name[], const int64_t val);
|
void printField(const char name[], const int64_t val);
|
||||||
void printField(const char name[], const float val);
|
void printField(const char name[], const float val);
|
||||||
void printField(const char name[], const char *val);
|
void printField(const char name[], const char *val);
|
||||||
@@ -60,6 +61,7 @@ static const std::string htmlTest = R"rawliteral(
|
|||||||
|
|
||||||
<div style="max-width: 900px; margin: 0 auto; text-align: left;">
|
<div style="max-width: 900px; margin: 0 auto; text-align: left;">
|
||||||
<p><strong>Timestamp:</strong> <span id="timestamp">-</span></p>
|
<p><strong>Timestamp:</strong> <span id="timestamp">-</span></p>
|
||||||
|
<p><strong>Data Valid:</strong> <span id="datavalid">-</span></p>
|
||||||
<p><strong>Generator voltage:</strong> <span id="volts_gen">-</span></p>
|
<p><strong>Generator voltage:</strong> <span id="volts_gen">-</span></p>
|
||||||
<p><strong>Engine RPM:</strong> <span id="eng_rpm">-</span></p>
|
<p><strong>Engine RPM:</strong> <span id="eng_rpm">-</span></p>
|
||||||
<p><strong>ADC read time:</strong> <span id="adc_read_time">-</span></p>
|
<p><strong>ADC read time:</strong> <span id="adc_read_time">-</span></p>
|
||||||
@@ -153,6 +155,7 @@ static const std::string htmlTest = R"rawliteral(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById("datavalid").textContent = data.datavalid ?? "-";
|
||||||
document.getElementById("timestamp").textContent = data.timestamp ?? "-";
|
document.getElementById("timestamp").textContent = data.timestamp ?? "-";
|
||||||
document.getElementById("volts_gen").textContent = data.volts_gen ?? "-";
|
document.getElementById("volts_gen").textContent = data.volts_gen ?? "-";
|
||||||
document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-";
|
document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-";
|
||||||
|
|||||||
Reference in New Issue
Block a user