Use base class for Cell power BMS

This commit is contained in:
Jaakko Haakana 2025-05-19 20:11:24 +03:00
parent 50a4510601
commit 6b21cc3b07
2 changed files with 127 additions and 117 deletions

View file

@ -1,115 +1,12 @@
#include "../include.h" #include "../include.h"
#ifdef CELLPOWER_BMS #ifdef CELLPOWER_BMS
#include "../communication/can/comm_can.h"
#include "../datalayer/datalayer.h" #include "../datalayer/datalayer.h"
#include "../datalayer/datalayer_extended.h" //For "More battery info" webpage #include "../datalayer/datalayer_extended.h" //For "More battery info" webpage
#include "../devboard/utils/events.h" #include "../devboard/utils/events.h"
#include "CELLPOWER-BMS.h" #include "CELLPOWER-BMS.h"
/* Do not change code below unless you are sure what you are doing */ void CellPowerBms::update_values() {
static unsigned long previousMillis1s = 0; // will store last time a 1s CAN Message was sent
//Actual content messages
// Optional add-on charger module. Might not be needed to send these towards the BMS to keep it happy.
CAN_frame CELLPOWER_18FF50E9 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E9,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E8 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E8,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E7 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E7,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E5 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E5,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
static bool system_state_discharge = false;
static bool system_state_charge = false;
static bool system_state_cellbalancing = false;
static bool system_state_tricklecharge = false;
static bool system_state_idle = false;
static bool system_state_chargecompleted = false;
static bool system_state_maintenancecharge = false;
static bool IO_state_main_positive_relay = false;
static bool IO_state_main_negative_relay = false;
static bool IO_state_charge_enable = false;
static bool IO_state_precharge_relay = false;
static bool IO_state_discharge_enable = false;
static bool IO_state_IO_6 = false;
static bool IO_state_IO_7 = false;
static bool IO_state_IO_8 = false;
static bool error_Cell_overvoltage = false;
static bool error_Cell_undervoltage = false;
static bool error_Cell_end_of_life_voltage = false;
static bool error_Cell_voltage_misread = false;
static bool error_Cell_over_temperature = false;
static bool error_Cell_under_temperature = false;
static bool error_Cell_unmanaged = false;
static bool error_LMU_over_temperature = false;
static bool error_LMU_under_temperature = false;
static bool error_Temp_sensor_open_circuit = false;
static bool error_Temp_sensor_short_circuit = false;
static bool error_SUB_communication = false;
static bool error_LMU_communication = false;
static bool error_Over_current_IN = false;
static bool error_Over_current_OUT = false;
static bool error_Short_circuit = false;
static bool error_Leak_detected = false;
static bool error_Leak_detection_failed = false;
static bool error_Voltage_difference = false;
static bool error_BMCU_supply_over_voltage = false;
static bool error_BMCU_supply_under_voltage = false;
static bool error_Main_positive_contactor = false;
static bool error_Main_negative_contactor = false;
static bool error_Precharge_contactor = false;
static bool error_Midpack_contactor = false;
static bool error_Precharge_timeout = false;
static bool error_Emergency_connector_override = false;
static bool warning_High_cell_voltage = false;
static bool warning_Low_cell_voltage = false;
static bool warning_High_cell_temperature = false;
static bool warning_Low_cell_temperature = false;
static bool warning_High_LMU_temperature = false;
static bool warning_Low_LMU_temperature = false;
static bool warning_SUB_communication_interfered = false;
static bool warning_LMU_communication_interfered = false;
static bool warning_High_current_IN = false;
static bool warning_High_current_OUT = false;
static bool warning_Pack_resistance_difference = false;
static bool warning_High_pack_resistance = false;
static bool warning_Cell_resistance_difference = false;
static bool warning_High_cell_resistance = false;
static bool warning_High_BMCU_supply_voltage = false;
static bool warning_Low_BMCU_supply_voltage = false;
static bool warning_Low_SOC = false;
static bool warning_Balancing_required_OCV_model = false;
static bool warning_Charger_not_responding = false;
static uint16_t cell_voltage_max_mV = 3700;
static uint16_t cell_voltage_min_mV = 3700;
static int8_t pack_temperature_high_C = 0;
static int8_t pack_temperature_low_C = 0;
static uint16_t battery_pack_voltage_dV = 3700;
static int16_t battery_pack_current_dA = 0;
static uint8_t battery_SOH_percentage = 99;
static uint8_t battery_SOC_percentage = 50;
static uint16_t battery_remaining_dAh = 0;
static uint8_t cell_with_highest_voltage = 0;
static uint8_t cell_with_lowest_voltage = 0;
static uint16_t requested_charge_current_dA = 0;
static uint16_t average_charge_current_dA = 0;
static uint16_t actual_charge_current_dA = 0;
static bool requested_exceeding_average_current = 0;
static bool error_state = false;
void update_values_battery() {
/* Update values from CAN */ /* Update values from CAN */
@ -213,7 +110,8 @@ void update_values_battery() {
//TODO, shall we react on this? //TODO, shall we react on this?
} }
} }
void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
void CellPowerBms::handle_incoming_can_frame(CAN_frame rx_frame) {
switch (rx_frame.ID) { switch (rx_frame.ID) {
case 0x1A4: //PDO1_TX - 200ms case 0x1A4: //PDO1_TX - 200ms
@ -316,7 +214,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
} }
} }
void transmit_can_battery(unsigned long currentMillis) { void CellPowerBms::transmit_can(unsigned long currentMillis) {
// Send 1s CAN Message // Send 1s CAN Message
if (currentMillis - previousMillis1s >= INTERVAL_1_S) { if (currentMillis - previousMillis1s >= INTERVAL_1_S) {
@ -331,7 +229,7 @@ void transmit_can_battery(unsigned long currentMillis) {
} }
} }
void setup_battery(void) { // Performs one time setup at startup void CellPowerBms::setup(void) { // Performs one time setup at startup
strncpy(datalayer.system.info.battery_protocol, "Cellpower BMS", 63); strncpy(datalayer.system.info.battery_protocol, "Cellpower BMS", 63);
datalayer.system.info.battery_protocol[63] = '\0'; datalayer.system.info.battery_protocol[63] = '\0';
datalayer.system.status.battery_allows_contactor_closing = true; datalayer.system.status.battery_allows_contactor_closing = true;

View file

@ -2,18 +2,130 @@
#define CELLPOWER_BMS_H #define CELLPOWER_BMS_H
#include <Arduino.h> #include <Arduino.h>
#include "../include.h" #include "../include.h"
#include "CanBattery.h"
/* Tweak these according to your battery build */ #define BATTERY_SELECTED
#define MAX_PACK_VOLTAGE_DV 5000 //5000 = 500.0V #define SELECTED_BATTERY_CLASS CellPowerBms
#define MIN_PACK_VOLTAGE_DV 1500
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value class CellPowerBms : public CanBattery {
#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value public:
virtual void setup(void);
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
virtual void update_values();
virtual void transmit_can(unsigned long currentMillis);
private:
/* Tweak these according to your battery build */
static const int MAX_PACK_VOLTAGE_DV = 5000; //5000 = 500.0V
static const int MIN_PACK_VOLTAGE_DV = 1500;
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
static const int MIN_CELL_VOLTAGE_MV = 2700; //Battery is put into emergency stop if one cell goes below this value
unsigned long previousMillis1s = 0; // will store last time a 1s CAN Message was sent
//Actual content messages
// Optional add-on charger module. Might not be needed to send these towards the BMS to keep it happy.
CAN_frame CELLPOWER_18FF50E9 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E9,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E8 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E8,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E7 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E7,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame CELLPOWER_18FF50E5 = {.FD = false,
.ext_ID = true,
.DLC = 5,
.ID = 0x18FF50E5,
.data = {0x00, 0x00, 0x00, 0x00, 0x00}};
bool system_state_discharge = false;
bool system_state_charge = false;
bool system_state_cellbalancing = false;
bool system_state_tricklecharge = false;
bool system_state_idle = false;
bool system_state_chargecompleted = false;
bool system_state_maintenancecharge = false;
bool IO_state_main_positive_relay = false;
bool IO_state_main_negative_relay = false;
bool IO_state_charge_enable = false;
bool IO_state_precharge_relay = false;
bool IO_state_discharge_enable = false;
bool IO_state_IO_6 = false;
bool IO_state_IO_7 = false;
bool IO_state_IO_8 = false;
bool error_Cell_overvoltage = false;
bool error_Cell_undervoltage = false;
bool error_Cell_end_of_life_voltage = false;
bool error_Cell_voltage_misread = false;
bool error_Cell_over_temperature = false;
bool error_Cell_under_temperature = false;
bool error_Cell_unmanaged = false;
bool error_LMU_over_temperature = false;
bool error_LMU_under_temperature = false;
bool error_Temp_sensor_open_circuit = false;
bool error_Temp_sensor_short_circuit = false;
bool error_SUB_communication = false;
bool error_LMU_communication = false;
bool error_Over_current_IN = false;
bool error_Over_current_OUT = false;
bool error_Short_circuit = false;
bool error_Leak_detected = false;
bool error_Leak_detection_failed = false;
bool error_Voltage_difference = false;
bool error_BMCU_supply_over_voltage = false;
bool error_BMCU_supply_under_voltage = false;
bool error_Main_positive_contactor = false;
bool error_Main_negative_contactor = false;
bool error_Precharge_contactor = false;
bool error_Midpack_contactor = false;
bool error_Precharge_timeout = false;
bool error_Emergency_connector_override = false;
bool warning_High_cell_voltage = false;
bool warning_Low_cell_voltage = false;
bool warning_High_cell_temperature = false;
bool warning_Low_cell_temperature = false;
bool warning_High_LMU_temperature = false;
bool warning_Low_LMU_temperature = false;
bool warning_SUB_communication_interfered = false;
bool warning_LMU_communication_interfered = false;
bool warning_High_current_IN = false;
bool warning_High_current_OUT = false;
bool warning_Pack_resistance_difference = false;
bool warning_High_pack_resistance = false;
bool warning_Cell_resistance_difference = false;
bool warning_High_cell_resistance = false;
bool warning_High_BMCU_supply_voltage = false;
bool warning_Low_BMCU_supply_voltage = false;
bool warning_Low_SOC = false;
bool warning_Balancing_required_OCV_model = false;
bool warning_Charger_not_responding = false;
uint16_t cell_voltage_max_mV = 3700;
uint16_t cell_voltage_min_mV = 3700;
int8_t pack_temperature_high_C = 0;
int8_t pack_temperature_low_C = 0;
uint16_t battery_pack_voltage_dV = 3700;
int16_t battery_pack_current_dA = 0;
uint8_t battery_SOH_percentage = 99;
uint8_t battery_SOC_percentage = 50;
uint16_t battery_remaining_dAh = 0;
uint8_t cell_with_highest_voltage = 0;
uint8_t cell_with_lowest_voltage = 0;
uint16_t requested_charge_current_dA = 0;
uint16_t average_charge_current_dA = 0;
uint16_t actual_charge_current_dA = 0;
bool requested_exceeding_average_current = 0;
bool error_state = false;
};
/* Do not modify any rows below*/ /* Do not modify any rows below*/
#define BATTERY_SELECTED
#define NATIVECAN_250KBPS #define NATIVECAN_250KBPS
void setup_battery(void);
void transmit_can_frame(CAN_frame* tx_frame, int interface);
#endif #endif