Merge branch 'main' into bugfix/ota-improvement

This commit is contained in:
Cabooman 2024-02-16 19:20:04 +01:00
commit 6f33d5121c
12 changed files with 118 additions and 100 deletions

View file

@ -103,6 +103,7 @@ void update_values_i3_battery() { //This function maps all the values fetched v
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB

View file

@ -108,6 +108,7 @@ void update_values_chademo_battery() { //This function maps all the values fetc
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB

View file

@ -109,6 +109,7 @@ void update_values_imiev_battery() { //This function maps all the values fetche
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (!BMU_Detected) { if (!BMU_Detected) {

View file

@ -200,6 +200,7 @@ void update_values_kiaHyundai_64_battery() { //This function maps all the value
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (waterleakageSensor == 0) { if (waterleakageSensor == 0) {
@ -221,6 +222,8 @@ void update_values_kiaHyundai_64_battery() { //This function maps all the value
} }
if (cell_deviation_mV > MAX_CELL_DEVIATION) { if (cell_deviation_mV > MAX_CELL_DEVIATION) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0); set_event(EVENT_CELL_DEVIATION_HIGH, 0);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
} }
if (bms_status == FAULT) { //Incase we enter a critical fault state, zero out the allowed limits if (bms_status == FAULT) { //Incase we enter a critical fault state, zero out the allowed limits

View file

@ -104,7 +104,7 @@ static int16_t LB_SOC = 500; //0 - 100.0 % (0-1000) The real S
static int16_t CalculatedSOC = 0; // Temporary value used for calculating SOC static int16_t CalculatedSOC = 0; // Temporary value used for calculating SOC
static uint16_t LB_TEMP = 0; //Temporary value used in status checks static uint16_t LB_TEMP = 0; //Temporary value used in status checks
static uint16_t LB_Wh_Remaining = 0; //Amount of energy in battery, in Wh static uint16_t LB_Wh_Remaining = 0; //Amount of energy in battery, in Wh
static uint16_t LB_GIDS = 0; static uint16_t LB_GIDS = 273; //Startup in 24kWh mode
static uint16_t LB_MAX = 0; static uint16_t LB_MAX = 0;
static uint16_t LB_Max_GIDS = 273; //Startup in 24kWh mode static uint16_t LB_Max_GIDS = 273; //Startup in 24kWh mode
static uint16_t LB_StateOfHealth = 99; //State of health % static uint16_t LB_StateOfHealth = 99; //State of health %
@ -247,8 +247,9 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
} }
/*Extra safety functions below*/ /*Extra safety functions below*/
if (LB_GIDS < 10) //800Wh left in battery if (LB_GIDS < 6) //500Wh left in battery
{ //Battery is running abnormally low, some discharge logic might have failed. Zero it all out. { //Battery is running abnormally low, some discharge logic might have failed. Zero it all out.
set_event(EVENT_BATTERY_EMPTY, 0);
SOC = 0; SOC = 0;
max_target_discharge_power = 0; max_target_discharge_power = 0;
} }
@ -264,11 +265,17 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
} }
if (LB_Full_CHARGE_flag) { //Battery reports that it is fully charged stop all further charging incase it hasn't already if (LB_Full_CHARGE_flag) { //Battery reports that it is fully charged stop all further charging incase it hasn't already
set_event(EVENT_BATTERY_FULL, 0);
max_target_charge_power = 0; max_target_charge_power = 0;
} else {
clear_event(EVENT_BATTERY_FULL);
} }
if (LB_Capacity_Empty) { //Battery reports that it is fully discharged. Stop all further discharging incase it hasn't already if (LB_Capacity_Empty) { //Battery reports that it is fully discharged. Stop all further discharging incase it hasn't already
set_event(EVENT_BATTERY_EMPTY, 0);
max_target_discharge_power = 0; max_target_discharge_power = 0;
} else {
clear_event(EVENT_BATTERY_EMPTY);
} }
if (LB_Relay_Cut_Request) { //LB_FAIL, BMS requesting shutdown and contactors to be opened if (LB_Relay_Cut_Request) { //LB_FAIL, BMS requesting shutdown and contactors to be opened
@ -320,14 +327,18 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
default: default:
break; break;
} }
} else { //LB_Failsafe_Status == 0
clear_event(EVENT_BATTERY_DISCHG_STOP_REQ);
clear_event(EVENT_BATTERY_CHG_STOP_REQ);
clear_event(EVENT_BATTERY_CHG_DISCHG_STOP_REQ);
} }
if (LB_StateOfHealth < 25) { //Battery is extremely degraded, not fit for secondlifestorage. Zero it all out. if (LB_StateOfHealth < 25) { //Battery is extremely degraded, not fit for secondlifestorage. Zero it all out.
if (LB_StateOfHealth != 0) { //Extra check to see that we actually have a SOH Value available if (LB_StateOfHealth != 0) { //Extra check to see that we actually have a SOH Value available
errorCode = 5; errorCode = 5;
set_event(EVENT_LOW_SOH, LB_StateOfHealth); set_event(EVENT_LOW_SOH, LB_StateOfHealth);
max_target_discharge_power = 0; } else {
max_target_charge_power = 0; clear_event(EVENT_LOW_SOH);
} }
} }
@ -335,9 +346,8 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
if (!LB_Interlock) { if (!LB_Interlock) {
set_event(EVENT_HVIL_FAILURE, 0); set_event(EVENT_HVIL_FAILURE, 0);
errorCode = 6; errorCode = 6;
SOC = 0; } else {
max_target_discharge_power = 0; clear_event(EVENT_HVIL_FAILURE);
max_target_charge_power = 0;
} }
#endif #endif
@ -347,6 +357,7 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (CANerror > if (CANerror >
MAX_CAN_FAILURES) //Also check if we have recieved too many malformed CAN messages. If so, signal via LED MAX_CAN_FAILURES) //Also check if we have recieved too many malformed CAN messages. If so, signal via LED
@ -355,6 +366,11 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
set_event(EVENT_CAN_RX_WARNING, 0); set_event(EVENT_CAN_RX_WARNING, 0);
} }
if (bms_status == FAULT) { //Incase we enter a critical fault state, zero out the allowed limits
max_target_charge_power = 0;
max_target_discharge_power = 0;
}
/*Finally print out values to serial if configured to do so*/ /*Finally print out values to serial if configured to do so*/
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB
if (errorCode > 0) { if (errorCode > 0) {

View file

@ -126,6 +126,7 @@ void update_values_kangoo_battery() { //This function maps all the values fetch
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) {
@ -136,6 +137,8 @@ void update_values_kangoo_battery() { //This function maps all the values fetch
} }
if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) { if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0); set_event(EVENT_CELL_DEVIATION_HIGH, 0);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
} }
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB

