Webpage is OK, html in memory since SPIFFS is to slow.

Moving average to be fixed
This commit is contained in:
Emanuele Trabattoni
2026-04-08 15:23:21 +02:00
parent 07eb06f67b
commit 4dc45954e9
7 changed files with 629 additions and 78 deletions

View File

@@ -5,6 +5,10 @@
#include <DebugLog.h>
#include <DebugLogEnable.h>
#include <SPI.h>
#include <WiFi.h>
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
// Definitions
#include <tasks.h>
@@ -19,6 +23,23 @@
// #define CH_B_ENABLE
#define TEST
#define WIFI_SSID "AstroRotaxMonitor"
#define WIFI_PASSWORD "maledettirotax"
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client,
AwsEventType type, void *arg, uint8_t *data, size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Serial.printf("WS client IP[%s]-ID[%u] CONNECTED\r\n", client->remoteIP().toString().c_str(), client->id());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WS client ID[%u] DISCONNECTED\r\n", client->remoteIP().toString().c_str(), client->id());
break;
}
}
void setup()
{
Serial.begin(921600);
@@ -29,21 +50,43 @@ void setup()
LOG_SET_LEVEL(DebugLogLevel::LVL_INFO);
// Print Processor Info
LOG_INFO("ESP32 Chip:", ESP.getChipModel());
LOG_DEBUG("ESP32 Chip:", ESP.getChipModel());
if (psramFound())
{
LOG_INFO("ESP32 PSram Found");
LOG_INFO("ESP32 PSram:", ESP.getPsramSize());
LOG_DEBUG("ESP32 PSram Found");
LOG_DEBUG("ESP32 PSram:", ESP.getPsramSize());
psramInit();
}
LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize());
LOG_INFO("ESP32 Heap:", ESP.getHeapSize());
LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace());
LOG_DEBUG("ESP32 Flash:", ESP.getFlashChipSize());
LOG_DEBUG("ESP32 Heap:", ESP.getHeapSize());
LOG_DEBUG("ESP32 Sketch:", ESP.getFreeSketchSpace());
// Initialize Interrupt pins on PICKUP detectors
initTriggerPinsInputs();
// Initialize Interrupt pins on SPARK detectors
initSparkPinInputs();
// Init Wifi station
LOG_INFO("Initializing WiFi...");
WiFi.mode(WIFI_AP);
IPAddress local_IP(10, 11, 12, 1);
IPAddress gateway(10, 11, 12, 1);
IPAddress subnet(255, 255, 255, 0);
WiFi.softAPConfig(local_IP, gateway, subnet);
if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD))
{
LOG_INFO("WiFi AP Mode Started");
LOG_INFO("Wifi SSID:", WIFI_SSID);
LOG_INFO("Wifi Password:", WIFI_PASSWORD);
LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString());
}
else
{
LOG_ERROR("Failed to start WiFi AP Mode");
LOG_ERROR("5 seconds to restart...");
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
}
}
void loop()
@@ -79,7 +122,7 @@ void loop()
.spark_pin_34 = SPARK_PIN_A34},
.rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_A12P, .rst_io_12n = RST_EXT_A12N, .rst_io_34p = RST_EXT_A34P, .rst_io_34n = RST_EXT_A34N}};
LOG_INFO("Task Variables OK");
LOG_DEBUG("Task Variables OK");
#ifdef CH_B_ENABLE
QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus));
@@ -118,7 +161,7 @@ void loop()
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
}
LOG_INFO("Init SPI OK");
LOG_DEBUG("Init SPI OK");
// Init ADC_A
dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A);
@@ -134,7 +177,7 @@ void loop()
dev.adc_a->setDRATE(DRATE_1000SPS);
#endif
LOG_INFO("Init ADC OK");
LOG_DEBUG("Init ADC OK");
// Ignition A on Core 0
auto ignA_task_success = pdPASS;
@@ -168,17 +211,29 @@ void loop()
esp_restart();
}
LOG_INFO("Real Time Tasks A & B initialized");
LOG_DEBUG("Real Time Tasks A & B initialized");
////////////////////// MAIN LOOP //////////////////////
clearScreen();
setCursor(0, 0);
bool partial_save = false; // flag to indicate if a partial save has been done after a timeout
uint32_t counter = 0;
uint32_t wait_count = 0;
ignitionBoxStatus ign_info;
int64_t last = esp_timer_get_time();
uint32_t missed_firings12 = 0;
uint32_t missed_firings34 = 0;
ignitionBoxStatusAverage ignA_avg(max_queue); // moving average calculator for ignition box A with a window of 100 samples
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
ws.onEvent(onWsEvent);
server.addHandler(&ws);
auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
server.begin();
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(200, "text/html", htmlTest.c_str()); });
while (running)
{
@@ -189,23 +244,10 @@ void loop()
auto *temp = active_history;
active_history = writable_history; // switch active and writable buffers
writable_history = temp; // ensure writable_history points to the buffer we just filled
dataSaveParams save_params {
dataSaveParams save_params{
.history = writable_history,
.file_path = "ignition_history.csv"};
save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data
// if (SAVE_HISTORY_TO_SPIFFS)
// if (pdFAIL ==
// xTaskCreatePinnedToCore(
// saveHistoryTask,
// "saveHistoryTask",
// RT_TASK_STACK,
// &save_params,
// RT_TASK_PRIORITY - 1, // higher priority to ensure it runs asap after buffer switch
// NULL,
// CORE_1))
// {
// LOG_ERROR("Unable to create saveHistoryTask");
// }
save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay
}
if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE)
@@ -213,17 +255,26 @@ void loop()
// printInfo(ign_info);
auto &hist = *active_history;
hist[counter++ % active_history->size()] = ign_info;
ignA_avg.update(ign_info); // update moving average with latest ignition status
Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r');
if (ws.count() > 0 && counter % max_queue == 0)
{
Serial.println();
LOG_INFO("Sending average ignition status to websocket clients...");
auto msg = ignA_avg.toJson().as<String>();
ws.textAll(msg);
}
}
else
{
Serial.println("Waiting for data... ");
Serial.printf("[%d] Waiting for data...\r", wait_count++);
if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout
{
active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records
save_history(*active_history, "ignition_history.csv");
active_history->resize(max_history); // resize back to max history size for next data cycle
counter = 0; // reset counter after saving
counter = 0; // reset counter after saving
partial_save = true;
first_save = true;
}