diff --git a/Software/src/battery/CMFA-EV-BATTERY.cpp b/Software/src/battery/CMFA-EV-BATTERY.cpp index 322fa140..e9eddf64 100644 --- a/Software/src/battery/CMFA-EV-BATTERY.cpp +++ b/Software/src/battery/CMFA-EV-BATTERY.cpp @@ -1,92 +1,15 @@ #include "../include.h" #ifdef CMFA_EV_BATTERY +#include "../communication/can/comm_can.h" #include "../datalayer/datalayer.h" #include "../datalayer/datalayer_extended.h" #include "../devboard/utils/events.h" #include "CMFA-EV-BATTERY.h" -/* Do not change code below unless you are sure what you are doing */ -CAN_frame CMFA_1EA = {.FD = false, .ext_ID = false, .DLC = 1, .ID = 0x1EA, .data = {0x00}}; -CAN_frame CMFA_125 = {.FD = false, - .ext_ID = false, - .DLC = 7, - .ID = 0x125, - .data = {0x7D, 0x7D, 0x7D, 0x07, 0x82, 0x6A, 0x8A}}; -CAN_frame CMFA_134 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x134, - .data = {0x90, 0x8A, 0x7E, 0x3E, 0xB2, 0x4C, 0x80, 0x00}}; -CAN_frame CMFA_135 = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x135, .data = {0xD5, 0x85, 0x38, 0x80, 0x01}}; -CAN_frame CMFA_3D3 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x3D3, - .data = {0x47, 0x30, 0x00, 0x02, 0x5D, 0x80, 0x5D, 0xE7}}; -CAN_frame CMFA_59B = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x59B, .data = {0x00, 0x02, 0x00}}; -CAN_frame CMFA_ACK = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x79B, - .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame CMFA_POLLING_FRAME = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x79B, - .data = {0x03, 0x22, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00}}; -static bool end_of_charge = false; -static bool interlock_flag = false; -static uint16_t soc_z = 0; -static uint16_t soc_u = 0; -static uint16_t max_regen_power = 0; -static uint16_t max_discharge_power = 0; -static int16_t average_temperature = 0; -static int16_t minimum_temperature = 0; -static int16_t maximum_temperature = 0; -static uint16_t maximum_charge_power = 0; -static uint16_t SOH_available_power = 0; -static uint16_t SOH_generated_power = 0; -static uint32_t average_voltage_of_cells = 270000; -static uint16_t highest_cell_voltage_mv = 3700; -static uint16_t lowest_cell_voltage_mv = 3700; -static uint16_t lead_acid_voltage = 12000; -static uint8_t highest_cell_voltage_number = 0; -static uint8_t lowest_cell_voltage_number = 0; -static uint64_t cumulative_energy_when_discharging = 0; -static uint64_t cumulative_energy_when_charging = 0; -static uint64_t cumulative_energy_in_regen = 0; -static uint16_t soh_average = 10000; -static uint16_t cellvoltages_mv[72]; -static uint32_t poll_pid = PID_POLL_SOH_AVERAGE; -static uint16_t pid_reply = 0; - -static uint8_t counter_10ms = 0; -static uint8_t content_125[16] = {0x07, 0x0C, 0x01, 0x06, 0x0B, 0x00, 0x05, 0x0A, - 0x0F, 0x04, 0x09, 0x0E, 0x03, 0x08, 0x0D, 0x02}; -static uint8_t content_135[16] = {0x85, 0xD5, 0x25, 0x75, 0xC5, 0x15, 0x65, 0xB5, - 0x05, 0x55, 0xA5, 0xF5, 0x45, 0x95, 0xE5, 0x35}; -static unsigned long previousMillis200ms = 0; -static unsigned long previousMillis100ms = 0; -static unsigned long previousMillis10ms = 0; - -#define MAXSOC 9000 //90.00 Raw SOC displays this value when battery is at 100% -#define MINSOC 500 //5.00 Raw SOC displays this value when battery is at 0% - -static uint8_t heartbeat = 0; //Alternates between 0x55 and 0xAA every 5th frame -static uint8_t heartbeat2 = 0; //Alternates between 0x55 and 0xAA every 5th frame -static uint32_t SOC_raw = 0; -static uint16_t SOH = 99; -static int16_t current = 0; -static uint16_t pack_voltage = 2700; -static int16_t highest_cell_temperature = 0; -static int16_t lowest_cell_temperature = 0; -static uint32_t discharge_power_w = 0; -static uint32_t charge_power_w = 0; - /* The raw SOC value sits at 90% when the battery is full, so we should report back 100% once this value is reached Same goes for low point, when 10% is reached we report 0% */ -uint16_t rescale_raw_SOC(uint32_t raw_SOC) { +uint16_t CmfaEvBattery::rescale_raw_SOC(uint32_t raw_SOC) { uint32_t calc_soc; calc_soc = (raw_SOC * 0.25); @@ -103,7 +26,8 @@ uint16_t rescale_raw_SOC(uint32_t raw_SOC) { return (uint16_t)calc_soc; } -void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus +void CmfaEvBattery:: + update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus datalayer.battery.status.soh_pptt = (SOH * 100); datalayer.battery.status.real_soc = rescale_raw_SOC(SOC_raw); @@ -157,7 +81,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.CMFAEV.soh_average = soh_average; } -void handle_incoming_can_frame_battery(CAN_frame rx_frame) { +void CmfaEvBattery::handle_incoming_can_frame(CAN_frame rx_frame) { switch (rx_frame.ID) { //These frames are transmitted by the battery case 0x127: //10ms , Same structure as old Zoe 0x155 message! datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; @@ -513,7 +437,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) { } } -void transmit_can_battery(unsigned long currentMillis) { +void CmfaEvBattery::transmit_can(unsigned long currentMillis) { // Send 10ms CAN Message if (currentMillis - previousMillis10ms >= INTERVAL_10_MS) { previousMillis10ms = currentMillis; @@ -1016,7 +940,7 @@ void transmit_can_battery(unsigned long currentMillis) { } } -void setup_battery(void) { // Performs one time setup at startup +void CmfaEvBattery::setup(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "CMFA platform, 27 kWh battery", 63); datalayer.system.info.battery_protocol[63] = '\0'; datalayer.system.status.battery_allows_contactor_closing = true; diff --git a/Software/src/battery/CMFA-EV-BATTERY.h b/Software/src/battery/CMFA-EV-BATTERY.h index 0b2b87eb..d3c8a9a1 100644 --- a/Software/src/battery/CMFA-EV-BATTERY.h +++ b/Software/src/battery/CMFA-EV-BATTERY.h @@ -2,157 +2,211 @@ #define CMFA_EV_BATTERY_H #include "../include.h" +#include "CanBattery.h" + #define BATTERY_SELECTED -#define MAX_PACK_VOLTAGE_DV 3040 //5000 = 500.0V -#define MIN_PACK_VOLTAGE_DV 2185 -#define MAX_CELL_DEVIATION_MV 100 -#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value -#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value +#define SELECTED_BATTERY_CLASS CmfaEvBattery -// OBD2 PID polls. Some of these have been reverse engineered, but there are many unknown values still -#define PID_POLL_SOCZ 0x9001 //122 in log -#define PID_POLL_USOC 0x9002 //5531 (Possible SOC candidate) -#define PID_POLL_SOH_AVERAGE 0x9003 -#define PID_POLL_AVERAGE_VOLTAGE_OF_CELLS 0x9006 -#define PID_POLL_HIGHEST_CELL_VOLTAGE 0x9007 -#define PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE 0x9008 -#define PID_POLL_LOWEST_CELL_VOLTAGE 0x9009 -#define PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE 0x900A -#define PID_POLL_CURRENT_OFFSET 0x900C -#define PID_POLL_INSTANT_CURRENT 0x900D -#define PID_POLL_MAX_REGEN 0x900E -#define PID_POLL_MAX_DISCHARGE_POWER 0x900F -#define PID_POLL_12V_BATTERY 0x9011 -#define PID_POLL_AVERAGE_TEMPERATURE 0x9012 //749 in log -#define PID_POLL_MIN_TEMPERATURE 0x9013 //736 in log -#define PID_POLL_MAX_TEMPERATURE 0x9014 //752 in log -#define PID_POLL_MAX_CHARGE_POWER 0x9018 -#define PID_POLL_END_OF_CHARGE_FLAG 0x9019 -#define PID_POLL_INTERLOCK_FLAG 0x901A -#define PID_POLL_BATTERY_IDENTIFICATION 0x901B // Multi frame message -#define PID_POLL_CELL_1 0x9021 -#define PID_POLL_CELL_2 0x9022 -#define PID_POLL_CELL_3 0x9023 -#define PID_POLL_CELL_4 0x9024 -#define PID_POLL_CELL_5 0x9025 -#define PID_POLL_CELL_6 0x9026 -#define PID_POLL_CELL_7 0x9027 -#define PID_POLL_CELL_8 0x9028 -#define PID_POLL_CELL_9 0x9029 -#define PID_POLL_CELL_10 0x902A -#define PID_POLL_CELL_11 0x902B -#define PID_POLL_CELL_12 0x902C -#define PID_POLL_CELL_13 0x902D -#define PID_POLL_CELL_14 0x902E -#define PID_POLL_CELL_15 0x902F -#define PID_POLL_CELL_16 0x9030 -#define PID_POLL_CELL_17 0x9031 -#define PID_POLL_CELL_18 0x9032 -#define PID_POLL_CELL_19 0x9033 -#define PID_POLL_CELL_20 0x9034 -#define PID_POLL_CELL_21 0x9035 -#define PID_POLL_CELL_22 0x9036 -#define PID_POLL_CELL_23 0x9037 -#define PID_POLL_CELL_24 0x9038 -#define PID_POLL_CELL_25 0x9039 -#define PID_POLL_CELL_26 0x903A -#define PID_POLL_CELL_27 0x903B -#define PID_POLL_CELL_28 0x903C -#define PID_POLL_CELL_29 0x903D -#define PID_POLL_CELL_30 0x903E -#define PID_POLL_CELL_31 0x903F -#define PID_POLL_DIDS_SUPPORTED_IN_RANGE_9041_9060 0x9040 -#define PID_POLL_CELL_32 0x9041 -#define PID_POLL_CELL_33 0x9042 -#define PID_POLL_CELL_34 0x9043 -#define PID_POLL_CELL_35 0x9044 -#define PID_POLL_CELL_36 0x9045 -#define PID_POLL_CELL_37 0x9046 -#define PID_POLL_CELL_38 0x9047 -#define PID_POLL_CELL_39 0x9048 -#define PID_POLL_CELL_40 0x9049 -#define PID_POLL_CELL_41 0x904A -#define PID_POLL_CELL_42 0x904B -#define PID_POLL_CELL_43 0x904C -#define PID_POLL_CELL_44 0x904D -#define PID_POLL_CELL_45 0x904E -#define PID_POLL_CELL_46 0x904F -#define PID_POLL_CELL_47 0x9050 -#define PID_POLL_CELL_48 0x9051 -#define PID_POLL_CELL_49 0x9052 -#define PID_POLL_CELL_50 0x9053 -#define PID_POLL_CELL_51 0x9054 -#define PID_POLL_CELL_52 0x9055 -#define PID_POLL_CELL_53 0x9056 -#define PID_POLL_CELL_54 0x9057 -#define PID_POLL_CELL_55 0x9058 -#define PID_POLL_CELL_56 0x9059 -#define PID_POLL_CELL_57 0x905A -#define PID_POLL_CELL_58 0x905B -#define PID_POLL_CELL_59 0x905C -#define PID_POLL_CELL_60 0x905D -#define PID_POLL_CELL_61 0x905E -#define PID_POLL_CELL_62 0x905F -#define PID_POLL_DIDS_SUPPORTED_IN_RANGE_9061_9080 0x9060 -#define PID_POLL_CELL_63 0x9061 -#define PID_POLL_CELL_64 0x9062 -#define PID_POLL_CELL_65 0x9063 -#define PID_POLL_CELL_66 0x9064 -#define PID_POLL_CELL_67 0x9065 -#define PID_POLL_CELL_68 0x9066 -#define PID_POLL_CELL_69 0x9067 -#define PID_POLL_CELL_70 0x9068 -#define PID_POLL_CELL_71 0x9069 -#define PID_POLL_CELL_72 0x906A -/* -#define PID_POLL_UNKNOWNX 0x912F // Multi frame message, empty -#define PID_POLL_UNKNOWNX 0x9129 -#define PID_POLL_UNKNOWNX 0x9131 -#define PID_POLL_UNKNOWNX 0x9132 -#define PID_POLL_UNKNOWNX 0x9133 -#define PID_POLL_UNKNOWNX 0x9134 -#define PID_POLL_UNKNOWNX 0x9135 -#define PID_POLL_UNKNOWNX 0x9136 -#define PID_POLL_UNKNOWNX 0x9137 -#define PID_POLL_UNKNOWNX 0x9138 -#define PID_POLL_UNKNOWNX 0x9139 -#define PID_POLL_UNKNOWNX 0x913A -#define PID_POLL_UNKNOWNX 0x913B -#define PID_POLL_UNKNOWNX 0x913C -#define PID_POLL_UNKNOWN5 0x912F -#define PID_POLL_UNKNOWNX 0x91B7 -*/ -#define PID_POLL_SOH_AVAILABLE_POWER_CALCULATION 0x91BC // 0-100% -#define PID_POLL_SOH_GENERATED_POWER_CALCULATION 0x91BD // 0-100% -/* -#define PID_POLL_UNKNOWNX 0x91C1 -#define PID_POLL_UNKNOWNX 0x91CD -#define PID_POLL_UNKNOWNX 0x91CF -#define PID_POLL_UNKNOWNX 0x91F6 -#define PID_POLL_UNKNOWNX 0x91F7 -#define PID_POLL_UNKNOWNX 0x920F -#define PID_POLL_UNKNOWNx 0x9242 -*/ -#define PID_POLL_CUMULATIVE_ENERGY_WHEN_CHARGING 0x9243 -#define PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING 0x9245 -#define PID_POLL_CUMULATIVE_ENERGY_IN_REGEN 0x9247 -/* -#define PID_POLL_UNKNOWNx 0x9256 -#define PID_POLL_UNKNOWNx 0x9261 -#define PID_POLL_UNKNOWN7 0x9284 -#define PID_POLL_UNKNOWNx 0xF012 -#define PID_POLL_UNKNOWNx 0xF1A0 -#define PID_POLL_UNKNOWNx 0xF182 -#define PID_POLL_UNKNOWNx 0xF187 -#define PID_POLL_UNKNOWNx 0xF188 -#define PID_POLL_UNKNOWNx 0xF18A -#define PID_POLL_UNKNOWNx 0xF18C -#define PID_POLL_UNKNOWNx 0xF191 -#define PID_POLL_UNKNOWNx 0xF194 -#define PID_POLL_UNKNOWNx 0xF195 -*/ +class CmfaEvBattery : 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); -void setup_battery(void); -void transmit_can_frame(CAN_frame* tx_frame, int interface); + private: + uint16_t rescale_raw_SOC(uint32_t raw_SOC); + + static const int MAX_PACK_VOLTAGE_DV = 3040; // 5000 = 500.0V + static const int MIN_PACK_VOLTAGE_DV = 2185; + static const int MAX_CELL_DEVIATION_MV = 100; + static const int MAX_CELL_VOLTAGE_MV = 4250; // Emergency stop if above + static const int MIN_CELL_VOLTAGE_MV = 2700; // Emergency stop if below + + // OBD2 PID polls + static const int PID_POLL_SOCZ = 0x9001; + static const int PID_POLL_USOC = 0x9002; + static const int PID_POLL_SOH_AVERAGE = 0x9003; + static const int PID_POLL_AVERAGE_VOLTAGE_OF_CELLS = 0x9006; + static const int PID_POLL_HIGHEST_CELL_VOLTAGE = 0x9007; + static const int PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE = 0x9008; + static const int PID_POLL_LOWEST_CELL_VOLTAGE = 0x9009; + static const int PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE = 0x900A; + static const int PID_POLL_CURRENT_OFFSET = 0x900C; + static const int PID_POLL_INSTANT_CURRENT = 0x900D; + static const int PID_POLL_MAX_REGEN = 0x900E; + static const int PID_POLL_MAX_DISCHARGE_POWER = 0x900F; + static const int PID_POLL_12V_BATTERY = 0x9011; + static const int PID_POLL_AVERAGE_TEMPERATURE = 0x9012; + static const int PID_POLL_MIN_TEMPERATURE = 0x9013; + static const int PID_POLL_MAX_TEMPERATURE = 0x9014; + static const int PID_POLL_MAX_CHARGE_POWER = 0x9018; + static const int PID_POLL_END_OF_CHARGE_FLAG = 0x9019; + static const int PID_POLL_INTERLOCK_FLAG = 0x901A; + static const int PID_POLL_BATTERY_IDENTIFICATION = 0x901B; + + static const int PID_POLL_CELL_1 = 0x9021; + static const int PID_POLL_CELL_2 = 0x9022; + static const int PID_POLL_CELL_3 = 0x9023; + static const int PID_POLL_CELL_4 = 0x9024; + static const int PID_POLL_CELL_5 = 0x9025; + static const int PID_POLL_CELL_6 = 0x9026; + static const int PID_POLL_CELL_7 = 0x9027; + static const int PID_POLL_CELL_8 = 0x9028; + static const int PID_POLL_CELL_9 = 0x9029; + static const int PID_POLL_CELL_10 = 0x902A; + static const int PID_POLL_CELL_11 = 0x902B; + static const int PID_POLL_CELL_12 = 0x902C; + static const int PID_POLL_CELL_13 = 0x902D; + static const int PID_POLL_CELL_14 = 0x902E; + static const int PID_POLL_CELL_15 = 0x902F; + static const int PID_POLL_CELL_16 = 0x9030; + static const int PID_POLL_CELL_17 = 0x9031; + static const int PID_POLL_CELL_18 = 0x9032; + static const int PID_POLL_CELL_19 = 0x9033; + static const int PID_POLL_CELL_20 = 0x9034; + static const int PID_POLL_CELL_21 = 0x9035; + static const int PID_POLL_CELL_22 = 0x9036; + static const int PID_POLL_CELL_23 = 0x9037; + static const int PID_POLL_CELL_24 = 0x9038; + static const int PID_POLL_CELL_25 = 0x9039; + static const int PID_POLL_CELL_26 = 0x903A; + static const int PID_POLL_CELL_27 = 0x903B; + static const int PID_POLL_CELL_28 = 0x903C; + static const int PID_POLL_CELL_29 = 0x903D; + static const int PID_POLL_CELL_30 = 0x903E; + static const int PID_POLL_CELL_31 = 0x903F; + + static const int PID_POLL_DIDS_SUPPORTED_IN_RANGE_9041_9060 = 0x9040; + + static const int PID_POLL_CELL_32 = 0x9041; + static const int PID_POLL_CELL_33 = 0x9042; + static const int PID_POLL_CELL_34 = 0x9043; + static const int PID_POLL_CELL_35 = 0x9044; + static const int PID_POLL_CELL_36 = 0x9045; + static const int PID_POLL_CELL_37 = 0x9046; + static const int PID_POLL_CELL_38 = 0x9047; + static const int PID_POLL_CELL_39 = 0x9048; + static const int PID_POLL_CELL_40 = 0x9049; + static const int PID_POLL_CELL_41 = 0x904A; + static const int PID_POLL_CELL_42 = 0x904B; + static const int PID_POLL_CELL_43 = 0x904C; + static const int PID_POLL_CELL_44 = 0x904D; + static const int PID_POLL_CELL_45 = 0x904E; + static const int PID_POLL_CELL_46 = 0x904F; + static const int PID_POLL_CELL_47 = 0x9050; + static const int PID_POLL_CELL_48 = 0x9051; + static const int PID_POLL_CELL_49 = 0x9052; + static const int PID_POLL_CELL_50 = 0x9053; + static const int PID_POLL_CELL_51 = 0x9054; + static const int PID_POLL_CELL_52 = 0x9055; + static const int PID_POLL_CELL_53 = 0x9056; + static const int PID_POLL_CELL_54 = 0x9057; + static const int PID_POLL_CELL_55 = 0x9058; + static const int PID_POLL_CELL_56 = 0x9059; + static const int PID_POLL_CELL_57 = 0x905A; + static const int PID_POLL_CELL_58 = 0x905B; + static const int PID_POLL_CELL_59 = 0x905C; + static const int PID_POLL_CELL_60 = 0x905D; + static const int PID_POLL_CELL_61 = 0x905E; + static const int PID_POLL_CELL_62 = 0x905F; + + static const int PID_POLL_DIDS_SUPPORTED_IN_RANGE_9061_9080 = 0x9060; + + static const int PID_POLL_CELL_63 = 0x9061; + static const int PID_POLL_CELL_64 = 0x9062; + static const int PID_POLL_CELL_65 = 0x9063; + static const int PID_POLL_CELL_66 = 0x9064; + static const int PID_POLL_CELL_67 = 0x9065; + static const int PID_POLL_CELL_68 = 0x9066; + static const int PID_POLL_CELL_69 = 0x9067; + static const int PID_POLL_CELL_70 = 0x9068; + static const int PID_POLL_CELL_71 = 0x9069; + static const int PID_POLL_CELL_72 = 0x906A; + + static const int PID_POLL_SOH_AVAILABLE_POWER_CALCULATION = 0x91BC; + static const int PID_POLL_SOH_GENERATED_POWER_CALCULATION = 0x91BD; + + static const int PID_POLL_CUMULATIVE_ENERGY_WHEN_CHARGING = 0x9243; + static const int PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING = 0x9245; + static const int PID_POLL_CUMULATIVE_ENERGY_IN_REGEN = 0x9247; + + CAN_frame CMFA_1EA = {.FD = false, .ext_ID = false, .DLC = 1, .ID = 0x1EA, .data = {0x00}}; + CAN_frame CMFA_125 = {.FD = false, + .ext_ID = false, + .DLC = 7, + .ID = 0x125, + .data = {0x7D, 0x7D, 0x7D, 0x07, 0x82, 0x6A, 0x8A}}; + CAN_frame CMFA_134 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x134, + .data = {0x90, 0x8A, 0x7E, 0x3E, 0xB2, 0x4C, 0x80, 0x00}}; + CAN_frame CMFA_135 = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x135, .data = {0xD5, 0x85, 0x38, 0x80, 0x01}}; + CAN_frame CMFA_3D3 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x3D3, + .data = {0x47, 0x30, 0x00, 0x02, 0x5D, 0x80, 0x5D, 0xE7}}; + CAN_frame CMFA_59B = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x59B, .data = {0x00, 0x02, 0x00}}; + CAN_frame CMFA_ACK = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x79B, + .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CAN_frame CMFA_POLLING_FRAME = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x79B, + .data = {0x03, 0x22, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00}}; + bool end_of_charge = false; + bool interlock_flag = false; + uint16_t soc_z = 0; + uint16_t soc_u = 0; + uint16_t max_regen_power = 0; + uint16_t max_discharge_power = 0; + int16_t average_temperature = 0; + int16_t minimum_temperature = 0; + int16_t maximum_temperature = 0; + uint16_t maximum_charge_power = 0; + uint16_t SOH_available_power = 0; + uint16_t SOH_generated_power = 0; + uint32_t average_voltage_of_cells = 270000; + uint16_t highest_cell_voltage_mv = 3700; + uint16_t lowest_cell_voltage_mv = 3700; + uint16_t lead_acid_voltage = 12000; + uint8_t highest_cell_voltage_number = 0; + uint8_t lowest_cell_voltage_number = 0; + uint64_t cumulative_energy_when_discharging = 0; + uint64_t cumulative_energy_when_charging = 0; + uint64_t cumulative_energy_in_regen = 0; + uint16_t soh_average = 10000; + uint16_t cellvoltages_mv[72]; + uint32_t poll_pid = PID_POLL_SOH_AVERAGE; + uint16_t pid_reply = 0; + + uint8_t counter_10ms = 0; + uint8_t content_125[16] = {0x07, 0x0C, 0x01, 0x06, 0x0B, 0x00, 0x05, 0x0A, + 0x0F, 0x04, 0x09, 0x0E, 0x03, 0x08, 0x0D, 0x02}; + uint8_t content_135[16] = {0x85, 0xD5, 0x25, 0x75, 0xC5, 0x15, 0x65, 0xB5, + 0x05, 0x55, 0xA5, 0xF5, 0x45, 0x95, 0xE5, 0x35}; + unsigned long previousMillis200ms = 0; + unsigned long previousMillis100ms = 0; + unsigned long previousMillis10ms = 0; + + static const int MAXSOC = 9000; //90.00 Raw SOC displays this value when battery is at 100% + static const int MINSOC = 500; //5.00 Raw SOC displays this value when battery is at 0% + + uint8_t heartbeat = 0; //Alternates between 0x55 and 0xAA every 5th frame + uint8_t heartbeat2 = 0; //Alternates between 0x55 and 0xAA every 5th frame + uint32_t SOC_raw = 0; + uint16_t SOH = 99; + int16_t current = 0; + uint16_t pack_voltage = 2700; + int16_t highest_cell_temperature = 0; + int16_t lowest_cell_temperature = 0; + uint32_t discharge_power_w = 0; + uint32_t charge_power_w = 0; +}; #endif