Changes due to review comments

- Split bms_status (system status) to real_bms_status (bms status)
- Put #ifdef DEBUG_LOG around all log calls.
- Do not update bms_status (system status) directly, fire event instead from automatic precharge control
- Add Battery BMS status to webserver for MEB battery type only
This commit is contained in:
mvgalen 2025-01-14 22:26:31 +01:00
parent 753b506068
commit 9410b8732b
11 changed files with 103 additions and 50 deletions

View file

@ -306,30 +306,9 @@ void core_loop(void* task_time_us) {
if (check_pause_2s.elapsed()) { if (check_pause_2s.elapsed()) {
emulator_pause_state_transmit_can_battery(); emulator_pause_state_transmit_can_battery();
} }
static bms_status_enum previous_state = FAULT; #ifdef DEBUG_LOG
if (previous_state != datalayer.battery.status.bms_status) { logging.log_bms_status(datalayer.battery.status.real_bms_status, 1);
switch (datalayer.battery.status.bms_status) { #endif
case ACTIVE:
logging.printf("BMS state changed to: OK\n");
break;
case UPDATING:
logging.printf("BMS state changed to: UPDATING\n");
break;
case FAULT:
logging.printf("BMS state changed to: FAULT\n");
break;
case INACTIVE:
logging.printf("BMS state changed to: INACTIVE\n");
break;
case STANDBY:
logging.printf("BMS state changed to: STANDBY\n");
break;
default:
logging.printf("BMS state changed to: ??\n");
break;
}
previous_state = datalayer.battery.status.bms_status;
}
vTaskDelayUntil(&xLastWakeTime, xFrequency); vTaskDelayUntil(&xLastWakeTime, xFrequency);
} }

View file