View file

@ -87,6 +87,7 @@ void update_values_zoe_battery() { //This function maps all the values fetched
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) {
@ -97,6 +98,8 @@ void update_values_zoe_battery() { //This function maps all the values fetched
} }
if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) { if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0); set_event(EVENT_CELL_DEVIATION_HIGH, 0);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
} }
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB

View file

@ -84,6 +84,7 @@ void update_values_santafe_phev_battery() { //This function maps all the values
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
CANstillAlive--; CANstillAlive--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
#ifdef DEBUG_VIA_USB #ifdef DEBUG_VIA_USB

View file

@ -231,10 +231,13 @@ void update_values_tesla_model_3_battery() { //This function maps all the value
set_event(EVENT_CAN_RX_FAILURE, 0); set_event(EVENT_CAN_RX_FAILURE, 0);
} else { } else {
stillAliveCAN--; stillAliveCAN--;
clear_event(EVENT_CAN_RX_FAILURE);
} }
if (hvil_status == 3) { //INTERNAL_OPEN_FAULT - Someone disconnected a high voltage cable while battery was in use if (hvil_status == 3) { //INTERNAL_OPEN_FAULT - Someone disconnected a high voltage cable while battery was in use
set_event(EVENT_INTERNAL_OPEN_FAULT, 0); set_event(EVENT_INTERNAL_OPEN_FAULT, 0);
} else {
clear_event(EVENT_INTERNAL_OPEN_FAULT);
} }
cell_deviation_mV = (cell_max_v - cell_min_v); cell_deviation_mV = (cell_max_v - cell_min_v);
@ -269,23 +272,27 @@ void update_values_tesla_model_3_battery() { //This function maps all the value
if (LFP_Chemistry) { //LFP limits used for voltage safeties if (LFP_Chemistry) { //LFP limits used for voltage safeties
if (cell_max_v >= MAX_CELL_VOLTAGE_LFP) { if (cell_max_v >= MAX_CELL_VOLTAGE_LFP) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0); set_event(EVENT_CELL_OVER_VOLTAGE, (cell_max_v - MAX_CELL_VOLTAGE_LFP));
} }
if (cell_min_v <= MIN_CELL_VOLTAGE_LFP) { if (cell_min_v <= MIN_CELL_VOLTAGE_LFP) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0); set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_LFP - cell_min_v));
} }
if (cell_deviation_mV > MAX_CELL_DEVIATION_LFP) { if (cell_deviation_mV > MAX_CELL_DEVIATION_LFP) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0); set_event(EVENT_CELL_DEVIATION_HIGH, cell_deviation_mV);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
} }
} else { //NCA/NCM limits used } else { //NCA/NCM limits used
if (cell_max_v >= MAX_CELL_VOLTAGE_NCA_NCM) { if (cell_max_v >= MAX_CELL_VOLTAGE_NCA_NCM) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0); set_event(EVENT_CELL_OVER_VOLTAGE, (cell_max_v - MAX_CELL_VOLTAGE_NCA_NCM));
} }
if (cell_min_v <= MIN_CELL_VOLTAGE_NCA_NCM) { if (cell_min_v <= MIN_CELL_VOLTAGE_NCA_NCM) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0); set_event(EVENT_CELL_UNDER_VOLTAGE, (MIN_CELL_VOLTAGE_NCA_NCM - cell_min_v));
} }
if (cell_deviation_mV > MAX_CELL_DEVIATION_NCA_NCM) { if (cell_deviation_mV > MAX_CELL_DEVIATION_NCA_NCM) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0); set_event(EVENT_CELL_DEVIATION_HIGH, cell_deviation_mV);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
} }
} }

