Merge branch 'main' into feature/double-battery

This commit is contained in:
Daniel Öster 2024-07-11 12:29:21 +03:00
commit 1f295871b9
111 changed files with 6451 additions and 1698 deletions

View file

@ -5,8 +5,14 @@
#endif
#include "../../../USER_SETTINGS.h"
#include "../../lib/YiannisBourkelis-Uptime-Library/src/uptime.h"
#include "timer.h"
// Time conversion macros
#define DAYS_TO_SECS 86400 // 24 * 60 * 60
#define HOURS_TO_SECS 3600 // 60 * 60
#define MINUTES_TO_SECS 60
#define EE_NOF_EVENT_ENTRIES 30
#define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE)
#define EE_WRITE_PERIOD_MINUTES 10
@ -44,7 +50,7 @@ typedef struct {
typedef struct {
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
uint32_t time_seconds;
unsigned long time_seconds;
MyTimer second_timer;
MyTimer ee_timer;
MyTimer update_timer;
@ -134,20 +140,30 @@ void init_events(void) {
events.entries[EVENT_CAN_RX_WARNING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_TX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_WATER_INGRESS].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CHARGE_LIMIT_EXCEEDED].level = EVENT_LEVEL_INFO;
events.entries[EVENT_DISCHARGE_LIMIT_EXCEEDED].level = EVENT_LEVEL_INFO;
events.entries[EVENT_12V_LOW].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_SOC_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BATTERY_EMPTY].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BATTERY_FULL].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BATTERY_FROZEN].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BATTERY_CAUTION].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BATTERY_CHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_BATTERY_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_BATTERY_OVERHEAT].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_BATTERY_OVERVOLTAGE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_BATTERY_UNDERVOLTAGE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_BATTERY_ISOLATION].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_VOLTAGE_DIFFERENCE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_LOW_SOH].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_HVIL_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_PRECHARGE_FAILURE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_INVERTER_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO;
events.entries[EVENT_MODBUS_INVERTER_MISSING].level = EVENT_LEVEL_INFO;
events.entries[EVENT_ERROR_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO;
events.entries[EVENT_CELL_UNDER_VOLTAGE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CELL_OVER_VOLTAGE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CELL_DEVIATION_HIGH].level = EVENT_LEVEL_WARNING;
@ -163,10 +179,26 @@ void init_events(void) {
events.entries[EVENT_SERIAL_TX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_SERIAL_TRANSMITTER_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_EEPROM_WRITE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_UNKNOWN].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_POWERON].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_EXT].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_SW].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_PANIC].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_RESET_INT_WDT].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_RESET_TASK_WDT].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_RESET_WDT].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_RESET_DEEPSLEEP].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_BROWNOUT].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_SDIO].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_USB].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_JTAG].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_EFUSE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_PWR_GLITCH].level = EVENT_LEVEL_INFO;
events.entries[EVENT_RESET_CPU_LOCKUP].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger...
events.second_timer.set_interval(1000);
events.second_timer.set_interval(600);
// Write to EEPROM every X minutes (if an event has been set)
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000);
events.update_timer.set_interval(2000);
@ -204,6 +236,10 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!";
case EVENT_CAN_TX_FAILURE:
return "ERROR: CAN messages failed to transmit, or no one on the bus to ACK the message!";
case EVENT_CHARGE_LIMIT_EXCEEDED:
return "Info: Inverter is charging faster than battery is allowing.";
case EVENT_DISCHARGE_LIMIT_EXCEEDED:
return "Info: Inverter is discharging faster than battery is allowing.";
case EVENT_WATER_INGRESS:
return "Water leakage inside battery detected. Operation halted. Inspect battery!";
case EVENT_12V_LOW:
@ -216,6 +252,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "Info: Battery is completely discharged";
case EVENT_BATTERY_FULL:
return "Info: Battery is fully charged";
case EVENT_BATTERY_FROZEN:
return "Info: Battery is too cold to operate optimally. Consider warming it up!";
case EVENT_BATTERY_CAUTION:
return "Info: Battery has raised a general caution flag. Might want to inspect it closely.";
case EVENT_BATTERY_CHG_STOP_REQ:
@ -228,18 +266,33 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "Info: COLD BATTERY! Battery requesting heating pads to activate!";
case EVENT_BATTERY_WARMED_UP:
return "Info: Battery requesting heating pads to stop. The battery is now warm enough.";
case EVENT_BATTERY_OVERHEAT:
return "ERROR: Battery overheated. Shutting down to prevent thermal runaway!";
case EVENT_BATTERY_OVERVOLTAGE:
return "Warning: Battery exceeding maximum design voltage. Discharge battery to prevent damage!";
case EVENT_BATTERY_UNDERVOLTAGE:
return "Warning: Battery under minimum design voltage. Charge battery to prevent damage!";
case EVENT_BATTERY_ISOLATION:
return "Warning: Battery reports isolation error. High voltage might be leaking to ground. Check battery!";
case EVENT_VOLTAGE_DIFFERENCE:
return "Info: Too large voltage diff between the batteries. Second battery cannot join the DC-link";
case EVENT_LOW_SOH:
return "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle "
"battery.";
case EVENT_HVIL_FAILURE:
return "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be "
"disabled!";
return "ERROR: Battery interlock loop broken. Check that high voltage / low voltage connectors are seated. "
"Battery will be disabled!";
case EVENT_PRECHARGE_FAILURE:
return "Info: Battery failed to precharge. Check that capacitor is seated on high voltage output.";
case EVENT_INTERNAL_OPEN_FAULT:
return "ERROR: High voltage cable removed while battery running. Opening contactors!";
case EVENT_INVERTER_OPEN_CONTACTOR:
return "Info: Inverter side opened contactors. Normal operation.";
case EVENT_ERROR_OPEN_CONTACTOR:
return "Info: Too much time spent in error state. Opening contactors, not safe to continue charging. "
"Check other error code for reason!";
case EVENT_MODBUS_INVERTER_MISSING:
return "Info: Modbus inverter has not sent any data. Inspect communication wiring!";
case EVENT_CELL_UNDER_VOLTAGE:
return "ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!";
case EVENT_CELL_OVER_VOLTAGE:
@ -270,6 +323,39 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "OTA update timed out!";
case EVENT_EEPROM_WRITE:
return "Info: The EEPROM was written";
case EVENT_RESET_UNKNOWN:
return "Info: The board was reset unexpectedly, and reason can't be determined";
case EVENT_RESET_POWERON:
return "Info: The board was reset from a power-on event. Normal operation";
case EVENT_RESET_EXT:
return "Info: The board was reset from an external pin";
case EVENT_RESET_SW:
return "Info: The board was reset via software, webserver or OTA. Normal operation";
case EVENT_RESET_PANIC:
return "Warning: The board was reset due to an exception or panic. Inform developers!";
case EVENT_RESET_INT_WDT:
return "Warning: The board was reset due to an interrupt watchdog timeout. Inform developers!";
case EVENT_RESET_TASK_WDT:
return "Warning: The board was reset due to a task watchdog timeout. Inform developers!";
case EVENT_RESET_WDT:
return "Warning: The board was reset due to other watchdog timeout. Inform developers!";
case EVENT_RESET_DEEPSLEEP:
return "Info: The board was reset after exiting deep sleep mode";
case EVENT_RESET_BROWNOUT:
return "Info: The board was reset due to a momentary low voltage condition. This is expected during certain "
"operations like flashing via USB";
case EVENT_RESET_SDIO:
return "Info: The board was reset over SDIO";
case EVENT_RESET_USB:
return "Info: The board was reset by the USB peripheral";
case EVENT_RESET_JTAG:
return "Info: The board was reset by JTAG";
case EVENT_RESET_EFUSE:
return "Info: The board was reset due to an efuse error";
case EVENT_RESET_PWR_GLITCH:
return "Info: The board was reset due to a detected power glitch";
case EVENT_RESET_CPU_LOCKUP:
return "Warning: The board was reset due to CPU lockup. Inform developers!";
default:
return "";
}
@ -355,11 +441,20 @@ static void update_event_level(void) {
}
static void update_event_time(void) {
// This should run roughly 2 times per second
if (events.second_timer.elapsed() == true) {
events.time_seconds++;
uptime::calculateUptime(); // millis() overflows every 50 days, so update occasionally to adjust
events.time_seconds = uptime::getDays() * DAYS_TO_SECS;
events.time_seconds += uptime::getHours() * HOURS_TO_SECS;
events.time_seconds += uptime::getMinutes() * MINUTES_TO_SECS;
events.time_seconds += uptime::getSeconds();
}
}
unsigned long get_current_event_time_secs(void) {
return events.time_seconds;
}
static void log_event(EVENTS_ENUM_TYPE event, uint8_t data) {
// Update head with wrap to 0
if (++events.event_log_head_index == EE_NOF_EVENT_ENTRIES) {