Various additions, still WIP

This commit is contained in:
Cabooman 2024-02-09 22:27:13 +01:00
parent cfc2c6a439
commit c839646e58
7 changed files with 228 additions and 112 deletions

View file

@ -2,157 +2,254 @@
#include "../../../USER_SETTINGS.h"
#include "../config.h"
#include "timer.h"
typedef enum {
EVENT_STATE_INIT = 0,
EVENT_STATE_INACTIVE,
EVENT_STATE_ACTIVE,
EVENT_STATE_ACTIVE_LATCHED
} EVENT_STATE_TYPE;
typedef struct {
uint32_t timestamp; // Time in seconds since startup when the event occurred
uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage
uint8_t occurences; // Number of occurrences since startup
uint8_t led_color; // Weirdly indented comment
uint32_t timestamp; // Time in seconds since startup when the event occurred
uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage
uint8_t occurences; // Number of occurrences since startup
uint8_t led_color; // LED indication
EVENT_STATE_TYPE state; // Event state
} EVENTS_STRUCT_TYPE;
static EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
static unsigned long previous_millis = 0;
static uint32_t time_seconds = 0;
static uint8_t total_led_color = GREEN;
static char event_message[256];
typedef struct {
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
uint32_t time_seconds;
char message[256];
MyTimer second_timer;
uint8_t nof_yellow_events;
uint8_t nof_blue_events;
uint8_t nof_red_events;
} EVENT_TYPE;
/* Local variables */
static EVENT_TYPE events;
/* Local function prototypes */
static void update_event_time(void);
static void set_event_message(EVENTS_ENUM_TYPE event);
static void update_led_color(EVENTS_ENUM_TYPE event);
static void set_message(EVENTS_ENUM_TYPE event);
static void update_led_color(void);
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched);
static void update_event_numbers(void);
static void update_bms_status(void);
/* Exported functions */
/* Main execution function, should handle various continuous functionality */
void run_event_handling(void) {
update_event_time();
}
/* Initialization function */
void init_events(void) {
for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) {
entries[i].timestamp = 0;
entries[i].data = 0;
entries[i].occurences = 0;
entries[i].led_color = RED; // Most events are RED
events.entries[i].timestamp = 0;
events.entries[i].data = 0;
events.entries[i].occurences = 0;
events.entries[i].led_color = RED; // Most events are RED
events.entries[i].state = EVENT_STATE_INACTIVE;
}
// YELLOW events below
entries[EVENT_12V_LOW].led_color = YELLOW;
entries[EVENT_CAN_WARNING].led_color = YELLOW;
entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW;
entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW;
events.entries[EVENT_12V_LOW].led_color = YELLOW;
events.entries[EVENT_CAN_WARNING].led_color = YELLOW;
events.entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW;
events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW;
// BLUE...
entries[EVENT_OTA_UPDATE].led_color = BLUE;
events.entries[EVENT_OTA_UPDATE].led_color = BLUE;
events.second_timer.interval = 1000;
events.nof_blue_events = 0;
events.nof_red_events = 0;
events.nof_yellow_events = 0;
}
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
if (event >= EVENT_NOF_EVENTS) {
event = EVENT_UNKNOWN_EVENT_SET;
}
entries[event].timestamp = time_seconds;
entries[event].data = data;
entries[event].occurences++;
update_led_color(event);
if (total_led_color == RED) {
bms_status = FAULT;
} else if (total_led_color) {
bms_status = UPDATING;
}
set_event_message(event);
#ifdef DEBUG_VIA_USB
Serial.println(event_message);
#endif
set_event(event, data, false);
}
uint8_t get_event_ledcolor(void) {
return total_led_color;
void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data) {
set_event(event, data, true);
}
void clear_event(EVENTS_ENUM_TYPE event) {
if (events.entries[event].state == EVENT_STATE_ACTIVE) {
events.entries[event].state = EVENT_STATE_INACTIVE;
update_event_numbers();
update_led_color();
update_bms_status();
}
}
/* Local functions */
static void update_event_time(void) {
unsigned long new_millis = millis();
if (new_millis - previous_millis >= 1000) {
time_seconds++;
previous_millis = new_millis;
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
// Just some defensive stuff if someone sets an unknown event
if (event >= EVENT_NOF_EVENTS) {
event = EVENT_UNKNOWN_EVENT_SET;
}
// If the event is already set, no reason to continue
if ((events.entries[event].state == EVENT_STATE_ACTIVE) ||
(events.entries[event].state == EVENT_STATE_ACTIVE_LATCHED)) {
return;
}
// We should set the event, update event info
events.entries[event].timestamp = events.time_seconds;
events.entries[event].data = data;
events.entries[event].occurences++;
// Check if the event is latching
events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE;
update_event_numbers();
update_led_color();
update_bms_status();
// Set the associated event message, even if debug is disabled
set_message(event);
#ifdef DEBUG_VIA_USB
Serial.println(events.message);
#endif
}
static void update_bms_status(void) {
if (events.nof_red_events > 0) {
bms_status = FAULT;
} else if (events.nof_blue_events > 0) {
bms_status = UPDATING;
} else if (events.nof_yellow_events > 0) {
// No bms_status update
}
}
static void update_led_color(EVENTS_ENUM_TYPE event) {
total_led_color = max(total_led_color, entries[event].led_color);
static void update_event_numbers(void) {
events.nof_red_events = 0;
events.nof_blue_events = 0;
events.nof_yellow_events = 0;
for (uint8_t i = 0u; i < EVENT_NOF_EVENTS; i++) {
if ((events.entries[i].state == EVENT_STATE_ACTIVE) || (events.entries[i].state == EVENT_STATE_ACTIVE_LATCHED)) {
switch (events.entries[i].led_color) {
case GREEN:
// Just informative
break;
case YELLOW:
events.nof_yellow_events++;
break;
case BLUE:
events.nof_blue_events++;
break;
case RED:
events.nof_red_events++;
break;
default:
break;
}
}
}
}
static void set_event_message(EVENTS_ENUM_TYPE event) {
static void update_event_time(void) {
unsigned long new_millis = millis();
if (events.second_timer.elapsed() == true) {
events.time_seconds++;
}
}
static void update_led_color(void) {
if (events.nof_red_events > 0) {
LEDcolor = RED;
} else if (events.nof_blue_events > 0) {
LEDcolor = BLUE;
} else if (events.nof_yellow_events > 0) {
LEDcolor = YELLOW;
} else {
LEDcolor = GREEN;
}
// events.total_led_color = max(events.total_led_color, events.entries[event].led_color);
}
static void set_message(EVENTS_ENUM_TYPE event) {
switch (event) {
case EVENT_CAN_FAILURE:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"No CAN communication detected for 60s. Shutting down battery control.");
break;
case EVENT_CAN_WARNING:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!");
break;
case EVENT_WATER_INGRESS:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"Water leakage inside battery detected. Operation halted. Inspect battery!");
break;
case EVENT_12V_LOW:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"12V battery source below required voltage to safely close contactors. Inspect the supply/battery!");
break;
case EVENT_SOC_PLAUSIBILITY_ERROR:
snprintf(event_message, sizeof(event_message), "ERROR: SOC reported by battery not plausible. Restart battery!");
snprintf(events.message, sizeof(events.message),
"ERROR: SOC reported by battery not plausible. Restart battery!");
break;
case EVENT_KWH_PLAUSIBILITY_ERROR:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"Warning: kWh remaining reported by battery not plausible. Battery needs cycling.");
break;
case EVENT_BATTERY_CHG_STOP_REQ:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!");
break;
case EVENT_BATTERY_DISCHG_STOP_REQ:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!");
break;
case EVENT_BATTERY_CHG_DISCHG_STOP_REQ:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!");
break;
case EVENT_LOW_SOH:
snprintf(
event_message, sizeof(event_message),
events.message, sizeof(events.message),
"ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery.");
break;
case EVENT_HVIL_FAILURE:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be "
"disabled!");
break;
case EVENT_INTERNAL_OPEN_FAULT:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: High voltage cable removed while battery running. Opening contactors!");
break;
case EVENT_CELL_UNDER_VOLTAGE:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
break;
case EVENT_CELL_OVER_VOLTAGE:
snprintf(event_message, sizeof(event_message),
snprintf(events.message, sizeof(events.message),
"ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
break;
case EVENT_CELL_DEVIATION_HIGH:
snprintf(event_message, sizeof(event_message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!");
snprintf(events.message, sizeof(events.message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!");
break;
case EVENT_UNKNOWN_EVENT_SET:
snprintf(event_message, sizeof(event_message), "An unknown event was set! Review your code!");
snprintf(events.message, sizeof(events.message), "An unknown event was set! Review your code!");
break;
case EVENT_OTA_UPDATE:
snprintf(event_message, sizeof(event_message), "OTA update started!");
snprintf(events.message, sizeof(events.message), "OTA update started!");
break;
case EVENT_DUMMY:
snprintf(event_message, sizeof(event_message), "The dummy event was set!"); // Don't change this event message!
snprintf(events.message, sizeof(events.message), "The dummy event was set!"); // Don't change this event message!
break;
default:
break;