View file

@ -8,7 +8,7 @@
#include "../config.h" #include "../config.h"
#include "timer.h" #include "timer.h"
#define EE_MAGIC_HEADER_VALUE 0xAA55 #define EE_MAGIC_HEADER_VALUE 0xA5A5
#define EE_NOF_EVENT_ENTRIES 30 #define EE_NOF_EVENT_ENTRIES 30
#define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE) #define EE_EVENT_ENTRY_SIZE sizeof(EVENT_LOG_ENTRY_TYPE)
#define EE_WRITE_PERIOD_MINUTES 10 #define EE_WRITE_PERIOD_MINUTES 10
@ -52,6 +52,8 @@ typedef struct {
EVENTS_LEVEL_TYPE level; EVENTS_LEVEL_TYPE level;
uint16_t event_log_head_index; uint16_t event_log_head_index;
uint16_t event_log_tail_index; uint16_t event_log_tail_index;
uint8_t nof_logged_events;
uint16_t nof_eeprom_writes;
} EVENT_TYPE; } EVENT_TYPE;
/* Local variables */ /* Local variables */
@ -82,12 +84,27 @@ void run_event_handling(void) {
void init_events(void) { void init_events(void) {
EEPROM.begin(1024); EEPROM.begin(1024);
events.nof_logged_events = 0;
uint16_t header = EEPROM.readUShort(EE_EVENT_LOG_START_ADDRESS); uint16_t header = EEPROM.readUShort(EE_EVENT_LOG_START_ADDRESS);
if (header != EE_MAGIC_HEADER_VALUE) { if (header != EE_MAGIC_HEADER_VALUE) {
// The header doesn't appear to be a compatible event log, clear it and initialize
EEPROM.writeUShort(EE_EVENT_LOG_START_ADDRESS, EE_MAGIC_HEADER_VALUE); EEPROM.writeUShort(EE_EVENT_LOG_START_ADDRESS, EE_MAGIC_HEADER_VALUE);
EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, 0); EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, 0);
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, 0); EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, 0);
// Prepare an empty event block to write
EVENT_LOG_ENTRY_TYPE entry = {.event = EVENT_NOF_EVENTS, .timestamp = 0, .data = 0};
// Put the event in (what I guess is) the RAM EEPROM mirror, or write buffer
for (int i = 0; i < EE_NOF_EVENT_ENTRIES; i++) {
// Start at the oldest event, work through the log all the way the the head
int address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * i;
EEPROM.put(address, entry);
}
// Push changes to eeprom
EEPROM.commit(); EEPROM.commit();
Serial.println("EEPROM wasn't ready"); Serial.println("EEPROM wasn't ready");
} else { } else {
@ -102,7 +119,7 @@ void init_events(void) {
events.entries[i].data = 0; events.entries[i].data = 0;
events.entries[i].timestamp = 0; events.entries[i].timestamp = 0;
events.entries[i].occurences = 0; events.entries[i].occurences = 0;
events.entries[i].log = false; events.entries[i].log = true;
} }
events.entries[EVENT_CAN_RX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CAN_RX_FAILURE].level = EVENT_LEVEL_ERROR;
@ -111,7 +128,9 @@ void init_events(void) {
events.entries[EVENT_WATER_INGRESS].level = EVENT_LEVEL_ERROR; events.entries[EVENT_WATER_INGRESS].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_12V_LOW].level = EVENT_LEVEL_WARNING; events.entries[EVENT_12V_LOW].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_SOC_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_ERROR; events.entries[EVENT_SOC_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_WARNING; 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_CHG_STOP_REQ].level = EVENT_LEVEL_ERROR; 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_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR; events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].level = EVENT_LEVEL_ERROR;
@ -123,6 +142,7 @@ void init_events(void) {
events.entries[EVENT_CELL_DEVIATION_HIGH].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CELL_DEVIATION_HIGH].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_UNKNOWN_EVENT_SET].level = EVENT_LEVEL_ERROR; events.entries[EVENT_UNKNOWN_EVENT_SET].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_OTA_UPDATE].level = EVENT_LEVEL_UPDATE; events.entries[EVENT_OTA_UPDATE].level = EVENT_LEVEL_UPDATE;
events.entries[EVENT_OTA_UPDATE_TIMEOUT].level = EVENT_LEVEL_INFO;
events.entries[EVENT_DUMMY_INFO].level = EVENT_LEVEL_INFO; events.entries[EVENT_DUMMY_INFO].level = EVENT_LEVEL_INFO;
events.entries[EVENT_DUMMY_DEBUG].level = EVENT_LEVEL_DEBUG; events.entries[EVENT_DUMMY_DEBUG].level = EVENT_LEVEL_DEBUG;
events.entries[EVENT_DUMMY_WARNING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_DUMMY_WARNING].level = EVENT_LEVEL_WARNING;
@ -131,15 +151,13 @@ void init_events(void) {
events.entries[EVENT_SERIAL_RX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_SERIAL_RX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_SERIAL_TX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_SERIAL_TX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_SERIAL_TRANSMITTER_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_SERIAL_TRANSMITTER_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_OTA_UPDATE_TIMEOUT].level = EVENT_LEVEL_INFO; events.entries[EVENT_EEPROM_WRITE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_DUMMY_INFO].log = true; events.entries[EVENT_EEPROM_WRITE].log = false; // Don't log the logger...
events.entries[EVENT_DUMMY_DEBUG].log = true;
events.entries[EVENT_DUMMY_WARNING].log = true;
events.entries[EVENT_DUMMY_ERROR].log = true;
events.second_timer.set_interval(1000); events.second_timer.set_interval(1000);
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000); // Write to EEPROM every X minutes // Write to EEPROM every X minutes (if an event has been set)
events.ee_timer.set_interval(EE_WRITE_PERIOD_MINUTES * 60 * 1000);
} }
void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { void set_event(EVENTS_ENUM_TYPE event, uint8_t data) {
@ -173,7 +191,11 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
case EVENT_SOC_PLAUSIBILITY_ERROR: case EVENT_SOC_PLAUSIBILITY_ERROR:
return "ERROR: SOC% reported by battery not plausible. Restart battery!"; return "ERROR: SOC% reported by battery not plausible. Restart battery!";
case EVENT_KWH_PLAUSIBILITY_ERROR: case EVENT_KWH_PLAUSIBILITY_ERROR:
return "Warning: kWh remaining reported by battery not plausible. Battery needs cycling."; return "Info: kWh remaining reported by battery not plausible. Battery needs cycling.";
case EVENT_BATTERY_EMPTY:
return "Info: Battery is completely discharged";
case EVENT_BATTERY_FULL:
return "Info: Battery is fully charged";
case EVENT_BATTERY_CHG_STOP_REQ: case EVENT_BATTERY_CHG_STOP_REQ:
return "ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"; return "ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!";
case EVENT_BATTERY_DISCHG_STOP_REQ: case EVENT_BATTERY_DISCHG_STOP_REQ:
@ -216,6 +238,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "OTA update started!"; return "OTA update started!";
case EVENT_OTA_UPDATE_TIMEOUT: case EVENT_OTA_UPDATE_TIMEOUT:
return "OTA update timed out!"; return "OTA update timed out!";
case EVENT_EEPROM_WRITE:
return "Info: The EEPROM was written";
default: default:
return ""; return "";
} }
@ -331,6 +355,9 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t data) {
EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index); EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index);
//Serial.println("Wrote event " + String(event) + " to " + String(entry_address)); //Serial.println("Wrote event " + String(event) + " to " + String(entry_address));
//Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index)); //Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index));
// We don't need the exact number, it's just for deciding to store or not
events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0;
} }
static void print_event_log(void) { static void print_event_log(void) {
@ -347,6 +374,10 @@ static void print_event_log(void) {
int address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * index; int address = EE_EVENT_ENTRY_START_ADDRESS + EE_EVENT_ENTRY_SIZE * index;
EEPROM.get(address, entry); EEPROM.get(address, entry);
if (entry.event == EVENT_NOF_EVENTS) {
// The entry is a blank that has been left behind somehow
continue;
}
Serial.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) + Serial.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) +
", time: " + String(entry.timestamp)); ", time: " + String(entry.timestamp));
@ -357,8 +388,17 @@ static void print_event_log(void) {
} }
static void check_ee_write(void) { static void check_ee_write(void) {
// Only actually write to flash emulated EEPROM every EE_WRITE_PERIOD_MINUTES minutes // Only actually write to flash emulated EEPROM every EE_WRITE_PERIOD_MINUTES minutes,
if (events.ee_timer.elapsed()) { // and only if we've logged any events
if (events.ee_timer.elapsed() && (events.nof_logged_events > 0)) {
EEPROM.commit(); EEPROM.commit();
events.nof_eeprom_writes += (events.nof_eeprom_writes < 65535) ? 1 : 0;
events.nof_logged_events = 0;
// We want to know how many writes we have, and to increment the occurrence counter
// we need to clear it first. It's just the way life is. Using events is a smooth
// way to visualize it in the web UI
clear_event(EVENT_EEPROM_WRITE);
set_event(EVENT_EEPROM_WRITE, events.nof_eeprom_writes);
} }
} }