@ -643,7 +643,9 @@ void update_values_battery() { //This function maps all the values fetched via
void handle_incoming_can_frame_battery(CAN_frame rx_frame) { void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
last_can_msg_timestamp = millis(); last_can_msg_timestamp = millis();
if (first_can_msg == 0) { if (first_can_msg == 0) {
#ifdef DEBUG_LOG
logging.printf("MEB: First CAN msg received\n"); logging.printf("MEB: First CAN msg received\n");
#endif
first_can_msg = last_can_msg_timestamp; first_can_msg = last_can_msg_timestamp;
} }
switch (rx_frame.ID) { switch (rx_frame.ID) {
@ -1013,31 +1015,39 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
case 3: // EXTERN CHARGING case 3: // EXTERN CHARGING
case 4: // AC_CHARGING case 4: // AC_CHARGING
case 6: // DC_CHARGING case 6: // DC_CHARGING
#ifdef DEBUG_LOG
if (!datalayer.system.status.battery_allows_contactor_closing) if (!datalayer.system.status.battery_allows_contactor_closing)
logging.printf("MEB Contactors closed\n"); logging.printf("MEB Contactors closed\n");
if (datalayer.battery.status.bms_status != FAULT) #endif
datalayer.battery.status.bms_status = ACTIVE; if (datalayer.battery.status.real_bms_status != BMS_FAULT)
datalayer.battery.status.real_bms_status = BMS_ACTIVE;
datalayer.system.status.battery_allows_contactor_closing = true; datalayer.system.status.battery_allows_contactor_closing = true;
break; break;
case 5: // Error case 5: // Error
#ifdef DEBUG_LOG
if (datalayer.system.status.battery_allows_contactor_closing) if (datalayer.system.status.battery_allows_contactor_closing)
logging.printf("MEB Contactors opened\n"); logging.printf("MEB Contactors opened\n");
datalayer.battery.status.bms_status = FAULT; #endif
datalayer.battery.status.real_bms_status = BMS_FAULT;
datalayer.system.status.battery_allows_contactor_closing = false; datalayer.system.status.battery_allows_contactor_closing = false;
break; break;
case 7: // Init case 7: // Init
#ifdef DEBUG_LOG
if (datalayer.system.status.battery_allows_contactor_closing) if (datalayer.system.status.battery_allows_contactor_closing)
logging.printf("MEB Contactors opened\n"); logging.printf("MEB Contactors opened\n");
if (datalayer.battery.status.bms_status != FAULT) #endif
datalayer.battery.status.bms_status = INACTIVE; if (datalayer.battery.status.real_bms_status != BMS_FAULT)
datalayer.battery.status.real_bms_status = BMS_STANDBY;
datalayer.system.status.battery_allows_contactor_closing = false; datalayer.system.status.battery_allows_contactor_closing = false;
break; break;
case 2: // BALANCING case 2: // BALANCING
default: default:
#ifdef DEBUG_LOG
if (datalayer.system.status.battery_allows_contactor_closing) if (datalayer.system.status.battery_allows_contactor_closing)
logging.printf("MEB Contactors opened\n"); logging.printf("MEB Contactors opened\n");
if (datalayer.battery.status.bms_status != FAULT) #endif
datalayer.battery.status.bms_status = STANDBY; if (datalayer.battery.status.real_bms_status != BMS_FAULT)
datalayer.battery.status.real_bms_status = BMS_STANDBY;
datalayer.system.status.battery_allows_contactor_closing = false; datalayer.system.status.battery_allows_contactor_closing = false;
} }
BMS_HVIL_status = (rx_frame.data.u8[2] & 0x18) >> 3; BMS_HVIL_status = (rx_frame.data.u8[2] & 0x18) >> 3;
@ -1511,14 +1521,16 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
handle_obd_frame(rx_frame); handle_obd_frame(rx_frame);
break; break;
default: default:
#ifdef DEBUG_LOG
logging.printf("Unknown CAN frame received:\n"); logging.printf("Unknown CAN frame received:\n");
#endif
dump_can_frame(rx_frame, MSG_RX); dump_can_frame(rx_frame, MSG_RX);
break; break;
} }
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
if (can_msg_received == 0xFFFF && nof_cells_determined) { if (can_msg_received == 0xFFFF && nof_cells_determined) {
if (datalayer.battery.status.bms_status == INACTIVE) if (datalayer.battery.status.real_bms_status == BMS_DISCONNECTED)
datalayer.battery.status.bms_status = STANDBY; datalayer.battery.status.real_bms_status = BMS_STANDBY;
} }
} }
@ -1526,12 +1538,16 @@ void transmit_can_battery() {
unsigned long currentMillis = millis(); unsigned long currentMillis = millis();
// Send 10ms CAN Message // Send 10ms CAN Message
if (datalayer.system.settings.equipment_stop_active || currentMillis > last_can_msg_timestamp + 500) { if (datalayer.system.settings.equipment_stop_active || currentMillis > last_can_msg_timestamp + 500) {
#ifdef DEBUG_LOG
if (first_can_msg) if (first_can_msg)
logging.printf("MEB: No CAN msg received for 500ms\n"); logging.printf("MEB: No CAN msg received for 500ms\n");
#endif
can_msg_received = RX_DEFAULT; can_msg_received = RX_DEFAULT;
first_can_msg = 0; first_can_msg = 0;
if (datalayer.battery.status.bms_status != FAULT) if (datalayer.battery.status.real_bms_status != BMS_FAULT){
datalayer.battery.status.bms_status = INACTIVE; datalayer.battery.status.real_bms_status = BMS_DISCONNECTED;
datalayer.system.status.battery_allows_contactor_closing = false;
}
} }
if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) {
@ -1601,15 +1617,17 @@ void transmit_can_battery() {
//HV request and DC/DC control lies in 0x503 //HV request and DC/DC control lies in 0x503
if (datalayer.battery.status.bms_status != FAULT && /*first_can_msg > 0 && currentMillis > first_can_msg + 2000*/ if (datalayer.battery.status.real_bms_status != BMS_FAULT && /*first_can_msg > 0 && currentMillis > first_can_msg + 2000*/
(datalayer.battery.status.bms_status == STANDBY || datalayer.battery.status.bms_status == ACTIVE) && (datalayer.battery.status.real_bms_status == BMS_STANDBY || datalayer.battery.status.real_bms_status == BMS_ACTIVE) &&
(labs(((int32_t)datalayer.battery.status.voltage_dV) - (labs(((int32_t)datalayer.battery.status.voltage_dV) -
((int32_t)datalayer_extended.meb.BMS_voltage_intermediate_dV)) < 200)) { ((int32_t)datalayer_extended.meb.BMS_voltage_intermediate_dV)) < 200)) {
#ifdef DEBUG_LOG
if (MEB_503.data.u8[3] == BMS_TARGET_HV_OFF) { if (MEB_503.data.u8[3] == BMS_TARGET_HV_OFF) {
logging.printf("MEB Requesting HV\n"); logging.printf("MEB Requesting HV\n");
} }
#endif
MEB_503.data.u8[1] = MEB_503.data.u8[1] =
0x30 | (datalayer.battery.status.bms_status == ACTIVE ? 0x00 : 0x80); // Disable precharing if ACTIVE 0x30 | (datalayer.battery.status.real_bms_status == BMS_ACTIVE ? 0x00 : 0x80); // Disable precharing if ACTIVE
MEB_503.data.u8[3] = BMS_TARGET_HV_ON; //TODO, should we try AC_2 or DC charging? MEB_503.data.u8[3] = BMS_TARGET_HV_ON; //TODO, should we try AC_2 or DC charging?
MEB_503.data.u8[5] = 0x82; // Bordnetz Active MEB_503.data.u8[5] = 0x82; // Bordnetz Active
MEB_503.data.u8[6] = 0xE0; // Request emergency shutdown HV system == 0, false MEB_503.data.u8[6] = 0xE0; // Request emergency shutdown HV system == 0, false

View file

@ -23,6 +23,7 @@ void show_dtc(uint8_t byte0, uint8_t byte1) {
} }
void handle_obd_frame(CAN_frame& rx_frame) { void handle_obd_frame(CAN_frame& rx_frame) {
#ifdef DEBUG_LOG
if (rx_frame.data.u8[1] == 0x7F) { if (rx_frame.data.u8[1] == 0x7F) {
const char* error_str = "?"; const char* error_str = "?";
switch (rx_frame.data.u8[3]) { // See https://automotive.wiki/index.php/ISO_14229 switch (rx_frame.data.u8[3]) { // See https://automotive.wiki/index.php/ISO_14229
@ -105,6 +106,7 @@ void handle_obd_frame(CAN_frame& rx_frame) {
} }
} }
dump_can_frame(rx_frame, MSG_RX); dump_can_frame(rx_frame, MSG_RX);
#endif
} }
void transmit_obd_can_frame(unsigned int address, int interface) { void transmit_obd_can_frame(unsigned int address, int interface) {

View file

@ -27,9 +27,12 @@ static int32_t prev_external_voltage = 20000;
void init_precharge_control() { void init_precharge_control() {
// Setup PWM Channel Frequency and Resolution // Setup PWM Channel Frequency and Resolution
#ifdef DEBUG_LOG
logging.printf("Precharge control initialised\n"); logging.printf("Precharge control initialised\n");
#endif
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
} }
// Main functions // Main functions
@ -44,8 +47,8 @@ void handle_precharge_control() {
switch (prechargeStatus) { switch (prechargeStatus) {
case PRECHARGE_IDLE: case PRECHARGE_IDLE:
if (datalayer.battery.status.bms_status == STANDBY && datalayer.system.status.inverter_allows_contactor_closing && if (datalayer.battery.status.bms_status != FAULT && datalayer.battery.status.real_bms_status == BMS_STANDBY &&
!datalayer.system.settings.equipment_stop_active) { datalayer.system.status.inverter_allows_contactor_closing && !datalayer.system.settings.equipment_stop_active) {
prechargeStatus = START_PRECHARGE; prechargeStatus = START_PRECHARGE;
} }
break; break;
@ -56,7 +59,9 @@ void handle_precharge_control() {
ledcWriteTone(PRECHARGE_PIN, freq); // Set frequency and set dutycycle to 50% ledcWriteTone(PRECHARGE_PIN, freq); // Set frequency and set dutycycle to 50%
prechargeStartTime = currentTime; prechargeStartTime = currentTime;
prechargeStatus = PRECHARGE; prechargeStatus = PRECHARGE;
#ifdef DEBUG_LOG
logging.printf("Precharge: Starting sequence\n"); logging.printf("Precharge: Starting sequence\n");
#endif
digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH); digitalWrite(POSITIVE_CONTACTOR_PIN, HIGH);
break; break;
@ -82,39 +87,50 @@ void handle_precharge_control() {
freq = Precharge_max_PWM_Freq; freq = Precharge_max_PWM_Freq;
if (freq < Precharge_min_PWM_Freq) if (freq < Precharge_min_PWM_Freq)
freq = Precharge_min_PWM_Freq; freq = Precharge_min_PWM_Freq;
#ifdef DEBUG_LOG
logging.printf("Precharge: Target: %d V Extern: %d V Frequency: %u\n", target_voltage / 10, logging.printf("Precharge: Target: %d V Extern: %d V Frequency: %u\n", target_voltage / 10,
external_voltage / 10, freq); external_voltage / 10, freq);
#endif
ledcWriteTone(PRECHARGE_PIN, freq); ledcWriteTone(PRECHARGE_PIN, freq);
} }
if ((datalayer.battery.status.bms_status != STANDBY && datalayer.battery.status.bms_status != ACTIVE) || if ((datalayer.battery.status.real_bms_status != BMS_STANDBY && datalayer.battery.status.real_bms_status != BMS_ACTIVE) ||
datalayer.system.settings.equipment_stop_active) { datalayer.battery.status.bms_status != ACTIVE || datalayer.system.settings.equipment_stop_active) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
prechargeStatus = PRECHARGE_IDLE; prechargeStatus = PRECHARGE_IDLE;
#ifdef DEBUG_LOG
logging.printf("Precharge: Disabling Precharge bms not standby/active or equipment stop\n"); logging.printf("Precharge: Disabling Precharge bms not standby/active or equipment stop\n");
#endif
} else if (currentTime - prechargeStartTime >= MAX_PRECHARGE_TIME_MS) { } else if (currentTime - prechargeStartTime >= MAX_PRECHARGE_TIME_MS) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
prechargeStatus = PRECHARGE_OFF; prechargeStatus = PRECHARGE_OFF;
datalayer.battery.status.bms_status = FAULT; #ifdef DEBUG_LOG
logging.printf("Precharge: Disabled (timeout reached) -> PRECHARGE_OFF\n"); logging.printf("Precharge: Disabled (timeout reached) -> PRECHARGE_OFF\n");
#endif
set_event(EVENT_AUTOMATIC_PRECHARGE_FAILURE, 0);
// Add event // Add event
} else if (datalayer.system.status.battery_allows_contactor_closing) { } else if (datalayer.system.status.battery_allows_contactor_closing) {
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
digitalWrite(POSITIVE_CONTACTOR_PIN, LOW); digitalWrite(POSITIVE_CONTACTOR_PIN, LOW);
prechargeStatus = COMPLETED; prechargeStatus = COMPLETED;
#ifdef DEBUG_LOG
logging.printf("Precharge: Disabled (contacts closed) -> COMPLETED\n"); logging.printf("Precharge: Disabled (contacts closed) -> COMPLETED\n");
#endif
} }
break; break;
case COMPLETED: case COMPLETED:
if (datalayer.system.settings.equipment_stop_active || datalayer.battery.status.bms_status != ACTIVE) { if (datalayer.system.settings.equipment_stop_active || datalayer.battery.status.bms_status != ACTIVE) {
prechargeStatus = PRECHARGE_IDLE; prechargeStatus = PRECHARGE_IDLE;
#ifdef DEBUG_LOG
logging.printf("Precharge: equipment stop activated -> IDLE\n"); logging.printf("Precharge: equipment stop activated -> IDLE\n");
#endif
} }
break; break;
@ -125,7 +141,9 @@ void handle_precharge_control() {
prechargeStatus = PRECHARGE_IDLE; prechargeStatus = PRECHARGE_IDLE;
pinMode(PRECHARGE_PIN, OUTPUT); pinMode(PRECHARGE_PIN, OUTPUT);
digitalWrite(PRECHARGE_PIN, LOW); digitalWrite(PRECHARGE_PIN, LOW);
#ifdef DEBUG_LOG
logging.printf("Precharge: equipment stop activated -> IDLE\n"); logging.printf("Precharge: equipment stop activated -> IDLE\n");
#endif
} }
break; break;

View file

@ -92,8 +92,11 @@ typedef struct {
uint8_t CAN_battery_still_alive = CAN_STILL_ALIVE; uint8_t CAN_battery_still_alive = CAN_STILL_ALIVE;
/** Other */ /** Other */
/** The current BMS status */ /** The current system status, which for now still has the name bms_status */
bms_status_enum bms_status = ACTIVE; bms_status_enum bms_status = ACTIVE;
/** The current battery status, which for now has the name real_bms_status */
real_bms_status_enum real_bms_status = BMS_DISCONNECTED;
} DATALAYER_BATTERY_STATUS_TYPE; } DATALAYER_BATTERY_STATUS_TYPE;
typedef struct { typedef struct {

View file

@ -343,12 +343,16 @@ void emulator_pause_state_transmit_can_battery() {
allowed_to_send_CAN = (!emulator_pause_CAN_send_ON || emulator_pause_status == NORMAL); allowed_to_send_CAN = (!emulator_pause_CAN_send_ON || emulator_pause_status == NORMAL);
if (previous_allowed_to_send_CAN && !allowed_to_send_CAN) { if (previous_allowed_to_send_CAN && !allowed_to_send_CAN) {
#ifdef DEBUG_LOG
logging.printf("Safety: Pausing CAN sending"); logging.printf("Safety: Pausing CAN sending");
#endif
//completely force stop the CAN communication //completely force stop the CAN communication
ESP32Can.CANStop(); ESP32Can.CANStop();
} else if (!previous_allowed_to_send_CAN && allowed_to_send_CAN) { } else if (!previous_allowed_to_send_CAN && allowed_to_send_CAN) {
//resume CAN communication //resume CAN communication
#ifdef DEBUG_LOG
logging.printf("Safety: Resuming CAN sending"); logging.printf("Safety: Resuming CAN sending");
#endif
ESP32Can.CANInit(); ESP32Can.CANInit();
} }
} }

View file

@ -168,6 +168,7 @@ void init_events(void) {
events.entries[EVENT_SOH_LOW].level = EVENT_LEVEL_ERROR; events.entries[EVENT_SOH_LOW].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_HVIL_FAILURE].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_PRECHARGE_FAILURE].level = EVENT_LEVEL_INFO;
events.entries[EVENT_AUTOMATIC_PRECHARGE_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR; events.entries[EVENT_INTERNAL_OPEN_FAULT].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_INVERTER_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO; events.entries[EVENT_INVERTER_OPEN_CONTACTOR].level = EVENT_LEVEL_INFO;
events.entries[EVENT_INTERFACE_MISSING].level = EVENT_LEVEL_INFO; events.entries[EVENT_INTERFACE_MISSING].level = EVENT_LEVEL_INFO;
@ -340,6 +341,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
"Battery will be disabled!"; "Battery will be disabled!";
case EVENT_PRECHARGE_FAILURE: case EVENT_PRECHARGE_FAILURE:
return "Battery failed to precharge. Check that capacitor is seated on high voltage output."; return "Battery failed to precharge. Check that capacitor is seated on high voltage output.";
case EVENT_AUTOMATIC_PRECHARGE_FAILURE:
return "Automatic precharge failed to reach target voltae.";
case EVENT_INTERNAL_OPEN_FAULT: case EVENT_INTERNAL_OPEN_FAULT:
return "High voltage cable removed while battery running. Opening contactors!"; return "High voltage cable removed while battery running. Opening contactors!";
case EVENT_INVERTER_OPEN_CONTACTOR: case EVENT_INVERTER_OPEN_CONTACTOR:
@ -501,15 +504,9 @@ static void update_bms_status(void) {
break; break;
case EVENT_LEVEL_UPDATE: case EVENT_LEVEL_UPDATE:
datalayer.battery.status.bms_status = UPDATING; datalayer.battery.status.bms_status = UPDATING;
#ifdef DOUBLE_BATTERY
datalayer.battery2.status.bms_status = UPDATING;
#endif
break; break;
case EVENT_LEVEL_ERROR: case EVENT_LEVEL_ERROR:
datalayer.battery.status.bms_status = FAULT; datalayer.battery.status.bms_status = FAULT;
#ifdef DOUBLE_BATTERY
datalayer.battery2.status.bms_status = FAULT;
#endif
break; break;
default: default:
break; break;

View file

@ -112,6 +112,7 @@
XX(EVENT_MQTT_CONNECT) \ XX(EVENT_MQTT_CONNECT) \
XX(EVENT_MQTT_DISCONNECT) \ XX(EVENT_MQTT_DISCONNECT) \
XX(EVENT_EQUIPMENT_STOP) \ XX(EVENT_EQUIPMENT_STOP) \
XX(EVENT_AUTOMATIC_PRECHARGE_FAILURE) \
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

@ -134,3 +134,31 @@ void Logging::printf(const char* fmt, ...) {
previous_message_was_newline = message_buffer[size - 1] == '\n'; previous_message_was_newline = message_buffer[size - 1] == '\n';
#endif // DEBUG_LOG #endif // DEBUG_LOG
} }
void Logging::log_bms_status(real_bms_status_enum bms_status, int battery_id){
static real_bms_status_enum previous_state = BMS_FAULT;
const char *id = "";
if (battery_id == 2){
id = "2";
}
if (previous_state != bms_status) {
switch (bms_status) {
case BMS_ACTIVE:
logging.printf("Battery%s BMS state changed to: OK\n", id);
break;
case BMS_DISCONNECTED:
logging.printf("Battery%s BMS state changed to: DISCONNECTED\n");
break;
case BMS_FAULT:
logging.printf("Battery%s BMS state changed to: FAULT\n");
break;
case BMS_STANDBY:
logging.printf("Battery%s BMS state changed to: STANDBY\n");
break;
default:
logging.printf("Battery%s BMS state changed to: ??\n");
break;
}
previous_state = bms_status;
}
}

View file

@ -3,6 +3,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #include "Print.h"
#include "types.h"
class Logging : public Print { class Logging : public Print {
void add_timestamp(size_t size); void add_timestamp(size_t size);
@ -11,6 +12,7 @@ class Logging : public Print {
virtual size_t write(const uint8_t* buffer, size_t size); virtual size_t write(const uint8_t* buffer, size_t size);
virtual size_t write(uint8_t) { return 0; } virtual size_t write(uint8_t) { return 0; }
void printf(const char* fmt, ...); void printf(const char* fmt, ...);
void log_bms_status(real_bms_status_enum bms_status, int battery_id);
Logging() {} Logging() {}
}; };

View file

@ -4,6 +4,7 @@
#include <string> #include <string>
enum bms_status_enum { STANDBY = 0, INACTIVE = 1, DARKSTART = 2, ACTIVE = 3, FAULT = 4, UPDATING = 5 }; enum bms_status_enum { STANDBY = 0, INACTIVE = 1, DARKSTART = 2, ACTIVE = 3, FAULT = 4, UPDATING = 5 };
enum real_bms_status_enum { BMS_DISCONNECTED = 0, BMS_STANDBY = 1, BMS_ACTIVE = 2, BMS_FAULT = 3 };
enum battery_chemistry_enum { NCA, NMC, LFP }; enum battery_chemistry_enum { NCA, NMC, LFP };
enum led_color { GREEN, YELLOW, RED, BLUE }; enum led_color { GREEN, YELLOW, RED, BLUE };