diff --git a/Software/include/globals.h b/Software/include/globals.h index a36cee3..2123a07 100644 --- a/Software/include/globals.h +++ b/Software/include/globals.h @@ -33,6 +33,7 @@ typedef struct Globals_s bool measurementActive; /**< Flag indicating active measurement */ uint32_t measuredPulses; /**< Number of measured pulses */ bool toggle_wifi; + uint16_t isr_debug; } Globals_t; extern Globals_t globals; /**< Global variable struct */ diff --git a/Software/src/button_actions.cpp b/Software/src/button_actions.cpp index f6792c9..fdea54a 100644 --- a/Software/src/button_actions.cpp +++ b/Software/src/button_actions.cpp @@ -25,9 +25,7 @@ void ButtonAction_StartPurge() void ButtonAction_ToggleWiFi() { - extern void toggleWiFiAP(bool shutdown = false); - toggleWiFiAP(); - + globals.toggle_wifi = true; Debug_pushMessage("Toggling WiFi\n"); } @@ -40,8 +38,9 @@ void ButtonAction_WashMode() // Liste der Aktionen, sortiert nach Mindest-Haltezeit (ms) const ButtonActionEntry buttonActions[] = { {500, LED_RAIN_COLOR, ButtonAction_ToggleMode}, - {3500, LED_PURGE_COLOR, ButtonAction_StartPurge}, - {6500, LED_WIFI_COLOR, ButtonAction_ToggleWiFi}, - {9500, LED_WASH_COLOR, ButtonAction_WashMode}}; + {3500, LED_WASH_COLOR, ButtonAction_WashMode}, + {6500, LED_PURGE_COLOR, ButtonAction_StartPurge}, + {9500, LED_WIFI_COLOR, ButtonAction_ToggleWiFi}, +}; const uint8_t buttonActionCount = sizeof(buttonActions) / sizeof(ButtonActionEntry); diff --git a/Software/src/debugger.cpp b/Software/src/debugger.cpp index 7f56d22..57aa644 100644 --- a/Software/src/debugger.cpp +++ b/Software/src/debugger.cpp @@ -11,12 +11,11 @@ * @date 09.04.2024 */ - #include "debugger.h" - #include - #include - #include - -DebugStatus_t DebuggerStatus[dbg_cntElements]; +#include "debugger.h" +#include +#include +#include +#include void processCmdDebug(String command); void Debug_formatCFG(); @@ -32,6 +31,9 @@ void Debug_printHelp(); void Debug_Purge(); void Debug_refillTank(); const char *uint32_to_binary_string(uint32_t num); +template +void RegisterDebugPrintAuto(const T* ptr, const String& name, uint32_t interval_ms, uint32_t duration_ms); +void Debug_UpdateWatches(); /** * @brief Initializes the debugger by setting the initial status for different debug ports. @@ -98,11 +100,12 @@ void Debug_Process() } // Check for input buffer overflow - if (inputCnt >= sizeof(inputBuffer) - 1) { + if (inputCnt >= sizeof(inputBuffer) - 1) + { inputBuffer[sizeof(inputBuffer) - 1] = '\0'; inputCnt = 0; InputProcessed = CMD_OVERFLOW; - } + } } // Process the command based on the detected state of input processing @@ -128,7 +131,11 @@ void Debug_Process() Serial.print(">"); InputProcessed = IDLE; + + Debug_UpdateWatches(); + } + /** * @brief Sets the status of a specific debug port (Serial or WebUI). * Updates the status in the DebuggerStatus array and provides debug messages. @@ -150,8 +157,6 @@ void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status) Debug_pushMessage("Enabled DebugPort %s\n", sDebugPorts[port]); } - - void Debug_log(LogLevel level, const char *format, ...) { if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled)) @@ -248,17 +253,22 @@ void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data) std::vector splitArgs(const String &input) { std::vector tokens; - int start = 0, end = 0; - while ((end = input.indexOf(' ', start)) != -1) + size_t start = 0; + + while (true) { + int end = input.indexOf(' ', start); + if (end == -1) break; tokens.push_back(input.substring(start, end)); - start = end + 1; + start = static_cast(end) + 1; } + if (start < input.length()) tokens.push_back(input.substring(start)); return tokens; } + // === getArg helper === String getArg(const std::vector &args, size_t index, const String &defaultVal = "") { @@ -273,19 +283,28 @@ typedef std::function DebugCmdHandler; static const std::map &getCmdMap() { static const std::map cmdMap = { - {"help", [](const String &) { + {"help", [](const String &) + { Debug_log(LOG_INFO, "Available commands:\n"); for (const auto &entry : getCmdMap()) Debug_log(LOG_INFO, " - %s\n", entry.first.c_str()); }}, - {"sysinfo", [](const String &) { Debug_printSystemInfo(); }}, - {"netinfo", [](const String &) { Debug_printWifiInfo(); }}, - {"formatCFG", [](const String &) { Debug_formatCFG(); }}, - {"formatPDS", [](const String &) { Debug_formatPersistence(); }}, - {"checkEE", [](const String &) { Debug_CheckEEPOM(false); }}, - {"checkEEfix", [](const String &) { Debug_CheckEEPOM(true); }}, - {"dumpEE1k", [](const String &) { dumpEEPROM(0, 1024); }}, - {"dumpEE", [](const String &args) { + {"sysinfo", [](const String &) + { Debug_printSystemInfo(); }}, + {"netinfo", [](const String &) + { Debug_printWifiInfo(); }}, + {"formatCFG", [](const String &) + { Debug_formatCFG(); }}, + {"formatPDS", [](const String &) + { Debug_formatPersistence(); }}, + {"checkEE", [](const String &) + { Debug_CheckEEPOM(false); }}, + {"checkEEfix", [](const String &) + { Debug_CheckEEPOM(true); }}, + {"dumpEE1k", [](const String &) + { dumpEEPROM(0, 1024); }}, + {"dumpEE", [](const String &args) + { int start = 0, len = EEPROM_SIZE_BYTES; auto tokens = splitArgs(args); if (tokens.size() >= 2) @@ -295,24 +314,42 @@ static const std::map &getCmdMap() } dumpEEPROM(start, len); }}, - {"resetPageEE", [](const String &) { MovePersistencePage_EEPROM(true); }}, - {"dumpCFG", [](const String &) { Debug_dumpConfig(); }}, - {"dumpPDS", [](const String &) { Debug_dumpPersistance(); }}, - {"saveEE", [](const String &) { globals.requestEEAction = EE_ALL_SAVE; }}, - {"dumpGlobals", [](const String &) { Debug_dumpGlobals(); }}, - {"sdbg", [](const String &) { SetDebugportStatus(dbg_Serial, enabled); }}, - {"dtc_show", [](const String &) { Debug_ShowDTCs(); }}, - {"dtc_clear", [](const String &) { ClearAllDTC(); }}, - {"dtc_crit", [](const String &) { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); }}, - {"dtc_warn", [](const String &) { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); }}, - {"dtc_info", [](const String &) { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); }}, - {"notify_error", [](const String &) { Websocket_PushNotification("Debug Error Notification", error); }}, - {"notify_warning", [](const String &) { Websocket_PushNotification("Debug Warning Notification", warning); }}, - {"notify_success", [](const String &) { Websocket_PushNotification("Debug Success Notification", success); }}, - {"notify_info", [](const String &) { Websocket_PushNotification("Debug Info Notification", info); }}, - {"purge", [](const String &) { Debug_Purge(); }}, - {"toggle_wifi", [](const String &) { globals.toggle_wifi = true; }}, - {"dtc_add", [](const String &args) { + {"resetPageEE", [](const String &) + { MovePersistencePage_EEPROM(true); }}, + {"dumpCFG", [](const String &) + { Debug_dumpConfig(); }}, + {"dumpPDS", [](const String &) + { Debug_dumpPersistance(); }}, + {"saveEE", [](const String &) + { globals.requestEEAction = EE_ALL_SAVE; }}, + {"dumpGlobals", [](const String &) + { Debug_dumpGlobals(); }}, + {"sdbg", [](const String &) + { SetDebugportStatus(dbg_Serial, enabled); }}, + {"dtc_show", [](const String &) + { Debug_ShowDTCs(); }}, + {"dtc_clear", [](const String &) + { ClearAllDTC(); }}, + {"dtc_crit", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); }}, + {"dtc_warn", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); }}, + {"dtc_info", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); }}, + {"notify_error", [](const String &) + { Websocket_PushNotification("Debug Error Notification", error); }}, + {"notify_warning", [](const String &) + { Websocket_PushNotification("Debug Warning Notification", warning); }}, + {"notify_success", [](const String &) + { Websocket_PushNotification("Debug Success Notification", success); }}, + {"notify_info", [](const String &) + { Websocket_PushNotification("Debug Info Notification", info); }}, + {"purge", [](const String &) + { Debug_Purge(); }}, + {"toggle_wifi", [](const String &) + { globals.toggle_wifi = true; }}, + {"dtc_add", [](const String &args) + { auto tokens = splitArgs(args); if (!tokens.empty()) { @@ -320,7 +357,12 @@ static const std::map &getCmdMap() MaintainDTC((DTCNum_t)code, true, millis()); } }}, - {"tank_refill", [](const String &) { Debug_refillTank(); }}, + {"tank_refill", [](const String &) + { Debug_refillTank(); }}, + {"isr_debug", [](const String &) + { + RegisterDebugPrintAuto(&globals.isr_debug, "isr_debug", 100, 20000); + }}, }; return cmdMap; } @@ -531,7 +573,6 @@ void Debug_ShowDTCs() } } - /** * @brief Start purging for 10 pulses. */ @@ -578,4 +619,77 @@ const char *uint32_to_binary_string(uint32_t num) } binary_str[j] = '\0'; // Null terminator return binary_str; -} \ No newline at end of file +} + +DebugStatus_t DebuggerStatus[dbg_cntElements]; + +struct DebugWatchEntry +{ + const void *ptr; + String name; + uint32_t interval_ms; + uint32_t duration_ms; + uint32_t lastPrint_ms; + uint32_t start_ms; + std::function printer; +}; + +#define MAX_DEBUG_WATCHES 8 +DebugWatchEntry debugWatches[MAX_DEBUG_WATCHES]; + +// === Typabhängige Druckfunktion === +template +void debugPrinterImpl(const void* ptr, const String& name) { + const T* typed = static_cast(ptr); + if constexpr (std::is_same::value) { + Debug_pushMessage("%s = %s\n", name.c_str(), *typed ? "true" : "false"); + } else if constexpr (std::is_floating_point::value) { + Debug_pushMessage("%s = %.3f\n", name.c_str(), *typed); + } else if constexpr (std::is_signed::value) { + Debug_pushMessage("%s = %ld\n", name.c_str(), static_cast(*typed)); + } else if constexpr (std::is_unsigned::value) { + Debug_pushMessage("%s = %lu\n", name.c_str(), static_cast(*typed)); + } +} + +// === Automatisches DebugPrint-Register === +template +void RegisterDebugPrintAuto(const T* ptr, const String& name, uint32_t interval_ms, uint32_t duration_ms) +{ + for (int i = 0; i < MAX_DEBUG_WATCHES; ++i) { + if (debugWatches[i].ptr == nullptr) { + debugWatches[i] = { + ptr, + name, + interval_ms, + duration_ms, + 0, + millis(), + debugPrinterImpl + }; + Debug_pushMessage("Registered Watch: %s\n", name.c_str()); + return; + } + } + Debug_pushMessage("Debug Watch list full!\n"); +} + +// Debug-Ausgabe in Debug_Process(): +void Debug_UpdateWatches() { + uint32_t now = millis(); + for (int i = 0; i < MAX_DEBUG_WATCHES; ++i) { + auto& w = debugWatches[i]; + if (!w.ptr) continue; + + if (now - w.start_ms >= w.duration_ms) { + Debug_pushMessage("Watch expired: %s\n", w.name.c_str()); + w.ptr = nullptr; + continue; + } + + if (now - w.lastPrint_ms >= w.interval_ms) { + w.lastPrint_ms = now; + if (w.printer) w.printer(w.ptr, w.name); + } + } +} diff --git a/Software/src/lubeapp.cpp b/Software/src/lubeapp.cpp index 17d1132..af2be61 100644 --- a/Software/src/lubeapp.cpp +++ b/Software/src/lubeapp.cpp @@ -29,7 +29,7 @@ uint32_t lubePulseTimestamp = 0; void RunLubeApp(uint32_t add_milimeters) { static tSystem_Status lastSystemStatus = sysStat_Startup; - static uint16_t washModeDistance = 0; + static uint16_t washModeRemainDistance = 0; // Calculate and update tank percentage globals.TankPercentage = PersistenceData.tankRemain_microL / (LubeConfig.tankCapacity_ml * 10); @@ -46,7 +46,7 @@ void RunLubeApp(uint32_t add_milimeters) if (PersistenceData.odometer_mm >= 1000000) { PersistenceData.odometer++; - PersistenceData.odometer_mm = 0; + PersistenceData.odometer_mm -= 1000000; } // Handle different system statuses @@ -106,7 +106,7 @@ void RunLubeApp(uint32_t add_milimeters) case sysStat_Wash: if (lastSystemStatus != globals.systemStatus) { - washModeDistance = LubeConfig.WashMode_Distance; + washModeRemainDistance = LubeConfig.WashMode_Distance; strcpy_P(globals.systemStatustxt, PSTR("Wash")); LEDControl_SetBasic(LED_WASH_COLOR, LED_PATTERN_BREATH); lastSystemStatus = globals.systemStatus; @@ -118,9 +118,10 @@ void RunLubeApp(uint32_t add_milimeters) LubePulse(); PersistenceData.TravelDistance_highRes_mm = 0; - if (washModeDistance >= LubeConfig.WashMode_Distance) + if (washModeRemainDistance >= LubeConfig.WashMode_Interval) { - washModeDistance = washModeDistance - LubeConfig.WashMode_Interval; + washModeRemainDistance -= LubeConfig.WashMode_Interval; + Debug_pushMessage("Wash Distance remain: %d\n", washModeRemainDistance); } else { diff --git a/Software/src/main.cpp b/Software/src/main.cpp index 7ba86be..8ba9e97 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -43,7 +43,6 @@ #include "button_actions.h" #include "ledcontrol.h" - #ifdef FEATURE_ENABLE_WIFI_CLIENT #include @@ -260,7 +259,8 @@ void loop() DTC_Process(); Debug_Process(); - if (globals.toggle_wifi == true){ + if (globals.toggle_wifi == true) + { globals.toggle_wifi = false; toggleWiFiAP(); @@ -339,12 +339,19 @@ void EEPROMCyclicPDS_callback() * 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() +volatile uint32_t lastTriggerMicros = 0; + +void IRAM_ATTR trigger_ISR() { + uint32_t now = micros(); + if (now - lastTriggerMicros < 2500) + return; + lastTriggerMicros = now; + + globals.isr_debug++; wheel_pulse++; } - #ifdef FEATURE_ENABLE_OLED /** * @brief Manages the display content based on the current system status and updates the OLED display. @@ -372,7 +379,19 @@ void Display_Process() 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; + uint32_t DistRemain = 0; + switch (globals.systemStatus) + { + case sysStat_Normal: + DistRemain = LubeConfig.DistancePerLube_Default; + break; + case sysStat_Rain: + DistRemain = LubeConfig.DistancePerLube_Rain; + break; + case sysStat_Wash: + DistRemain = LubeConfig.WashMode_Interval; + break; + } DistRemain = DistRemain - (PersistenceData.TravelDistance_highRes_mm / 1000); // Display relevant information on the OLED screen based on system status @@ -479,36 +498,6 @@ void SystemShutdown(bool restart) } } -void onToggleMode() -{ - if (globals.systemStatus == sysStat_Normal) - { - globals.systemStatus = sysStat_Rain; - globals.resumeStatus = sysStat_Rain; - } - else if (globals.systemStatus == sysStat_Rain) - { - globals.systemStatus = sysStat_Normal; - globals.resumeStatus = sysStat_Normal; - } - Debug_pushMessage("Toggling Mode\n"); -} - -void onStartPurge() -{ - globals.systemStatus = sysStat_Purge; - globals.purgePulses = LubeConfig.BleedingPulses; - Debug_pushMessage("Starting Purge\n"); -} - - -void onWashMode() -{ - Debug_pushMessage("Wash mode start\n"); - // Hier könntest du später gezieltes Nachölen implementieren -} - - /** * @brief Processes the impulses from the wheel speed sensor and converts them into traveled distance. *