View file

@ -28,6 +28,8 @@
XX(EVENT_12V_LOW) \ XX(EVENT_12V_LOW) \
XX(EVENT_SOC_PLAUSIBILITY_ERROR) \ XX(EVENT_SOC_PLAUSIBILITY_ERROR) \
XX(EVENT_KWH_PLAUSIBILITY_ERROR) \ XX(EVENT_KWH_PLAUSIBILITY_ERROR) \
XX(EVENT_BATTERY_EMPTY) \
XX(EVENT_BATTERY_FULL) \
XX(EVENT_BATTERY_CHG_STOP_REQ) \ XX(EVENT_BATTERY_CHG_STOP_REQ) \
XX(EVENT_BATTERY_DISCHG_STOP_REQ) \ XX(EVENT_BATTERY_DISCHG_STOP_REQ) \
XX(EVENT_BATTERY_CHG_DISCHG_STOP_REQ) \ XX(EVENT_BATTERY_CHG_DISCHG_STOP_REQ) \
@ -48,6 +50,7 @@
XX(EVENT_SERIAL_RX_FAILURE) \ XX(EVENT_SERIAL_RX_FAILURE) \
XX(EVENT_SERIAL_TX_FAILURE) \ XX(EVENT_SERIAL_TX_FAILURE) \
XX(EVENT_SERIAL_TRANSMITTER_FAILURE) \ XX(EVENT_SERIAL_TRANSMITTER_FAILURE) \
XX(EVENT_EEPROM_WRITE) \
XX(EVENT_NOF_EVENTS) XX(EVENT_NOF_EVENTS)
typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE; typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE;

