mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 02:39:57 +02:00
Various additions, still WIP
This commit is contained in:
parent
cfc2c6a439
commit
c839646e58
7 changed files with 228 additions and 112 deletions
|
@ -259,7 +259,9 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
|
||||||
if (battery_voltage >
|
if (battery_voltage >
|
||||||
(ABSOLUTE_MAX_VOLTAGE - 100)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT
|
(ABSOLUTE_MAX_VOLTAGE - 100)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT
|
||||||
if (LB_SOC < 650) {
|
if (LB_SOC < 650) {
|
||||||
set_event(EVENT_SOC_PLAUSIBILITY_ERROR, LB_SOC / 10);
|
set_event(EVENT_SOC_PLAUSIBILITY_ERROR, LB_SOC / 10); // Set event with the SOC as data
|
||||||
|
} else {
|
||||||
|
clear_event(EVENT_SOC_PLAUSIBILITY_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,157 +2,254 @@
|
||||||
|
|
||||||
#include "../../../USER_SETTINGS.h"
|
#include "../../../USER_SETTINGS.h"
|
||||||
#include "../config.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 {
|
typedef struct {
|
||||||
uint32_t timestamp; // Time in seconds since startup when the event occurred
|
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 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 occurences; // Number of occurrences since startup
|
||||||
uint8_t led_color; // Weirdly indented comment
|
uint8_t led_color; // LED indication
|
||||||
|
EVENT_STATE_TYPE state; // Event state
|
||||||
} EVENTS_STRUCT_TYPE;
|
} EVENTS_STRUCT_TYPE;
|
||||||
|
|
||||||
static EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
|
typedef struct {
|
||||||
static unsigned long previous_millis = 0;
|
EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS];
|
||||||
static uint32_t time_seconds = 0;
|
uint32_t time_seconds;
|
||||||
static uint8_t total_led_color = GREEN;
|
char message[256];
|
||||||
static char event_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 */
|
/* Local function prototypes */
|
||||||
static void update_event_time(void);
|
static void update_event_time(void);
|
||||||
static void set_event_message(EVENTS_ENUM_TYPE event);
|
static void set_message(EVENTS_ENUM_TYPE event);
|
||||||
static void update_led_color(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 */
|
/* Exported functions */
|
||||||
|
|
||||||
|
/* Main execution function, should handle various continuous functionality */
|
||||||
void run_event_handling(void) {
|
void run_event_handling(void) {
|
||||||
update_event_time();
|
update_event_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialization function */
|
||||||
void init_events(void) {
|
void init_events(void) {
|
||||||
for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||||
entries[i].timestamp = 0;
|
events.entries[i].timestamp = 0;
|
||||||
entries[i].data = 0;
|
events.entries[i].data = 0;
|
||||||
entries[i].occurences = 0;
|
events.entries[i].occurences = 0;
|
||||||
entries[i].led_color = RED; // Most events are RED
|
events.entries[i].led_color = RED; // Most events are RED
|
||||||
|
events.entries[i].state = EVENT_STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// YELLOW events below
|
// YELLOW events below
|
||||||
entries[EVENT_12V_LOW].led_color = YELLOW;
|
events.entries[EVENT_12V_LOW].led_color = YELLOW;
|
||||||
entries[EVENT_CAN_WARNING].led_color = YELLOW;
|
events.entries[EVENT_CAN_WARNING].led_color = YELLOW;
|
||||||
entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW;
|
events.entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW;
|
||||||
entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW;
|
events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW;
|
||||||
|
|
||||||
// BLUE...
|
// 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) {
|
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
|
||||||
if (event >= EVENT_NOF_EVENTS) {
|
set_event(event, data, false);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_event_ledcolor(void) {
|
void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data) {
|
||||||
return total_led_color;
|
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 */
|
/* Local functions */
|
||||||
static void update_event_time(void) {
|
|
||||||
unsigned long new_millis = millis();
|
static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) {
|
||||||
if (new_millis - previous_millis >= 1000) {
|
// Just some defensive stuff if someone sets an unknown event
|
||||||
time_seconds++;
|
if (event >= EVENT_NOF_EVENTS) {
|
||||||
previous_millis = new_millis;
|
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) {
|
static void update_event_numbers(void) {
|
||||||
total_led_color = max(total_led_color, entries[event].led_color);
|
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) {
|
switch (event) {
|
||||||
case EVENT_CAN_FAILURE:
|
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.");
|
"No CAN communication detected for 60s. Shutting down battery control.");
|
||||||
break;
|
break;
|
||||||
case EVENT_CAN_WARNING:
|
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!");
|
"ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!");
|
||||||
break;
|
break;
|
||||||
case EVENT_WATER_INGRESS:
|
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!");
|
"Water leakage inside battery detected. Operation halted. Inspect battery!");
|
||||||
break;
|
break;
|
||||||
case EVENT_12V_LOW:
|
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!");
|
"12V battery source below required voltage to safely close contactors. Inspect the supply/battery!");
|
||||||
break;
|
break;
|
||||||
case EVENT_SOC_PLAUSIBILITY_ERROR:
|
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;
|
break;
|
||||||
case EVENT_KWH_PLAUSIBILITY_ERROR:
|
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.");
|
"Warning: kWh remaining reported by battery not plausible. Battery needs cycling.");
|
||||||
break;
|
break;
|
||||||
case EVENT_BATTERY_CHG_STOP_REQ:
|
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!");
|
"ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!");
|
||||||
break;
|
break;
|
||||||
case EVENT_BATTERY_DISCHG_STOP_REQ:
|
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!");
|
"ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!");
|
||||||
break;
|
break;
|
||||||
case EVENT_BATTERY_CHG_DISCHG_STOP_REQ:
|
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!");
|
"ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!");
|
||||||
break;
|
break;
|
||||||
case EVENT_LOW_SOH:
|
case EVENT_LOW_SOH:
|
||||||
snprintf(
|
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.");
|
"ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery.");
|
||||||
break;
|
break;
|
||||||
case EVENT_HVIL_FAILURE:
|
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 "
|
"ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be "
|
||||||
"disabled!");
|
"disabled!");
|
||||||
break;
|
break;
|
||||||
case EVENT_INTERNAL_OPEN_FAULT:
|
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!");
|
"ERROR: High voltage cable removed while battery running. Opening contactors!");
|
||||||
break;
|
break;
|
||||||
case EVENT_CELL_UNDER_VOLTAGE:
|
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!");
|
"ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
|
||||||
break;
|
break;
|
||||||
case EVENT_CELL_OVER_VOLTAGE:
|
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!");
|
"ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
|
||||||
break;
|
break;
|
||||||
case EVENT_CELL_DEVIATION_HIGH:
|
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;
|
break;
|
||||||
case EVENT_UNKNOWN_EVENT_SET:
|
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;
|
break;
|
||||||
case EVENT_OTA_UPDATE:
|
case EVENT_OTA_UPDATE:
|
||||||
snprintf(event_message, sizeof(event_message), "OTA update started!");
|
snprintf(events.message, sizeof(events.message), "OTA update started!");
|
||||||
break;
|
break;
|
||||||
case EVENT_DUMMY:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,32 +8,35 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EVENT_CAN_FAILURE = 0u,
|
EVENT_CAN_FAILURE = 0u, // RED event
|
||||||
EVENT_CAN_WARNING,
|
EVENT_CAN_WARNING, // YELLOW event
|
||||||
EVENT_WATER_INGRESS,
|
EVENT_WATER_INGRESS, // RED event
|
||||||
EVENT_12V_LOW,
|
EVENT_12V_LOW, // YELLOW event
|
||||||
EVENT_SOC_PLAUSIBILITY_ERROR,
|
EVENT_SOC_PLAUSIBILITY_ERROR, // RED event
|
||||||
EVENT_KWH_PLAUSIBILITY_ERROR,
|
EVENT_KWH_PLAUSIBILITY_ERROR, // YELLOW event
|
||||||
EVENT_BATTERY_CHG_STOP_REQ,
|
EVENT_BATTERY_CHG_STOP_REQ, // RED event
|
||||||
EVENT_BATTERY_DISCHG_STOP_REQ,
|
EVENT_BATTERY_DISCHG_STOP_REQ, // RED event
|
||||||
EVENT_BATTERY_CHG_DISCHG_STOP_REQ,
|
EVENT_BATTERY_CHG_DISCHG_STOP_REQ, // RED event
|
||||||
EVENT_LOW_SOH,
|
EVENT_LOW_SOH, // RED event
|
||||||
EVENT_HVIL_FAILURE,
|
EVENT_HVIL_FAILURE, // RED event
|
||||||
EVENT_INTERNAL_OPEN_FAULT,
|
EVENT_INTERNAL_OPEN_FAULT, // RED event
|
||||||
EVENT_CELL_UNDER_VOLTAGE,
|
EVENT_CELL_UNDER_VOLTAGE, // RED event
|
||||||
EVENT_CELL_OVER_VOLTAGE,
|
EVENT_CELL_OVER_VOLTAGE, // RED event
|
||||||
EVENT_CELL_DEVIATION_HIGH,
|
EVENT_CELL_DEVIATION_HIGH, // YELLOW event
|
||||||
EVENT_UNKNOWN_EVENT_SET,
|
EVENT_UNKNOWN_EVENT_SET, // RED event
|
||||||
EVENT_OTA_UPDATE,
|
EVENT_OTA_UPDATE, // BLUE event
|
||||||
EVENT_DUMMY,
|
EVENT_DUMMY, // RED event
|
||||||
EVENT_NOF_EVENTS
|
EVENT_NOF_EVENTS // RED event
|
||||||
} EVENTS_ENUM_TYPE;
|
} EVENTS_ENUM_TYPE;
|
||||||
|
|
||||||
void init_events(void);
|
void init_events(void);
|
||||||
|
void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data);
|
||||||
void set_event(EVENTS_ENUM_TYPE event, uint8_t data);
|
void set_event(EVENTS_ENUM_TYPE event, uint8_t data);
|
||||||
|
void clear_event(EVENTS_ENUM_TYPE event);
|
||||||
|
|
||||||
void run_event_handling(void);
|
void run_event_handling(void);
|
||||||
uint8_t get_event_ledcolor(void);
|
|
||||||
|
|
||||||
extern uint8_t bms_status; //Enum, 0-5
|
extern uint8_t bms_status; //Enum, 0-5
|
||||||
|
extern uint8_t LEDcolor;
|
||||||
|
|
||||||
#endif // __MYTIMER_H__
|
#endif // __MYTIMER_H__
|
||||||
|
|
|
@ -7,13 +7,16 @@
|
||||||
|
|
||||||
class MyTimer {
|
class MyTimer {
|
||||||
public:
|
public:
|
||||||
|
/** Default constructor */
|
||||||
|
MyTimer() : interval(0), previous_millis(0) {}
|
||||||
|
|
||||||
/** interval in ms */
|
/** interval in ms */
|
||||||
MyTimer(unsigned long interval);
|
MyTimer(unsigned long interval);
|
||||||
/** Returns true and resets the timer if it has elapsed */
|
/** Returns true and resets the timer if it has elapsed */
|
||||||
bool elapsed();
|
bool elapsed();
|
||||||
|
unsigned long interval;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned long interval;
|
|
||||||
unsigned long previous_millis;
|
unsigned long previous_millis;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "config.h"
|
#include "../Software/src/devboard/config.h"
|
||||||
|
|
||||||
MySerial Serial;
|
MySerial Serial;
|
||||||
|
|
||||||
unsigned long testlib_millis = 0;
|
unsigned long testlib_millis = 0;
|
||||||
|
|
||||||
uint8_t bms_status = ACTIVE;
|
uint8_t bms_status = ACTIVE;
|
||||||
|
|
||||||
|
uint8_t LEDcolor = GREEN;
|
||||||
|
|
|
@ -16,6 +16,7 @@ class MySerial;
|
||||||
extern unsigned long testlib_millis;
|
extern unsigned long testlib_millis;
|
||||||
extern MySerial Serial;
|
extern MySerial Serial;
|
||||||
extern uint8_t bms_status;
|
extern uint8_t bms_status;
|
||||||
|
extern uint8_t LEDcolor;
|
||||||
|
|
||||||
/* Mock millis() */
|
/* Mock millis() */
|
||||||
static inline unsigned long millis(void) {
|
static inline unsigned long millis(void) {
|
||||||
|
|
|
@ -1,79 +1,87 @@
|
||||||
// The test library must be included first!
|
// The test library must be included first!
|
||||||
#include "../test_lib.h"
|
#include "../test_lib.h"
|
||||||
|
|
||||||
|
#include "../../Software/src/devboard/config.h"
|
||||||
#include "events.cpp"
|
#include "events.cpp"
|
||||||
|
#include "timer.cpp"
|
||||||
|
|
||||||
|
/* Local rest variables */
|
||||||
|
bool elapsed = false;
|
||||||
|
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
|
// bool MyTimer::elapsed(void) { return true; }
|
||||||
|
|
||||||
static void reset_event_msg(void) {
|
static void reset_event_msg(void) {
|
||||||
snprintf(event_message, sizeof(event_message), "");
|
snprintf(events.message, sizeof(events.message), ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(init_events_test) {
|
TEST(init_events_test) {
|
||||||
init_events();
|
init_events();
|
||||||
|
|
||||||
for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) {
|
||||||
ASSERT_EQ(entries[i].occurences, 0);
|
ASSERT_EQ(events.entries[i].occurences, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(update_event_time_test) {
|
TEST(update_event_time_test) {
|
||||||
// Reset
|
// Reset
|
||||||
init_events();
|
init_events();
|
||||||
time_seconds = 0;
|
events.time_seconds = 0;
|
||||||
|
|
||||||
// No delta, so time shouldn't increase
|
// No delta, so time shouldn't increase
|
||||||
testlib_millis = 0;
|
testlib_millis = 0;
|
||||||
update_event_time();
|
update_event_time();
|
||||||
ASSERT_EQ(time_seconds, 0);
|
ASSERT_EQ(events.time_seconds, 0);
|
||||||
|
|
||||||
// Almost time to bump the seconds
|
// Almost time to bump the seconds
|
||||||
testlib_millis = 999;
|
testlib_millis = 999;
|
||||||
update_event_time();
|
update_event_time();
|
||||||
ASSERT_EQ(time_seconds, 0);
|
ASSERT_EQ(events.time_seconds, 0);
|
||||||
ASSERT_EQ(previous_millis, 0);
|
|
||||||
|
|
||||||
// millis == 1000, so we should add a second
|
// millis == 1000, so we should add a second
|
||||||
testlib_millis = 1000;
|
testlib_millis = 1000;
|
||||||
update_event_time();
|
update_event_time();
|
||||||
ASSERT_EQ(time_seconds, 1);
|
ASSERT_EQ(events.time_seconds, 1);
|
||||||
ASSERT_EQ(previous_millis, 1000);
|
|
||||||
|
|
||||||
// We shouldn't add more seconds until 2000 now
|
// We shouldn't add more seconds until 2000 now
|
||||||
testlib_millis = 1999;
|
testlib_millis = 1999;
|
||||||
update_event_time();
|
update_event_time();
|
||||||
ASSERT_EQ(time_seconds, 1);
|
ASSERT_EQ(events.time_seconds, 1);
|
||||||
ASSERT_EQ(previous_millis, 1000);
|
|
||||||
testlib_millis = 2000;
|
testlib_millis = 2000;
|
||||||
update_event_time();
|
update_event_time();
|
||||||
ASSERT_EQ(time_seconds, 2);
|
ASSERT_EQ(events.time_seconds, 2);
|
||||||
ASSERT_EQ(previous_millis, 2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(set_event_test) {
|
TEST(set_event_test) {
|
||||||
// Reset
|
// Reset
|
||||||
init_events();
|
init_events();
|
||||||
time_seconds = 0;
|
events.time_seconds = 0;
|
||||||
|
|
||||||
// Initially, the event should not have any data or occurences
|
// Initially, the event should not have any data or occurences
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 0);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].data, 0);
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 0);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].occurences, 0);
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 0);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 0);
|
||||||
// Set current time and overvoltage event for cell 23 (RED color, bms_status == FAULT)
|
// Set current time and overvoltage event for cell 23 (RED color, bms_status == FAULT)
|
||||||
time_seconds = 345;
|
events.time_seconds = 345;
|
||||||
set_event(EVENT_CELL_OVER_VOLTAGE, 123);
|
set_event(EVENT_CELL_OVER_VOLTAGE, 123);
|
||||||
// Ensure proper event data
|
// Ensure proper event data
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 123);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].data, 123);
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 1);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].occurences, 1);
|
||||||
ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345);
|
ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345);
|
||||||
ASSERT_EQ(bms_status, FAULT);
|
ASSERT_EQ(bms_status, FAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(event_message_test) {
|
TEST(events_message_test) {
|
||||||
reset_event_msg();
|
reset_event_msg();
|
||||||
|
|
||||||
set_event(EVENT_DUMMY, 0); // Set dummy event with no data
|
set_event(EVENT_DUMMY, 0); // Set dummy event with no data
|
||||||
|
|
||||||
ASSERT_STREQ("The dummy event was set!", event_message);
|
ASSERT_STREQ("The dummy event was set!", events.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(event_priority_test) {
|
||||||
|
ASSERT_TRUE(RED > BLUE);
|
||||||
|
ASSERT_TRUE(BLUE > YELLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_MAIN();
|
TEST_MAIN();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue