From 3ea71788c2cfa89b449edc0e8bd725b510c9905b Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Fri, 27 Mar 2026 18:28:00 +0100 Subject: [PATCH] Added battery low warning message --- src/base/task.h | 2 ++ src/custom_types.h | 1 + src/modules/battery/battery.cpp | 8 ++++++++ src/modules/battery/battery.h | 3 +++ src/modules/cmd/cmd.cpp | 28 ++++++++++++++++++++++++++++ src/modules/cmd/cmd.h | 8 +++++--- src/modules/config/config.cpp | 12 ++++++++++++ src/modules/config/config.h | 1 + src/modules/lcd/lcd.cpp | 18 ++++++++++++++++++ src/modules/lcd/lcd.h | 2 ++ 10 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/base/task.h b/src/base/task.h index c8bf956..87e985a 100644 --- a/src/base/task.h +++ b/src/base/task.h @@ -23,11 +23,13 @@ enum task_type : uint8_t { TASK_DISPLAY_MSG_GPS_FIX, TASK_DISPLAY_MSG_TRACK_DETECT_OK, TASK_DISPLAY_MSG_CONFIG_NO_TRACKS, + TASK_DISPLAY_MSG_BAT_LOW, TASK_CONFIG_TRACK_DETECT, TASK_CONFIG_WRITE_TEMP_TRACK, TASK_CONFIG_TRACK_DELETE, TASK_CONFIG_CFG_RESET, TASK_CONFIG_VBAT_CAL_SET, + TASK_CONFIG_VBAT_SET_LOW, TASK_BATTERY_CAL, TASK_ALL_CONFIG_UPDATED, }; diff --git a/src/custom_types.h b/src/custom_types.h index c4ab8ab..c945d87 100644 --- a/src/custom_types.h +++ b/src/custom_types.h @@ -12,6 +12,7 @@ struct vehicle_config{ uint8_t track_fallback = 0; bool track_slot_occupied[8] = {false}; double vbat_calibration = 0; + double vbat_low = 0; }; struct lat_lng { diff --git a/src/modules/battery/battery.cpp b/src/modules/battery/battery.cpp index cd0c720..e05fb91 100644 --- a/src/modules/battery/battery.cpp +++ b/src/modules/battery/battery.cpp @@ -31,6 +31,7 @@ int battery::init() { vehicle_config config; config_global_read(config); _cal = config.vbat_calibration; + _low = config.vbat_low; } int battery::loop(unsigned long timeout_ms) { @@ -39,6 +40,12 @@ int battery::loop(unsigned long timeout_ms) { _vbat = _cal * adc_read; vbat_global_write(_vbat); + if (_vbat < _low) { + if (_warning_sent == 0 || millis() > _warning_sent + _warning_timeout) { + router::send(MOD_LCD, TASK_DISPLAY_MSG_BAT_LOW, 2000); + _warning_sent = millis(); + } + } } Task active_task; int res = _queue.pop(active_task); @@ -60,6 +67,7 @@ int battery::loop(unsigned long timeout_ms) { vehicle_config config; config_global_read(config); _cal = config.vbat_calibration; + _low = config.vbat_low; break; } diff --git a/src/modules/battery/battery.h b/src/modules/battery/battery.h index 688c9a3..c0fdc95 100644 --- a/src/modules/battery/battery.h +++ b/src/modules/battery/battery.h @@ -16,6 +16,9 @@ private: ring_buffer _queue; double _vbat = 0; double _cal = 0; + double _low = 0; + unsigned long _warning_sent = 0; + unsigned long _warning_timeout = 10000; unsigned long _update_interval = 1000; unsigned long _last_read = 0; int calibrate(const Task& task); diff --git a/src/modules/cmd/cmd.cpp b/src/modules/cmd/cmd.cpp index 3b19aa2..a8d6678 100644 --- a/src/modules/cmd/cmd.cpp +++ b/src/modules/cmd/cmd.cpp @@ -116,6 +116,10 @@ cmd::command_id cmd::parse_command_name(const char *input) { return CMD_BATTERY_PRINT_VBAT; } + if (strcmp(input, "BATTERY_SET_LOW") == 0) { + return CMD_BATTERY_SET_LOW; + } + return CMD_UNKNOWN; } @@ -411,6 +415,27 @@ int cmd::handle_battery_print_vbat(unsigned short argc) { #endif } +int cmd::handle_battery_set_low(unsigned short argc, char* argv[]) { + if (argc != 2) { +#ifdef ERROR + if (_logger != nullptr) { + _logger->error("BATTERY_SET_LOW expects 1 argument"); + } +#endif + return 1; + } + double low = strtod(argv[1], nullptr); + uint32_t task_data; + memcpy(&task_data, &low, sizeof(uint32_t)); +#ifdef INFO + if (_logger != nullptr) { + _logger->info("Setting warning level for VBAT"); + } +#endif + router::send(MOD_CFG, TASK_CONFIG_VBAT_SET_LOW, task_data); + return 0; +} + int cmd::handle_unknown_command(unsigned short argc, char *argv[]) { #ifdef ERROR if (_logger != nullptr) { @@ -458,6 +483,9 @@ int cmd::dispatch_command(command_id command, unsigned short argc, char *argv[]) case CMD_BATTERY_PRINT_VBAT: return this->handle_battery_print_vbat(argc); + + case CMD_BATTERY_SET_LOW: + return this->handle_battery_set_low(argc, argv); case CMD_UNKNOWN: default: diff --git a/src/modules/cmd/cmd.h b/src/modules/cmd/cmd.h index f2d3134..e86d224 100644 --- a/src/modules/cmd/cmd.h +++ b/src/modules/cmd/cmd.h @@ -6,11 +6,11 @@ #include #include +#include "base/module_base.h" +#include "base/ring_buffer.h" +#include "base/task.h" #include "custom_types.h" #include "modules/logger/system_logger.h" -#include "base/task.h" -#include "base/ring_buffer.h" -#include "base/module_base.h" class cmd : public module_base { private: @@ -27,6 +27,7 @@ private: CMD_DISPLAY_DRIVER_PRIMARY, CMD_BATTERY_CAL, CMD_BATTERY_PRINT_VBAT, + CMD_BATTERY_SET_LOW, }; HardwareSerial *_data_stream; @@ -57,6 +58,7 @@ private: int handle_display_driver_primary(unsigned short argc); int handle_battery_cal(unsigned short argc, char *argv[]); int handle_battery_print_vbat(unsigned short argc); + int handle_battery_set_low(unsigned short argc, char *argv[]); int handle_unknown_command(unsigned short argc, char *argv[]); public: diff --git a/src/modules/config/config.cpp b/src/modules/config/config.cpp index 3cb0e87..935eec0 100644 --- a/src/modules/config/config.cpp +++ b/src/modules/config/config.cpp @@ -104,6 +104,11 @@ int config::write_vbat_cal(double val) { return this->write_cfg(); } +int config::write_vbat_low(double val) { + _config.vbat_low = val; + return this->write_cfg(); +} + config::config() : _logger(nullptr), _valid_config(true) {} config::config(system_logger *logger) : _logger(logger), _valid_config(true) {} @@ -246,6 +251,13 @@ int config::handle_active_task(unsigned long timeout_ms) { this->task_complete(); } + case TASK_CONFIG_VBAT_SET_LOW: { + double low_value; + memcpy(&low_value, &_active_task.data, sizeof(double)); + int res = this->write_vbat_low(low_value); + this->task_complete(); + } + default: break; } diff --git a/src/modules/config/config.h b/src/modules/config/config.h index db383fe..31ab65b 100644 --- a/src/modules/config/config.h +++ b/src/modules/config/config.h @@ -48,6 +48,7 @@ private: int delete_track(unsigned short idx); int reset_cfg(); int write_vbat_cal(double val); + int write_vbat_low(double val); public: int push(const Task &task) override; diff --git a/src/modules/lcd/lcd.cpp b/src/modules/lcd/lcd.cpp index de39e9c..8f876a1 100644 --- a/src/modules/lcd/lcd.cpp +++ b/src/modules/lcd/lcd.cpp @@ -61,6 +61,7 @@ bool lcd::is_message_task(task_type type) { case TASK_DISPLAY_MSG_GPS_FIX: case TASK_DISPLAY_MSG_TRACK_DETECT_OK: case TASK_DISPLAY_MSG_CONFIG_NO_TRACKS: + case TASK_DISPLAY_MSG_BAT_LOW: return true; default: @@ -203,6 +204,15 @@ int lcd::render_msg_config_no_tracks() { return 0; } +int lcd::render_msg_battery_low() { + this->clear(); + _display->setCursor(2, 1); + this->print("BATTERY WARNING"); + _display->setCursor(6, 2); + this->print("VBAT LOW"); + return 0; +} + int lcd::push(const Task &task) { return _queue.push(task); } @@ -399,6 +409,10 @@ int lcd::loop(unsigned long timeout_ms) { case TASK_DISPLAY_MSG_CONFIG_NO_TRACKS: activate_message(screen::msg_config_no_tracks, next_task.data); break; + + case TASK_DISPLAY_MSG_BAT_LOW: + activate_message(screen::msg_battery_low, next_task.data); + break; default: break; @@ -449,6 +463,10 @@ int lcd::loop(unsigned long timeout_ms) { case screen::msg_config_no_tracks: this->render_msg_config_no_tracks(); break; + + case screen::msg_battery_low: + this->render_msg_battery_low(); + break; default: break; diff --git a/src/modules/lcd/lcd.h b/src/modules/lcd/lcd.h index d468129..f58dd45 100644 --- a/src/modules/lcd/lcd.h +++ b/src/modules/lcd/lcd.h @@ -25,6 +25,7 @@ typedef enum lcd_screen { msg_gps_fix, msg_track_detect_ok, msg_config_no_tracks, + msg_battery_low, } lcd_screen; } // namespace screen @@ -66,6 +67,7 @@ private: int render_msg_gps_fix(); int render_msg_track_detect_ok(); int render_msg_config_no_tracks(); + int render_msg_battery_low(); public: int push(const Task &task) override;