View file

@ -2,33 +2,9 @@
#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h"
#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h"
//TODO: change CAN sending routine once confirmed that 500ms interval is OK for this battery type
/* Do not change code below unless you are sure what you are doing */ /* Do not change code below unless you are sure what you are doing */
static unsigned long previousMillis1s = 0; // will store last time a Xs CAN Message was send static unsigned long previousMillis100ms = 0; // will store last time a 100ms CAN Message was send
static unsigned long previousMillis2s = 0; // will store last time a Xs CAN Message was send static const int interval100ms = 100; // interval (ms) at which send CAN Messages
static unsigned long previousMillis3s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis4s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis5s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis6s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis7s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis8s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis9s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis10s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis11s = 0; // will store last time a Xs CAN Message was send
static unsigned long previousMillis12s = 0; // will store last time a Xs CAN Message was send
static const int interval1s = 100; // interval (ms) at which send CAN Messages
static const int interval2s = 102; // interval (ms) at which send CAN Messages
static const int interval3s = 104; // interval (ms) at which send CAN Messages
static const int interval4s = 106; // interval (ms) at which send CAN Messages
static const int interval5s = 108; // interval (ms) at which send CAN Messages
static const int interval6s = 110; // interval (ms) at which send CAN Messages
static const int interval7s = 112; // interval (ms) at which send CAN Messages
static const int interval8s = 114; // interval (ms) at which send CAN Messages
static const int interval9s = 116; // interval (ms) at which send CAN Messages
static const int interval10s = 118; // interval (ms) at which send CAN Messages
static const int interval11s = 120; // interval (ms) at which send CAN Messages
static const int interval12s = 122; // interval (ms) at which send CAN Messages
//Actual content messages //Actual content messages
static const CAN_frame_t SMA_558 = { static const CAN_frame_t SMA_558 = {
@ -176,11 +152,18 @@ void update_values_can_sma() { //This function maps all the values fetched from
//Error bits //Error bits
//SMA_158.data.u8[0] = //bit12 Fault high temperature, bit34Battery cellundervoltage, bit56 Battery cell overvoltage, bit78 batterysystemdefect //SMA_158.data.u8[0] = //bit12 Fault high temperature, bit34Battery cellundervoltage, bit56 Battery cell overvoltage, bit78 batterysystemdefect
//TODO: add all error bits //TODO: add all error bits. Sending message with all 0xAA until that.
} }
void receive_can_sma(CAN_frame_t rx_frame) { void receive_can_sma(CAN_frame_t rx_frame) {
switch (rx_frame.MsgID) { switch (rx_frame.MsgID) {
case 0x360: //Message originating from SMA inverter - Voltage and current
//Frame0-1 Voltage
//Frame2-3 Current
break;
case 0x420: //Message originating from SMA inverter - Timestamp
//Frame0-3 Timestamp
break;
case 0x660: //Message originating from SMA inverter case 0x660: //Message originating from SMA inverter
break; break;
case 0x5E0: //Message originating from SMA inverter case 0x5E0: //Message originating from SMA inverter
@ -195,65 +178,21 @@ void receive_can_sma(CAN_frame_t rx_frame) {
void send_can_sma() { void send_can_sma() {
unsigned long currentMillis = millis(); unsigned long currentMillis = millis();
// Send CAN Message every X ms, 1000 for testing // Send CAN Message every 100ms
if (currentMillis - previousMillis1s >= interval1s) { if (currentMillis - previousMillis100ms >= interval100ms) {
previousMillis1s = currentMillis; previousMillis100ms = currentMillis;
ESP32Can.CANWriteFrame(&SMA_558); ESP32Can.CANWriteFrame(&SMA_558);
}
if (currentMillis - previousMillis2s >= interval2s) {
previousMillis2s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_598); ESP32Can.CANWriteFrame(&SMA_598);
}
if (currentMillis - previousMillis3s >= interval3s) {
previousMillis3s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_5D8); ESP32Can.CANWriteFrame(&SMA_5D8);
}
if (currentMillis - previousMillis4s >= interval4s) {
previousMillis4s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_618_1); ESP32Can.CANWriteFrame(&SMA_618_1);
}
if (currentMillis - previousMillis5s >= interval5s) {
previousMillis5s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_618_2); ESP32Can.CANWriteFrame(&SMA_618_2);
}
if (currentMillis - previousMillis6s >= interval6s) {
previousMillis6s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_618_3); ESP32Can.CANWriteFrame(&SMA_618_3);
}
if (currentMillis - previousMillis7s >= interval7s) {
previousMillis7s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_358); ESP32Can.CANWriteFrame(&SMA_358);
}
if (currentMillis - previousMillis8s >= interval8s) {
previousMillis8s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_3D8); ESP32Can.CANWriteFrame(&SMA_3D8);
}
if (currentMillis - previousMillis9s >= interval9s) {
previousMillis9s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_458); ESP32Can.CANWriteFrame(&SMA_458);
}
if (currentMillis - previousMillis10s >= interval10s) {
previousMillis10s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_518); ESP32Can.CANWriteFrame(&SMA_518);
}
if (currentMillis - previousMillis11s >= interval11s) {
previousMillis11s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_4D8); ESP32Can.CANWriteFrame(&SMA_4D8);
}
if (currentMillis - previousMillis12s >= interval12s) {
previousMillis12s = currentMillis;
ESP32Can.CANWriteFrame(&SMA_158); ESP32Can.CANWriteFrame(&SMA_158);
} }
} }