From eae05aea517114efb98185d3c06beaf66ea84e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 26 Nov 2024 22:42:17 +0200 Subject: [PATCH 01/12] Add skeleton for Bolt-Ampera battery --- Software/USER_SETTINGS.h | 1 + Software/src/battery/BATTERIES.h | 4 + Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 81 ++++++++++++++++++++ Software/src/battery/BOLT-AMPERA-BATTERY.h | 18 +++++ 4 files changed, 104 insertions(+) create mode 100644 Software/src/battery/BOLT-AMPERA-BATTERY.cpp create mode 100644 Software/src/battery/BOLT-AMPERA-BATTERY.h diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index e9687df5..3637eea0 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -11,6 +11,7 @@ /* Select battery used */ //#define BMW_I3_BATTERY //#define BMW_IX_BATTERY +//#define BOLT_AMPERA_BATTERY //#define BYD_ATTO_3_BATTERY //#define CELLPOWER_BMS //#define CHADEMO_BATTERY //NOTE: inherently enables CONTACTOR_CONTROL below diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index e17d1c06..daf5386f 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -10,6 +10,10 @@ #include "BMW-IX-BATTERY.h" #endif +#ifdef BOLT_AMPERA_BATTERY +#include "BOLT-AMPERA-BATTERY.h" +#endif + #ifdef BYD_ATTO_3_BATTERY #include "BYD-ATTO-3-BATTERY.h" #endif diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp new file mode 100644 index 00000000..a6ecdd79 --- /dev/null +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -0,0 +1,81 @@ +#include "../include.h" +#ifdef BOLT_AMPERA_BATTERY +#include "../datalayer/datalayer.h" +#include "../datalayer/datalayer_extended.h" +#include "../devboard/utils/events.h" +#include "BOLT-AMPERA-BATTERY.h" + +/* Do not change code below unless you are sure what you are doing */ +static unsigned long previousMillis20 = 0; // will store last time a 20ms CAN Message was send + +CAN_frame BOLT_778 = {.FD = false, + .ext_ID = false, + .DLC = 7, + .ID = 0x778, + .data = {0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer + + datalayer.battery.status.real_soc; + + datalayer.battery.status.voltage_dV; + + datalayer.battery.status.current_dA; + + datalayer.battery.info.total_capacity_Wh; + + datalayer.battery.status.remaining_capacity_Wh; + + datalayer.battery.status.soh_pptt; + + datalayer.battery.status.max_discharge_power_W; + + datalayer.battery.status.max_charge_power_W; + + datalayer.battery.status.temperature_min_dC; + + datalayer.battery.status.temperature_max_dC; +} + +void receive_can_battery(CAN_frame rx_frame) { + switch (rx_frame.ID) { + case 0x2C7: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x3E3: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + default: + break; + } +} + +void send_can_battery() { + unsigned long currentMillis = millis(); + + //Send 20ms message + if (currentMillis - previousMillis20 >= INTERVAL_20_MS) { + // Check if sending of CAN messages has been delayed too much. + if ((currentMillis - previousMillis20 >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20)); + } else { + clear_event(EVENT_CAN_OVERRUN); + } + previousMillis20 = currentMillis; + transmit_can(&BOLT_778, can_config.battery); + } +} + +void setup_battery(void) { // Performs one time setup at startup + strncpy(datalayer.system.info.battery_protocol, "Chevrolet Bolt EV/Opel Ampera-e", 63); + datalayer.system.info.battery_protocol[63] = '\0'; + + datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; + datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; + datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; + datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV; + datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV; + datalayer.system.status.battery_allows_contactor_closing = true; +} + +#endif diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.h b/Software/src/battery/BOLT-AMPERA-BATTERY.h new file mode 100644 index 00000000..42d743d5 --- /dev/null +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.h @@ -0,0 +1,18 @@ +#ifndef BOLT_AMPERA_BATTERY_H +#define BOLT_AMPERA_BATTERY_H +#include +#include "../include.h" + +#define BATTERY_SELECTED + +#define MAX_PACK_VOLTAGE_DV 4150 //5000 = 500.0V +#define MIN_PACK_VOLTAGE_DV 2500 +#define MAX_CELL_DEVIATION_MV 500 +#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 MAX_CHARGE_POWER_W 5000 // Battery can be charged with this amount of power + +void setup_battery(void); +void transmit_can(CAN_frame* tx_frame, int interface); + +#endif From 6f9da5b33062cc4e3b55b6e47463e9eddca8e03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 2 Dec 2024 23:37:50 +0200 Subject: [PATCH 02/12] Add OBD2 PID polling for BoltAmpera --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 537 ++++++++++++++++++- Software/src/battery/BOLT-AMPERA-BATTERY.h | 117 +++- 2 files changed, 643 insertions(+), 11 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index a6ecdd79..a0cb0e95 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -6,21 +6,168 @@ #include "BOLT-AMPERA-BATTERY.h" /* Do not change code below unless you are sure what you are doing */ -static unsigned long previousMillis20 = 0; // will store last time a 20ms CAN Message was send +static unsigned long previousMillis20ms = 0; // will store last time a 20ms CAN Message was send +static unsigned long previousMillis200ms = 0; // will store last time a 200ms CAN Message was send -CAN_frame BOLT_778 = {.FD = false, +CAN_frame BOLT_778 = {.FD = false, // Unsure of what this message is, added only as example .ext_ID = false, .DLC = 7, .ID = 0x778, .data = {0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame BOLT_POLL_7E4 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E4, + .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages +static uint16_t battery_capacity_my17_18 = 0; +static uint16_t battery_capacity_my19plus = 0; +static uint16_t battery_SOC_display = 0; +static uint16_t battery_SOC_raw_highprec = 0; +static uint16_t battery_max_temperature = 0; +static uint16_t battery_min_temperature = 0; +static uint16_t battery_min_cell_voltage = 0; +static uint16_t battery_max_cell_voltage = 0; +static uint16_t battery_internal_resistance = 0; +static uint16_t battery_min_voltage = 0; +static uint16_t battery_max_voltage = 0; +static uint16_t battery_voltage = 3700; +static uint16_t battery_vehicle_isolation = 0; +static uint16_t battery_isolation_kohm = 0; +static uint16_t battery_HV_locked = 0; +static uint16_t battery_crash_event = 0; +static uint16_t battery_HVIL = 0; +static uint16_t battery_HVIL_status = 0; +static int16_t battery_current = 0; + +static uint8_t poll_index = 0; +static uint16_t currentpoll = POLL_CAPACITY_EST_GEN1; +static uint16_t reply_poll = 0; + +const uint16_t poll_commands[115] = {POLL_CAPACITY_EST_GEN1, + POLL_CAPACITY_EST_GEN2, + POLL_SOC_DISPLAY, + POLL_SOC_RAW_HIGHPREC, + POLL_MAX_TEMPERATURE, + POLL_MIN_TEMPERATURE, + POLL_MIN_CELL_V, + POLL_MAX_CELL_V, + POLL_INTERNAL_RES, + POLL_MIN_BATT_V, + POLL_MAX_BATT_V, + POLL_VOLTAGE, + POLL_VEHICLE_ISOLATION, + POLL_ISOLATION_TEST_KOHM, + POLL_HV_LOCKED_OUT, + POLL_CRASH_EVENT, + POLL_HVIL, + POLL_HVIL_STATUS, + POLL_CURRENT, + POLL_CELL_01, + POLL_CELL_02, + POLL_CELL_03, + POLL_CELL_04, + POLL_CELL_05, + POLL_CELL_06, + POLL_CELL_07, + POLL_CELL_08, + POLL_CELL_09, + POLL_CELL_10, + POLL_CELL_11, + POLL_CELL_12, + POLL_CELL_13, + POLL_CELL_14, + POLL_CELL_15, + POLL_CELL_16, + POLL_CELL_17, + POLL_CELL_18, + POLL_CELL_19, + POLL_CELL_20, + POLL_CELL_21, + POLL_CELL_22, + POLL_CELL_23, + POLL_CELL_24, + POLL_CELL_25, + POLL_CELL_26, + POLL_CELL_27, + POLL_CELL_28, + POLL_CELL_29, + POLL_CELL_30, + POLL_CELL_31, + POLL_CELL_32, + POLL_CELL_33, + POLL_CELL_34, + POLL_CELL_35, + POLL_CELL_36, + POLL_CELL_37, + POLL_CELL_38, + POLL_CELL_39, + POLL_CELL_40, + POLL_CELL_41, + POLL_CELL_42, + POLL_CELL_43, + POLL_CELL_44, + POLL_CELL_45, + POLL_CELL_46, + POLL_CELL_47, + POLL_CELL_48, + POLL_CELL_49, + POLL_CELL_50, + POLL_CELL_51, + POLL_CELL_52, + POLL_CELL_53, + POLL_CELL_54, + POLL_CELL_55, + POLL_CELL_56, + POLL_CELL_57, + POLL_CELL_58, + POLL_CELL_59, + POLL_CELL_60, + POLL_CELL_61, + POLL_CELL_62, + POLL_CELL_63, + POLL_CELL_64, + POLL_CELL_65, + POLL_CELL_66, + POLL_CELL_67, + POLL_CELL_68, + POLL_CELL_69, + POLL_CELL_70, + POLL_CELL_71, + POLL_CELL_72, + POLL_CELL_73, + POLL_CELL_74, + POLL_CELL_75, + POLL_CELL_76, + POLL_CELL_77, + POLL_CELL_78, + POLL_CELL_79, + POLL_CELL_80, + POLL_CELL_81, + POLL_CELL_82, + POLL_CELL_83, + POLL_CELL_84, + POLL_CELL_85, + POLL_CELL_86, + POLL_CELL_87, + POLL_CELL_88, + POLL_CELL_89, + POLL_CELL_90, + POLL_CELL_91, + POLL_CELL_92, + POLL_CELL_93, + POLL_CELL_94, + POLL_CELL_95, + POLL_CELL_96}; void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer - datalayer.battery.status.real_soc; + datalayer.battery.status.real_soc = (battery_SOC_display * 100 / 255); - datalayer.battery.status.voltage_dV; + datalayer.battery.status.voltage_dV = battery_voltage * 0.52; - datalayer.battery.status.current_dA; + datalayer.battery.status.current_dA = battery_current / -6.675; datalayer.battery.info.total_capacity_Wh; @@ -35,6 +182,9 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_min_dC; datalayer.battery.status.temperature_max_dC; + + //Map all cell voltages to the global array + memcpy(datalayer.battery.status.cell_voltages_mV, battery_cell_voltages, 96 * sizeof(uint16_t)); } void receive_can_battery(CAN_frame rx_frame) { @@ -45,6 +195,359 @@ void receive_can_battery(CAN_frame rx_frame) { case 0x3E3: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; + case 0x7EC: //TODO: Confirm if this is the reply from BMS when polling + //Frame 2 & 3 contains reply + reply_poll = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + + switch (reply_poll) { + case POLL_CAPACITY_EST_GEN1: + battery_capacity_my17_18 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CAPACITY_EST_GEN2: + battery_capacity_my19plus = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_SOC_DISPLAY: + battery_SOC_display = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_SOC_RAW_HIGHPREC: + battery_SOC_raw_highprec = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MAX_TEMPERATURE: + battery_max_temperature = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MIN_TEMPERATURE: + battery_min_temperature = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MIN_CELL_V: + battery_min_cell_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MAX_CELL_V: + battery_max_cell_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_INTERNAL_RES: + battery_internal_resistance = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MIN_BATT_V: + battery_min_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_MAX_BATT_V: + battery_max_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_VOLTAGE: + battery_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_VEHICLE_ISOLATION: + battery_vehicle_isolation = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_ISOLATION_TEST_KOHM: + battery_isolation_kohm = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_HV_LOCKED_OUT: + battery_HV_locked = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CRASH_EVENT: + battery_crash_event = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_HVIL: + battery_HVIL = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_HVIL_STATUS: + battery_HVIL_status = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CURRENT: + battery_current = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_01: + battery_cell_voltages[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_02: + battery_cell_voltages[1] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_03: + battery_cell_voltages[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_04: + battery_cell_voltages[3] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_05: + battery_cell_voltages[4] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_06: + battery_cell_voltages[5] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_07: + battery_cell_voltages[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_08: + battery_cell_voltages[7] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_09: + battery_cell_voltages[8] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_10: + battery_cell_voltages[9] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_11: + battery_cell_voltages[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_12: + battery_cell_voltages[11] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_13: + battery_cell_voltages[12] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_14: + battery_cell_voltages[13] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_15: + battery_cell_voltages[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_16: + battery_cell_voltages[15] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_17: + battery_cell_voltages[16] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_18: + battery_cell_voltages[17] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_19: + battery_cell_voltages[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_20: + battery_cell_voltages[19] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_21: + battery_cell_voltages[20] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_22: + battery_cell_voltages[21] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_23: + battery_cell_voltages[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_24: + battery_cell_voltages[23] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_25: + battery_cell_voltages[24] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_26: + battery_cell_voltages[25] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_27: + battery_cell_voltages[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_28: + battery_cell_voltages[27] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_29: + battery_cell_voltages[28] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_30: + battery_cell_voltages[29] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_31: + battery_cell_voltages[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_32: + battery_cell_voltages[31] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_33: + battery_cell_voltages[32] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_34: + battery_cell_voltages[33] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_35: + battery_cell_voltages[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_36: + battery_cell_voltages[35] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_37: + battery_cell_voltages[36] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_38: + battery_cell_voltages[37] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_39: + battery_cell_voltages[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_40: + battery_cell_voltages[39] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_41: + battery_cell_voltages[40] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_42: + battery_cell_voltages[41] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_43: + battery_cell_voltages[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_44: + battery_cell_voltages[43] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_45: + battery_cell_voltages[44] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_46: + battery_cell_voltages[45] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_47: + battery_cell_voltages[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_48: + battery_cell_voltages[47] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_49: + battery_cell_voltages[48] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_50: + battery_cell_voltages[49] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_51: + battery_cell_voltages[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_52: + battery_cell_voltages[51] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_53: + battery_cell_voltages[52] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_54: + battery_cell_voltages[53] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_55: + battery_cell_voltages[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_56: + battery_cell_voltages[55] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_57: + battery_cell_voltages[56] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_58: + battery_cell_voltages[57] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_59: + battery_cell_voltages[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_60: + battery_cell_voltages[59] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_61: + battery_cell_voltages[60] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_62: + battery_cell_voltages[61] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_63: + battery_cell_voltages[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_64: + battery_cell_voltages[63] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_65: + battery_cell_voltages[64] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_66: + battery_cell_voltages[65] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_67: + battery_cell_voltages[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_68: + battery_cell_voltages[67] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_69: + battery_cell_voltages[68] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_70: + battery_cell_voltages[69] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_71: + battery_cell_voltages[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_72: + battery_cell_voltages[71] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_73: + battery_cell_voltages[72] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_74: + battery_cell_voltages[73] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_75: + battery_cell_voltages[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_76: + battery_cell_voltages[75] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_77: + battery_cell_voltages[76] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_78: + battery_cell_voltages[77] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_79: + battery_cell_voltages[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_80: + battery_cell_voltages[79] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_81: + battery_cell_voltages[80] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_82: + battery_cell_voltages[81] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_83: + battery_cell_voltages[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_84: + battery_cell_voltages[83] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_85: + battery_cell_voltages[84] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_86: + battery_cell_voltages[85] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_87: + battery_cell_voltages[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_88: + battery_cell_voltages[87] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_89: + battery_cell_voltages[88] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_90: + battery_cell_voltages[89] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_91: + battery_cell_voltages[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_92: + battery_cell_voltages[91] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_93: + battery_cell_voltages[92] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_94: + battery_cell_voltages[93] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_95: + battery_cell_voltages[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_CELL_96: + battery_cell_voltages[95] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + default: + break; + } default: break; } @@ -54,22 +557,36 @@ void send_can_battery() { unsigned long currentMillis = millis(); //Send 20ms message - if (currentMillis - previousMillis20 >= INTERVAL_20_MS) { + if (currentMillis - previousMillis20ms >= INTERVAL_20_MS) { // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis20 >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20)); + if ((currentMillis - previousMillis20ms >= INTERVAL_20_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis20ms)); } else { clear_event(EVENT_CAN_OVERRUN); } - previousMillis20 = currentMillis; + previousMillis20ms = currentMillis; transmit_can(&BOLT_778, can_config.battery); } + + //Send 200ms message + if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) { + previousMillis200ms = currentMillis; + + // Update current poll from the array + currentpoll = poll_commands[poll_index]; + poll_index = (poll_index + 1) % 115; + + BOLT_POLL_7E4.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); + BOLT_POLL_7E4.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); + + transmit_can(&BOLT_POLL_7E4, can_config.battery); + } } void setup_battery(void) { // Performs one time setup at startup strncpy(datalayer.system.info.battery_protocol, "Chevrolet Bolt EV/Opel Ampera-e", 63); datalayer.system.info.battery_protocol[63] = '\0'; - + datalayer.battery.info.number_of_cells = 96; datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_DV; datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_DV; datalayer.battery.info.max_cell_voltage_mV = MAX_CELL_VOLTAGE_MV; diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.h b/Software/src/battery/BOLT-AMPERA-BATTERY.h index 42d743d5..46c28f0a 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.h +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.h @@ -10,7 +10,122 @@ #define MAX_CELL_DEVIATION_MV 500 #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 MAX_CHARGE_POWER_W 5000 // Battery can be charged with this amount of power + +#define POLL_CAPACITY_EST_GEN1 0x41A3 +#define POLL_CAPACITY_EST_GEN2 0x45F9 +#define POLL_SOC_DISPLAY 0x8334 +#define POLL_SOC_RAW_HIGHPREC 0x43AF +#define POLL_MAX_TEMPERATURE 0x4349 +#define POLL_MIN_TEMPERATURE 0x434A +#define POLL_MIN_CELL_V 0x4329 +#define POLL_MAX_CELL_V 0x432B +#define POLL_INTERNAL_RES 0x40E9 +#define POLL_MIN_BATT_V 0x433B +#define POLL_MAX_BATT_V 0x433C +#define POLL_VOLTAGE 0x432D +#define POLL_VEHICLE_ISOLATION 0x41EC +#define POLL_ISOLATION_TEST_KOHM 0x43A6 +#define POLL_HV_LOCKED_OUT 0x44F8 +#define POLL_CRASH_EVENT 0x4522 +#define POLL_HVIL 0x4310 +#define POLL_HVIL_STATUS 0x4311 +#define POLL_CURRENT 0x4356 +#define POLL_CELL_01 0x4181 +#define POLL_CELL_02 0x4182 +#define POLL_CELL_03 0x4183 +#define POLL_CELL_04 0x4184 +#define POLL_CELL_05 0x4185 +#define POLL_CELL_06 0x4186 +#define POLL_CELL_07 0x4187 +#define POLL_CELL_08 0x4188 +#define POLL_CELL_09 0x4189 +#define POLL_CELL_10 0x418A +#define POLL_CELL_11 0x418B +#define POLL_CELL_12 0x418C +#define POLL_CELL_13 0x418D +#define POLL_CELL_14 0x418E +#define POLL_CELL_15 0x418F +#define POLL_CELL_16 0x4190 +#define POLL_CELL_17 0x4191 +#define POLL_CELL_18 0x4192 +#define POLL_CELL_19 0x4193 +#define POLL_CELL_20 0x4194 +#define POLL_CELL_21 0x4195 +#define POLL_CELL_22 0x4196 +#define POLL_CELL_23 0x4197 +#define POLL_CELL_24 0x4198 +#define POLL_CELL_25 0x4199 +#define POLL_CELL_26 0x419A +#define POLL_CELL_27 0x419B +#define POLL_CELL_28 0x419C +#define POLL_CELL_29 0x419D +#define POLL_CELL_30 0x419E +#define POLL_CELL_31 0x419F +#define POLL_CELL_32 0x4200 +#define POLL_CELL_33 0x4201 +#define POLL_CELL_34 0x4202 +#define POLL_CELL_35 0x4203 +#define POLL_CELL_36 0x4204 +#define POLL_CELL_37 0x4205 +#define POLL_CELL_38 0x4206 +#define POLL_CELL_39 0x4207 +#define POLL_CELL_40 0x4208 +#define POLL_CELL_41 0x4209 +#define POLL_CELL_42 0x420A +#define POLL_CELL_43 0x420B +#define POLL_CELL_44 0x420C +#define POLL_CELL_45 0x420D +#define POLL_CELL_46 0x420E +#define POLL_CELL_47 0x420F +#define POLL_CELL_48 0x4210 +#define POLL_CELL_49 0x4211 +#define POLL_CELL_50 0x4212 +#define POLL_CELL_51 0x4213 +#define POLL_CELL_52 0x4214 +#define POLL_CELL_53 0x4215 +#define POLL_CELL_54 0x4216 +#define POLL_CELL_55 0x4217 +#define POLL_CELL_56 0x4218 +#define POLL_CELL_57 0x4219 +#define POLL_CELL_58 0x421A +#define POLL_CELL_59 0x421B +#define POLL_CELL_60 0x421C +#define POLL_CELL_61 0x421D +#define POLL_CELL_62 0x421E +#define POLL_CELL_63 0x421F +#define POLL_CELL_64 0x4220 +#define POLL_CELL_65 0x4221 +#define POLL_CELL_66 0x4222 +#define POLL_CELL_67 0x4223 +#define POLL_CELL_68 0x4224 +#define POLL_CELL_69 0x4225 +#define POLL_CELL_70 0x4226 +#define POLL_CELL_71 0x4227 +#define POLL_CELL_72 0x4228 +#define POLL_CELL_73 0x4229 +#define POLL_CELL_74 0x422A +#define POLL_CELL_75 0x422B +#define POLL_CELL_76 0x422C +#define POLL_CELL_77 0x422D +#define POLL_CELL_78 0x422E +#define POLL_CELL_79 0x422F +#define POLL_CELL_80 0x4230 +#define POLL_CELL_81 0x4231 +#define POLL_CELL_82 0x4232 +#define POLL_CELL_83 0x4233 +#define POLL_CELL_84 0x4234 +#define POLL_CELL_85 0x4235 +#define POLL_CELL_86 0x4236 +#define POLL_CELL_87 0x4237 +#define POLL_CELL_88 0x4238 +#define POLL_CELL_89 0x4239 +#define POLL_CELL_90 0x423A +#define POLL_CELL_91 0x423B +#define POLL_CELL_92 0x423C +#define POLL_CELL_93 0x423D +#define POLL_CELL_94 0x423E +#define POLL_CELL_95 0x423F +#define POLL_CELL_96 0x4240 void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); From 12215bdbd237a626c1769e2005b838f3f7d9b56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 4 Dec 2024 22:42:37 +0200 Subject: [PATCH 03/12] Add temperature mappings and more CAN messages --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 79 +++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index a0cb0e95..49dcb996 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -40,6 +40,14 @@ static uint16_t battery_crash_event = 0; static uint16_t battery_HVIL = 0; static uint16_t battery_HVIL_status = 0; static int16_t battery_current = 0; +static int16_t temperature_1 = 0; +static int16_t temperature_2 = 0; +static int16_t temperature_3 = 0; +static int16_t temperature_4 = 0; +static int16_t temperature_5 = 0; +static int16_t temperature_6 = 0; +static int16_t temperature_highest = 0; +static int16_t temperature_lowest = 0; static uint8_t poll_index = 0; static uint16_t currentpoll = POLL_CAPACITY_EST_GEN1; @@ -179,9 +187,26 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.max_charge_power_W; - datalayer.battery.status.temperature_min_dC; + // Store temperatures in an array + int16_t temperatures[] = {temperature_1, temperature_2, temperature_3, temperature_4, temperature_5, temperature_6}; - datalayer.battery.status.temperature_max_dC; + // Initialize highest and lowest to the first element + temperature_highest = temperatures[0]; + temperature_lowest = temperatures[0]; + + // Iterate through the array to find the highest and lowest values + for (uint8_t i = 1; i < 6; ++i) { + if (temperatures[i] > temperature_highest) { + temperature_highest = temperatures[i]; + } + if (temperatures[i] < temperature_lowest) { + temperature_lowest = temperatures[i]; + } + } + + datalayer.battery.status.temperature_min_dC = temperature_lowest * 10; + + datalayer.battery.status.temperature_max_dC = temperature_highest * 10; //Map all cell voltages to the global array memcpy(datalayer.battery.status.cell_voltages_mV, battery_cell_voltages, 96 * sizeof(uint16_t)); @@ -189,12 +214,62 @@ void update_values_battery() { //This function maps all the values fetched via void receive_can_battery(CAN_frame rx_frame) { switch (rx_frame.ID) { + case 0x200: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x202: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x204: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x206: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x208: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x20C: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x216: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; case 0x2C7: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; + case 0x260: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x270: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x272: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x274: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x302: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + //302 8 03 5C 5C 5D 5D 5C 5C 1E + //Could be temperatures here? + temperature_1 = (rx_frame.data.u8[1] - 40); + temperature_2 = (rx_frame.data.u8[2] - 40); + temperature_3 = (rx_frame.data.u8[3] - 40); + temperature_4 = (rx_frame.data.u8[4] - 40); + temperature_5 = (rx_frame.data.u8[5] - 40); + temperature_6 = (rx_frame.data.u8[6] - 40); + break; case 0x3E3: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; + case 0x460: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; + case 0x5EF: + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + break; case 0x7EC: //TODO: Confirm if this is the reply from BMS when polling //Frame 2 & 3 contains reply reply_poll = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; From 3340e029023ba5b00bdb9982658263ac8c7d8d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 4 Dec 2024 23:20:25 +0200 Subject: [PATCH 04/12] Add voltage candidate --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index 49dcb996..a871f579 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -33,6 +33,7 @@ static uint16_t battery_internal_resistance = 0; static uint16_t battery_min_voltage = 0; static uint16_t battery_max_voltage = 0; static uint16_t battery_voltage = 3700; +static uint16_t battery_voltage_periodic = 0; static uint16_t battery_vehicle_isolation = 0; static uint16_t battery_isolation_kohm = 0; static uint16_t battery_HV_locked = 0; @@ -48,6 +49,7 @@ static int16_t temperature_5 = 0; static int16_t temperature_6 = 0; static int16_t temperature_highest = 0; static int16_t temperature_lowest = 0; +static uint8_t mux = 0; static uint8_t poll_index = 0; static uint16_t currentpoll = POLL_CAPACITY_EST_GEN1; @@ -173,7 +175,8 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.real_soc = (battery_SOC_display * 100 / 255); - datalayer.battery.status.voltage_dV = battery_voltage * 0.52; + //datalayer.battery.status.voltage_dV = battery_voltage * 0.52; + datalayer.battery.status.voltage_dV = (battery_voltage_periodic / 8) * 10; datalayer.battery.status.current_dA = battery_current / -6.675; @@ -216,18 +219,23 @@ void receive_can_battery(CAN_frame rx_frame) { switch (rx_frame.ID) { case 0x200: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7 break; case 0x202: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7 break; case 0x204: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7 break; case 0x206: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7 break; case 0x208: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + mux = ((rx_frame.data.u8[6] & 0xE0) >> 5); //goes from 0-7 break; case 0x20C: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; @@ -237,6 +245,7 @@ void receive_can_battery(CAN_frame rx_frame) { break; case 0x2C7: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + battery_voltage_periodic = (rx_frame.data.u8[3] << 4) | (rx_frame.data.u8[4] >> 4); break; case 0x260: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; From f68fec57cb86fa6ef9c3737856820e4bd3225059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Thu, 5 Dec 2024 22:25:29 +0200 Subject: [PATCH 05/12] Fix temperatures scaled wrong --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index a871f579..5a22e8c2 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -263,12 +263,12 @@ void receive_can_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; //302 8 03 5C 5C 5D 5D 5C 5C 1E //Could be temperatures here? - temperature_1 = (rx_frame.data.u8[1] - 40); - temperature_2 = (rx_frame.data.u8[2] - 40); - temperature_3 = (rx_frame.data.u8[3] - 40); - temperature_4 = (rx_frame.data.u8[4] - 40); - temperature_5 = (rx_frame.data.u8[5] - 40); - temperature_6 = (rx_frame.data.u8[6] - 40); + temperature_1 = ((rx_frame.data.u8[1] / 2) - 40); + temperature_2 = ((rx_frame.data.u8[2] / 2) - 40); + temperature_3 = ((rx_frame.data.u8[3] / 2) - 40); + temperature_4 = ((rx_frame.data.u8[4] / 2) - 40); + temperature_5 = ((rx_frame.data.u8[5] / 2) - 40); + temperature_6 = ((rx_frame.data.u8[6] / 2) - 40); break; case 0x3E3: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; From 257ee27d5c7ba8deb7b71f394474c2b4e78f18c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Fri, 6 Dec 2024 22:41:13 +0200 Subject: [PATCH 06/12] Tweak 7E4 bit0 --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index 5a22e8c2..c804643b 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -18,7 +18,7 @@ CAN_frame BOLT_POLL_7E4 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x7E4, - .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + .data = {0x01, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages static uint16_t battery_capacity_my17_18 = 0; From 5023415a83b15c8a074a1d24ec20b012ff72579d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 8 Dec 2024 01:07:15 +0200 Subject: [PATCH 07/12] Improve polling --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 51 ++++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index c804643b..30b476f9 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -18,7 +18,25 @@ CAN_frame BOLT_POLL_7E4 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x7E4, - .data = {0x01, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame BOLT_ACK_7E4 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E4, + .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame BOLT_POLL_7E7 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E7, + .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame BOLT_ACK_7E7 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x7E7, + .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +// 7E4 Battery , reply 000007EC +// 7E7 Battery (Cell voltages), reply 000007EF static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages static uint16_t battery_capacity_my17_18 = 0; @@ -261,14 +279,12 @@ void receive_can_battery(CAN_frame rx_frame) { break; case 0x302: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; - //302 8 03 5C 5C 5D 5D 5C 5C 1E - //Could be temperatures here? - temperature_1 = ((rx_frame.data.u8[1] / 2) - 40); - temperature_2 = ((rx_frame.data.u8[2] / 2) - 40); - temperature_3 = ((rx_frame.data.u8[3] / 2) - 40); - temperature_4 = ((rx_frame.data.u8[4] / 2) - 40); - temperature_5 = ((rx_frame.data.u8[5] / 2) - 40); - temperature_6 = ((rx_frame.data.u8[6] / 2) - 40); + temperature_1 = ((rx_frame.data.u8[1] / 2) - 40); //Module 1 Temperature + temperature_2 = ((rx_frame.data.u8[2] / 2) - 40); //Module 2 Temperature + temperature_3 = ((rx_frame.data.u8[3] / 2) - 40); //Module 3 Temperature + temperature_4 = ((rx_frame.data.u8[4] / 2) - 40); //Module 4 Temperature + temperature_5 = ((rx_frame.data.u8[5] / 2) - 40); //Module 5 Temperature + temperature_6 = ((rx_frame.data.u8[6] / 2) - 40); //Module 6 Temperature break; case 0x3E3: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; @@ -279,7 +295,18 @@ void receive_can_battery(CAN_frame rx_frame) { case 0x5EF: datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; - case 0x7EC: //TODO: Confirm if this is the reply from BMS when polling + case 0x7EC: //When polling 7E4 BMS replies with 7EC ?? + case 0x7EF: //When polling 7E7 BMS replies with 7EF ?? + + if (rx_frame.data.u8[0] == 0x10) { //"PID Header" + if (rx_frame.ID == 0x7EC) { + transmit_can(&BOLT_ACK_7E4, can_config.battery); + } + if (rx_frame.ID == 0x7EF) { + transmit_can(&BOLT_ACK_7E7, can_config.battery); + } + } + //Frame 2 & 3 contains reply reply_poll = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; @@ -663,7 +690,11 @@ void send_can_battery() { BOLT_POLL_7E4.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); BOLT_POLL_7E4.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); + BOLT_POLL_7E7.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); + BOLT_POLL_7E7.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); + transmit_can(&BOLT_POLL_7E4, can_config.battery); + transmit_can(&BOLT_POLL_7E7, can_config.battery); } } From 0c1e7d5ed916afd9cff2aca21102d97ef9b4de52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 8 Dec 2024 17:30:19 +0200 Subject: [PATCH 08/12] Refactor 7E7 polls --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 503 ++++++++---------- Software/src/battery/BOLT-AMPERA-BATTERY.h | 223 ++++---- Software/src/datalayer/datalayer_extended.h | 18 + .../webserver/advanced_battery_html.cpp | 23 +- 4 files changed, 366 insertions(+), 401 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index 30b476f9..a113d3a9 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -28,14 +28,14 @@ CAN_frame BOLT_POLL_7E7 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x7E7, - .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + .data = {0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; CAN_frame BOLT_ACK_7E7 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x7E7, .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -// 7E4 Battery , reply 000007EC +// 7E4 Battery , reply 000007EC (For some reason does not work) // 7E7 Battery (Cell voltages), reply 000007EF static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages @@ -58,6 +58,17 @@ static uint16_t battery_HV_locked = 0; static uint16_t battery_crash_event = 0; static uint16_t battery_HVIL = 0; static uint16_t battery_HVIL_status = 0; +static uint16_t battery_5V_ref = 0; +static uint16_t battery_module_temp_1 = 0; +static uint16_t battery_module_temp_2 = 0; +static uint16_t battery_module_temp_3 = 0; +static uint16_t battery_module_temp_4 = 0; +static uint16_t battery_module_temp_5 = 0; +static uint16_t battery_module_temp_6 = 0; +static uint16_t battery_cell_average_voltage = 0; +static uint16_t battery_cell_average_voltage_2 = 0; +static uint16_t battery_terminal_voltage = 0; +static uint16_t battery_ignition_power_mode = 0; static int16_t battery_current = 0; static int16_t temperature_1 = 0; static int16_t temperature_2 = 0; @@ -70,124 +81,63 @@ static int16_t temperature_lowest = 0; static uint8_t mux = 0; static uint8_t poll_index = 0; -static uint16_t currentpoll = POLL_CAPACITY_EST_GEN1; +static uint16_t currentpoll = POLL_7E7_CURRENT; static uint16_t reply_poll = 0; -const uint16_t poll_commands[115] = {POLL_CAPACITY_EST_GEN1, - POLL_CAPACITY_EST_GEN2, - POLL_SOC_DISPLAY, - POLL_SOC_RAW_HIGHPREC, - POLL_MAX_TEMPERATURE, - POLL_MIN_TEMPERATURE, - POLL_MIN_CELL_V, - POLL_MAX_CELL_V, - POLL_INTERNAL_RES, - POLL_MIN_BATT_V, - POLL_MAX_BATT_V, - POLL_VOLTAGE, - POLL_VEHICLE_ISOLATION, - POLL_ISOLATION_TEST_KOHM, - POLL_HV_LOCKED_OUT, - POLL_CRASH_EVENT, - POLL_HVIL, - POLL_HVIL_STATUS, - POLL_CURRENT, - POLL_CELL_01, - POLL_CELL_02, - POLL_CELL_03, - POLL_CELL_04, - POLL_CELL_05, - POLL_CELL_06, - POLL_CELL_07, - POLL_CELL_08, - POLL_CELL_09, - POLL_CELL_10, - POLL_CELL_11, - POLL_CELL_12, - POLL_CELL_13, - POLL_CELL_14, - POLL_CELL_15, - POLL_CELL_16, - POLL_CELL_17, - POLL_CELL_18, - POLL_CELL_19, - POLL_CELL_20, - POLL_CELL_21, - POLL_CELL_22, - POLL_CELL_23, - POLL_CELL_24, - POLL_CELL_25, - POLL_CELL_26, - POLL_CELL_27, - POLL_CELL_28, - POLL_CELL_29, - POLL_CELL_30, - POLL_CELL_31, - POLL_CELL_32, - POLL_CELL_33, - POLL_CELL_34, - POLL_CELL_35, - POLL_CELL_36, - POLL_CELL_37, - POLL_CELL_38, - POLL_CELL_39, - POLL_CELL_40, - POLL_CELL_41, - POLL_CELL_42, - POLL_CELL_43, - POLL_CELL_44, - POLL_CELL_45, - POLL_CELL_46, - POLL_CELL_47, - POLL_CELL_48, - POLL_CELL_49, - POLL_CELL_50, - POLL_CELL_51, - POLL_CELL_52, - POLL_CELL_53, - POLL_CELL_54, - POLL_CELL_55, - POLL_CELL_56, - POLL_CELL_57, - POLL_CELL_58, - POLL_CELL_59, - POLL_CELL_60, - POLL_CELL_61, - POLL_CELL_62, - POLL_CELL_63, - POLL_CELL_64, - POLL_CELL_65, - POLL_CELL_66, - POLL_CELL_67, - POLL_CELL_68, - POLL_CELL_69, - POLL_CELL_70, - POLL_CELL_71, - POLL_CELL_72, - POLL_CELL_73, - POLL_CELL_74, - POLL_CELL_75, - POLL_CELL_76, - POLL_CELL_77, - POLL_CELL_78, - POLL_CELL_79, - POLL_CELL_80, - POLL_CELL_81, - POLL_CELL_82, - POLL_CELL_83, - POLL_CELL_84, - POLL_CELL_85, - POLL_CELL_86, - POLL_CELL_87, - POLL_CELL_88, - POLL_CELL_89, - POLL_CELL_90, - POLL_CELL_91, - POLL_CELL_92, - POLL_CELL_93, - POLL_CELL_94, - POLL_CELL_95, - POLL_CELL_96}; +const uint16_t poll_commands_7E7[108] = {POLL_7E7_CURRENT, POLL_7E7_5V_REF, + POLL_7E7_MODULE_TEMP_1, POLL_7E7_MODULE_TEMP_2, + POLL_7E7_MODULE_TEMP_3, POLL_7E7_MODULE_TEMP_4, + POLL_7E7_MODULE_TEMP_5, POLL_7E7_MODULE_TEMP_6, + POLL_7E7_CELL_AVG_VOLTAGE, POLL_7E7_CELL_AVG_VOLTAGE_2, + POLL_7E7_TERMINAL_VOLTAGE, POLL_7E7_IGNITION_POWER_MODE, + POLL_7E7_CELL_01, POLL_7E7_CELL_02, + POLL_7E7_CELL_03, POLL_7E7_CELL_04, + POLL_7E7_CELL_05, POLL_7E7_CELL_06, + POLL_7E7_CELL_07, POLL_7E7_CELL_08, + POLL_7E7_CELL_09, POLL_7E7_CELL_10, + POLL_7E7_CELL_11, POLL_7E7_CELL_12, + POLL_7E7_CELL_13, POLL_7E7_CELL_14, + POLL_7E7_CELL_15, POLL_7E7_CELL_16, + POLL_7E7_CELL_17, POLL_7E7_CELL_18, + POLL_7E7_CELL_19, POLL_7E7_CELL_20, + POLL_7E7_CELL_21, POLL_7E7_CELL_22, + POLL_7E7_CELL_23, POLL_7E7_CELL_24, + POLL_7E7_CELL_25, POLL_7E7_CELL_26, + POLL_7E7_CELL_27, POLL_7E7_CELL_28, + POLL_7E7_CELL_29, POLL_7E7_CELL_30, + POLL_7E7_CELL_31, POLL_7E7_CELL_32, + POLL_7E7_CELL_33, POLL_7E7_CELL_34, + POLL_7E7_CELL_35, POLL_7E7_CELL_36, + POLL_7E7_CELL_37, POLL_7E7_CELL_38, + POLL_7E7_CELL_39, POLL_7E7_CELL_40, + POLL_7E7_CELL_41, POLL_7E7_CELL_42, + POLL_7E7_CELL_43, POLL_7E7_CELL_44, + POLL_7E7_CELL_45, POLL_7E7_CELL_46, + POLL_7E7_CELL_47, POLL_7E7_CELL_48, + POLL_7E7_CELL_49, POLL_7E7_CELL_50, + POLL_7E7_CELL_51, POLL_7E7_CELL_52, + POLL_7E7_CELL_53, POLL_7E7_CELL_54, + POLL_7E7_CELL_55, POLL_7E7_CELL_56, + POLL_7E7_CELL_57, POLL_7E7_CELL_58, + POLL_7E7_CELL_59, POLL_7E7_CELL_60, + POLL_7E7_CELL_61, POLL_7E7_CELL_62, + POLL_7E7_CELL_63, POLL_7E7_CELL_64, + POLL_7E7_CELL_65, POLL_7E7_CELL_66, + POLL_7E7_CELL_67, POLL_7E7_CELL_68, + POLL_7E7_CELL_69, POLL_7E7_CELL_70, + POLL_7E7_CELL_71, POLL_7E7_CELL_72, + POLL_7E7_CELL_73, POLL_7E7_CELL_74, + POLL_7E7_CELL_75, POLL_7E7_CELL_76, + POLL_7E7_CELL_77, POLL_7E7_CELL_78, + POLL_7E7_CELL_79, POLL_7E7_CELL_80, + POLL_7E7_CELL_81, POLL_7E7_CELL_82, + POLL_7E7_CELL_83, POLL_7E7_CELL_84, + POLL_7E7_CELL_85, POLL_7E7_CELL_86, + POLL_7E7_CELL_87, POLL_7E7_CELL_88, + POLL_7E7_CELL_89, POLL_7E7_CELL_90, + POLL_7E7_CELL_91, POLL_7E7_CELL_92, + POLL_7E7_CELL_93, POLL_7E7_CELL_94, + POLL_7E7_CELL_95, POLL_7E7_CELL_96}; void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer @@ -196,7 +146,7 @@ void update_values_battery() { //This function maps all the values fetched via //datalayer.battery.status.voltage_dV = battery_voltage * 0.52; datalayer.battery.status.voltage_dV = (battery_voltage_periodic / 8) * 10; - datalayer.battery.status.current_dA = battery_current / -6.675; + datalayer.battery.status.current_dA = (battery_current / 20) - 400; datalayer.battery.info.total_capacity_Wh; @@ -231,6 +181,20 @@ void update_values_battery() { //This function maps all the values fetched via //Map all cell voltages to the global array memcpy(datalayer.battery.status.cell_voltages_mV, battery_cell_voltages, 96 * sizeof(uint16_t)); + + // Update webserver datalayer + datalayer_extended.boltampera.battery_5V_ref = battery_5V_ref; + datalayer_extended.boltampera.battery_module_temp_1 = battery_module_temp_1; + datalayer_extended.boltampera.battery_module_temp_2 = battery_module_temp_2; + datalayer_extended.boltampera.battery_module_temp_3 = battery_module_temp_3; + datalayer_extended.boltampera.battery_module_temp_4 = battery_module_temp_4; + datalayer_extended.boltampera.battery_module_temp_5 = battery_module_temp_5; + datalayer_extended.boltampera.battery_module_temp_6 = battery_module_temp_6; + datalayer_extended.boltampera.battery_cell_average_voltage = battery_cell_average_voltage; + datalayer_extended.boltampera.battery_cell_average_voltage_2 = battery_cell_average_voltage_2; + datalayer_extended.boltampera.battery_terminal_voltage = battery_terminal_voltage; + datalayer_extended.boltampera.battery_ignition_power_mode = battery_ignition_power_mode; + datalayer_extended.boltampera.battery_current = battery_current; } void receive_can_battery(CAN_frame rx_frame) { @@ -296,364 +260,339 @@ void receive_can_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; case 0x7EC: //When polling 7E4 BMS replies with 7EC ?? - case 0x7EF: //When polling 7E7 BMS replies with 7EF ?? + break; + case 0x7EF: //When polling 7E7 BMS replies with 7EF if (rx_frame.data.u8[0] == 0x10) { //"PID Header" - if (rx_frame.ID == 0x7EC) { - transmit_can(&BOLT_ACK_7E4, can_config.battery); - } - if (rx_frame.ID == 0x7EF) { - transmit_can(&BOLT_ACK_7E7, can_config.battery); - } + transmit_can(&BOLT_ACK_7E7, can_config.battery); } //Frame 2 & 3 contains reply reply_poll = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; switch (reply_poll) { - case POLL_CAPACITY_EST_GEN1: - battery_capacity_my17_18 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_CAPACITY_EST_GEN2: - battery_capacity_my19plus = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_SOC_DISPLAY: - battery_SOC_display = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_SOC_RAW_HIGHPREC: - battery_SOC_raw_highprec = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MAX_TEMPERATURE: - battery_max_temperature = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MIN_TEMPERATURE: - battery_min_temperature = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MIN_CELL_V: - battery_min_cell_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MAX_CELL_V: - battery_max_cell_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_INTERNAL_RES: - battery_internal_resistance = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MIN_BATT_V: - battery_min_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_MAX_BATT_V: - battery_max_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_VOLTAGE: - battery_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_VEHICLE_ISOLATION: - battery_vehicle_isolation = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_ISOLATION_TEST_KOHM: - battery_isolation_kohm = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_HV_LOCKED_OUT: - battery_HV_locked = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_CRASH_EVENT: - battery_crash_event = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_HVIL: - battery_HVIL = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_HVIL_STATUS: - battery_HVIL_status = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; - break; - case POLL_CURRENT: + case POLL_7E7_CURRENT: battery_current = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_01: + case POLL_7E7_5V_REF: + battery_5V_ref = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_1: + battery_module_temp_1 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_2: + battery_module_temp_2 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_3: + battery_module_temp_3 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_4: + battery_module_temp_4 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_5: + battery_module_temp_5 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_MODULE_TEMP_6: + battery_module_temp_6 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_CELL_AVG_VOLTAGE: + battery_cell_average_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_CELL_AVG_VOLTAGE_2: + battery_cell_average_voltage_2 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_TERMINAL_VOLTAGE: + battery_terminal_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_IGNITION_POWER_MODE: + battery_ignition_power_mode = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case POLL_7E7_CELL_01: battery_cell_voltages[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_02: + case POLL_7E7_CELL_02: battery_cell_voltages[1] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_03: + case POLL_7E7_CELL_03: battery_cell_voltages[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_04: + case POLL_7E7_CELL_04: battery_cell_voltages[3] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_05: + case POLL_7E7_CELL_05: battery_cell_voltages[4] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_06: + case POLL_7E7_CELL_06: battery_cell_voltages[5] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_07: + case POLL_7E7_CELL_07: battery_cell_voltages[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_08: + case POLL_7E7_CELL_08: battery_cell_voltages[7] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_09: + case POLL_7E7_CELL_09: battery_cell_voltages[8] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_10: + case POLL_7E7_CELL_10: battery_cell_voltages[9] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_11: + case POLL_7E7_CELL_11: battery_cell_voltages[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_12: + case POLL_7E7_CELL_12: battery_cell_voltages[11] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_13: + case POLL_7E7_CELL_13: battery_cell_voltages[12] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_14: + case POLL_7E7_CELL_14: battery_cell_voltages[13] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_15: + case POLL_7E7_CELL_15: battery_cell_voltages[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_16: + case POLL_7E7_CELL_16: battery_cell_voltages[15] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_17: + case POLL_7E7_CELL_17: battery_cell_voltages[16] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_18: + case POLL_7E7_CELL_18: battery_cell_voltages[17] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_19: + case POLL_7E7_CELL_19: battery_cell_voltages[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_20: + case POLL_7E7_CELL_20: battery_cell_voltages[19] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_21: + case POLL_7E7_CELL_21: battery_cell_voltages[20] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_22: + case POLL_7E7_CELL_22: battery_cell_voltages[21] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_23: + case POLL_7E7_CELL_23: battery_cell_voltages[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_24: + case POLL_7E7_CELL_24: battery_cell_voltages[23] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_25: + case POLL_7E7_CELL_25: battery_cell_voltages[24] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_26: + case POLL_7E7_CELL_26: battery_cell_voltages[25] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_27: + case POLL_7E7_CELL_27: battery_cell_voltages[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_28: + case POLL_7E7_CELL_28: battery_cell_voltages[27] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_29: + case POLL_7E7_CELL_29: battery_cell_voltages[28] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_30: + case POLL_7E7_CELL_30: battery_cell_voltages[29] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_31: + case POLL_7E7_CELL_31: battery_cell_voltages[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_32: + case POLL_7E7_CELL_32: battery_cell_voltages[31] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_33: + case POLL_7E7_CELL_33: battery_cell_voltages[32] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_34: + case POLL_7E7_CELL_34: battery_cell_voltages[33] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_35: + case POLL_7E7_CELL_35: battery_cell_voltages[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_36: + case POLL_7E7_CELL_36: battery_cell_voltages[35] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_37: + case POLL_7E7_CELL_37: battery_cell_voltages[36] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_38: + case POLL_7E7_CELL_38: battery_cell_voltages[37] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_39: + case POLL_7E7_CELL_39: battery_cell_voltages[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_40: + case POLL_7E7_CELL_40: battery_cell_voltages[39] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_41: + case POLL_7E7_CELL_41: battery_cell_voltages[40] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_42: + case POLL_7E7_CELL_42: battery_cell_voltages[41] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_43: + case POLL_7E7_CELL_43: battery_cell_voltages[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_44: + case POLL_7E7_CELL_44: battery_cell_voltages[43] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_45: + case POLL_7E7_CELL_45: battery_cell_voltages[44] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_46: + case POLL_7E7_CELL_46: battery_cell_voltages[45] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_47: + case POLL_7E7_CELL_47: battery_cell_voltages[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_48: + case POLL_7E7_CELL_48: battery_cell_voltages[47] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_49: + case POLL_7E7_CELL_49: battery_cell_voltages[48] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_50: + case POLL_7E7_CELL_50: battery_cell_voltages[49] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_51: + case POLL_7E7_CELL_51: battery_cell_voltages[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_52: + case POLL_7E7_CELL_52: battery_cell_voltages[51] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_53: + case POLL_7E7_CELL_53: battery_cell_voltages[52] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_54: + case POLL_7E7_CELL_54: battery_cell_voltages[53] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_55: + case POLL_7E7_CELL_55: battery_cell_voltages[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_56: + case POLL_7E7_CELL_56: battery_cell_voltages[55] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_57: + case POLL_7E7_CELL_57: battery_cell_voltages[56] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_58: + case POLL_7E7_CELL_58: battery_cell_voltages[57] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_59: + case POLL_7E7_CELL_59: battery_cell_voltages[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_60: + case POLL_7E7_CELL_60: battery_cell_voltages[59] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_61: + case POLL_7E7_CELL_61: battery_cell_voltages[60] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_62: + case POLL_7E7_CELL_62: battery_cell_voltages[61] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_63: + case POLL_7E7_CELL_63: battery_cell_voltages[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_64: + case POLL_7E7_CELL_64: battery_cell_voltages[63] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_65: + case POLL_7E7_CELL_65: battery_cell_voltages[64] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_66: + case POLL_7E7_CELL_66: battery_cell_voltages[65] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_67: + case POLL_7E7_CELL_67: battery_cell_voltages[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_68: + case POLL_7E7_CELL_68: battery_cell_voltages[67] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_69: + case POLL_7E7_CELL_69: battery_cell_voltages[68] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_70: + case POLL_7E7_CELL_70: battery_cell_voltages[69] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_71: + case POLL_7E7_CELL_71: battery_cell_voltages[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_72: + case POLL_7E7_CELL_72: battery_cell_voltages[71] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_73: + case POLL_7E7_CELL_73: battery_cell_voltages[72] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_74: + case POLL_7E7_CELL_74: battery_cell_voltages[73] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_75: + case POLL_7E7_CELL_75: battery_cell_voltages[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_76: + case POLL_7E7_CELL_76: battery_cell_voltages[75] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_77: + case POLL_7E7_CELL_77: battery_cell_voltages[76] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_78: + case POLL_7E7_CELL_78: battery_cell_voltages[77] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_79: + case POLL_7E7_CELL_79: battery_cell_voltages[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_80: + case POLL_7E7_CELL_80: battery_cell_voltages[79] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_81: + case POLL_7E7_CELL_81: battery_cell_voltages[80] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_82: + case POLL_7E7_CELL_82: battery_cell_voltages[81] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_83: + case POLL_7E7_CELL_83: battery_cell_voltages[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_84: + case POLL_7E7_CELL_84: battery_cell_voltages[83] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_85: + case POLL_7E7_CELL_85: battery_cell_voltages[84] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_86: + case POLL_7E7_CELL_86: battery_cell_voltages[85] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_87: + case POLL_7E7_CELL_87: battery_cell_voltages[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_88: + case POLL_7E7_CELL_88: battery_cell_voltages[87] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_89: + case POLL_7E7_CELL_89: battery_cell_voltages[88] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_90: + case POLL_7E7_CELL_90: battery_cell_voltages[89] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_91: + case POLL_7E7_CELL_91: battery_cell_voltages[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_92: + case POLL_7E7_CELL_92: battery_cell_voltages[91] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_93: + case POLL_7E7_CELL_93: battery_cell_voltages[92] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_94: + case POLL_7E7_CELL_94: battery_cell_voltages[93] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_95: + case POLL_7E7_CELL_95: battery_cell_voltages[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; - case POLL_CELL_96: + case POLL_7E7_CELL_96: battery_cell_voltages[95] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; default: @@ -683,17 +622,13 @@ void send_can_battery() { if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) { previousMillis200ms = currentMillis; - // Update current poll from the array - currentpoll = poll_commands[poll_index]; - poll_index = (poll_index + 1) % 115; - - BOLT_POLL_7E4.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); - BOLT_POLL_7E4.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); + // Update current poll from the 7E7 array + currentpoll = poll_commands_7E7[poll_index]; + poll_index = (poll_index + 1) % 108; BOLT_POLL_7E7.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); BOLT_POLL_7E7.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); - transmit_can(&BOLT_POLL_7E4, can_config.battery); transmit_can(&BOLT_POLL_7E7, can_config.battery); } } diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.h b/Software/src/battery/BOLT-AMPERA-BATTERY.h index 46c28f0a..acc55375 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.h +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.h @@ -11,121 +11,114 @@ #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 POLL_CAPACITY_EST_GEN1 0x41A3 -#define POLL_CAPACITY_EST_GEN2 0x45F9 -#define POLL_SOC_DISPLAY 0x8334 -#define POLL_SOC_RAW_HIGHPREC 0x43AF -#define POLL_MAX_TEMPERATURE 0x4349 -#define POLL_MIN_TEMPERATURE 0x434A -#define POLL_MIN_CELL_V 0x4329 -#define POLL_MAX_CELL_V 0x432B -#define POLL_INTERNAL_RES 0x40E9 -#define POLL_MIN_BATT_V 0x433B -#define POLL_MAX_BATT_V 0x433C -#define POLL_VOLTAGE 0x432D -#define POLL_VEHICLE_ISOLATION 0x41EC -#define POLL_ISOLATION_TEST_KOHM 0x43A6 -#define POLL_HV_LOCKED_OUT 0x44F8 -#define POLL_CRASH_EVENT 0x4522 -#define POLL_HVIL 0x4310 -#define POLL_HVIL_STATUS 0x4311 -#define POLL_CURRENT 0x4356 -#define POLL_CELL_01 0x4181 -#define POLL_CELL_02 0x4182 -#define POLL_CELL_03 0x4183 -#define POLL_CELL_04 0x4184 -#define POLL_CELL_05 0x4185 -#define POLL_CELL_06 0x4186 -#define POLL_CELL_07 0x4187 -#define POLL_CELL_08 0x4188 -#define POLL_CELL_09 0x4189 -#define POLL_CELL_10 0x418A -#define POLL_CELL_11 0x418B -#define POLL_CELL_12 0x418C -#define POLL_CELL_13 0x418D -#define POLL_CELL_14 0x418E -#define POLL_CELL_15 0x418F -#define POLL_CELL_16 0x4190 -#define POLL_CELL_17 0x4191 -#define POLL_CELL_18 0x4192 -#define POLL_CELL_19 0x4193 -#define POLL_CELL_20 0x4194 -#define POLL_CELL_21 0x4195 -#define POLL_CELL_22 0x4196 -#define POLL_CELL_23 0x4197 -#define POLL_CELL_24 0x4198 -#define POLL_CELL_25 0x4199 -#define POLL_CELL_26 0x419A -#define POLL_CELL_27 0x419B -#define POLL_CELL_28 0x419C -#define POLL_CELL_29 0x419D -#define POLL_CELL_30 0x419E -#define POLL_CELL_31 0x419F -#define POLL_CELL_32 0x4200 -#define POLL_CELL_33 0x4201 -#define POLL_CELL_34 0x4202 -#define POLL_CELL_35 0x4203 -#define POLL_CELL_36 0x4204 -#define POLL_CELL_37 0x4205 -#define POLL_CELL_38 0x4206 -#define POLL_CELL_39 0x4207 -#define POLL_CELL_40 0x4208 -#define POLL_CELL_41 0x4209 -#define POLL_CELL_42 0x420A -#define POLL_CELL_43 0x420B -#define POLL_CELL_44 0x420C -#define POLL_CELL_45 0x420D -#define POLL_CELL_46 0x420E -#define POLL_CELL_47 0x420F -#define POLL_CELL_48 0x4210 -#define POLL_CELL_49 0x4211 -#define POLL_CELL_50 0x4212 -#define POLL_CELL_51 0x4213 -#define POLL_CELL_52 0x4214 -#define POLL_CELL_53 0x4215 -#define POLL_CELL_54 0x4216 -#define POLL_CELL_55 0x4217 -#define POLL_CELL_56 0x4218 -#define POLL_CELL_57 0x4219 -#define POLL_CELL_58 0x421A -#define POLL_CELL_59 0x421B -#define POLL_CELL_60 0x421C -#define POLL_CELL_61 0x421D -#define POLL_CELL_62 0x421E -#define POLL_CELL_63 0x421F -#define POLL_CELL_64 0x4220 -#define POLL_CELL_65 0x4221 -#define POLL_CELL_66 0x4222 -#define POLL_CELL_67 0x4223 -#define POLL_CELL_68 0x4224 -#define POLL_CELL_69 0x4225 -#define POLL_CELL_70 0x4226 -#define POLL_CELL_71 0x4227 -#define POLL_CELL_72 0x4228 -#define POLL_CELL_73 0x4229 -#define POLL_CELL_74 0x422A -#define POLL_CELL_75 0x422B -#define POLL_CELL_76 0x422C -#define POLL_CELL_77 0x422D -#define POLL_CELL_78 0x422E -#define POLL_CELL_79 0x422F -#define POLL_CELL_80 0x4230 -#define POLL_CELL_81 0x4231 -#define POLL_CELL_82 0x4232 -#define POLL_CELL_83 0x4233 -#define POLL_CELL_84 0x4234 -#define POLL_CELL_85 0x4235 -#define POLL_CELL_86 0x4236 -#define POLL_CELL_87 0x4237 -#define POLL_CELL_88 0x4238 -#define POLL_CELL_89 0x4239 -#define POLL_CELL_90 0x423A -#define POLL_CELL_91 0x423B -#define POLL_CELL_92 0x423C -#define POLL_CELL_93 0x423D -#define POLL_CELL_94 0x423E -#define POLL_CELL_95 0x423F -#define POLL_CELL_96 0x4240 +#define POLL_7E7_CURRENT 0x40D4 +#define POLL_7E7_5V_REF 0x40D3 +#define POLL_7E7_MODULE_TEMP_1 0x40D7 +#define POLL_7E7_MODULE_TEMP_2 0x40D9 +#define POLL_7E7_MODULE_TEMP_3 0x40DB +#define POLL_7E7_MODULE_TEMP_4 0x40DD +#define POLL_7E7_MODULE_TEMP_5 0x40DF +#define POLL_7E7_MODULE_TEMP_6 0x40E1 +#define POLL_7E7_CELL_AVG_VOLTAGE 0xC218 +#define POLL_7E7_CELL_AVG_VOLTAGE_2 0x44B9 +#define POLL_7E7_TERMINAL_VOLTAGE 0x82A3 +#define POLL_7E7_IGNITION_POWER_MODE 0x8002 +#define POLL_7E7_CELL_01 0x4181 +#define POLL_7E7_CELL_02 0x4182 +#define POLL_7E7_CELL_03 0x4183 +#define POLL_7E7_CELL_04 0x4184 +#define POLL_7E7_CELL_05 0x4185 +#define POLL_7E7_CELL_06 0x4186 +#define POLL_7E7_CELL_07 0x4187 +#define POLL_7E7_CELL_08 0x4188 +#define POLL_7E7_CELL_09 0x4189 +#define POLL_7E7_CELL_10 0x418A +#define POLL_7E7_CELL_11 0x418B +#define POLL_7E7_CELL_12 0x418C +#define POLL_7E7_CELL_13 0x418D +#define POLL_7E7_CELL_14 0x418E +#define POLL_7E7_CELL_15 0x418F +#define POLL_7E7_CELL_16 0x4190 +#define POLL_7E7_CELL_17 0x4191 +#define POLL_7E7_CELL_18 0x4192 +#define POLL_7E7_CELL_19 0x4193 +#define POLL_7E7_CELL_20 0x4194 +#define POLL_7E7_CELL_21 0x4195 +#define POLL_7E7_CELL_22 0x4196 +#define POLL_7E7_CELL_23 0x4197 +#define POLL_7E7_CELL_24 0x4198 +#define POLL_7E7_CELL_25 0x4199 +#define POLL_7E7_CELL_26 0x419A +#define POLL_7E7_CELL_27 0x419B +#define POLL_7E7_CELL_28 0x419C +#define POLL_7E7_CELL_29 0x419D +#define POLL_7E7_CELL_30 0x419E +#define POLL_7E7_CELL_31 0x419F +#define POLL_7E7_CELL_32 0x4200 +#define POLL_7E7_CELL_33 0x4201 +#define POLL_7E7_CELL_34 0x4202 +#define POLL_7E7_CELL_35 0x4203 +#define POLL_7E7_CELL_36 0x4204 +#define POLL_7E7_CELL_37 0x4205 +#define POLL_7E7_CELL_38 0x4206 +#define POLL_7E7_CELL_39 0x4207 +#define POLL_7E7_CELL_40 0x4208 +#define POLL_7E7_CELL_41 0x4209 +#define POLL_7E7_CELL_42 0x420A +#define POLL_7E7_CELL_43 0x420B +#define POLL_7E7_CELL_44 0x420C +#define POLL_7E7_CELL_45 0x420D +#define POLL_7E7_CELL_46 0x420E +#define POLL_7E7_CELL_47 0x420F +#define POLL_7E7_CELL_48 0x4210 +#define POLL_7E7_CELL_49 0x4211 +#define POLL_7E7_CELL_50 0x4212 +#define POLL_7E7_CELL_51 0x4213 +#define POLL_7E7_CELL_52 0x4214 +#define POLL_7E7_CELL_53 0x4215 +#define POLL_7E7_CELL_54 0x4216 +#define POLL_7E7_CELL_55 0x4217 +#define POLL_7E7_CELL_56 0x4218 +#define POLL_7E7_CELL_57 0x4219 +#define POLL_7E7_CELL_58 0x421A +#define POLL_7E7_CELL_59 0x421B +#define POLL_7E7_CELL_60 0x421C +#define POLL_7E7_CELL_61 0x421D +#define POLL_7E7_CELL_62 0x421E +#define POLL_7E7_CELL_63 0x421F +#define POLL_7E7_CELL_64 0x4220 +#define POLL_7E7_CELL_65 0x4221 +#define POLL_7E7_CELL_66 0x4222 +#define POLL_7E7_CELL_67 0x4223 +#define POLL_7E7_CELL_68 0x4224 +#define POLL_7E7_CELL_69 0x4225 +#define POLL_7E7_CELL_70 0x4226 +#define POLL_7E7_CELL_71 0x4227 +#define POLL_7E7_CELL_72 0x4228 +#define POLL_7E7_CELL_73 0x4229 +#define POLL_7E7_CELL_74 0x422A +#define POLL_7E7_CELL_75 0x422B +#define POLL_7E7_CELL_76 0x422C +#define POLL_7E7_CELL_77 0x422D +#define POLL_7E7_CELL_78 0x422E +#define POLL_7E7_CELL_79 0x422F +#define POLL_7E7_CELL_80 0x4230 +#define POLL_7E7_CELL_81 0x4231 +#define POLL_7E7_CELL_82 0x4232 +#define POLL_7E7_CELL_83 0x4233 +#define POLL_7E7_CELL_84 0x4234 +#define POLL_7E7_CELL_85 0x4235 +#define POLL_7E7_CELL_86 0x4236 +#define POLL_7E7_CELL_87 0x4237 +#define POLL_7E7_CELL_88 0x4238 +#define POLL_7E7_CELL_89 0x4239 +#define POLL_7E7_CELL_90 0x423A +#define POLL_7E7_CELL_91 0x423B +#define POLL_7E7_CELL_92 0x423C +#define POLL_7E7_CELL_93 0x423D +#define POLL_7E7_CELL_94 0x423E +#define POLL_7E7_CELL_95 0x423F +#define POLL_7E7_CELL_96 0x4240 void setup_battery(void); void transmit_can(CAN_frame* tx_frame, int interface); diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index 7a9c2cd1..55cfde9b 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -3,6 +3,23 @@ #include "../include.h" +typedef struct { + /** uint16_t */ + /** PID polling parameters */ + uint16_t battery_5V_ref = 0; + uint16_t battery_module_temp_1 = 0; + uint16_t battery_module_temp_2 = 0; + uint16_t battery_module_temp_3 = 0; + uint16_t battery_module_temp_4 = 0; + uint16_t battery_module_temp_5 = 0; + uint16_t battery_module_temp_6 = 0; + uint16_t battery_cell_average_voltage = 0; + uint16_t battery_cell_average_voltage_2 = 0; + uint16_t battery_terminal_voltage = 0; + uint16_t battery_ignition_power_mode = 0; + int16_t battery_current = 0; +} DATALAYER_INFO_BOLTAMPERA; + typedef struct { /** uint16_t */ /** Terminal 30 - 12V SME Supply Voltage */ @@ -326,6 +343,7 @@ typedef struct { class DataLayerExtended { public: + DATALAYER_INFO_BOLTAMPERA boltampera; DATALAYER_INFO_BMWIX bmwix; DATALAYER_INFO_BMWI3 bmwi3; DATALAYER_INFO_BYDATTO3 bydAtto3; diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index b3cba77f..816325d8 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -20,6 +20,24 @@ String advanced_battery_processor(const String& var) { // Start a new block with a specific background color content += "
"; +#ifdef BOLT_AMPERA_BATTERY + content += "

5V Reference: " + String(datalayer_extended.boltampera.battery_5V_ref) + "

"; + content += "

Module 1 temp: " + String(datalayer_extended.boltampera.battery_module_temp_1) + "

"; + content += "

Module 2 temp: " + String(datalayer_extended.boltampera.battery_module_temp_2) + "

"; + content += "

Module 3 temp: " + String(datalayer_extended.boltampera.battery_module_temp_3) + "

"; + content += "

Module 4 temp: " + String(datalayer_extended.boltampera.battery_module_temp_4) + "

"; + content += "

Module 5 temp: " + String(datalayer_extended.boltampera.battery_module_temp_5) + "

"; + content += "

Module 6 temp: " + String(datalayer_extended.boltampera.battery_module_temp_6) + "

"; + content += + "

Cell average voltage: " + String(datalayer_extended.boltampera.battery_cell_average_voltage) + "

"; + content += + "

Cell average voltage 2: " + String(datalayer_extended.boltampera.battery_cell_average_voltage_2) + "

"; + content += "

Terminal voltage: " + String(datalayer_extended.boltampera.battery_terminal_voltage) + "

"; + content += + "

Ignition power mode: " + String(datalayer_extended.boltampera.battery_ignition_power_mode) + "

"; + content += "

Battery current: " + String(datalayer_extended.boltampera.battery_current) + "

"; +#endif //BOLT_AMPERA_BATTERY + #ifdef BMW_IX_BATTERY content += "

Battery Voltage after Contactor: " + String(datalayer_extended.bmwix.battery_voltage_after_contactor) + @@ -467,8 +485,9 @@ String advanced_battery_processor(const String& var) { content += "

soc max: " + String(datalayer_extended.zoePH2.battery_soc_max) + "

"; #endif //RENAULT_ZOE_GEN2_BATTERY -#if !defined(TESLA_BATTERY) && !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && \ - !defined(BYD_ATTO_3_BATTERY) && !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) +#if !defined(BMW_IX_BATTERY) && !defined(BOLT_AMPERA_BATTERY) && !defined(TESLA_BATTERY) && \ + !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && !defined(BYD_ATTO_3_BATTERY) && \ + !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) content += "No extra information available for this battery type"; #endif From 691173c9c06d2668d22919955ced6ff20ad916d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 8 Dec 2024 18:33:52 +0200 Subject: [PATCH 09/12] Fix scaling on 7E7 polls --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 228 +++++++++---------- Software/src/datalayer/datalayer_extended.h | 12 +- 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index a113d3a9..ac15f68c 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -59,12 +59,12 @@ static uint16_t battery_crash_event = 0; static uint16_t battery_HVIL = 0; static uint16_t battery_HVIL_status = 0; static uint16_t battery_5V_ref = 0; -static uint16_t battery_module_temp_1 = 0; -static uint16_t battery_module_temp_2 = 0; -static uint16_t battery_module_temp_3 = 0; -static uint16_t battery_module_temp_4 = 0; -static uint16_t battery_module_temp_5 = 0; -static uint16_t battery_module_temp_6 = 0; +static int16_t battery_module_temp_1 = 0; +static int16_t battery_module_temp_2 = 0; +static int16_t battery_module_temp_3 = 0; +static int16_t battery_module_temp_4 = 0; +static int16_t battery_module_temp_5 = 0; +static int16_t battery_module_temp_6 = 0; static uint16_t battery_cell_average_voltage = 0; static uint16_t battery_cell_average_voltage_2 = 0; static uint16_t battery_terminal_voltage = 0; @@ -146,7 +146,7 @@ void update_values_battery() { //This function maps all the values fetched via //datalayer.battery.status.voltage_dV = battery_voltage * 0.52; datalayer.battery.status.voltage_dV = (battery_voltage_periodic / 8) * 10; - datalayer.battery.status.current_dA = (battery_current / 20) - 400; + datalayer.battery.status.current_dA = battery_current; datalayer.battery.info.total_capacity_Wh; @@ -275,325 +275,325 @@ void receive_can_battery(CAN_frame rx_frame) { battery_current = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; case POLL_7E7_5V_REF: - battery_5V_ref = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_5V_ref = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5) / 65535); break; case POLL_7E7_MODULE_TEMP_1: - battery_module_temp_1 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_1 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_MODULE_TEMP_2: - battery_module_temp_2 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_2 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_MODULE_TEMP_3: - battery_module_temp_3 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_3 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_MODULE_TEMP_4: - battery_module_temp_4 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_4 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_MODULE_TEMP_5: - battery_module_temp_5 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_5 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_MODULE_TEMP_6: - battery_module_temp_6 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_module_temp_6 = (rx_frame.data.u8[4] - 40); break; case POLL_7E7_CELL_AVG_VOLTAGE: - battery_cell_average_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_average_voltage = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_AVG_VOLTAGE_2: - battery_cell_average_voltage_2 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_average_voltage_2 = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 8000) * 1000); break; case POLL_7E7_TERMINAL_VOLTAGE: - battery_terminal_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_terminal_voltage = rx_frame.data.u8[4] * 2; break; case POLL_7E7_IGNITION_POWER_MODE: - battery_ignition_power_mode = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_ignition_power_mode = rx_frame.data.u8[4]; break; case POLL_7E7_CELL_01: - battery_cell_voltages[0] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[0] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_02: - battery_cell_voltages[1] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[1] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_03: - battery_cell_voltages[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[2] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_04: - battery_cell_voltages[3] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[3] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_05: - battery_cell_voltages[4] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[4] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_06: - battery_cell_voltages[5] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[5] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_07: - battery_cell_voltages[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[6] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_08: - battery_cell_voltages[7] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[7] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_09: - battery_cell_voltages[8] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[8] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_10: - battery_cell_voltages[9] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[9] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_11: - battery_cell_voltages[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[10] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_12: - battery_cell_voltages[11] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[11] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_13: - battery_cell_voltages[12] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[12] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_14: - battery_cell_voltages[13] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[13] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_15: - battery_cell_voltages[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[14] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_16: - battery_cell_voltages[15] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[15] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_17: - battery_cell_voltages[16] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[16] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_18: - battery_cell_voltages[17] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[17] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_19: - battery_cell_voltages[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[18] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_20: - battery_cell_voltages[19] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[19] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_21: - battery_cell_voltages[20] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[20] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_22: - battery_cell_voltages[21] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[21] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_23: - battery_cell_voltages[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[22] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_24: - battery_cell_voltages[23] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[23] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_25: - battery_cell_voltages[24] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[24] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_26: - battery_cell_voltages[25] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[25] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_27: - battery_cell_voltages[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[26] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_28: - battery_cell_voltages[27] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[27] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_29: - battery_cell_voltages[28] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[28] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_30: - battery_cell_voltages[29] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[29] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_31: - battery_cell_voltages[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[30] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_32: - battery_cell_voltages[31] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[31] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_33: - battery_cell_voltages[32] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[32] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_34: - battery_cell_voltages[33] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[33] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_35: - battery_cell_voltages[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[34] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_36: - battery_cell_voltages[35] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[35] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_37: - battery_cell_voltages[36] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[36] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_38: - battery_cell_voltages[37] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[37] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_39: - battery_cell_voltages[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[38] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_40: - battery_cell_voltages[39] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[39] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_41: - battery_cell_voltages[40] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[40] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_42: - battery_cell_voltages[41] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[41] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_43: - battery_cell_voltages[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[42] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_44: - battery_cell_voltages[43] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[43] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_45: - battery_cell_voltages[44] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[44] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_46: - battery_cell_voltages[45] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[45] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_47: - battery_cell_voltages[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[46] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_48: - battery_cell_voltages[47] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[47] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_49: - battery_cell_voltages[48] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[48] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_50: - battery_cell_voltages[49] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[49] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_51: - battery_cell_voltages[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[50] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_52: - battery_cell_voltages[51] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[51] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_53: - battery_cell_voltages[52] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[52] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_54: - battery_cell_voltages[53] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[53] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_55: - battery_cell_voltages[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[54] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_56: - battery_cell_voltages[55] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[55] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_57: - battery_cell_voltages[56] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[56] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_58: - battery_cell_voltages[57] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[57] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_59: - battery_cell_voltages[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[58] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_60: - battery_cell_voltages[59] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[59] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_61: - battery_cell_voltages[60] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[60] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_62: - battery_cell_voltages[61] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[61] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_63: - battery_cell_voltages[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[62] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_64: - battery_cell_voltages[63] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[63] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_65: - battery_cell_voltages[64] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[64] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_66: - battery_cell_voltages[65] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[65] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_67: - battery_cell_voltages[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[66] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_68: - battery_cell_voltages[67] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[67] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_69: - battery_cell_voltages[68] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[68] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_70: - battery_cell_voltages[69] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[69] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_71: - battery_cell_voltages[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[70] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_72: - battery_cell_voltages[71] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[71] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_73: - battery_cell_voltages[72] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[72] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_74: - battery_cell_voltages[73] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[73] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_75: - battery_cell_voltages[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[74] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_76: - battery_cell_voltages[75] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[75] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_77: - battery_cell_voltages[76] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[76] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_78: - battery_cell_voltages[77] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[77] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_79: - battery_cell_voltages[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[78] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_80: - battery_cell_voltages[79] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[79] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_81: - battery_cell_voltages[80] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[80] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_82: - battery_cell_voltages[81] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[81] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_83: - battery_cell_voltages[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[82] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_84: - battery_cell_voltages[83] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[83] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_85: - battery_cell_voltages[84] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[84] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_86: - battery_cell_voltages[85] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[85] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_87: - battery_cell_voltages[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[86] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_88: - battery_cell_voltages[87] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[87] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_89: - battery_cell_voltages[88] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[88] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_90: - battery_cell_voltages[89] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[89] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_91: - battery_cell_voltages[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[90] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_92: - battery_cell_voltages[91] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[91] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_93: - battery_cell_voltages[92] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[92] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_94: - battery_cell_voltages[93] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[93] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_95: - battery_cell_voltages[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[94] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; case POLL_7E7_CELL_96: - battery_cell_voltages[95] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_cell_voltages[95] = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5000) / 65535); break; default: break; diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index 55cfde9b..77efc642 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -7,12 +7,12 @@ typedef struct { /** uint16_t */ /** PID polling parameters */ uint16_t battery_5V_ref = 0; - uint16_t battery_module_temp_1 = 0; - uint16_t battery_module_temp_2 = 0; - uint16_t battery_module_temp_3 = 0; - uint16_t battery_module_temp_4 = 0; - uint16_t battery_module_temp_5 = 0; - uint16_t battery_module_temp_6 = 0; + int16_t battery_module_temp_1 = 0; + int16_t battery_module_temp_2 = 0; + int16_t battery_module_temp_3 = 0; + int16_t battery_module_temp_4 = 0; + int16_t battery_module_temp_5 = 0; + int16_t battery_module_temp_6 = 0; uint16_t battery_cell_average_voltage = 0; uint16_t battery_cell_average_voltage_2 = 0; uint16_t battery_terminal_voltage = 0; From 8b221924a87546039cef5fd2e164b70ccaf33b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 8 Dec 2024 20:49:21 +0200 Subject: [PATCH 10/12] Add 7E4 mappings --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 173 +++++++++++++++--- Software/src/battery/BOLT-AMPERA-BATTERY.h | 20 ++ Software/src/datalayer/datalayer_extended.h | 21 ++- .../webserver/advanced_battery_html.cpp | 22 ++- 4 files changed, 211 insertions(+), 25 deletions(-) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index ac15f68c..510b90b7 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -7,7 +7,8 @@ /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis20ms = 0; // will store last time a 20ms CAN Message was send -static unsigned long previousMillis200ms = 0; // will store last time a 200ms CAN Message was send +static unsigned long previousMillis100ms = 0; // will store last time a 100ms CAN Message was send +static unsigned long previousMillis120ms = 0; // will store last time a 120ms CAN Message was send CAN_frame BOLT_778 = {.FD = false, // Unsure of what this message is, added only as example .ext_ID = false, @@ -18,7 +19,7 @@ CAN_frame BOLT_POLL_7E4 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x7E4, - .data = {0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + .data = {0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; CAN_frame BOLT_ACK_7E4 = {.FD = false, .ext_ID = false, .DLC = 8, @@ -35,7 +36,7 @@ CAN_frame BOLT_ACK_7E7 = {.FD = false, .ID = 0x7E7, .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -// 7E4 Battery , reply 000007EC (For some reason does not work) +// 7E4 Battery , reply 000007EC // 7E7 Battery (Cell voltages), reply 000007EF static uint16_t battery_cell_voltages[96]; //array with all the cellvoltages @@ -48,9 +49,9 @@ static uint16_t battery_min_temperature = 0; static uint16_t battery_min_cell_voltage = 0; static uint16_t battery_max_cell_voltage = 0; static uint16_t battery_internal_resistance = 0; -static uint16_t battery_min_voltage = 0; -static uint16_t battery_max_voltage = 0; -static uint16_t battery_voltage = 3700; +static uint16_t battery_lowest_cell = 0; +static uint16_t battery_highest_cell = 0; +static uint16_t battery_voltage_polled = 0; static uint16_t battery_voltage_periodic = 0; static uint16_t battery_vehicle_isolation = 0; static uint16_t battery_isolation_kohm = 0; @@ -59,6 +60,7 @@ static uint16_t battery_crash_event = 0; static uint16_t battery_HVIL = 0; static uint16_t battery_HVIL_status = 0; static uint16_t battery_5V_ref = 0; +static int16_t battery_current_7E4 = 0; static int16_t battery_module_temp_1 = 0; static int16_t battery_module_temp_2 = 0; static int16_t battery_module_temp_3 = 0; @@ -69,7 +71,7 @@ static uint16_t battery_cell_average_voltage = 0; static uint16_t battery_cell_average_voltage_2 = 0; static uint16_t battery_terminal_voltage = 0; static uint16_t battery_ignition_power_mode = 0; -static int16_t battery_current = 0; +static int16_t battery_current_7E7 = 0; static int16_t temperature_1 = 0; static int16_t temperature_2 = 0; static int16_t temperature_3 = 0; @@ -79,10 +81,32 @@ static int16_t temperature_6 = 0; static int16_t temperature_highest = 0; static int16_t temperature_lowest = 0; static uint8_t mux = 0; +static uint8_t poll_index_7E4 = 0; +static uint16_t currentpoll_7E4 = POLL_7E4_CAPACITY_EST_GEN1; +static uint16_t reply_poll_7E4 = 0; +static uint8_t poll_index_7E7 = 0; +static uint16_t currentpoll_7E7 = POLL_7E7_CURRENT; +static uint16_t reply_poll_7E7 = 0; -static uint8_t poll_index = 0; -static uint16_t currentpoll = POLL_7E7_CURRENT; -static uint16_t reply_poll = 0; +const uint16_t poll_commands_7E4[19] = {POLL_7E4_CAPACITY_EST_GEN1, + POLL_7E4_CAPACITY_EST_GEN2, + POLL_7E4_SOC_DISPLAY, + POLL_7E4_SOC_RAW_HIGHPREC, + POLL_7E4_MAX_TEMPERATURE, + POLL_7E4_MIN_TEMPERATURE, + POLL_7E4_MIN_CELL_V, + POLL_7E4_MAX_CELL_V, + POLL_7E4_INTERNAL_RES, + POLL_7E4_LOWEST_CELL_NUMBER, + POLL_7E4_HIGHEST_CELL_NUMBER, + POLL_7E4_VOLTAGE, + POLL_7E4_VEHICLE_ISOLATION, + POLL_7E4_ISOLATION_TEST_KOHM, + POLL_7E4_HV_LOCKED_OUT, + POLL_7E4_CRASH_EVENT, + POLL_7E4_HVIL, + POLL_7E4_HVIL_STATUS, + POLL_7E4_CURRENT}; const uint16_t poll_commands_7E7[108] = {POLL_7E7_CURRENT, POLL_7E7_5V_REF, POLL_7E7_MODULE_TEMP_1, POLL_7E7_MODULE_TEMP_2, @@ -141,12 +165,12 @@ const uint16_t poll_commands_7E7[108] = {POLL_7E7_CURRENT, POLL_7E7_5V_ void update_values_battery() { //This function maps all the values fetched via CAN to the battery datalayer - datalayer.battery.status.real_soc = (battery_SOC_display * 100 / 255); + datalayer.battery.status.real_soc = battery_SOC_display; //datalayer.battery.status.voltage_dV = battery_voltage * 0.52; datalayer.battery.status.voltage_dV = (battery_voltage_periodic / 8) * 10; - datalayer.battery.status.current_dA = battery_current; + datalayer.battery.status.current_dA = battery_current_7E7; datalayer.battery.info.total_capacity_Wh; @@ -194,7 +218,26 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.boltampera.battery_cell_average_voltage_2 = battery_cell_average_voltage_2; datalayer_extended.boltampera.battery_terminal_voltage = battery_terminal_voltage; datalayer_extended.boltampera.battery_ignition_power_mode = battery_ignition_power_mode; - datalayer_extended.boltampera.battery_current = battery_current; + datalayer_extended.boltampera.battery_current_7E7 = battery_current_7E7; + datalayer_extended.boltampera.battery_capacity_my17_18 = battery_capacity_my17_18; + datalayer_extended.boltampera.battery_capacity_my19plus = battery_capacity_my19plus; + datalayer_extended.boltampera.battery_SOC_display = battery_SOC_display; + datalayer_extended.boltampera.battery_SOC_raw_highprec = battery_SOC_raw_highprec; + datalayer_extended.boltampera.battery_max_temperature = battery_max_temperature; + datalayer_extended.boltampera.battery_min_temperature = battery_min_temperature; + datalayer_extended.boltampera.battery_min_cell_voltage = battery_min_cell_voltage; + datalayer_extended.boltampera.battery_max_cell_voltage = battery_max_cell_voltage; + datalayer_extended.boltampera.battery_lowest_cell = battery_lowest_cell; + datalayer_extended.boltampera.battery_highest_cell = battery_highest_cell; + datalayer_extended.boltampera.battery_internal_resistance = battery_internal_resistance; + datalayer_extended.boltampera.battery_voltage_polled = battery_voltage_polled; + datalayer_extended.boltampera.battery_vehicle_isolation = battery_vehicle_isolation; + datalayer_extended.boltampera.battery_isolation_kohm = battery_isolation_kohm; + datalayer_extended.boltampera.battery_HV_locked = battery_HV_locked; + datalayer_extended.boltampera.battery_crash_event = battery_crash_event; + datalayer_extended.boltampera.battery_HVIL = battery_HVIL; + datalayer_extended.boltampera.battery_HVIL_status = battery_HVIL_status; + datalayer_extended.boltampera.battery_current_7E4 = battery_current_7E4; } void receive_can_battery(CAN_frame rx_frame) { @@ -260,6 +303,76 @@ void receive_can_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; break; case 0x7EC: //When polling 7E4 BMS replies with 7EC ?? + + if (rx_frame.data.u8[0] == 0x10) { //"PID Header" + transmit_can(&BOLT_ACK_7E4, can_config.battery); + } + + //Frame 2 & 3 contains reply + reply_poll_7E4 = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + + switch (reply_poll_7E4) { + case POLL_7E4_CAPACITY_EST_GEN1: + battery_capacity_my17_18 = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]); + break; + case POLL_7E4_CAPACITY_EST_GEN2: + battery_capacity_my19plus = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]); + break; + case POLL_7E4_SOC_DISPLAY: + battery_SOC_display = ((rx_frame.data.u8[4] * 100) / 255); + break; + case POLL_7E4_SOC_RAW_HIGHPREC: + battery_SOC_raw_highprec = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 100) / 65535); + break; + case POLL_7E4_MAX_TEMPERATURE: + battery_max_temperature = (rx_frame.data.u8[4] - 40); + break; + case POLL_7E4_MIN_TEMPERATURE: + battery_min_temperature = (rx_frame.data.u8[4] - 40); + break; + case POLL_7E4_MIN_CELL_V: + battery_min_cell_voltage = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 1666; + break; + case POLL_7E4_MAX_CELL_V: + battery_max_cell_voltage = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 1666; + break; + case POLL_7E4_INTERNAL_RES: + battery_internal_resistance = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / 2; + break; + case POLL_7E4_LOWEST_CELL_NUMBER: + battery_lowest_cell = rx_frame.data.u8[4]; + break; + case POLL_7E4_HIGHEST_CELL_NUMBER: + battery_highest_cell = rx_frame.data.u8[4]; + break; + case POLL_7E4_VOLTAGE: + battery_voltage_polled = (((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 0.52); + break; + case POLL_7E4_VEHICLE_ISOLATION: + battery_vehicle_isolation = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]); + break; + case POLL_7E4_ISOLATION_TEST_KOHM: + battery_isolation_kohm = (rx_frame.data.u8[4] * 25); + break; + case POLL_7E4_HV_LOCKED_OUT: + battery_HV_locked = rx_frame.data.u8[4]; + break; + case POLL_7E4_CRASH_EVENT: + battery_crash_event = rx_frame.data.u8[4]; + break; + case POLL_7E4_HVIL: + battery_HVIL = rx_frame.data.u8[4]; + break; + case POLL_7E4_HVIL_STATUS: + battery_HVIL_status = rx_frame.data.u8[4]; + break; + case POLL_7E4_CURRENT: + battery_current_7E4 = (((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) / (-6.675)); + break; + default: + break; + } + break; case 0x7EF: //When polling 7E7 BMS replies with 7EF @@ -268,11 +381,11 @@ void receive_can_battery(CAN_frame rx_frame) { } //Frame 2 & 3 contains reply - reply_poll = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + reply_poll_7E7 = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; - switch (reply_poll) { + switch (reply_poll_7E7) { case POLL_7E7_CURRENT: - battery_current = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + battery_current_7E7 = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; break; case POLL_7E7_5V_REF: battery_5V_ref = ((((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]) * 5) / 65535); @@ -618,19 +731,33 @@ void send_can_battery() { transmit_can(&BOLT_778, can_config.battery); } - //Send 200ms message - if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) { - previousMillis200ms = currentMillis; + //Send 100ms message + if (currentMillis - previousMillis100ms >= INTERVAL_100_MS) { + previousMillis100ms = currentMillis; // Update current poll from the 7E7 array - currentpoll = poll_commands_7E7[poll_index]; - poll_index = (poll_index + 1) % 108; + currentpoll_7E7 = poll_commands_7E7[poll_index_7E7]; + poll_index_7E7 = (poll_index_7E7 + 1) % 108; - BOLT_POLL_7E7.data.u8[2] = (uint8_t)((currentpoll & 0xFF00) >> 8); - BOLT_POLL_7E7.data.u8[3] = (uint8_t)(currentpoll & 0x00FF); + BOLT_POLL_7E7.data.u8[2] = (uint8_t)((currentpoll_7E7 & 0xFF00) >> 8); + BOLT_POLL_7E7.data.u8[3] = (uint8_t)(currentpoll_7E7 & 0x00FF); transmit_can(&BOLT_POLL_7E7, can_config.battery); } + + //Send 120ms message + if (currentMillis - previousMillis120ms >= 120) { + previousMillis120ms = currentMillis; + + // Update current poll from the 7E4 array + currentpoll_7E4 = poll_commands_7E4[poll_index_7E4]; + poll_index_7E4 = (poll_index_7E4 + 1) % 19; + + BOLT_POLL_7E4.data.u8[2] = (uint8_t)((currentpoll_7E4 & 0xFF00) >> 8); + BOLT_POLL_7E4.data.u8[3] = (uint8_t)(currentpoll_7E4 & 0x00FF); + + transmit_can(&BOLT_POLL_7E4, can_config.battery); + } } void setup_battery(void) { // Performs one time setup at startup diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.h b/Software/src/battery/BOLT-AMPERA-BATTERY.h index acc55375..7d877220 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.h +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.h @@ -11,6 +11,26 @@ #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 POLL_7E4_CAPACITY_EST_GEN1 0x41A3 +#define POLL_7E4_CAPACITY_EST_GEN2 0x45F9 +#define POLL_7E4_SOC_DISPLAY 0x8334 +#define POLL_7E4_SOC_RAW_HIGHPREC 0x43AF +#define POLL_7E4_MAX_TEMPERATURE 0x4349 +#define POLL_7E4_MIN_TEMPERATURE 0x434A +#define POLL_7E4_MIN_CELL_V 0x4329 +#define POLL_7E4_MAX_CELL_V 0x432B +#define POLL_7E4_INTERNAL_RES 0x40E9 +#define POLL_7E4_LOWEST_CELL_NUMBER 0x433B +#define POLL_7E4_HIGHEST_CELL_NUMBER 0x433C +#define POLL_7E4_VOLTAGE 0x432D +#define POLL_7E4_VEHICLE_ISOLATION 0x41EC +#define POLL_7E4_ISOLATION_TEST_KOHM 0x43A6 +#define POLL_7E4_HV_LOCKED_OUT 0x44F8 +#define POLL_7E4_CRASH_EVENT 0x4522 +#define POLL_7E4_HVIL 0x4310 +#define POLL_7E4_HVIL_STATUS 0x4311 +#define POLL_7E4_CURRENT 0x4356 + #define POLL_7E7_CURRENT 0x40D4 #define POLL_7E7_5V_REF 0x40D3 #define POLL_7E7_MODULE_TEMP_1 0x40D7 diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index 77efc642..a46fde12 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -17,7 +17,26 @@ typedef struct { uint16_t battery_cell_average_voltage_2 = 0; uint16_t battery_terminal_voltage = 0; uint16_t battery_ignition_power_mode = 0; - int16_t battery_current = 0; + int16_t battery_current_7E7 = 0; + uint16_t battery_capacity_my17_18 = 0; + uint16_t battery_capacity_my19plus = 0; + uint16_t battery_SOC_display = 0; + uint16_t battery_SOC_raw_highprec = 0; + uint16_t battery_max_temperature = 0; + uint16_t battery_min_temperature = 0; + uint16_t battery_max_cell_voltage = 0; + uint16_t battery_min_cell_voltage = 0; + uint16_t battery_lowest_cell = 0; + uint16_t battery_highest_cell = 0; + uint16_t battery_internal_resistance = 0; + uint16_t battery_voltage_polled = 0; + uint16_t battery_vehicle_isolation = 0; + uint16_t battery_isolation_kohm = 0; + uint16_t battery_HV_locked = 0; + uint16_t battery_crash_event = 0; + uint16_t battery_HVIL = 0; + uint16_t battery_HVIL_status = 0; + int16_t battery_current_7E4 = 0; } DATALAYER_INFO_BOLTAMPERA; typedef struct { diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 816325d8..fc4da60e 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -35,7 +35,27 @@ String advanced_battery_processor(const String& var) { content += "

Terminal voltage: " + String(datalayer_extended.boltampera.battery_terminal_voltage) + "

"; content += "

Ignition power mode: " + String(datalayer_extended.boltampera.battery_ignition_power_mode) + "

"; - content += "

Battery current: " + String(datalayer_extended.boltampera.battery_current) + "

"; + content += "

Battery current (7E7): " + String(datalayer_extended.boltampera.battery_current_7E7) + "

"; + content += "

Capacity MY17-18: " + String(datalayer_extended.boltampera.battery_capacity_my17_18) + "

"; + content += "

Capacity MY19+: " + String(datalayer_extended.boltampera.battery_capacity_my19plus) + "

"; + content += "

SOC Display: " + String(datalayer_extended.boltampera.battery_SOC_display) + "

"; + content += "

SOC Raw highprec: " + String(datalayer_extended.boltampera.battery_SOC_raw_highprec) + "

"; + content += "

Max temp: " + String(datalayer_extended.boltampera.battery_max_temperature) + "

"; + content += "

Min temp: " + String(datalayer_extended.boltampera.battery_min_temperature) + "

"; + content += "

Cell max mV: " + String(datalayer_extended.boltampera.battery_max_cell_voltage) + "

"; + content += "

Cell min mV: " + String(datalayer_extended.boltampera.battery_min_cell_voltage) + "

"; + content += "

Lowest cell: " + String(datalayer_extended.boltampera.battery_lowest_cell) + "

"; + content += "

Highest cell: " + String(datalayer_extended.boltampera.battery_highest_cell) + "

"; + content += + "

Internal resistance: " + String(datalayer_extended.boltampera.battery_internal_resistance) + "

"; + content += "

Voltage: " + String(datalayer_extended.boltampera.battery_voltage_polled) + "

"; + content += "

Isolation Ohm: " + String(datalayer_extended.boltampera.battery_vehicle_isolation) + "

"; + content += "

Isolation kOhm: " + String(datalayer_extended.boltampera.battery_isolation_kohm) + "

"; + content += "

HV locked: " + String(datalayer_extended.boltampera.battery_HV_locked) + "

"; + content += "

Crash event: " + String(datalayer_extended.boltampera.battery_crash_event) + "

"; + content += "

HVIL: " + String(datalayer_extended.boltampera.battery_HVIL) + "

"; + content += "

HVIL status: " + String(datalayer_extended.boltampera.battery_HVIL_status) + "

"; + content += "

Current (7E4): " + String(datalayer_extended.boltampera.battery_current_7E4) + "

"; #endif //BOLT_AMPERA_BATTERY #ifdef BMW_IX_BATTERY From 5faf6c1a9e3901abfe97d3515b6fdcb0bd814dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Dec 2024 15:53:35 +0200 Subject: [PATCH 11/12] Add TODOs to .cpp file --- Software/src/battery/BOLT-AMPERA-BATTERY.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp index 510b90b7..90d85eb5 100644 --- a/Software/src/battery/BOLT-AMPERA-BATTERY.cpp +++ b/Software/src/battery/BOLT-AMPERA-BATTERY.cpp @@ -5,6 +5,20 @@ #include "../devboard/utils/events.h" #include "BOLT-AMPERA-BATTERY.h" +/* +TODOs left for this implementation +- The battery has 3 CAN ports. One of them is responsible for the 7E4 polls, the other for the 7E7 polls +- Current implementation only seems to get the 7E7 polls working. +- Could on of the CAN channels be GMLAN? + +- The values missing for a working implementation is: +- SOC% missing! This is absolutely mandatory to fix before starting to use this! +- Capacity (kWh) (can be estimated) +- Charge max power (can be estimated) +- Discharge max power (can be estimated) +- SOH% (low prio)) +*/ + /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis20ms = 0; // will store last time a 20ms CAN Message was send static unsigned long previousMillis100ms = 0; // will store last time a 100ms CAN Message was send From 173091a7f3ce60802f32760841d479f5108def7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Dec 2024 16:10:58 +0200 Subject: [PATCH 12/12] Pre-commit fix --- Software/src/devboard/webserver/advanced_battery_html.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 03fb0540..a634ef7c 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -720,7 +720,8 @@ String advanced_battery_processor(const String& var) { #if !defined(BMW_IX_BATTERY) && !defined(BOLT_AMPERA_BATTERY) && !defined(TESLA_BATTERY) && \ !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && !defined(BYD_ATTO_3_BATTERY) && \ - !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) && !defined(MEB_BATTERY) // Only the listed types have extra info + !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) && \ + !defined(MEB_BATTERY) // Only the listed types have extra info content += "No extra information available for this battery type"; #endif