diff --git a/Software/src/battery/FOXESS-BATTERY.cpp b/Software/src/battery/FOXESS-BATTERY.cpp index a716843f..5c78dc08 100644 --- a/Software/src/battery/FOXESS-BATTERY.cpp +++ b/Software/src/battery/FOXESS-BATTERY.cpp @@ -1,5 +1,6 @@ #include "../include.h" #ifdef FOXESS_BATTERY +#include "../communication/can/comm_can.h" #include "../datalayer/datalayer.h" #include "../devboard/utils/events.h" #include "FOXESS-BATTERY.h" @@ -12,81 +13,8 @@ TODO: - Check that current is signed right way */ -/* Do not change code below unless you are sure what you are doing */ -static unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was send - -CAN_frame FOX_1871 = {.FD = false, //Inverter request data from battery. Content varies depending on state - .ext_ID = true, - .DLC = 8, - .ID = 0x1871, - .data = {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; -static uint32_t total_watt_hours = 0; -static uint16_t max_charge_power_dA = 0; -static uint16_t max_discharge_power_dA = 0; -static uint16_t cut_mv_max = 0; -static uint16_t cut_mv_min = 0; -static uint16_t cycle_count = 0; -static uint16_t max_ac_voltage = 0; -static uint16_t cellvoltages_mV[128] = {0}; -static int16_t temperature_average = 0; -static int16_t pack1_current_sensor = 0; -static int16_t pack2_current_sensor = 0; -static int16_t pack3_current_sensor = 0; -static int16_t pack4_current_sensor = 0; -static int16_t pack5_current_sensor = 0; -static int16_t pack6_current_sensor = 0; -static int16_t pack7_current_sensor = 0; -static int16_t pack8_current_sensor = 0; -static int16_t pack1_temperature_avg_high = 0; -static int16_t pack2_temperature_avg_high = 0; -static int16_t pack3_temperature_avg_high = 0; -static int16_t pack4_temperature_avg_high = 0; -static int16_t pack5_temperature_avg_high = 0; -static int16_t pack6_temperature_avg_high = 0; -static int16_t pack7_temperature_avg_high = 0; -static int16_t pack8_temperature_avg_high = 0; -static int16_t pack1_temperature_avg_low = 0; -static int16_t pack2_temperature_avg_low = 0; -static int16_t pack3_temperature_avg_low = 0; -static int16_t pack4_temperature_avg_low = 0; -static int16_t pack5_temperature_avg_low = 0; -static int16_t pack6_temperature_avg_low = 0; -static int16_t pack7_temperature_avg_low = 0; -static int16_t pack8_temperature_avg_low = 0; -static uint16_t pack1_voltage = 0; -static uint16_t pack2_voltage = 0; -static uint16_t pack3_voltage = 0; -static uint16_t pack4_voltage = 0; -static uint16_t pack5_voltage = 0; -static uint16_t pack6_voltage = 0; -static uint16_t pack7_voltage = 0; -static uint16_t pack8_voltage = 0; -static uint8_t pack1_SOC = 0; -static uint8_t pack2_SOC = 0; -static uint8_t pack3_SOC = 0; -static uint8_t pack4_SOC = 0; -static uint8_t pack5_SOC = 0; -static uint8_t pack6_SOC = 0; -static uint8_t pack7_SOC = 0; -static uint8_t pack8_SOC = 0; -static uint8_t pack_error = 0; -static uint8_t firmware_pack_minor = 0; -static uint8_t firmware_pack_major = 0; -static uint8_t STATUS_OPERATIONAL_PACKS = - 0; //0x1875 b2 contains status for operational packs (responding) in binary so 01111111 is pack 8 not operational, 11101101 is pack 5 & 2 not operational -static uint8_t NUMBER_OF_PACKS = 0; //1-8 -static uint8_t contactor_status = 0; -static uint8_t statemachine_polling = 0; -static bool charging_disabled = false; -static bool b0_idle = false; -static bool b1_ok_discharge = false; -static bool b2_ok_charge = false; -static bool b3_discharging = false; -static bool b4_charging = false; -static bool b5_operational = false; -static bool b6_active_error = false; - -void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus +void FoxessBattery:: + update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus datalayer.battery.status.remaining_capacity_Wh = static_cast( (static_cast(datalayer.battery.status.real_soc) / 10000) * datalayer.battery.info.total_capacity_Wh); @@ -146,7 +74,7 @@ void update_values_battery() { //This function maps all the values fetched via } } -void handle_incoming_can_frame_battery(CAN_frame rx_frame) { +void FoxessBattery::handle_incoming_can_frame(CAN_frame rx_frame) { switch (rx_frame.ID) { case 0x1872: //BMS_Limits datalayer.battery.info.max_design_voltage_dV = (uint16_t)(rx_frame.data.u8[1] << 8 | rx_frame.data.u8[0]); @@ -474,7 +402,8 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { break; } } -void transmit_can_battery(unsigned long currentMillis) { + +void FoxessBattery::transmit_can(unsigned long currentMillis) { // Send 500ms CAN Message if (currentMillis - previousMillis500 >= INTERVAL_500_MS) { previousMillis500 = currentMillis; @@ -643,7 +572,7 @@ void transmit_can_battery(unsigned long currentMillis) { } } -void setup_battery(void) { // Performs one time setup at startup +void FoxessBattery::setup(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "FoxESS HV2600/ECS4100 OEM battery", 63); datalayer.system.info.battery_protocol[63] = '\0'; datalayer.battery.info.number_of_cells = 0; //Startup with no cells, populates later when we know packsize diff --git a/Software/src/battery/FOXESS-BATTERY.h b/Software/src/battery/FOXESS-BATTERY.h index 6eebdcaf..b5102b8e 100644 --- a/Software/src/battery/FOXESS-BATTERY.h +++ b/Software/src/battery/FOXESS-BATTERY.h @@ -3,14 +3,97 @@ #include #include "../include.h" -#define BATTERY_SELECTED +#include "CanBattery.h" -#define MAX_PACK_VOLTAGE_DV 4672 //467.2V for HS20.8 (used during startup, refined later) -#define MIN_PACK_VOLTAGE_DV 800 //80.V for HS5.2 (used during startup, refined later) -#define MAX_CELL_DEVIATION_MV 250 -#define MAX_CELL_VOLTAGE_MV 3800 //LiFePO4 Prismaticc Cell -#define MIN_CELL_VOLTAGE_MV 2700 //LiFePO4 Prismatic Cell -void setup_battery(void); -void transmit_can_frame(CAN_frame* tx_frame, int interface); +#define BATTERY_SELECTED +#define SELECTED_BATTERY_CLASS FoxessBattery + +class FoxessBattery : public CanBattery { + 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: + static const int MAX_PACK_VOLTAGE_DV = 4672; //467.2V for HS20.8 (used during startup, refined later) + static const int MIN_PACK_VOLTAGE_DV = 800; //80.V for HS5.2 (used during startup, refined later) + static const int MAX_CELL_DEVIATION_MV = 250; + static const int MAX_CELL_VOLTAGE_MV = 3800; //LiFePO4 Prismaticc Cell + static const int MIN_CELL_VOLTAGE_MV = 2700; //LiFePO4 Prismatic Cell + + unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was send + + CAN_frame FOX_1871 = {.FD = false, //Inverter request data from battery. Content varies depending on state + .ext_ID = true, + .DLC = 8, + .ID = 0x1871, + .data = {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; + uint32_t total_watt_hours = 0; + uint16_t max_charge_power_dA = 0; + uint16_t max_discharge_power_dA = 0; + uint16_t cut_mv_max = 0; + uint16_t cut_mv_min = 0; + uint16_t cycle_count = 0; + uint16_t max_ac_voltage = 0; + uint16_t cellvoltages_mV[128] = {0}; + int16_t temperature_average = 0; + int16_t pack1_current_sensor = 0; + int16_t pack2_current_sensor = 0; + int16_t pack3_current_sensor = 0; + int16_t pack4_current_sensor = 0; + int16_t pack5_current_sensor = 0; + int16_t pack6_current_sensor = 0; + int16_t pack7_current_sensor = 0; + int16_t pack8_current_sensor = 0; + int16_t pack1_temperature_avg_high = 0; + int16_t pack2_temperature_avg_high = 0; + int16_t pack3_temperature_avg_high = 0; + int16_t pack4_temperature_avg_high = 0; + int16_t pack5_temperature_avg_high = 0; + int16_t pack6_temperature_avg_high = 0; + int16_t pack7_temperature_avg_high = 0; + int16_t pack8_temperature_avg_high = 0; + int16_t pack1_temperature_avg_low = 0; + int16_t pack2_temperature_avg_low = 0; + int16_t pack3_temperature_avg_low = 0; + int16_t pack4_temperature_avg_low = 0; + int16_t pack5_temperature_avg_low = 0; + int16_t pack6_temperature_avg_low = 0; + int16_t pack7_temperature_avg_low = 0; + int16_t pack8_temperature_avg_low = 0; + uint16_t pack1_voltage = 0; + uint16_t pack2_voltage = 0; + uint16_t pack3_voltage = 0; + uint16_t pack4_voltage = 0; + uint16_t pack5_voltage = 0; + uint16_t pack6_voltage = 0; + uint16_t pack7_voltage = 0; + uint16_t pack8_voltage = 0; + uint8_t pack1_SOC = 0; + uint8_t pack2_SOC = 0; + uint8_t pack3_SOC = 0; + uint8_t pack4_SOC = 0; + uint8_t pack5_SOC = 0; + uint8_t pack6_SOC = 0; + uint8_t pack7_SOC = 0; + uint8_t pack8_SOC = 0; + uint8_t pack_error = 0; + uint8_t firmware_pack_minor = 0; + uint8_t firmware_pack_major = 0; + uint8_t STATUS_OPERATIONAL_PACKS = + 0; //0x1875 b2 contains status for operational packs (responding) in binary so 01111111 is pack 8 not operational, 11101101 is pack 5 & 2 not operational + uint8_t NUMBER_OF_PACKS = 0; //1-8 + uint8_t contactor_status = 0; + uint8_t statemachine_polling = 0; + bool charging_disabled = false; + bool b0_idle = false; + bool b1_ok_discharge = false; + bool b2_ok_charge = false; + bool b3_discharging = false; + bool b4_charging = false; + bool b5_operational = false; + bool b6_active_error = false; +}; #endif