task refactoring working, sometimes misses events, check priorities
This commit is contained in:
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
struct color_t
|
||||
{
|
||||
uint8_t a, g, r, b;
|
||||
uint8_t a, r, g, b;
|
||||
};
|
||||
|
||||
union color_u
|
||||
|
||||
@@ -64,7 +64,7 @@ build_flags =
|
||||
-DARDUINO_USB_MODE=0
|
||||
-DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
||||
-DCONFIG_ASYNC_TCP_PRIORITY=21
|
||||
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=64
|
||||
-DCONFIG_ASYNC_TCP_QUEUE_SIZE=128
|
||||
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
|
||||
-DCONFIG_ASYNC_TCP_STACK_SIZE=4096
|
||||
-DCONFIG_ASYNC_TCP_STACK_SIZE=8192
|
||||
-fstack-protector-all
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define CORE_0 0
|
||||
#define CORE_1 1
|
||||
#define RT_TASK_STACK 2048 // in words
|
||||
#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 6) // highest priority after wifi tasks
|
||||
#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 5) // highest priority after wifi tasks
|
||||
|
||||
struct isrParams
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ void setup()
|
||||
|
||||
// Setup Logger
|
||||
LOG_ATTACH_SERIAL(Serial);
|
||||
LOG_SET_LEVEL(DebugLogLevel::LVL_INFO);
|
||||
LOG_SET_LEVEL(DebugLogLevel::LVL_DEBUG);
|
||||
|
||||
// Print Processor Info
|
||||
LOG_DEBUG("ESP32 Chip:", ESP.getChipModel());
|
||||
@@ -82,19 +82,20 @@ void loop()
|
||||
led.setStatus(RGBled::LedStatus::INIT);
|
||||
bool running = true;
|
||||
std::mutex fs_mutex;
|
||||
LITTLEFSGuard fsGuard;
|
||||
|
||||
//////// INIT SPI PORTS ////////
|
||||
bool spiA_ok = true;
|
||||
bool spiB_ok = true;
|
||||
// Init 2 SPI interfaces
|
||||
SPIClass SPI_A(FSPI);
|
||||
spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI);
|
||||
SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
|
||||
#ifdef CH_B_ENABLE
|
||||
SPIClass SPI_B(HSPI);
|
||||
spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI);
|
||||
SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
|
||||
#endif
|
||||
// SPIClass SPI_A(FSPI);
|
||||
// spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI);
|
||||
// SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
|
||||
// #ifdef CH_B_ENABLE
|
||||
// SPIClass SPI_B(HSPI);
|
||||
// spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI);
|
||||
// SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1
|
||||
// #endif
|
||||
if (!spiA_ok || !spiB_ok)
|
||||
{
|
||||
LOG_ERROR("Unable to Initialize SPI Busses");
|
||||
@@ -106,20 +107,20 @@ void loop()
|
||||
|
||||
// Resources Initialization
|
||||
std::shared_ptr<Devices> dev = std::make_shared<Devices>();
|
||||
dev->m_spi_a = std::make_unique<SPIClass>(SPI_A);
|
||||
dev->m_spi_b = std::make_unique<SPIClass>(SPI_B);
|
||||
// dev->m_spi_a = std::make_unique<SPIClass>(SPI_A);
|
||||
// dev->m_spi_b = std::make_unique<SPIClass>(SPI_B);
|
||||
|
||||
// Init ADC_A
|
||||
dev->m_adc_a = std::make_unique<ADS1256>(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A);
|
||||
dev->m_adc_b = std::make_unique<ADS1256>(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B);
|
||||
// // Init ADC_A
|
||||
// dev->m_adc_a = std::make_unique<ADS1256>(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A);
|
||||
// dev->m_adc_b = std::make_unique<ADS1256>(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B);
|
||||
|
||||
dev->m_adc_a->InitializeADC();
|
||||
dev->m_adc_a->setPGA(PGA_1);
|
||||
dev->m_adc_a->setDRATE(DRATE_7500SPS);
|
||||
// dev->m_adc_a->InitializeADC();
|
||||
// dev->m_adc_a->setPGA(PGA_1);
|
||||
// dev->m_adc_a->setDRATE(DRATE_7500SPS);
|
||||
|
||||
dev->m_adc_b->InitializeADC();
|
||||
dev->m_adc_b->setPGA(PGA_1);
|
||||
dev->m_adc_b->setDRATE(DRATE_7500SPS);
|
||||
// dev->m_adc_b->InitializeADC();
|
||||
// dev->m_adc_b->setPGA(PGA_1);
|
||||
// dev->m_adc_b->setDRATE(DRATE_7500SPS);
|
||||
|
||||
const rtIgnitionTask::rtTaskParams taskA_params{
|
||||
.rt_running = true,
|
||||
@@ -183,8 +184,9 @@ void loop()
|
||||
.rt_queue = nullptr,
|
||||
.dev = dev};
|
||||
|
||||
auto task_A = rtIgnitionTask(taskA_params, 1024, 128, CORE_0, fs_mutex);
|
||||
auto task_B = rtIgnitionTask(taskA_params, 1024, 128, CORE_1, fs_mutex);
|
||||
auto task_A = rtIgnitionTask(taskA_params, 4096, 256, CORE_1, fs_mutex);
|
||||
delay(50);
|
||||
auto task_B = rtIgnitionTask(taskB_params, 4096, 256, CORE_1, fs_mutex);
|
||||
|
||||
// Ignition A on Core 0
|
||||
auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL;
|
||||
@@ -197,23 +199,43 @@ void loop()
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
const bool tasK_A_rt = task_A.start();
|
||||
delay(50);
|
||||
const bool task_B_rt = task_B.start();
|
||||
if (tasK_A_rt != true || task_B_rt != true)
|
||||
{
|
||||
led.setStatus(RGBled::LedStatus::ERROR);
|
||||
LOG_ERROR("Unable to start realtime tasks");
|
||||
} else
|
||||
LOG_DEBUG("Real Time Tasks A & B initialized");
|
||||
led.setStatus(RGBled::LedStatus::OK);
|
||||
|
||||
LITTLEFSGuard fsGuard;
|
||||
WebPage webPage(80, LittleFS); // Initialize webserver and Websocket
|
||||
|
||||
task_A.onMessage([&webPage](ignitionBoxStatusFiltered sts){
|
||||
ArduinoJson::JsonDocument doc;
|
||||
doc["box_a"] = sts.toJson();
|
||||
doc["box_b"] = ArduinoJson::JsonDocument();
|
||||
webPage.sendWsData(doc.as<String>());
|
||||
});
|
||||
|
||||
task_B.onMessage([&webPage](ignitionBoxStatusFiltered sts){
|
||||
ArduinoJson::JsonDocument doc;
|
||||
doc["box_a"] = ArduinoJson::JsonDocument();
|
||||
doc["box_b"] = sts.toJson();
|
||||
webPage.sendWsData(doc.as<String>());
|
||||
});
|
||||
|
||||
task_A.enableSave(true, "ignitionA_test.csv");
|
||||
task_B.enableSave(true, "ignitionB_test.csv");
|
||||
|
||||
uint32_t last_loop = millis();
|
||||
//////////////// INNER LOOP /////////////////////
|
||||
while (running)
|
||||
{
|
||||
led.setStatus(RGBled::LedStatus::IDLE);
|
||||
delay(100);
|
||||
|
||||
if ((millis() - last_loop) > 1000)
|
||||
if ((millis() - last_loop) > 2000)
|
||||
{
|
||||
clearScreen();
|
||||
Serial.println();
|
||||
printRunningTasksMod(Serial);
|
||||
last_loop = millis();
|
||||
}
|
||||
|
||||
@@ -296,20 +296,22 @@ rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history
|
||||
m_params.rt_queue = m_queue;
|
||||
|
||||
// create PSram history vectors
|
||||
m_history_0.resize(history_size);
|
||||
m_history_1.resize(history_size);
|
||||
m_history_0 = PSHistory(history_size);
|
||||
m_history_1 = PSHistory(history_size);
|
||||
// assing active and writable history
|
||||
m_active_history = std::unique_ptr<PSHistory>(&m_history_0);
|
||||
m_save_history = std::unique_ptr<PSHistory>(&m_history_1);
|
||||
|
||||
LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]");
|
||||
auto task_success = xTaskCreate(
|
||||
// auto task_success = pdPASS;
|
||||
auto task_success = xTaskCreatePinnedToCore(
|
||||
rtIgnitionTask_manager,
|
||||
(std::string("man_") + m_params.name).c_str(),
|
||||
m_params.rt_stack_size,
|
||||
8192,
|
||||
(void *)this,
|
||||
1,
|
||||
&m_manager_handle);
|
||||
m_params.rt_priority >> 2,
|
||||
&m_manager_handle,
|
||||
m_core);
|
||||
|
||||
if (task_success != pdPASS)
|
||||
{
|
||||
@@ -341,10 +343,12 @@ void rtIgnitionTask::run()
|
||||
|
||||
if (new_data == pdPASS)
|
||||
{
|
||||
m_last_data = millis();
|
||||
m_manager_status = rtTaskStatus::RUNNING;
|
||||
// if history buffer is full swap buffers and if enabled save history buffer
|
||||
if (m_counter_status >= m_active_history->size())
|
||||
{
|
||||
LOG_DEBUG("Save for Buffer Full: ", m_counter_status);
|
||||
m_counter_status = 0;
|
||||
m_partial_save = false; // reset partial save flag on new data cycle
|
||||
std::swap(m_active_history, m_save_history);
|
||||
@@ -356,13 +360,21 @@ void rtIgnitionTask::run()
|
||||
m_info_filtered.update(m_last_status);
|
||||
(*m_active_history)[m_counter_status] = m_last_status;
|
||||
|
||||
if (m_on_message_cb && m_counter_status % 10)
|
||||
{
|
||||
m_on_message_cb(m_info_filtered);
|
||||
}
|
||||
|
||||
// update data counter
|
||||
m_counter_status++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (millis() - m_last_data > c_idle_time){
|
||||
if (m_counter_status > 0 && !m_partial_save){
|
||||
if (millis() - m_last_data > c_idle_time)
|
||||
{
|
||||
if (m_counter_status > 0 && !m_partial_save)
|
||||
{
|
||||
LOG_DEBUG("Save Partial: ", m_counter_status);
|
||||
m_active_history->resize(m_counter_status);
|
||||
saveHistory(*m_active_history, m_history_path);
|
||||
m_active_history->resize(m_max_history);
|
||||
@@ -434,13 +446,18 @@ void rtIgnitionTask::enableSave(const bool enable, const std::filesystem::path f
|
||||
}
|
||||
}
|
||||
|
||||
void rtIgnitionTask::onMessage(std::function<void(ignitionBoxStatusFiltered)> callaback)
|
||||
{
|
||||
m_on_message_cb = callaback;
|
||||
}
|
||||
|
||||
void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name)
|
||||
{
|
||||
// Lock filesystem mutex to avoid concurrent access
|
||||
std::lock_guard<std::mutex> fs_lock(m_fs_mutex);
|
||||
|
||||
// Check for free space
|
||||
if (LittleFS.totalBytes() - LittleFS.usedBytes() < history.size() * sizeof(ignitionBoxStatus) * 200) // check if at least 1MB is free for saving history
|
||||
if (LittleFS.totalBytes() - LittleFS.usedBytes() < history.size() * sizeof(ignitionBoxStatus)) // check if at least 1MB is free for saving history
|
||||
{
|
||||
LOG_ERROR("Not enough space in SPIFFS to save history");
|
||||
return;
|
||||
@@ -454,9 +471,8 @@ void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const
|
||||
|
||||
// if firt save remove old file and create new
|
||||
auto save_flags = std::ios::out;
|
||||
if (m_first_save && m_filesystem.exists(file_path.c_str()))
|
||||
if (m_first_save)
|
||||
{
|
||||
m_first_save = false;
|
||||
save_flags |= std::ios::trunc; // overwrite existing file
|
||||
m_filesystem.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS
|
||||
LOG_INFO("Saving history to Flash, new file:", file_path.c_str());
|
||||
@@ -477,12 +493,12 @@ void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const
|
||||
// write csv header
|
||||
if (m_first_save)
|
||||
{
|
||||
ofs << "TS,\
|
||||
EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\
|
||||
EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\
|
||||
ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"
|
||||
ofs << "TS,EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,"
|
||||
<< "EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,"
|
||||
<< "ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"
|
||||
<< std::endl;
|
||||
ofs.flush();
|
||||
m_first_save = false;
|
||||
}
|
||||
|
||||
for (const auto &entry : history)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#include <datasave.h>
|
||||
#include <functional>
|
||||
|
||||
// ISR
|
||||
#include "isr.h"
|
||||
@@ -111,6 +112,8 @@ public:
|
||||
|
||||
void enableSave(const bool enable, const std::filesystem::path filename);
|
||||
|
||||
void onMessage(std::function<void(ignitionBoxStatusFiltered)> callaback);
|
||||
|
||||
private:
|
||||
void saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name);
|
||||
|
||||
@@ -147,7 +150,9 @@ private:
|
||||
ignitionBoxStatus m_last_status;
|
||||
ignitionBoxStatusFiltered m_info_filtered;
|
||||
|
||||
static const uint32_t c_idle_time = 2000; // in mS
|
||||
std::function<void(ignitionBoxStatusFiltered)> m_on_message_cb = nullptr;
|
||||
|
||||
static const uint32_t c_idle_time = 10000; // in mS
|
||||
static const uint32_t c_spark_timeout_max = 500; // uS
|
||||
static const uint8_t c_adc_time = 4; // in mS
|
||||
static const uint8_t c_io_time = 2; // in mS
|
||||
|
||||
@@ -5,25 +5,69 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portable.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_partition.h"
|
||||
#include "LittleFS.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#define FREERTOS_TASK_NUMBER_MAX_NUM 256 // RunTime stats for how many Tasks to be stored
|
||||
|
||||
std::string printBits(uint32_t value) {
|
||||
std::string printBits(uint32_t value)
|
||||
{
|
||||
std::string result;
|
||||
for (int i = 31; i >= 0; i--) {
|
||||
for (int i = 31; i >= 0; i--)
|
||||
{
|
||||
// ottieni il singolo bit
|
||||
result += ((value >> i) & 1) ? '1' : '0';
|
||||
// aggiungi uno spazio ogni 8 bit, tranne dopo l'ultimo
|
||||
if (i % 8 == 0 && i != 0) {
|
||||
if (i % 8 == 0 && i != 0)
|
||||
{
|
||||
result += ' ';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ANSI colors
|
||||
#define BAR_WIDTH 30
|
||||
#define COLOR_RESET "\033[0m"
|
||||
#define COLOR_RED "\033[31m"
|
||||
#define COLOR_GREEN "\033[32m"
|
||||
#define COLOR_BLUE "\033[34m"
|
||||
#define COLOR_MAGENTA "\033[35m"
|
||||
#define COLOR_CYAN "\033[36m"
|
||||
#define COLOR_YELLOW "\033[33m"
|
||||
#define COLOR_WHITE "\033[37m"
|
||||
#define COLOR_LBLUE "\033[94m"
|
||||
|
||||
void printBar(Print &printer, const char *label, size_t used, size_t total, const char *color)
|
||||
{
|
||||
float perc = total > 0 ? ((float)used / total) : 0;
|
||||
int filled = perc * BAR_WIDTH;
|
||||
|
||||
printer.printf("%s%-12s [" COLOR_RESET, color, label);
|
||||
|
||||
for (int i = 0; i < BAR_WIDTH; i++)
|
||||
{
|
||||
if (i < filled)
|
||||
printer.printf("%s#%s", color, COLOR_RESET);
|
||||
else
|
||||
printer.printf("-");
|
||||
}
|
||||
|
||||
printer.printf("] %s%6.2f%%%s (%5.3f/%5.3f)MB\n",
|
||||
color,
|
||||
perc * 100.0,
|
||||
COLOR_RESET,
|
||||
(used / 1024.0f / 1024.0f),
|
||||
(total / 1024.0f / 1024.0f));
|
||||
}
|
||||
|
||||
void printRunningTasksMod(Print &printer, std::function<bool(const TaskStatus_t &a, const TaskStatus_t &b)> orderBy)
|
||||
{
|
||||
static const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"};
|
||||
@@ -53,6 +97,68 @@ void printRunningTasksMod(Print &printer, std::function<bool(const TaskStatus_t
|
||||
ulCurrentRunTime = ulTotalRunTime - ulLastRunTime;
|
||||
ulLastRunTime = ulTotalRunTime;
|
||||
|
||||
// PRINT MEMORY INFO
|
||||
printer.printf("\033[H");
|
||||
printer.printf(COLOR_LBLUE "=================== ESP32 SYSTEM MONITOR ===================\n\n" COLOR_RESET);
|
||||
|
||||
// ===== HEAP =====
|
||||
size_t freeHeap = esp_get_free_heap_size();
|
||||
size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
|
||||
printBar(printer, "HEAP", totalHeap - freeHeap, totalHeap, COLOR_GREEN);
|
||||
|
||||
// ===== RAM INTERNA =====
|
||||
size_t freeInternal = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t totalInternal = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
|
||||
printBar(printer, "INTERNAL", totalInternal - freeInternal, totalInternal, COLOR_BLUE);
|
||||
|
||||
// ===== PSRAM =====
|
||||
size_t totalPsram = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
|
||||
if (totalPsram > 0)
|
||||
{
|
||||
size_t freePsram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
printBar(printer, "PSRAM", totalPsram - freePsram, totalPsram, COLOR_MAGENTA);
|
||||
}
|
||||
|
||||
printer.printf("\n");
|
||||
|
||||
// ===== FLASH APP (approssimato) =====
|
||||
const esp_partition_t *app_partition =
|
||||
esp_partition_find_first(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_FACTORY,
|
||||
NULL);
|
||||
|
||||
if (app_partition)
|
||||
{
|
||||
size_t totalAPP = app_partition->size; // dimensione reale partizione
|
||||
size_t sketchSize = ESP.getSketchSize();
|
||||
printBar(printer, "FLASH APP", sketchSize, totalAPP, COLOR_CYAN);
|
||||
}
|
||||
else
|
||||
{
|
||||
printer.printf(COLOR_YELLOW "%-12s [NOT FOUND]\n" COLOR_RESET, "FLASH APP");
|
||||
}
|
||||
|
||||
// ===== LITTLEFS (corretto con partition table) =====
|
||||
const esp_partition_t *fs_partition =
|
||||
esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
|
||||
ESP_PARTITION_SUBTYPE_DATA_LITTLEFS,
|
||||
"littlefs");
|
||||
|
||||
if (fs_partition)
|
||||
{
|
||||
size_t totalFS = fs_partition->size; // dimensione reale partizione
|
||||
size_t usedFS = LittleFS.usedBytes(); // spazio usato reale
|
||||
printBar(printer, "LITTLEFS", usedFS, totalFS, COLOR_YELLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
printer.printf(COLOR_YELLOW "%-12s [NOT FOUND]\n" COLOR_RESET, "LITTLEFS");
|
||||
}
|
||||
|
||||
// ===== MIN HEAP =====
|
||||
size_t minHeap = esp_get_minimum_free_heap_size();
|
||||
printer.printf("%s\nMin Heap Ever:%s %u KB\n\n", COLOR_RED, COLOR_RESET, minHeap / 1024);
|
||||
|
||||
// Print Runtime Information
|
||||
printer.printf("Tasks: %u, Runtime: %lus, Period: %luus\r\n", uxArraySize, ulTotalRunTime / 1000000, ulCurrentRunTime);
|
||||
|
||||
@@ -79,4 +185,3 @@ void printRunningTasksMod(Print &printer, std::function<bool(const TaskStatus_t
|
||||
}
|
||||
printer.println();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
WebPage::WebPage(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webserver(AsyncWebServer(port)), m_websocket(AsyncWebSocket("/ws")), m_filesystem(filesystem)
|
||||
{
|
||||
LOG_DEBUG("Initializing Web Server");
|
||||
m_websocket.onEvent([this](AsyncWebSocket *server, AsyncWebSocketClient *client,
|
||||
AwsEventType type, void *arg, uint8_t *data, size_t len)
|
||||
{ onWsEvent(server, client, type, arg, data, len); });
|
||||
@@ -17,6 +18,7 @@ WebPage::WebPage(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webse
|
||||
);
|
||||
|
||||
m_webserver.begin();
|
||||
LOG_DEBUG("Webserver Init OK");
|
||||
}
|
||||
|
||||
WebPage::~WebPage()
|
||||
|
||||
Reference in New Issue
Block a user