From a4c075e3565d288e6ef0158b6944457a76acd0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 16 Sep 2024 16:26:13 +0300 Subject: [PATCH 01/93] Add skeleton for eCMP --- Software/USER_SETTINGS.h | 1 + Software/src/battery/BATTERIES.h | 4 ++ Software/src/battery/ECMP-BATTERY.cpp | 74 +++++++++++++++++++++++++++ Software/src/battery/ECMP-BATTERY.h | 12 +++++ 4 files changed, 91 insertions(+) create mode 100644 Software/src/battery/ECMP-BATTERY.cpp create mode 100644 Software/src/battery/ECMP-BATTERY.h diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index b43581f1..81159629 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -18,6 +18,7 @@ //#define KIA_HYUNDAI_HYBRID_BATTERY //#define MG_5_BATTERY //#define NISSAN_LEAF_BATTERY +//#define ECMP_BATTERY //#define PYLON_BATTERY //#define RJXZS_BMS //#define RENAULT_KANGOO_BATTERY diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index 4cb112c1..d8136f75 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -14,6 +14,10 @@ #include "CHADEMO-BATTERY.h" #endif +#ifdef ECMP_BATTERY +#include "ECMP-BATTERY.h" +#endif + #ifdef IMIEV_CZERO_ION_BATTERY #include "IMIEV-CZERO-ION-BATTERY.h" #endif diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp new file mode 100644 index 00000000..82b02745 --- /dev/null +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -0,0 +1,74 @@ +#include "../include.h" +#ifdef ECMP_BATTERY +#include "../datalayer/datalayer.h" +#include "../devboard/utils/events.h" +#include "ECMP-BATTERY.h" + +/* Do not change code below unless you are sure what you are doing */ +static unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was sent + +//Actual content messages +CAN_frame PSA_XXX = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x301, + .data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +void update_values_battery() { + + datalayer.battery.status.real_soc; + + datalayer.battery.status.soh_pptt; + + datalayer.battery.status.voltage_dV; + + datalayer.battery.status.current_dA; + + datalayer.battery.status.active_power_W = //Power in watts, Negative = charging batt + ((datalayer.battery.status.voltage_dV * datalayer.battery.status.current_dA) / 100); + + datalayer.battery.status.max_charge_power_W; + + datalayer.battery.status.max_discharge_power_W; + + datalayer.battery.status.cell_max_voltage_mV; + + datalayer.battery.status.cell_min_voltage_mV; + + datalayer.battery.status.temperature_min_dC; + + datalayer.battery.status.temperature_max_dC; + + datalayer.battery.info.max_design_voltage_dV; + + datalayer.battery.info.min_design_voltage_dV; +} + +void receive_can_battery(CAN_frame rx_frame) { + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + switch (rx_frame.ID) { + case 0x123: + break; + default: + break; + } +} + +void send_can_battery() { + unsigned long currentMillis = millis(); + // Send 1s CAN Message + if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { + previousMillis1000 = currentMillis; + } +} + +void setup_battery(void) { // Performs one time setup at startup +#ifdef DEBUG_VIA_USB + Serial.println("PSA battery selected"); +#endif + + datalayer.battery.info.max_design_voltage_dV = 4040; // 404.0V, charging over this is not possible + datalayer.battery.info.min_design_voltage_dV = 3100; // 310.0V, under this, discharging further is disabled +} + +#endif diff --git a/Software/src/battery/ECMP-BATTERY.h b/Software/src/battery/ECMP-BATTERY.h new file mode 100644 index 00000000..ef4232f9 --- /dev/null +++ b/Software/src/battery/ECMP-BATTERY.h @@ -0,0 +1,12 @@ +#ifndef ECMP_BATTERY_H +#define ECMP_BATTERY_H +#include +#include "../include.h" + +#define BATTERY_SELECTED +#define MAX_CELL_DEVIATION_MV 250 + +void setup_battery(void); +void transmit_can(CAN_frame* tx_frame, int interface); + +#endif From 8ac0aecb108e6a1e73cea2ce43fffe975f4d2f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 16 Sep 2024 21:40:04 +0300 Subject: [PATCH 02/93] Add all CAN messages sent by BMS. Map voltage --- Software/src/battery/ECMP-BATTERY.cpp | 109 ++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp index 82b02745..bb25309f 100644 --- a/Software/src/battery/ECMP-BATTERY.cpp +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -8,11 +8,13 @@ static unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was sent //Actual content messages -CAN_frame PSA_XXX = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x301, - .data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame ECMP_XXX = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x301, + .data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +static uint16_t battery_voltage = 37000; void update_values_battery() { @@ -20,7 +22,7 @@ void update_values_battery() { datalayer.battery.status.soh_pptt; - datalayer.battery.status.voltage_dV; + datalayer.battery.status.voltage_dV = (battery_voltage / 10); datalayer.battery.status.current_dA; @@ -47,7 +49,100 @@ void update_values_battery() { void receive_can_battery(CAN_frame rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; switch (rx_frame.ID) { - case 0x123: + case 0x125: + break; + case 0x127: + break; + case 0x129: + break; + case 0x31B: + break; + case 0x358: + break; + case 0x359: + break; + case 0x361: + battery_voltage = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + break; + case 0x362: + break; + case 0x454: + break; + case 0x494: + break; + case 0x594: + break; + case 0x6D0: + break; + case 0x6D1: + break; + case 0x6D2: + break; + case 0x6D3: + break; + case 0x6D4: + break; + case 0x6E0: + break; + case 0x6E1: + break; + case 0x6E2: + break; + case 0x6E3: + break; + case 0x6E4: + break; + case 0x6E5: + break; + case 0x6E6: + break; + case 0x6E7: + break; + case 0x6E8: + break; + case 0x6E9: + break; + case 0x6EB: + break; + case 0x6ED: + break; + case 0x6EE: + break; + case 0x6EF: + break; + case 0x6F0: + break; + case 0x6F1: + break; + case 0x6F2: + break; + case 0x6F3: + break; + case 0x6F4: + break; + case 0x6F5: + break; + case 0x6F6: + break; + case 0x6F7: + break; + case 0x6F8: + break; + case 0x6F9: + break; + case 0x6FA: + break; + case 0x6FB: + break; + case 0x6FC: + break; + case 0x6FD: + break; + case 0x6FE: + break; + case 0x6FF: + break; + case 0x794: break; default: break; From a6adefdf3d11f6e48dc115381a9cc543cb82df3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 17 Sep 2024 21:44:53 +0300 Subject: [PATCH 03/93] Add SOC% candidate --- Software/src/battery/ECMP-BATTERY.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp index bb25309f..ae0ce9a8 100644 --- a/Software/src/battery/ECMP-BATTERY.cpp +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -15,10 +15,11 @@ CAN_frame ECMP_XXX = {.FD = false, .data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; static uint16_t battery_voltage = 37000; +static uint16_t battery_soc = 0; void update_values_battery() { - datalayer.battery.status.real_soc; + datalayer.battery.status.real_soc = battery_soc * 100; datalayer.battery.status.soh_pptt; @@ -73,6 +74,7 @@ void receive_can_battery(CAN_frame rx_frame) { case 0x594: break; case 0x6D0: + battery_soc = (100 - rx_frame.data.u8[0]); break; case 0x6D1: break; From 285d2798e1b5ea29b2e0813950c008f5529eadec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Thu, 19 Sep 2024 14:25:52 +0300 Subject: [PATCH 04/93] Add all 108 cellvoltages --- Software/src/battery/ECMP-BATTERY.cpp | 146 ++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 10 deletions(-) diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp index ae0ce9a8..f1ef2ea5 100644 --- a/Software/src/battery/ECMP-BATTERY.cpp +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -1,5 +1,6 @@ #include "../include.h" #ifdef ECMP_BATTERY +#include // For std::min and std::max #include "../datalayer/datalayer.h" #include "../devboard/utils/events.h" #include "ECMP-BATTERY.h" @@ -16,6 +17,7 @@ CAN_frame ECMP_XXX = {.FD = false, static uint16_t battery_voltage = 37000; static uint16_t battery_soc = 0; +static uint16_t cellvoltages[108]; void update_values_battery() { @@ -34,17 +36,29 @@ void update_values_battery() { datalayer.battery.status.max_discharge_power_W; - datalayer.battery.status.cell_max_voltage_mV; - - datalayer.battery.status.cell_min_voltage_mV; - datalayer.battery.status.temperature_min_dC; datalayer.battery.status.temperature_max_dC; - datalayer.battery.info.max_design_voltage_dV; + // Initialize min and max, lets find which cells are min and max! + uint16_t min_cell_mv_value = std::numeric_limits::max(); + uint16_t max_cell_mv_value = 0; + // Loop to find the min and max while ignoring zero values + for (uint8_t i = 0; i < datalayer.battery.info.number_of_cells; ++i) { + uint16_t voltage_mV = datalayer.battery.status.cell_voltages_mV[i]; + if (voltage_mV != 0) { // Skip unread values (0) + min_cell_mv_value = std::min(min_cell_mv_value, voltage_mV); + max_cell_mv_value = std::max(max_cell_mv_value, voltage_mV); + } + } + // If all array values are 0, reset min/max to 3700 + if (min_cell_mv_value == std::numeric_limits::max()) { + min_cell_mv_value = 3700; + max_cell_mv_value = 3700; + } - datalayer.battery.info.min_design_voltage_dV; + datalayer.battery.status.cell_min_voltage_mV = min_cell_mv_value; + datalayer.battery.status.cell_max_voltage_mV = max_cell_mv_value; } void receive_can_battery(CAN_frame rx_frame) { @@ -81,14 +95,30 @@ void receive_can_battery(CAN_frame rx_frame) { case 0x6D2: break; case 0x6D3: + cellvoltages[0] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[1] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[2] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[3] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6D4: + cellvoltages[4] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[5] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[6] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[7] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6E0: break; case 0x6E1: + cellvoltages[8] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[9] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[10] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[11] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6E2: + cellvoltages[12] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[13] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[14] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[15] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6E3: break; @@ -99,50 +129,146 @@ void receive_can_battery(CAN_frame rx_frame) { case 0x6E6: break; case 0x6E7: + cellvoltages[16] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[17] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[18] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[19] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6E8: + cellvoltages[20] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[21] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[22] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[23] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6E9: + cellvoltages[24] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[25] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[26] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[27] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6EB: + cellvoltages[28] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[29] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[30] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[31] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; + break; + case 0x6EC: + //Not available on e-C4 break; case 0x6ED: + cellvoltages[32] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[33] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[34] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[35] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6EE: + cellvoltages[36] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[37] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[38] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[39] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6EF: + cellvoltages[40] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[41] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[42] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[43] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F0: + cellvoltages[44] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[45] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[46] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[47] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F1: + cellvoltages[48] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[49] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[50] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[51] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F2: + cellvoltages[52] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[53] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[54] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[55] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F3: + cellvoltages[56] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[57] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[58] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[59] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F4: + cellvoltages[60] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[61] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[62] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[63] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F5: + cellvoltages[64] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[65] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[66] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[67] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F6: + cellvoltages[68] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[69] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[70] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[71] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F7: + cellvoltages[72] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[73] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[74] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[75] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F8: + cellvoltages[76] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[77] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[78] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[79] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6F9: + cellvoltages[80] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[81] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[82] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[83] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FA: + cellvoltages[84] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[85] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[86] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[87] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FB: + cellvoltages[88] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[89] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[90] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[91] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FC: + cellvoltages[92] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[93] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[94] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[95] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FD: + cellvoltages[96] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[97] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[98] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[99] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FE: + cellvoltages[100] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[101] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[102] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[103] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; break; case 0x6FF: + cellvoltages[104] = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + cellvoltages[105] = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + cellvoltages[106] = (rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]; + cellvoltages[107] = (rx_frame.data.u8[6] << 8) | rx_frame.data.u8[7]; + memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages, 108 * sizeof(uint16_t)); break; case 0x794: break; @@ -161,11 +287,11 @@ void send_can_battery() { void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB - Serial.println("PSA battery selected"); + Serial.println("ECMP battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 4040; // 404.0V, charging over this is not possible - datalayer.battery.info.min_design_voltage_dV = 3100; // 310.0V, under this, discharging further is disabled + datalayer.battery.info.number_of_cells = 108; + datalayer.battery.info.max_design_voltage_dV = 4546; // 454.6V, charging over this is not possible + datalayer.battery.info.min_design_voltage_dV = 3210; // 321.0V, under this, discharging further is disabled } #endif From faf22e6a4c01b20cd7726018095a90879ab9d834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 25 Nov 2024 23:05:34 +0200 Subject: [PATCH 05/93] Update SMA Tripower based on logs --- Software/Software.ino | 9 + Software/src/inverter/SMA-TRIPOWER-CAN.cpp | 373 +++++++-------------- Software/src/inverter/SMA-TRIPOWER-CAN.h | 3 + 3 files changed, 137 insertions(+), 248 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index d88ef46b..cd09171a 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -545,6 +545,10 @@ void init_contactors() { pinMode(BMS_POWER, OUTPUT); digitalWrite(BMS_POWER, HIGH); #endif //HW_STARK +#ifdef SMA_TRIPOWER_CAN + //pinMode(INVERTER_CONTACTOR_ENABLE_PIN, OUTPUT); //Incase this is an output + //digitalWrite(INVERTER_CONTACTOR_ENABLE_PIN, LOW); //Incase this is an output +#endif //SMA_TRIPOWER_CAN } void init_rs485() { @@ -742,6 +746,11 @@ void handle_contactors() { #ifdef BYD_SMA datalayer.system.status.inverter_allows_contactor_closing = digitalRead(INVERTER_CONTACTOR_ENABLE_PIN); #endif +#ifdef SMA_TRIPOWER_CAN + //set(INVERTER_CONTACTOR_ENABLE_PIN, ON); //TODO: is this an input, or an output? Figure out and make logic + datalayer.system.status.inverter_allows_contactor_closing = + digitalRead(INVERTER_CONTACTOR_ENABLE_PIN); //Incase it is input +#endif #ifdef CONTACTOR_CONTROL_DOUBLE_BATTERY handle_contactors_battery2(); diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp index 7a242dae..f6c9ea05 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp @@ -13,277 +13,146 @@ /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis500ms = 0; // will store last time a 100ms CAN Message was send +static unsigned long previousMillis2s = 0; // will store last time a 2s CAN Message was send +static unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send + +static uint32_t inverter_time = 0; +static uint16_t inverter_voltage = 0; +static int16_t inverter_current = 0; +static bool pairing_completed = false; //Actual content messages -CAN_frame SMA_00D = {.FD = false, +CAN_frame SMA_558 = {.FD = false, //Pairing first message .ext_ID = false, .DLC = 8, - .ID = 0x00D, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_00F = {.FD = false, + .ID = 0x558, // BYD HVS 10.2 kWh (0x66 might be kWh) + .data = {0x03, 0x24, 0x00, 0x04, 0x00, 0x66, 0x04, 0x09}}; //Amount of modules? Vendor ID? +CAN_frame SMA_598 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x00F, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_011 = {.FD = false, + .ID = 0x598, + .data = {0x12, 0x30, 0x8A, 0x5B, 0x00, 0x00, 0x00, 0x00}}; //B0-4 Serial? +CAN_frame SMA_5D8 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x011, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_013 = {.FD = false, + .ID = 0x5D8, + .data = {0x00, 0x42, 0x59, 0x44, 0x00, 0x00, 0x00, 0x00}}; //B Y D +CAN_frame SMA_618_0 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x618, + .data = {0x00, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79}}; //BATTERY +CAN_frame SMA_618_1 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x618, + .data = {0x01, 0x2D, 0x42, 0x6F, 0x78, 0x20, 0x50, 0x72}}; //-Box Pr +CAN_frame SMA_618_2 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x618, + .data = {0x02, 0x65, 0x6D, 0x69, 0x75, 0x6D, 0x20, 0x48}}; //emium H +CAN_frame SMA_618_3 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x618, + .data = {0x03, 0x56, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00}}; //VS +CAN_frame SMA_358 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x013, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_014 = {.FD = false, + .ID = 0x358, + .data = {0x12, 0x40, 0x0C, 0x80, 0x01, 0x00, 0x01, 0x00}}; +CAN_frame SMA_3D8 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x014, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_005 = {.FD = false, + .ID = 0x3D8, + .data = {0x04, 0x06, 0x27, 0x10, 0x00, 0x19, 0x00, 0xFA}}; +CAN_frame SMA_458 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x005, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_007 = {.FD = false, + .ID = 0x458, + .data = {0x00, 0x00, 0x73, 0xAE, 0x00, 0x00, 0x64, 0x64}}; +CAN_frame SMA_4D8 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x007, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_006 = {.FD = false, + .ID = 0x4D8, + .data = {0x10, 0x62, 0x00, 0x00, 0x00, 0x78, 0x02, 0x08}}; +CAN_frame SMA_518 = {.FD = false, .ext_ID = false, .DLC = 8, - .ID = 0x006, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_008 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x008, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_015 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x015, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_016 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x016, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_017 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x017, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; -CAN_frame SMA_018 = {.FD = false, - .ext_ID = false, - .DLC = 8, - .ID = 0x018, - .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; - -static int16_t temperature_average = 0; -static uint16_t ampere_hours_remaining = 0; -static uint16_t ampere_hours_max = 0; -static bool batteryAlarm = false; -static bool BMSevent = false; - -enum BatteryState { NA, INIT, BAT_STANDBY, OPERATE, WARNING, FAULTED, UPDATE, BAT_UPDATE }; -BatteryState batteryState = OPERATE; -enum InverterControlFlags { - EMG_CHARGE_REQUEST, - EMG_DISCHARGE_REQUEST, - NOT_ENOUGH_ENERGY_FOR_START, - INVERTER_STAY_ON, - FORCED_BATTERY_SHUTDOWN, - RESERVED, - BATTERY_UPDATE_AVAILABLE, - NO_BATTERY_UPDATED_BY_INV -}; -InverterControlFlags inverterControlFlags = BATTERY_UPDATE_AVAILABLE; -enum Events0 { - START_SOC_CALIBRATE, - STOP_SOC_CALIBRATE, - START_POWERLIMIT, - STOP_POWERLIMIT, - PREVENTATIVE_BAT_SHUTDOWN, - THERMAL_MANAGEMENT, - START_BALANCING, - STOP_BALANCING -}; -Events0 events0 = START_BALANCING; -enum Events1 { START_BATTERY_SELFTEST, STOP_BATTERY_SELFTEST }; -Events1 events1 = START_BATTERY_SELFTEST; -enum Command2Battery { IDLE, RUN, NOT_USED1, NOT_USED2, SHUTDOWN, FIRMWARE_UPDATE, BATSELFUPDATE, NOT_USED3 }; -Command2Battery command2Battery = RUN; -enum InvInitState { SYSTEM_FREQUENCY, XPHASE_SYSTEM, BLACKSTART_OPERATION }; -InvInitState invInitState = SYSTEM_FREQUENCY; + .ID = 0x518, + .data = {0x00, 0x96, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00}}; void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the inverter CAN - //Calculate values - - temperature_average = - ((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2); - - ampere_hours_remaining = - ((datalayer.battery.status.reported_remaining_capacity_Wh / datalayer.battery.status.voltage_dV) * - 100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah) - ampere_hours_max = ((datalayer.battery.info.total_capacity_Wh / datalayer.battery.status.voltage_dV) * - 100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah) - - batteryState = OPERATE; - inverterControlFlags = INVERTER_STAY_ON; //Map values to CAN messages - // Battery Limits - //Battery Max Charge Voltage (eg 400.0V = 4000 , 16bits long) - SMA_00D.data.u8[0] = (datalayer.battery.info.max_design_voltage_dV >> 8); - SMA_00D.data.u8[1] = (datalayer.battery.info.max_design_voltage_dV & 0x00FF); - //Battery Min Discharge Voltage (eg 300.0V = 3000 , 16bits long) - SMA_00D.data.u8[2] = (datalayer.battery.info.min_design_voltage_dV >> 8); - SMA_00D.data.u8[3] = (datalayer.battery.info.min_design_voltage_dV & 0x00FF); + + //Maxvoltage (eg 400.0V = 4000 , 16bits long) + SMA_358.data.u8[0] = (datalayer.battery.info.max_design_voltage_dV >> 8); + SMA_358.data.u8[1] = (datalayer.battery.info.max_design_voltage_dV & 0x00FF); + //Minvoltage (eg 300.0V = 3000 , 16bits long) + SMA_358.data.u8[2] = (datalayer.battery.info.min_design_voltage_dV >> 8); + SMA_358.data.u8[3] = (datalayer.battery.info.min_design_voltage_dV & 0x00FF); //Discharge limited current, 500 = 50A, (0.1, A) - SMA_00D.data.u8[4] = (datalayer.battery.status.max_discharge_current_dA >> 8); - SMA_00D.data.u8[5] = (datalayer.battery.status.max_discharge_current_dA & 0x00FF); + SMA_358.data.u8[4] = (datalayer.battery.status.max_discharge_current_dA >> 8); + SMA_358.data.u8[5] = (datalayer.battery.status.max_discharge_current_dA & 0x00FF); //Charge limited current, 125 =12.5A (0.1, A) - SMA_00D.data.u8[6] = (datalayer.battery.status.max_charge_current_dA >> 8); - SMA_00D.data.u8[7] = (datalayer.battery.status.max_charge_current_dA & 0x00FF); + SMA_358.data.u8[6] = (datalayer.battery.status.max_charge_current_dA >> 8); + SMA_358.data.u8[7] = (datalayer.battery.status.max_charge_current_dA & 0x00FF); - // Battery State //SOC (100.00%) - SMA_00F.data.u8[0] = (datalayer.battery.status.reported_soc >> 8); - SMA_00F.data.u8[1] = (datalayer.battery.status.reported_soc & 0x00FF); + SMA_3D8.data.u8[0] = (datalayer.battery.status.reported_soc >> 8); + SMA_3D8.data.u8[1] = (datalayer.battery.status.reported_soc & 0x00FF); //StateOfHealth (100.00%) - SMA_00F.data.u8[2] = (datalayer.battery.status.soh_pptt >> 8); - SMA_00F.data.u8[3] = (datalayer.battery.status.soh_pptt & 0x00FF); + SMA_3D8.data.u8[2] = (datalayer.battery.status.soh_pptt >> 8); + SMA_3D8.data.u8[3] = (datalayer.battery.status.soh_pptt & 0x00FF); //State of charge (AH, 0.1) - SMA_00F.data.u8[4] = (ampere_hours_remaining >> 8); - SMA_00F.data.u8[5] = (ampere_hours_remaining & 0x00FF); - //Fully charged (AH, 0.1) - SMA_00F.data.u8[6] = (ampere_hours_max >> 8); - SMA_00F.data.u8[7] = (ampere_hours_max & 0x00FF); + SMA_3D8.data.u8[4] = (ampere_hours_remaining >> 8); + SMA_3D8.data.u8[5] = (ampere_hours_remaining & 0x00FF); - // Battery Energy - //Charged Energy Counter TODO: are these needed? - //SMA_011.data.u8[0] = (X >> 8); - //SMA_011.data.u8[1] = (X & 0x00FF); - //SMA_011.data.u8[2] = (X >> 8); - //SMA_011.data.u8[3] = (X & 0x00FF); - //Discharged Energy Counter TODO: are these needed? - //SMA_011.data.u8[4] = (X >> 8); - //SMA_011.data.u8[5] = (X & 0x00FF); - //SMA_011.data.u8[6] = (X >> 8); - //SMA_011.data.u8[7] = (X & 0x00FF); - - // Battery Measurements //Voltage (370.0) - SMA_013.data.u8[0] = (datalayer.battery.status.voltage_dV >> 8); - SMA_013.data.u8[1] = (datalayer.battery.status.voltage_dV & 0x00FF); + SMA_4D8.data.u8[0] = (datalayer.battery.status.voltage_dV >> 8); + SMA_4D8.data.u8[1] = (datalayer.battery.status.voltage_dV & 0x00FF); //Current (TODO: signed OK?) - SMA_013.data.u8[2] = (datalayer.battery.status.current_dA >> 8); - SMA_013.data.u8[3] = (datalayer.battery.status.current_dA & 0x00FF); + SMA_4D8.data.u8[2] = (datalayer.battery.status.current_dA >> 8); + SMA_4D8.data.u8[3] = (datalayer.battery.status.current_dA & 0x00FF); //Temperature average - SMA_013.data.u8[4] = (temperature_average >> 8); - SMA_013.data.u8[5] = (temperature_average & 0x00FF); - //Battery state - SMA_013.data.u8[6] = batteryState; - SMA_013.data.u8[6] = inverterControlFlags; - - // Battery Temperature and Cellvoltages - // Battery max temperature - SMA_014.data.u8[0] = (datalayer.battery.status.temperature_max_dC >> 8); - SMA_014.data.u8[1] = (datalayer.battery.status.temperature_max_dC & 0x00FF); - // Battery min temperature - SMA_014.data.u8[2] = (datalayer.battery.status.temperature_min_dC >> 8); - SMA_014.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF); - // Battery Cell Voltage (sum) - //SMA_014.data.u8[4] = (??? >> 8); //TODO scaling? - //SMA_014.data.u8[5] = (??? & 0x00FF); //TODO scaling? - // Cell voltage min - //SMA_014.data.u8[6] = (??? >> 8); //TODO scaling? 0-255 - // Cell voltage max - //SMA_014.data.u8[7] = (??? >> 8); //TODO scaling? 0-255 - - //SMA_006.data.u8[0] = (ErrorCode >> 8); - //SMA_006.data.u8[1] = (ErrorCode & 0x00FF); - //SMA_006.data.u8[2] = ModuleNumber; - //SMA_006.data.u8[3] = ErrorLevel; - //SMA_008.data.u8[0] = Events0; - //SMA_008.data.u8[1] = Events1; - - //SMA_005.data.u8[0] = BMSalarms0; - //SMA_005.data.u8[1] = BMSalarms1; - //SMA_005.data.u8[2] = BMSalarms2; - //SMA_005.data.u8[3] = BMSalarms3; - //SMA_005.data.u8[4] = BMSalarms4; - //SMA_005.data.u8[5] = BMSalarms5; - //SMA_005.data.u8[6] = BMSalarms6; - //SMA_005.data.u8[7] = BMSalarms7; - - //SMA_007.data.u8[0] = DCDCalarms0; - //SMA_007.data.u8[1] = DCDCalarms1; - //SMA_007.data.u8[2] = DCDCalarms2; - //SMA_007.data.u8[3] = DCDCalarms3; - //SMA_007.data.u8[4] = DCDCwarnings0; - //SMA_007.data.u8[5] = DCDCwarnings1; - //SMA_007.data.u8[6] = DCDCwarnings2; - //SMA_007.data.u8[7] = DCDCwarnings3; - - //SMA_015.data.u8[0] = BatterySystemVersion; - //SMA_015.data.u8[1] = BatterySystemVersion; - //SMA_015.data.u8[2] = BatterySystemVersion; - //SMA_015.data.u8[3] = BatterySystemVersion; - //SMA_015.data.u8[4] = BatteryCapacity; - //SMA_015.data.u8[5] = BatteryCapacity; - //SMA_015.data.u8[6] = NumberOfModules; - //SMA_015.data.u8[7] = BatteryManufacturerID; - - //SMA_016.data.u8[0] = SerialNumber; - //SMA_016.data.u8[1] = SerialNumber; - //SMA_016.data.u8[2] = SerialNumber; - //SMA_016.data.u8[3] = SerialNumber; - //SMA_016.data.u8[4] = ManufacturingDate; - //SMA_016.data.u8[5] = ManufacturingDate; - //SMA_016.data.u8[6] = ManufacturingDate; - //SMA_016.data.u8[7] = ManufacturingDate; - - //SMA_017.data.u8[0] = Multiplex; - //SMA_017.data.u8[1] = ManufacturerName; - //SMA_017.data.u8[2] = ManufacturerName; - //SMA_017.data.u8[3] = ManufacturerName; - //SMA_017.data.u8[4] = ManufacturerName; - //SMA_017.data.u8[5] = ManufacturerName; - //SMA_017.data.u8[6] = ManufacturerName; - //SMA_017.data.u8[7] = ManufacturerName; - - //SMA_018.data.u8[0] = Multiplex; - //SMA_018.data.u8[1] = BatteryName; - //SMA_018.data.u8[2] = BatteryName; - //SMA_018.data.u8[3] = BatteryName; - //SMA_018.data.u8[4] = BatteryName; - //SMA_018.data.u8[5] = BatteryName; - //SMA_018.data.u8[6] = BatteryName; - //SMA_018.data.u8[7] = BatteryName; + SMA_4D8.data.u8[4] = (temperature_average >> 8); + SMA_4D8.data.u8[5] = (temperature_average & 0x00FF); + //Battery ready + if (datalayer.battery.status.bms_status == FAULT) { + SMA_4D8.data.u8[6] = STOP_STATE; + } else { + SMA_4D8.data.u8[6] = READY_STATE; + } } void receive_can_inverter(CAN_frame rx_frame) { switch (rx_frame.ID) { - case 0x00D: //Inverter Measurements + case 0x360: //Message originating from SMA inverter - Voltage and current + datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; + inverter_voltage = (rx_frame.data.u8[0] << 8) | rx_frame.data.u8[1]; + inverter_current = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + break; + case 0x3E0: //Message originating from SMA inverter - ? datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; break; - case 0x00F: //Inverter Feedback + case 0x420: //Message originating from SMA inverter - Timestamp + datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; + inverter_time = + (rx_frame.data.u8[0] << 24) | (rx_frame.data.u8[1] << 16) | (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]; + break; + case 0x560: //Message originating from SMA inverter - Init datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; break; - case 0x010: //Time from inverter + case 0x5E0: //Message originating from SMA inverter - String datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; + //Inverter brand (frame1-3 = 0x53 0x4D 0x41) = SMA break; - case 0x015: //Initialization message from inverter + case 0x660: //Message originating from SMA inverter - Pairing request datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; send_tripower_init(); break; - case 0x017: //Initialization message from inverter 2 - datalayer.system.status.CAN_inverter_still_alive = CAN_STILL_ALIVE; - //send_tripower_init(); - break; default: break; } @@ -292,33 +161,41 @@ void receive_can_inverter(CAN_frame rx_frame) { void send_can_inverter() { unsigned long currentMillis = millis(); - // Send CAN Message every 500ms - if (currentMillis - previousMillis500ms >= INTERVAL_500_MS) { - previousMillis500ms = currentMillis; + //TODO, should we break before pairing_completed? Or rely on Enable line? - transmit_can(&SMA_00D, can_config.inverter); //Battery limits - transmit_can(&SMA_00F, can_config.inverter); // Battery state - transmit_can(&SMA_011, can_config.inverter); // Battery Energy - transmit_can(&SMA_013, can_config.inverter); // Battery Measurements - transmit_can(&SMA_014, can_config.inverter); // Battery Temperatures and cellvoltages + // Send CAN Message every 2s + if (currentMillis - previousMillis2s >= INTERVAL_2_S) { + previousMillis2s = currentMillis; + transmit_can(&SMA_358, can_config.inverter); } - - if (batteryAlarm) { //Non-cyclic - transmit_can(&SMA_005, can_config.inverter); // Battery Alarms 1 - transmit_can(&SMA_007, can_config.inverter); // Battery Alarms 2 - } - - if (BMSevent) { //Non-cyclic - transmit_can(&SMA_006, can_config.inverter); // Battery Errorcode - transmit_can(&SMA_008, can_config.inverter); // Battery Events + // Send CAN Message every 10s + if (currentMillis - previousMillis10s >= INTERVAL_10_S) { + previousMillis10s = currentMillis; + transmit_can(&SMA_518, can_config.inverter); + transmit_can(&SMA_4D8, can_config.inverter); + transmit_can(&SMA_3D8, can_config.inverter); + if (pairing_completed) { + transmit_can( + &SMA_458, + can_config + .inverter); //TODO; not confirmed if battery sends. Transmission starts only after battery is paired + } } } - void send_tripower_init() { - transmit_can(&SMA_015, can_config.inverter); // Battery Data 1 - transmit_can(&SMA_016, can_config.inverter); // Battery Data 2 - transmit_can(&SMA_017, can_config.inverter); // Battery Manufacturer - transmit_can(&SMA_018, can_config.inverter); // Battery Name + transmit_can(&SMA_558, can_config.inverter); //Pairing start - Vendor + transmit_can(&SMA_598, can_config.inverter); //Serial + transmit_can(&SMA_5D8, can_config.inverter); //BYD + transmit_can(&SMA_618_0, can_config.inverter); //BATTERY + transmit_can(&SMA_618_1, can_config.inverter); //-Box Pr + transmit_can(&SMA_618_2, can_config.inverter); //emium H + transmit_can(&SMA_618_3, can_config.inverter); //VS + transmit_can(&SMA_358, can_config.inverter); + transmit_can(&SMA_3D8, can_config.inverter); + transmit_can(&SMA_458, can_config.inverter); + transmit_can(&SMA_4D8, can_config.inverter); + transmit_can(&SMA_518, can_config.inverter); + pairing_completed = true; } void setup_inverter(void) { // Performs one time setup at startup over CAN bus diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.h b/Software/src/inverter/SMA-TRIPOWER-CAN.h index 90967001..2645efce 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.h +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.h @@ -4,6 +4,9 @@ #define CAN_INVERTER_SELECTED +#define READY_STATE 0x03 +#define STOP_STATE 0x02 + void send_tripower_init(); void transmit_can(CAN_frame* tx_frame, int interface); void setup_inverter(void); From ab755aa9131f16dc5e7d718c89ed0443eb4231f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 25 Nov 2024 23:17:53 +0200 Subject: [PATCH 06/93] Add missing value mappings --- Software/src/inverter/SMA-TRIPOWER-CAN.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp index f6c9ea05..777f1f3e 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp @@ -20,6 +20,8 @@ static uint32_t inverter_time = 0; static uint16_t inverter_voltage = 0; static int16_t inverter_current = 0; static bool pairing_completed = false; +static int16_t temperature_average = 0; +static uint16_t ampere_hours_remaining = 0; //Actual content messages CAN_frame SMA_558 = {.FD = false, //Pairing first message @@ -84,7 +86,15 @@ CAN_frame SMA_518 = {.FD = false, .data = {0x00, 0x96, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00}}; void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the inverter CAN + // Update values + temperature_average = + ((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2); + if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0 + ampere_hours_remaining = + ((datalayer.battery.status.reported_remaining_capacity_Wh / datalayer.battery.status.voltage_dV) * + 100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah) + } //Map values to CAN messages //Maxvoltage (eg 400.0V = 4000 , 16bits long) 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 07/93] 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 d411b0a875812da642fb23d188734d807818f8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 1 Dec 2024 14:40:19 +0200 Subject: [PATCH 08/93] Change enable line logic --- Software/Software.ino | 11 +---------- Software/src/inverter/SMA-TRIPOWER-CAN.cpp | 5 ++++- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index cd09171a..5374625a 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -545,10 +545,6 @@ void init_contactors() { pinMode(BMS_POWER, OUTPUT); digitalWrite(BMS_POWER, HIGH); #endif //HW_STARK -#ifdef SMA_TRIPOWER_CAN - //pinMode(INVERTER_CONTACTOR_ENABLE_PIN, OUTPUT); //Incase this is an output - //digitalWrite(INVERTER_CONTACTOR_ENABLE_PIN, LOW); //Incase this is an output -#endif //SMA_TRIPOWER_CAN } void init_rs485() { @@ -743,14 +739,9 @@ void check_interconnect_available() { #endif //DOUBLE_BATTERY void handle_contactors() { -#ifdef BYD_SMA +#if defined(BYD_SMA) || defined(SMA_TRIPOWER_CAN) datalayer.system.status.inverter_allows_contactor_closing = digitalRead(INVERTER_CONTACTOR_ENABLE_PIN); #endif -#ifdef SMA_TRIPOWER_CAN - //set(INVERTER_CONTACTOR_ENABLE_PIN, ON); //TODO: is this an input, or an output? Figure out and make logic - datalayer.system.status.inverter_allows_contactor_closing = - digitalRead(INVERTER_CONTACTOR_ENABLE_PIN); //Incase it is input -#endif #ifdef CONTACTOR_CONTROL_DOUBLE_BATTERY handle_contactors_battery2(); diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp index 777f1f3e..1296cbe7 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp @@ -171,7 +171,10 @@ void receive_can_inverter(CAN_frame rx_frame) { void send_can_inverter() { unsigned long currentMillis = millis(); - //TODO, should we break before pairing_completed? Or rely on Enable line? + // Send CAN Message only if we're enabled by inverter + if (!datalayer.system.status.inverter_allows_contactor_closing) { + return; + } // Send CAN Message every 2s if (currentMillis - previousMillis2s >= INTERVAL_2_S) { 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 09/93] 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 10/93] 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 11/93] 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 12/93] 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 13/93] 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 14/93] 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 15/93] 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 16/93] 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 17/93] 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 320c58a22eaa3a99611bbec5881c009440223610 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:47:24 +1300 Subject: [PATCH 18/93] Update TESLA-BATTERY.cpp Update all CAN ID's battery is sending, reorganize and add comments for reference. Change names to match DBC files. Need to update DOUBLE BATTERY. --- Software/src/battery/TESLA-BATTERY.cpp | 1014 ++++++++++++++++++++++-- 1 file changed, 926 insertions(+), 88 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index f6db10a8..dd1273a1 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -8,7 +8,7 @@ /* Do not change code below unless you are sure what you are doing */ /* Credits: Most of the code comes from Per Carlen's bms_comms_tesla_model3.py (https://gitlab.com/pelle8/batt2gen24/) */ -static unsigned long previousMillis30 = 0; // will store last time a 30ms CAN Message was send +static unsigned long previousMillis50 = 0; // will store last time a 30ms CAN Message was send CAN_frame TESLA_221_1 = { .FD = false, @@ -22,14 +22,16 @@ CAN_frame TESLA_221_2 = { .DLC = 8, .ID = 0x221, .data = {0x61, 0x15, 0x01, 0x00, 0x00, 0x00, 0x20, 0xBA}}; //Contactor Frame 221 - hv_up_for_drive + + static uint16_t sendContactorClosingMessagesStill = 300; +static uint16_t battery_cell_max_v = 3700; +static uint16_t battery_cell_min_v = 3700; +static uint16_t battery_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV +//0x3d2: 978 BMS_kwhCounter static uint32_t battery_total_discharge = 0; static uint32_t battery_total_charge = 0; -static uint16_t battery_volts = 0; // V -static int16_t battery_amps = 0; // A -static uint16_t battery_raw_amps = 0; // A -static int16_t battery_max_temp = 0; // C* -static int16_t battery_min_temp = 0; // C* +//0x352: 850 BMS_energyStatus static uint16_t battery_energy_buffer = 0; // kWh static uint16_t battery_energy_buffer_m1 = 0; // kWh static uint16_t battery_energy_to_charge_complete = 0; // kWh @@ -44,29 +46,50 @@ static uint16_t battery_nominal_energy_remaining = 0; // kWh static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_full_pack_energy = 600; // Kwh static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh -static uint16_t battery_beginning_of_life = 600; // kWh +//0x132 306 HVBattAmpVolt +static uint16_t battery_volts = 0; // V +static int16_t battery_amps = 0; // A +static uint16_t battery_raw_amps = 0; // A static uint16_t battery_charge_time_remaining = 0; // Minutes -static uint16_t battery_regenerative_limit = 0; -static uint16_t battery_discharge_limit = 0; -static uint16_t battery_max_heat_park = 0; -static uint16_t battery_hvac_max_power = 0; +//0x252 594 BMS_powerAvailable +static uint16_t BMS_regenerative_limit = 0; //rename from battery_regenerative_limit +static uint16_t BMS_discharge_limit = 0; // rename from battery_discharge_limit +static uint16_t BMS_max_heat_park = 0; //rename from battery_max_heat_park +static uint16_t BMS_hvac_max_power = 0; //rename from battery_hvac_max_power +//0x2d2: 722 BMSVAlimits static uint16_t battery_max_discharge_current = 0; static uint16_t battery_max_charge_current = 0; static uint16_t battery_bms_max_voltage = 0; static uint16_t battery_bms_min_voltage = 0; +//0x2b4: 692 PCS_dcdcRailStatus static uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt static uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt -static uint16_t battery_dcdcLvOutputCurrent = - 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent +static uint16_t battery_dcdcLvOutputCurrent = 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent +//0x292: 658 BMS_socStatus +static uint16_t battery_beginning_of_life = 600; // kWh static uint16_t battery_soc_min = 0; static uint16_t battery_soc_max = 0; static uint16_t battery_soc_ui = 0; //Change name from battery_soc_vi to reflect DBC battery_soc_ui static uint16_t battery_soc_ave = 0; -static uint16_t battery_cell_max_v = 3700; -static uint16_t battery_cell_min_v = 3700; -static uint16_t battery_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV -static uint8_t battery_max_vno = 0; -static uint8_t battery_min_vno = 0; +static uint8_t battery_battTempPct = 0; +//0x392: BMS_packConfig +static uint32_t battery_packMass = 0; +static uint32_t battery_platformMaxBusVoltage = 0; +static uint32_t battery_packConfigMultiplexer = 0; +static uint32_t battery_moduleType = 0; +static uint32_t battery_reservedConfig = 0; +//0x332: 818 BattBrickMinMax:BMS_bmbMinMax +static int16_t battery_max_temp = 0; // C* +static int16_t battery_min_temp = 0; // C* +static uint16_t battery_BrickVoltageMax = 0; +static uint16_t battery_BrickVoltageMin = 0; +static uint8_t battery_BrickTempMaxNum = 0; +static uint8_t battery_BrickTempMinNum = 0; +static uint8_t battery_BrickModelTMax = 0; +static uint8_t battery_BrickModelTMin = 0; +static uint8_t battery_BrickVoltageMaxNum = 0; //rename from battery_max_vno +static uint8_t battery_BrickVoltageMinNum = 0; //rename from battery_min_vno +//0x20A: 522 HVP_contactorState static uint8_t battery_contactor = 0; //State of contactor static uint8_t battery_hvil_status = 0; static uint8_t battery_packContNegativeState = 0; @@ -74,13 +97,159 @@ static uint8_t battery_packContPositiveState = 0; static uint8_t battery_packContactorSetState = 0; static uint8_t battery_packCtrsClosingAllowed = 0; static uint8_t battery_pyroTestInProgress = 0; -static uint8_t battery_battTempPct = 0; -static uint32_t battery_packMass = 0; -static uint32_t battery_platformMaxBusVoltage = 0; -static uint32_t battery_packConfigMultiplexer = 0; -static uint32_t battery_moduleType = 0; -static uint32_t battery_reservedConfig = 0; -//Fault codes +static uint8_t battery_packCtrsOpenNowRequested = 0; +static uint8_t battery_packCtrsOpenRequested = 0; +static uint8_t battery_packCtrsRequestStatus = 0; +static uint8_t battery_packCtrsResetRequestRequired = 0; +static uint8_t battery_dcLinkAllowedToEnergize = 0; +static uint8_t battery_fcContNegativeAuxOpen = 0; +static uint8_t battery_fcContNegativeState = 0; +static uint8_t battery_fcContPositiveAuxOpen = 0; +static uint8_t battery_fcContPositiveState = 0; +static uint8_t battery_fcContactorSetState = 0; +static uint8_t battery_fcCtrsClosingAllowed = 0; +static uint8_t battery_fcCtrsOpenNowRequested = 0; +static uint8_t battery_fcCtrsOpenRequested = 0; +static uint8_t battery_fcCtrsRequestStatus = 0; +static uint8_t battery_fcCtrsResetRequestRequired = 0; +static uint8_t battery_fcLinkAllowedToEnergize = 0; +//0x212: 530 BMS_status +static uint8_t battery_BMS_hvacPowerRequest = 0; +static uint8_t battery_BMS_notEnoughPowerForDrive = 0; +static uint8_t battery_BMS_notEnoughPowerForSupport = 0; +static uint8_t battery_BMS_preconditionAllowed = 0; +static uint8_t battery_BMS_updateAllowed = 0; +static uint8_t battery_BMS_activeHeatingWorthwhile = 0; +static uint8_t battery_BMS_cpMiaOnHvs = 0; +static uint8_t battery_BMS_contactorState = 0; +static uint8_t battery_BMS_state = 0; +static uint8_t battery_BMS_hvState = 0; +static uint16_t battery_BMS_isolationResistance = 0; +static uint8_t battery_BMS_chargeRequest = 0; +static uint8_t battery_BMS_keepWarmRequest = 0; +static uint8_t battery_BMS_uiChargeStatus = 0; +static uint8_t battery_BMS_diLimpRequest = 0; +static uint8_t battery_BMS_okToShipByAir = 0; +static uint8_t battery_BMS_okToShipByLand = 0; +static uint32_t battery_BMS_chgPowerAvailable = 0; +static uint8_t battery_BMS_chargeRetryCount = 0; +static uint8_t battery_BMS_pcsPwmEnabled = 0; +static uint8_t battery_BMS_ecuLogUploadRequest = 0; +static uint8_t battery_BMS_minPackTemperature = 0; +// 0x224:548 PCS_dcdcStatus +static uint8_t battery_PCS_dcdcPrechargeStatus = 0; +static uint8_t battery_PCS_dcdc12VSupportStatus = 0; +static uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; +static uint16_t battery_PCS_dcdcMainState = 0; +static uint8_t battery_PCS_dcdcSubState = 0; +static uint8_t battery_PCS_dcdcFaulted = 0; +static uint8_t battery_PCS_dcdcOutputIsLimited = 0; +static uint32_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; +static uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; +static uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0; +static uint8_t battery_PCS_dcdcDischargeRtyCnt = 0; +static uint8_t battery_PCS_dcdcPwmEnableLine = 0; +static uint8_t battery_PCS_dcdcSupportingFixedLvTarget = 0; +static uint8_t battery_PCS_ecuLogUploadRequest = 0; +static uint8_t battery_PCS_dcdcPrechargeRestartCnt = 0; +static uint8_t battery_PCS_dcdcInitialPrechargeSubState = 0; +//0x312: 786 BMS_thermalStatus +static uint16_t BMS_powerDissipation = 0; +static uint16_t BMS_flowRequest = 0; +static uint16_t BMS_inletActiveCoolTargetT = 0; +static uint16_t BMS_inletPassiveTargetT = 0; +static uint16_t BMS_inletActiveHeatTargetT = 0; +static uint16_t BMS_packTMin = 0; +static uint16_t BMS_packTMax = 0; +static uint16_t BMS_pcsNoFlowRequest = 0; +static uint16_t BMS_noFlowRequest = 0; +//0x2A4; 676 PCS_thermalStatus +static uint16_t PCS_chgPhATemp = 0; +static uint16_t PCS_chgPhBTemp = 0; +static uint16_t PCS_chgPhCTemp = 0; +static uint16_t PCS_dcdcTemp = 0; +static uint16_t PCS_ambientTemp = 0; +//0x2C4; 708 PCS_logging +static uint16_t PCS_logMessageSelect = 0; +static uint16_t PCS_dcdcMaxLvOutputCurrent = 0; +static uint16_t PCS_dcdcCurrentLimit = 0; +static uint16_t PCS_dcdcLvOutputCurrentTempLimit = 0; +static uint16_t PCS_dcdcUnifiedCommand = 0; +static uint16_t PCS_dcdcCLAControllerOutput = 0; +static uint16_t PCS_dcdcTankVoltage = 0; +static uint16_t PCS_dcdcTankVoltageTarget = 0; +static uint16_t PCS_dcdcClaCurrentFreq = 0; +static uint16_t PCS_dcdcTCommMeasured = 0; +static uint16_t PCS_dcdcShortTimeUs = 0; +static uint16_t PCS_dcdcHalfPeriodUs = 0; +static uint16_t PCS_dcdcIntervalMaxFrequency = 0; +static uint16_t PCS_dcdcIntervalMaxHvBusVolt = 0; +static uint16_t PCS_dcdcIntervalMaxLvBusVolt = 0; +static uint16_t PCS_dcdcIntervalMaxLvOutputCurr = 0; +static uint16_t PCS_dcdcIntervalMinFrequency = 0; +static uint16_t PCS_dcdcIntervalMinHvBusVolt = 0; +static uint16_t PCS_dcdcIntervalMinLvBusVolt = 0; +static uint16_t PCS_dcdcIntervalMinLvOutputCurr = 0; +static uint32_t PCS_dcdc12vSupportLifetimekWh = 0; +//0x7AA: //1962 HVP_debugMessage: +static uint8_t HVP_debugMessageMultiplexer = 0; +static uint8_t HVP_gpioPassivePyroDepl = 0; +static uint8_t HVP_gpioPyroIsoEn = 0; +static uint8_t HVP_gpioCpFaultIn = 0; +static uint8_t HVP_gpioPackContPowerEn = 0; +static uint8_t HVP_gpioHvCablesOk = 0; +static uint8_t HVP_gpioHvpSelfEnable = 0; +static uint8_t HVP_gpioLed = 0; +static uint8_t HVP_gpioCrashSignal = 0; +static uint8_t HVP_gpioShuntDataReady = 0; +static uint8_t HVP_gpioFcContPosAux = 0; +static uint8_t HVP_gpioFcContNegAux = 0; +static uint8_t HVP_gpioBmsEout = 0; +static uint8_t HVP_gpioCpFaultOut = 0; +static uint8_t HVP_gpioPyroPor = 0; +static uint8_t HVP_gpioShuntEn = 0; +static uint8_t HVP_gpioHvpVerEn = 0; +static uint8_t HVP_gpioPackCoontPosFlywheel = 0; +static uint8_t HVP_gpioCpLatchEnable = 0; +static uint8_t HVP_gpioPcsEnable = 0; +static uint8_t HVP_gpioPcsDcdcPwmEnable = 0; +static uint8_t HVP_gpioPcsChargePwmEnable = 0; +static uint8_t HVP_gpioFcContPowerEnable = 0; +static uint8_t HVP_gpioHvilEnable = 0; +static uint8_t HVP_gpioSecDrdy = 0; +static uint16_t HVP_hvp1v5Ref = 0; +static uint16_t HVP_shuntCurrentDebug = 0; +static uint8_t HVP_packCurrentMia = 0; +static uint8_t HVP_auxCurrentMia = 0; +static uint8_t HVP_currentSenseMia = 0; +static uint8_t HVP_shuntRefVoltageMismatch = 0; +static uint8_t HVP_shuntThermistorMia = 0; +static uint8_t HVP_shuntHwMia = 0; +static uint16_t HVP_dcLinkVoltage = 0; +static uint16_t HVP_packVoltage = 0; +static uint16_t HVP_fcLinkVoltage = 0; +static uint16_t HVP_packContVoltage = 0; +static uint16_t HVP_packNegativeV = 0; +static uint16_t HVP_packPositiveV = 0; +static uint16_t HVP_pyroAnalog = 0; +static uint16_t HVP_dcLinkNegativeV = 0; +static uint16_t HVP_dcLinkPositiveV = 0; +static uint16_t HVP_fcLinkNegativeV = 0; +static uint16_t HVP_fcContCoilCurrent = 0; +static uint16_t HVP_fcContVoltage = 0; +static uint16_t HVP_hvilInVoltage = 0; +static uint16_t HVP_hvilOutVoltage = 0; +static uint16_t HVP_fcLinkPositiveV = 0; +static uint16_t HVP_packContCoilCurrent = 0; +static uint16_t HVP_battery12V = 0; +static uint16_t HVP_shuntRefVoltageDbg = 0; +static uint16_t HVP_shuntAuxCurrentDbg = 0; +static uint16_t HVP_shuntBarTempDbg = 0; +static uint16_t HVP_shuntAsicTempDbg = 0; +static uint8_t HVP_shuntAuxCurrentStatus = 0; +static uint8_t HVP_shuntBarTempStatus = 0; +static uint8_t HVP_shuntAsicTempStatus = 0; +//0x3aa: HVP_alertMatrix1 Fault codes static uint8_t battery_WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset. static uint8_t battery_PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss. static uint8_t battery_SwAssertion = 0; //An internal software assertion has failed. @@ -139,8 +308,102 @@ static uint8_t battery_logUploadRequest = 0; static uint8_t battery_packCtrCloseFailed = 0; static uint8_t battery_fcCtrCloseFailed = 0; static uint8_t battery_shuntThermistorMia = 0; +//0x320: 800 BMS_alertMatrix +static uint8_t battery_BMS_matrixIndex = 4; +static uint8_t battery_BMS_a061_robinBrickOverVoltage = 1; +static uint8_t battery_BMS_a062_SW_BrickV_Imbalance = 1; +static uint8_t battery_BMS_a063_SW_ChargePort_Fault = 1; +static uint8_t battery_BMS_a064_SW_SOC_Imbalance = 1; +static uint8_t battery_BMS_a127_SW_shunt_SNA = 1; +static uint8_t battery_BMS_a128_SW_shunt_MIA = 1; +static uint8_t battery_BMS_a069_SW_Low_Power = 1; +static uint8_t battery_BMS_a130_IO_CAN_Error = 1; +static uint8_t battery_BMS_a071_SW_SM_TransCon_Not_Met = 1; +static uint8_t battery_BMS_a132_HW_BMB_OTP_Uncorrctbl = 1; +static uint8_t battery_BMS_a134_SW_Delayed_Ctr_Off = 1; +static uint8_t battery_BMS_a075_SW_Chg_Disable_Failure = 1; +static uint8_t battery_BMS_a076_SW_Dch_While_Charging = 1; +static uint8_t battery_BMS_a017_SW_Brick_OV = 1; +static uint8_t battery_BMS_a018_SW_Brick_UV = 1; +static uint8_t battery_BMS_a019_SW_Module_OT = 1; +static uint8_t battery_BMS_a021_SW_Dr_Limits_Regulation = 1; +static uint8_t battery_BMS_a022_SW_Over_Current = 1; +static uint8_t battery_BMS_a023_SW_Stack_OV = 1; +static uint8_t battery_BMS_a024_SW_Islanded_Brick = 1; +static uint8_t battery_BMS_a025_SW_PwrBalance_Anomaly = 1; +static uint8_t battery_BMS_a026_SW_HFCurrent_Anomaly = 1; +static uint8_t battery_BMS_a087_SW_Feim_Test_Blocked = 1; +static uint8_t battery_BMS_a088_SW_VcFront_MIA_InDrive = 1; +static uint8_t battery_BMS_a089_SW_VcFront_MIA = 1; +static uint8_t battery_BMS_a090_SW_Gateway_MIA = 1; +static uint8_t battery_BMS_a091_SW_ChargePort_MIA = 1; +static uint8_t battery_BMS_a092_SW_ChargePort_Mia_On_Hv = 1; +static uint8_t battery_BMS_a034_SW_Passive_Isolation = 1; +static uint8_t battery_BMS_a035_SW_Isolation = 1; +static uint8_t battery_BMS_a036_SW_HvpHvilFault = 1; +static uint8_t battery_BMS_a037_SW_Flood_Port_Open = 1; +static uint8_t battery_BMS_a158_SW_HVP_HVI_Comms = 1; +static uint8_t battery_BMS_a039_SW_DC_Link_Over_Voltage = 1; +static uint8_t battery_BMS_a041_SW_Power_On_Reset = 1; +static uint8_t battery_BMS_a042_SW_MPU_Error = 1; +static uint8_t battery_BMS_a043_SW_Watch_Dog_Reset = 1; +static uint8_t battery_BMS_a044_SW_Assertion = 1; +static uint8_t battery_BMS_a045_SW_Exception = 1; +static uint8_t battery_BMS_a046_SW_Task_Stack_Usage = 1; +static uint8_t battery_BMS_a047_SW_Task_Stack_Overflow = 1; +static uint8_t battery_BMS_a048_SW_Log_Upload_Request = 1; +static uint8_t battery_BMS_a169_SW_FC_Pack_Weld = 1; +static uint8_t battery_BMS_a050_SW_Brick_Voltage_MIA = 1; +static uint8_t battery_BMS_a051_SW_HVC_Vref_Bad = 1; +static uint8_t battery_BMS_a052_SW_PCS_MIA = 1; +static uint8_t battery_BMS_a053_SW_ThermalModel_Sanity = 1; +static uint8_t battery_BMS_a054_SW_Ver_Supply_Fault = 1; +static uint8_t battery_BMS_a176_SW_GracefulPowerOff = 1; +static uint8_t battery_BMS_a059_SW_Pack_Voltage_Sensing = 1; +static uint8_t battery_BMS_a060_SW_Leakage_Test_Failure = 1; +static uint8_t battery_BMS_a077_SW_Charger_Regulation = 1; +static uint8_t battery_BMS_a081_SW_Ctr_Close_Blocked = 1; +static uint8_t battery_BMS_a082_SW_Ctr_Force_Open = 1; +static uint8_t battery_BMS_a083_SW_Ctr_Close_Failure = 1; +static uint8_t battery_BMS_a084_SW_Sleep_Wake_Aborted = 1; +static uint8_t battery_BMS_a094_SW_Drive_Inverter_MIA = 1; +static uint8_t battery_BMS_a099_SW_BMB_Communication = 1; +static uint8_t battery_BMS_a105_SW_One_Module_Tsense = 1; +static uint8_t battery_BMS_a106_SW_All_Module_Tsense = 1; +static uint8_t battery_BMS_a107_SW_Stack_Voltage_MIA = 1; +static uint8_t battery_BMS_a121_SW_NVRAM_Config_Error = 1; +static uint8_t battery_BMS_a122_SW_BMS_Therm_Irrational = 1; +static uint8_t battery_BMS_a123_SW_Internal_Isolation = 1; +static uint8_t battery_BMS_a129_SW_VSH_Failure = 1; +static uint8_t battery_BMS_a131_Bleed_FET_Failure = 1; +static uint8_t battery_BMS_a136_SW_Module_OT_Warning = 1; +static uint8_t battery_BMS_a137_SW_Brick_UV_Warning = 1; +static uint8_t battery_BMS_a138_SW_Brick_OV_Warning = 1; +static uint8_t battery_BMS_a139_SW_DC_Link_V_Irrational = 1; +static uint8_t battery_BMS_a141_SW_BMB_Status_Warning = 1; +static uint8_t battery_BMS_a144_Hvp_Config_Mismatch = 1; +static uint8_t battery_BMS_a145_SW_SOC_Change = 1; +static uint8_t battery_BMS_a146_SW_Brick_Overdischarged = 1; +static uint8_t battery_BMS_a149_SW_Missing_Config_Block = 1; +static uint8_t battery_BMS_a151_SW_external_isolation = 1; +static uint8_t battery_BMS_a156_SW_BMB_Vref_bad = 1; +static uint8_t battery_BMS_a157_SW_HVP_HVS_Comms = 1; +static uint8_t battery_BMS_a159_SW_HVP_ECU_Error = 1; +static uint8_t battery_BMS_a161_SW_DI_Open_Request = 1; +static uint8_t battery_BMS_a162_SW_No_Power_For_Support = 1; +static uint8_t battery_BMS_a163_SW_Contactor_Mismatch = 1; +static uint8_t battery_BMS_a164_SW_Uncontrolled_Regen = 1; +static uint8_t battery_BMS_a165_SW_Pack_Partial_Weld = 1; +static uint8_t battery_BMS_a166_SW_Pack_Full_Weld = 1; +static uint8_t battery_BMS_a167_SW_FC_Partial_Weld = 1; +static uint8_t battery_BMS_a168_SW_FC_Full_Weld = 1; +static uint8_t battery_BMS_a170_SW_Limp_Mode = 1; +static uint8_t battery_BMS_a171_SW_Stack_Voltage_Sense = 1; +static uint8_t battery_BMS_a174_SW_Charge_Failure = 1; +static uint8_t battery_BMS_a179_SW_Hvp_12V_Fault = 1; +static uint8_t battery_BMS_a180_SW_ECU_reset_blocked = 1; -#ifdef DOUBLE_BATTERY +#ifdef DOUBLE_BATTERY //need to update for battery2 static uint32_t battery2_total_discharge = 0; static uint32_t battery2_total_charge = 0; static uint16_t battery2_volts = 0; // V @@ -368,6 +631,7 @@ void update_values_battery() { //This function maps all the values fetched via #endif // TESLA_MODEL_3Y_BATTERY // Update webserver datalayer + //0x20A datalayer_extended.tesla.status_contactor = battery_contactor; datalayer_extended.tesla.hvil_status = battery_hvil_status; datalayer_extended.tesla.packContNegativeState = battery_packContNegativeState; @@ -375,11 +639,16 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.packContactorSetState = battery_packContactorSetState; datalayer_extended.tesla.packCtrsClosingAllowed = battery_packCtrsClosingAllowed; datalayer_extended.tesla.pyroTestInProgress = battery_pyroTestInProgress; - datalayer_extended.tesla.battery_beginning_of_life = battery_beginning_of_life; //add from her down - datalayer_extended.tesla.battery_battTempPct = battery_battTempPct; + datalayer_extended.tesla.battery_packCtrsOpenNowRequested = battery_packCtrsOpenNowRequested; + datalayer_extended.tesla.battery_packCtrsOpenRequested = battery_packCtrsOpenRequested; + datalayer_extended.tesla.battery_packCtrsRequestStatus = battery_packCtrsRequestStatus; + datalayer_extended.tesla.battery_packCtrsResetRequestRequired = battery_packCtrsResetRequestRequired; + datalayer_extended.tesla.battery_dcLinkAllowedToEnergize = battery_dcLinkAllowedToEnergize; + //0x2B4 datalayer_extended.tesla.battery_dcdcLvBusVolt = battery_dcdcLvBusVolt; datalayer_extended.tesla.battery_dcdcHvBusVolt = battery_dcdcHvBusVolt; datalayer_extended.tesla.battery_dcdcLvOutputCurrent = battery_dcdcLvOutputCurrent; + //0x352 datalayer_extended.tesla.battery_nominal_full_pack_energy = battery_nominal_full_pack_energy; datalayer_extended.tesla.battery_nominal_full_pack_energy_m0 = battery_nominal_full_pack_energy_m0; datalayer_extended.tesla.battery_nominal_energy_remaining = battery_nominal_energy_remaining; @@ -394,19 +663,120 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.battery_total_discharge = battery_total_discharge; datalayer_extended.tesla.battery_total_charge = battery_total_charge; datalayer_extended.tesla.battery_fully_charged = battery_fully_charged; - datalayer_extended.tesla.battery_packConfigMultiplexer = battery_packConfigMultiplexer; + //0x392 datalayer_extended.tesla.battery_moduleType = battery_moduleType; - datalayer_extended.tesla.battery_reservedConfig = battery_reservedConfig; datalayer_extended.tesla.battery_packMass = battery_packMass; datalayer_extended.tesla.battery_platformMaxBusVoltage = battery_platformMaxBusVoltage; + //0x2D2 datalayer_extended.tesla.battery_bms_min_voltage = battery_bms_min_voltage; datalayer_extended.tesla.battery_bms_max_voltage = battery_bms_max_voltage; datalayer_extended.tesla.battery_max_charge_current = battery_max_charge_current; datalayer_extended.tesla.battery_max_discharge_current = battery_max_discharge_current; + //0x292 + datalayer_extended.tesla.battery_beginning_of_life = battery_beginning_of_life; + datalayer_extended.tesla.battery_battTempPct = battery_battTempPct; datalayer_extended.tesla.battery_soc_ave = battery_soc_ave; datalayer_extended.tesla.battery_soc_max = battery_soc_max; datalayer_extended.tesla.battery_soc_min = battery_soc_min; datalayer_extended.tesla.battery_soc_ui = battery_soc_ui; + //0x332 + datalayer_extended.tesla.battery_BrickVoltageMax = battery_BrickVoltageMax; + datalayer_extended.tesla.battery_BrickVoltageMin = battery_BrickVoltageMin; + datalayer_extended.tesla.battery_BrickTempMaxNum = battery_BrickTempMaxNum; + datalayer_extended.tesla.battery_BrickTempMinNum = battery_BrickTempMinNum; + datalayer_extended.tesla.battery_BrickModelTMax = battery_BrickModelTMax; + datalayer_extended.tesla.battery_BrickModelTMin = battery_BrickModelTMin; + //0x212 + datalayer_extended.tesla.battery_BMS_isolationResistance = battery_BMS_isolationResistance; + datalayer_extended.tesla.battery_BMS_contactorState = battery_BMS_contactorState; + datalayer_extended.tesla.battery_BMS_state = battery_BMS_state; + datalayer_extended.tesla.battery_BMS_hvState = battery_BMS_hvState; + datalayer_extended.tesla.battery_BMS_uiChargeStatus = battery_BMS_uiChargeStatus; + datalayer_extended.tesla.battery_BMS_diLimpRequest = battery_BMS_diLimpRequest; + datalayer_extended.tesla.battery_BMS_chgPowerAvailable = battery_BMS_chgPowerAvailable; + datalayer_extended.tesla.battery_BMS_pcsPwmEnabled = battery_BMS_pcsPwmEnabled; + //0x224 + datalayer_extended.tesla.battery_PCS_dcdcPrechargeStatus = battery_PCS_dcdcPrechargeStatus; + datalayer_extended.tesla.battery_PCS_dcdc12VSupportStatus = battery_PCS_dcdc12VSupportStatus; + datalayer_extended.tesla.battery_PCS_dcdcHvBusDischargeStatus = battery_PCS_dcdcHvBusDischargeStatus; + datalayer_extended.tesla.battery_PCS_dcdcMainState = battery_PCS_dcdcMainState; + datalayer_extended.tesla.battery_PCS_dcdcSubState = battery_PCS_dcdcSubState; + datalayer_extended.tesla.battery_PCS_dcdcFaulted = battery_PCS_dcdcFaulted; + datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited = battery_PCS_dcdcOutputIsLimited; + datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed = battery_PCS_dcdcMaxOutputCurrentAllowed; + datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt = battery_PCS_dcdcPrechargeRtyCnt; + datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt = battery_PCS_dcdc12VSupportRtyCnt; + datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt = battery_PCS_dcdcDischargeRtyCnt; + datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine = battery_PCS_dcdcPwmEnableLine; + datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget = battery_PCS_dcdcSupportingFixedLvTarget; + datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt = battery_PCS_dcdcPrechargeRestartCnt; + datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState = battery_PCS_dcdcInitialPrechargeSubState; + //0x252 + datalayer_extended.tesla.BMS_regenerative_limit = BMS_regenerative_limit; + datalayer_extended.tesla.BMS_discharge_limit = BMS_discharge_limit; + datalayer_extended.tesla.BMS_max_heat_park = BMS_max_heat_park; + datalayer_extended.tesla.BMS_hvac_max_power = BMS_hvac_max_power; + //0x312 + datalayer_extended.tesla.BMS_powerDissipation = BMS_powerDissipation; + datalayer_extended.tesla.BMS_flowRequest = BMS_flowRequest; + datalayer_extended.tesla.BMS_inletActiveCoolTargetT = BMS_inletActiveCoolTargetT; + datalayer_extended.tesla.BMS_inletPassiveTargetT = BMS_inletPassiveTargetT; + datalayer_extended.tesla.BMS_inletActiveHeatTargetT = BMS_inletActiveHeatTargetT; + datalayer_extended.tesla.BMS_packTMin = BMS_packTMin; + datalayer_extended.tesla.BMS_packTMax = BMS_packTMax; + datalayer_extended.tesla.BMS_pcsNoFlowRequest = BMS_pcsNoFlowRequest; + datalayer_extended.tesla.BMS_noFlowRequest = BMS_noFlowRequest; + //0x2A4 + datalayer_extended.tesla.PCS_dcdcTemp = PCS_dcdcTemp; + datalayer_extended.tesla.PCS_ambientTemp = PCS_ambientTemp; + //0x2C4 + datalayer_extended.tesla.PCS_dcdcMaxLvOutputCurrent = PCS_dcdcMaxLvOutputCurrent; + datalayer_extended.tesla.PCS_dcdcCurrentLimit = PCS_dcdcCurrentLimit; + datalayer_extended.tesla.PCS_dcdcLvOutputCurrentTempLimit = PCS_dcdcLvOutputCurrentTempLimit; + datalayer_extended.tesla.PCS_dcdcUnifiedCommand = PCS_dcdcUnifiedCommand; + datalayer_extended.tesla.PCS_dcdcCLAControllerOutput = PCS_dcdcCLAControllerOutput; + datalayer_extended.tesla.PCS_dcdcTankVoltage = PCS_dcdcTankVoltage; + datalayer_extended.tesla.PCS_dcdcTankVoltageTarget = PCS_dcdcTankVoltageTarget; + datalayer_extended.tesla.PCS_dcdcClaCurrentFreq = PCS_dcdcClaCurrentFreq; + datalayer_extended.tesla.PCS_dcdcTCommMeasured = PCS_dcdcTCommMeasured; + datalayer_extended.tesla.PCS_dcdcShortTimeUs = PCS_dcdcShortTimeUs; + datalayer_extended.tesla.PCS_dcdcHalfPeriodUs = PCS_dcdcHalfPeriodUs; + datalayer_extended.tesla.PCS_dcdcIntervalMaxFrequency = PCS_dcdcIntervalMaxFrequency; + datalayer_extended.tesla.PCS_dcdcIntervalMaxHvBusVolt = PCS_dcdcIntervalMaxHvBusVolt; + datalayer_extended.tesla.PCS_dcdcIntervalMaxLvBusVolt = PCS_dcdcIntervalMaxLvBusVolt; + datalayer_extended.tesla.PCS_dcdcIntervalMaxLvOutputCurr = PCS_dcdcIntervalMaxLvOutputCurr; + datalayer_extended.tesla.PCS_dcdcIntervalMinFrequency = PCS_dcdcIntervalMinFrequency; + datalayer_extended.tesla.PCS_dcdcIntervalMinHvBusVolt = PCS_dcdcIntervalMinHvBusVolt; + datalayer_extended.tesla.PCS_dcdcIntervalMinLvBusVolt = PCS_dcdcIntervalMinLvBusVolt; + datalayer_extended.tesla.PCS_dcdcIntervalMinLvOutputCurr = PCS_dcdcIntervalMinLvOutputCurr; + datalayer_extended.tesla.PCS_dcdc12vSupportLifetimekWh = PCS_dcdc12vSupportLifetimekWh; + //0x7AA + datalayer_extended.tesla.HVP_hvp1v5Ref = HVP_hvp1v5Ref; + datalayer_extended.tesla.HVP_shuntCurrentDebug = HVP_shuntCurrentDebug; + datalayer_extended.tesla.HVP_dcLinkVoltage = HVP_dcLinkVoltage; + datalayer_extended.tesla.HVP_packVoltage = HVP_packVoltage; + datalayer_extended.tesla.HVP_fcLinkVoltage = HVP_fcLinkVoltage; + datalayer_extended.tesla.HVP_packContVoltage = HVP_packContVoltage; + datalayer_extended.tesla.HVP_packNegativeV = HVP_packNegativeV; + datalayer_extended.tesla.HVP_packPositiveV = HVP_packPositiveV; + datalayer_extended.tesla.HVP_pyroAnalog = HVP_pyroAnalog; + datalayer_extended.tesla.HVP_dcLinkNegativeV = HVP_dcLinkNegativeV; + datalayer_extended.tesla.HVP_dcLinkPositiveV = HVP_dcLinkPositiveV; + datalayer_extended.tesla.HVP_fcLinkNegativeV = HVP_fcLinkNegativeV; + datalayer_extended.tesla.HVP_fcContCoilCurrent = HVP_fcContCoilCurrent; + datalayer_extended.tesla.HVP_fcContVoltage = HVP_fcContVoltage; + datalayer_extended.tesla.HVP_hvilInVoltage = HVP_hvilInVoltage; + datalayer_extended.tesla.HVP_hvilOutVoltage = HVP_hvilOutVoltage; + datalayer_extended.tesla.HVP_fcLinkPositiveV = HVP_fcLinkPositiveV; + datalayer_extended.tesla.HVP_packContCoilCurrent = HVP_packContCoilCurrent; + datalayer_extended.tesla.HVP_battery12V = HVP_battery12V; + datalayer_extended.tesla.HVP_shuntRefVoltageDbg = HVP_shuntRefVoltageDbg; + datalayer_extended.tesla.HVP_shuntAuxCurrentDbg = HVP_shuntAuxCurrentDbg; + datalayer_extended.tesla.HVP_shuntBarTempDbg = HVP_shuntBarTempDbg; + datalayer_extended.tesla.HVP_shuntAsicTempDbg = HVP_shuntAsicTempDbg; + datalayer_extended.tesla.HVP_shuntAuxCurrentStatus = HVP_shuntAuxCurrentStatus; + datalayer_extended.tesla.HVP_shuntBarTempStatus = HVP_shuntBarTempStatus; + datalayer_extended.tesla.HVP_shuntAsicTempStatus = HVP_shuntAsicTempStatus; #ifdef DEBUG_VIA_USB @@ -482,15 +852,21 @@ void receive_can_battery(CAN_frame rx_frame) { mux = (rx_frame.data.u8[0] & 0x02); //BMS_energyStatusIndex M : 0|2@1+ (1,0) [0|0] "" X if (mux == 0) { - //battery_nominal_full_pack_energy_m0 = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); //BMS_nominalFullPackEnergy m0 : 16|16@1+ (0.02,0) [0|0] "kWh" X - //battery_nominal_energy_remaining_m0 = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); //BMS_nominalEnergyRemaining m0 : 32|16@1+ (0.02,0) [0|0] "kWh" X - //battery_ideal_energy_remaining_m0 = ((rx_frame.data.u8[7] << 8) | rx_frame.data.u8[6]); //BMS_idealEnergyRemaining m0 : 48|16@1+ (0.02,0) [0|0] "kWh" X + battery_nominal_full_pack_energy_m0 = + ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); //16|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended + battery_nominal_energy_remaining_m0 = + ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); //32|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended + battery_ideal_energy_remaining_m0 = + ((rx_frame.data.u8[7] << 8) | rx_frame.data.u8[6]); //48|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended } if (mux == 1) { - //battery_fully_charged = (rx_frame.data.u8[1] & 0x01); //BMS_fullyCharged m1 : 15|1@1+ (1,0) [0|1] "" X - //battery_energy_buffer_m1 = (rx_frame.data.u8[3] | rx_frame.data.u8[2]); //BMS_energyBuffer m1 : 16|16@1+ (0.01,0) [0|0] "kWh" X - //battery_expected_energy_remaining_m1 = (rx_frame.data.u8[5] | rx_frame.data.u8[4]); //BMS_expectedEnergyRemaining m1 : 32|16@1+ (0.02,0) [0|0] "kWh" X - //battery_energy_to_charge_complete_m1 = (rx_frame.data.u8[7] | rx_frame.data.u8[6]); //BMS_energyToChargeComplete m1 : 48|16@1+ (0.02,0) [0|0] "kWh" X + battery_fully_charged = (rx_frame.data.u8[1] & 0x01); //15|1@1+ (1,0) [0|1]//to datalayer_extended + battery_energy_buffer_m1 = + (rx_frame.data.u8[3] | rx_frame.data.u8[2]); //16|16@1+ (0.01,0) [0|0] "kWh"//to datalayer_extended + battery_expected_energy_remaining_m1 = + (rx_frame.data.u8[5] | rx_frame.data.u8[4]); //32|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended + battery_energy_to_charge_complete_m1 = + (rx_frame.data.u8[7] | rx_frame.data.u8[6]); //48|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended } if (mux == 2) {} // Additional information needed on this mux, example frame: 02 26 02 20 02 80 00 00 doesn't change @@ -511,39 +887,112 @@ void receive_can_battery(CAN_frame rx_frame) { battery_full_charge_complete = //BMS_fullChargeComplete : 63|1@1+ (1,0) [0|1] ""//((_d[7] >> 7) & (0x01U)); ((rx_frame.data.u8[7] & 0x01) >> 7); break; - case 0x20A: //Contactor state //HVP_contactorState: - battery_packContNegativeState = (rx_frame.data.u8[0] & 0x07); //0|3@1+ (1,0) [0|7] "" - battery_packContPositiveState = (rx_frame.data.u8[0] & 0x38) >> 3; //3|3@1+ (1,0) [0|7] "" - battery_contactor = (rx_frame.data.u8[1] & 0x0F); //HVP_packContactorSetState : 8|4@1+ (1,0) [0|9] "" - battery_packContactorSetState = (rx_frame.data.u8[1] & 0x0F); //HVP_packContactorSetState : 8|4@1+ (1,0) [0|9] "" - battery_packCtrsClosingAllowed = (rx_frame.data.u8[4] & 0x08) >> 3; //35|1@1+ (1,0) [0|1] "" - battery_pyroTestInProgress = (rx_frame.data.u8[4] & 0x20) >> 5; //37|1@1+ (1,0) [0|1] "" - battery_hvil_status = (rx_frame.data.u8[5] & 0x0F); //40|4@1+ (1,0) [0|9] "" - //HVP_packCtrsOpenNowRequested : 33|1@1+ (1,0) [0|1] "" - //HVP_packCtrsOpenRequested : 34|1@1+ (1,0) [0|1] "" - //HVP_packCtrsRequestStatus : 30|2@1+ (1,0) [0|2] "" - //HVP_packCtrsResetRequestRequired : 32|1@1+ (1,0) [0|1] "" - //HVP_dcLinkAllowedToEnergize : 36|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContNegativeAuxOpen : 7|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContNegativeState : 12|3@1+ (1,0) [0|7] "" Receiver - //HVP_fcContPositiveAuxOpen : 6|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContPositiveState : 16|3@1+ (1,0) [0|7] "" Receiver - //HVP_fcContactorSetState : 19|4@1+ (1,0) [0|9] "" Receiver - //HVP_fcCtrsClosingAllowed : 29|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsOpenNowRequested : 27|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsOpenRequested : 28|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsRequestStatus : 24|2@1+ (1,0) [0|2] "" Receiver - //HVP_fcCtrsResetRequestRequired : 26|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcLinkAllowedToEnergize : 44|2@1+ (1,0) [0|2] "" Receiver + case 0x20A: //522 HVP_contactorState: + battery_packContNegativeState = + (rx_frame.data.u8[0] & 0x07); //(_d[0] & (0x07U)); 0|3@1+ (1,0) [0|7] //to datalayer_extended + battery_packContPositiveState = + (rx_frame.data.u8[0] & 0x38) >> 3; //((_d[0] >> 3) & (0x07U)); 3|3@1+ (1,0) [0|7] //to datalayer_extended + battery_contactor = (rx_frame.data.u8[1] & 0x0F); // 8|4@1+ (1,0) [0|9] //to datalayer_extended + battery_packContactorSetState = + (rx_frame.data.u8[1] & 0x0F); //(_d[1] & (0x0FU)); 8|4@1+ (1,0) [0|9] //to datalayer_extended + battery_packCtrsClosingAllowed = + (rx_frame.data.u8[4] & 0x08) >> 3; //((_d[4] >> 3) & (0x01U)); 35|1@1+ (1,0) [0|1] //to datalayer_extended + battery_pyroTestInProgress = + (rx_frame.data.u8[4] & 0x20) >> 5; //((_d[4] >> 5) & (0x01U));//37|1@1+ (1,0) [0|1] //to datalayer_extended + battery_hvil_status = + (rx_frame.data.u8[5] & 0x0F); //(_d[5] & (0x0FU)); //40|4@1+ (1,0) [0|9] //to datalayer_extended + battery_packCtrsOpenNowRequested = + ((rx_frame.data.u8[4] >> 1) & (0x01U)); //33|1@1+ (1,0) [0|1] //to datalayer_extended + battery_packCtrsOpenRequested = + ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|1] //to datalayer_extended + battery_packCtrsRequestStatus = + ((rx_frame.data.u8[3] >> 6) & (0x03U)); //30|2@1+ (1,0) [0|2] //to datalayer_extended + battery_packCtrsResetRequestRequired = + (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|1] //to datalayer_extended + battery_dcLinkAllowedToEnergize = + ((rx_frame.data.u8[4] >> 4) & (0x01U)); //36|1@1+ (1,0) [0|1] //to datalayer_extended + battery_fcContNegativeAuxOpen = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //7|1@1+ (1,0) [0|1] "" Receiver + battery_fcContNegativeState = ((rx_frame.data.u8[1] >> 4) & (0x07U)); //12|3@1+ (1,0) [0|7] "" Receiver + battery_fcContPositiveAuxOpen = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|1] "" Receiver + battery_fcContPositiveState = (rx_frame.data.u8[2] & (0x07U)); //16|3@1+ (1,0) [0|7] "" Receiver + battery_fcContactorSetState = ((rx_frame.data.u8[2] >> 3) & (0x0FU)); //19|4@1+ (1,0) [0|9] "" Receiver + battery_fcCtrsClosingAllowed = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|1] "" Receiver + battery_fcCtrsOpenNowRequested = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|1] "" Receiver + battery_fcCtrsOpenRequested = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|1] "" Receiver + battery_fcCtrsRequestStatus = (rx_frame.data.u8[3] & (0x03U)); //24|2@1+ (1,0) [0|2] "" Receiver + battery_fcCtrsResetRequestRequired = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|1] "" Receiver + battery_fcLinkAllowedToEnergize = ((rx_frame.data.u8[5] >> 4) & (0x03U)); //44|2@1+ (1,0) [0|2] "" Receiver + break; + case 0x212: //530 BMS_status: 8 + battery_BMS_hvacPowerRequest = (rx_frame.data.u8[0] & (0x01U)); + battery_BMS_notEnoughPowerForDrive = ((rx_frame.data.u8[0] >> 1) & (0x01U)); + battery_BMS_notEnoughPowerForSupport = ((rx_frame.data.u8[0] >> 2) & (0x01U)); + battery_BMS_preconditionAllowed = ((rx_frame.data.u8[0] >> 3) & (0x01U)); + battery_BMS_updateAllowed = ((rx_frame.data.u8[0] >> 4) & (0x01U)); + battery_BMS_activeHeatingWorthwhile = ((rx_frame.data.u8[0] >> 5) & (0x01U)); + battery_BMS_cpMiaOnHvs = ((rx_frame.data.u8[0] >> 6) & (0x01U)); + battery_BMS_contactorState = + (rx_frame.data.u8[1] & + (0x07U)); //0 "SNA" 1 "OPEN" 2 "OPENING" 3 "CLOSING" 4 "CLOSED" 5 "WELDED" 6 "BLOCKED" ; + battery_BMS_state = + ((rx_frame.data.u8[1] >> 3) & + (0x0FU)); //0 "STANDBY" 1 "DRIVE" 2 "SUPPORT" 3 "CHARGE" 4 "FEIM" 5 "CLEAR_FAULT" 6 "FAULT" 7 "WELD" 8 "TEST" 9 "SNA" ; + battery_BMS_hvState = + (rx_frame.data.u8[2] & + (0x07U)); //0 "DOWN" 1 "COMING_UP" 2 "GOING_DOWN" 3 "UP_FOR_DRIVE" 4 "UP_FOR_CHARGE" 5 "UP_FOR_DC_CHARGE" 6 "UP" ; + battery_BMS_isolationResistance = + ((rx_frame.data.u8[3] & (0x1FU)) << 5) | + ((rx_frame.data.u8[2] >> 3) & (0x1FU)); //19|10@1+ (10,0) [0|0] "kOhm"/to datalayer_extended + battery_BMS_chargeRequest = ((rx_frame.data.u8[3] >> 5) & (0x01U)); + battery_BMS_keepWarmRequest = ((rx_frame.data.u8[3] >> 6) & (0x01U)); + battery_BMS_uiChargeStatus = + (rx_frame.data.u8[4] & + (0x07U)); // 0 "DISCONNECTED" 1 "NO_POWER" 2 "ABOUT_TO_CHARGE" 3 "CHARGING" 4 "CHARGE_COMPLETE" 5 "CHARGE_STOPPED" ; + battery_BMS_diLimpRequest = ((rx_frame.data.u8[4] >> 3) & (0x01U)); + battery_BMS_okToShipByAir = ((rx_frame.data.u8[4] >> 4) & (0x01U)); + battery_BMS_okToShipByLand = ((rx_frame.data.u8[4] >> 5) & (0x01U)); + battery_BMS_chgPowerAvailable = ((rx_frame.data.u8[6] & (0x01U)) << 10) | ((rx_frame.data.u8[5] & (0xFFU)) << 2) | + ((rx_frame.data.u8[4] >> 6) & (0x03U)); //38|11@1+ (0.125,0) [0|0] "kW" + battery_BMS_chargeRetryCount = ((rx_frame.data.u8[6] >> 1) & (0x0FU)); + battery_BMS_pcsPwmEnabled = ((rx_frame.data.u8[6] >> 5) & (0x01U)); + battery_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); + battery_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC + break; + case 0x224: //548 PCS_dcdcStatus: + battery_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; + battery_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" + battery_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" + battery_PCS_dcdcMainState = + ((rx_frame.data.u8[1] & (0x03U)) << 2) | + ((rx_frame.data.u8[0] >> 6) & + (0x03U)); //0 "STANDBY" 1 "12V_SUPPORT_ACTIVE" 2 "PRECHARGE_STARTUP" 3 "PRECHARGE_ACTIVE" 4 "DIS_HVBUS_ACTIVE" 5 "SHUTDOWN" 6 "FAULTED" ; + battery_PCS_dcdcSubState = + ((rx_frame.data.u8[1] >> 2) & + (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; + battery_PCS_dcdcFaulted = ((rx_frame.data.u8[1] >> 7) & (0x01U)); + battery_PCS_dcdcOutputIsLimited = ((rx_frame.data.u8[3] >> 4) & (0x01U)); + battery_PCS_dcdcMaxOutputCurrentAllowed = ((rx_frame.data.u8[5] & (0x01U)) << 11) | + ((rx_frame.data.u8[4] & (0xFFU)) << 3) | + ((rx_frame.data.u8[3] >> 5) & (0x07U)); //29|12@1+ (0.1,0) [0|0] "A" + battery_PCS_dcdcPrechargeRtyCnt = ((rx_frame.data.u8[5] >> 1) & (0x07U)); + battery_PCS_dcdc12VSupportRtyCnt = ((rx_frame.data.u8[5] >> 4) & (0x0FU)); + battery_PCS_dcdcDischargeRtyCnt = (rx_frame.data.u8[6] & (0x0FU)); + battery_PCS_dcdcPwmEnableLine = ((rx_frame.data.u8[6] >> 4) & (0x01U)); + battery_PCS_dcdcSupportingFixedLvTarget = ((rx_frame.data.u8[6] >> 5) & (0x01U)); + battery_PCS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); + battery_PCS_dcdcPrechargeRestartCnt = (rx_frame.data.u8[7] & (0x07U)); + battery_PCS_dcdcInitialPrechargeSubState = + ((rx_frame.data.u8[7] >> 3) & + (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; break; case 0x252: //Limit //BMS_powerAvailable252: - battery_regenerative_limit = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * + BMS_regenerative_limit = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * 0.01; //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW - battery_discharge_limit = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) * + BMS_discharge_limit = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) * 0.013; //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? - battery_max_heat_park = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]) * + BMS_max_heat_park = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]) * 0.01; //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW - battery_hvac_max_power = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))) * + BMS_hvac_max_power = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))) * 0.02; //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] "" Receiver @@ -584,27 +1033,122 @@ void receive_can_battery(CAN_frame rx_frame) { temp = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); temp = (temp & 0xFFF); battery_cell_min_v = temp * 2; - battery_max_vno = 1 + (rx_frame.data.u8[4] & 0x7F); //This cell has highest voltage - battery_min_vno = 1 + (rx_frame.data.u8[5] & 0x7F); //This cell has lowest voltage + //BattBrickVoltageMax m1 : 2|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[1] & (0x3FU)) << 6) | ((_d[0] >> 2) & (0x3FU)); + battery_BrickVoltageMax = + ((rx_frame.data.u8[1] & (0x3F)) << 6) | ((rx_frame.data.u8[0] >> 2) & (0x3F)); //to datalayer_extended + //BattBrickVoltageMin m1 : 16|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[3] & (0x0FU)) << 8) | (_d[2] & (0xFFU)); + battery_BrickVoltageMin = + ((rx_frame.data.u8[3] & (0x0F)) << 8) | (rx_frame.data.u8[2] & (0xFF)); //to datalayer_extended + //BattBrickVoltageMaxNum m1 : 32|7@1+ (1,1) [0|0] "" Receiver + battery_BrickVoltageMaxNum = + 1 + (rx_frame.data.u8[4] & 0x7F); //(_d[4] & (0x7FU)); //This cell has highest voltage + //BattBrickVoltageMinNum m1 : 40|7@1+ (1,1) [0|0] "" Receiver + battery_BrickVoltageMinNum = + 1 + (rx_frame.data.u8[5] & 0x7F); //(_d[5] & (0x7FU)); //This cell has lowest voltage } if (mux == 0) //Temperature sensors - { + { //BattBrickTempMax m0 : 16|8@1+ (0.5,-40) [0|0] "C" (_d[2] & (0xFFU)); battery_max_temp = (rx_frame.data.u8[2] * 5) - 400; //Temperature values have 40.0*C offset, 0.5*C /bit + //BattBrickTempMin m0 : 24|8@1+ (0.5,-40) [0|0] "C" (_d[3] & (0xFFU)); battery_min_temp = (rx_frame.data.u8[3] * 5) - 400; //Multiply by 5 and remove offset to get C+1 (0x61*5=485-400=8.5*C) + //BattBrickTempMaxNum m0 : 2|4@1+ (1,0) [0|0] "" ((_d[0] >> 2) & (0x0FU)); + battery_BrickTempMaxNum = ((rx_frame.data.u8[0] >> 2) & (0x0F)); //to datalayer_extended + //BattBrickTempMinNum m0 : 8|4@1+ (1,0) [0|0] "" (_d[1] & (0x0FU)); + battery_BrickTempMinNum = (rx_frame.data.u8[1] & (0x0F)); //to datalayer_extended + //BattBrickModelTMax m0 : 32|8@1+ (0.5,-40) [0|0] "C" (_d[4] & (0xFFU)); + battery_BrickModelTMax = (rx_frame.data.u8[4] & (0xFFU)); //to datalayer_extended + //BattBrickModelTMin m0 : 40|8@1+ (0.5,-40) [0|0] "C" (_d[5] & (0xFFU)); + battery_BrickModelTMin = (rx_frame.data.u8[5] & (0xFFU)); //to datalayer_extended } - //BattBrickMultiplexer M : 0|2@1+ (1,0) [0|0] "" Receiver - //BattBrickTempMaxNum m0 : 2|4@1+ (1,0) [0|0] "" Receiver - //BattBrickTempMinNum m0 : 8|4@1+ (1,0) [0|0] "" Receiver - //BattBrickTempMax m0 : 16|8@1+ (0.5,-40) [0|0] "C" Receiver - //BattBrickTempMin m0 : 24|8@1+ (0.5,-40) [0|0] "C" Receiver - //BattBrickModelTMax m0 : 32|8@1+ (0.5,-40) [0|0] "C" Receiver - //BattBrickModelTMin m0 : 40|8@1+ (0.5,-40) [0|0] "C" Receiver - //BattBrickVoltageMax m1 : 2|12@1+ (0.002,0) [0|0] "V" Receiver - //BattBrickVoltageMin m1 : 16|12@1+ (0.002,0) [0|0] "V" Receiver - //BattBrickVoltageMaxNum m1 : 32|7@1+ (1,1) [0|0] "" Receiver - //BattBrickVoltageMinNum m1 : 40|7@1+ (1,1) [0|0] "" Receiver break; + case 0x312: // 786 BMS_thermalStatus + BMS_powerDissipation = + ((rx_frame.data.u8[1] & (0x03U)) << 8) | (rx_frame.data.u8[0] & (0xFFU)); //0|10@1+ (0.02,0) [0|0] "kW" + BMS_flowRequest = ((rx_frame.data.u8[2] & (0x01U)) << 6) | + ((rx_frame.data.u8[1] >> 2) & (0x3FU)); //10|7@1+ (0.3,0) [0|0] "LPM" + BMS_inletActiveCoolTargetT = ((rx_frame.data.u8[3] & (0x03U)) << 7) | + ((rx_frame.data.u8[2] >> 1) & (0x7FU)); //17|9@1+ (0.25,-25) [0|0] "DegC" + BMS_inletPassiveTargetT = ((rx_frame.data.u8[4] & (0x07U)) << 6) | + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //26|9@1+ (0.25,-25) [0|0] "DegC" X + BMS_inletActiveHeatTargetT = ((rx_frame.data.u8[5] & (0x0FU)) << 5) | + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|9@1+ (0.25,-25) [0|0] "DegC" + BMS_packTMin = ((rx_frame.data.u8[6] & (0x1FU)) << 4) | + ((rx_frame.data.u8[5] >> 4) & (0x0FU)); //44|9@1+ (0.25,-25) [-25|100] "DegC" + BMS_packTMax = ((rx_frame.data.u8[7] & (0x3FU)) << 3) | + ((rx_frame.data.u8[6] >> 5) & (0x07U)); //53|9@1+ (0.25,-25) [-25|100] "DegC" + BMS_pcsNoFlowRequest = ((rx_frame.data.u8[7] >> 6) & (0x01U)); // 62|1@1+ (1,0) [0|0] "" + BMS_noFlowRequest = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" + break; + case 0x2A4: //676 PCS_thermalStatus + PCS_chgPhATemp = + ((rx_frame.data.u8[1] & (0x07U)) << 8) | (rx_frame.data.u8[0] & (0xFFU)); //0|11@1- (0.1,40) [0|0] "C + PCS_chgPhBTemp = + ((rx_frame.data.u8[2] & (0x3FU)) << 5) | ((rx_frame.data.u8[1] >> 3) & (0x1FU)); //11|11@1- (0.1,40) [0|0] "C + PCS_chgPhCTemp = + ((rx_frame.data.u8[4] & (0x07U)) << 8) | (rx_frame.data.u8[3] & (0xFFU)); //24|11@1- (0.1,40) [0|0] "C" + PCS_dcdcTemp = ((rx_frame.data.u8[5] & (0x3FU)) << 5) | + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|11@1- (0.1,40) [0|0] "C" + PCS_ambientTemp = + ((rx_frame.data.u8[7] & (0x07U)) << 8) | (rx_frame.data.u8[6] & (0xFFU)); //48|11@1- (0.1,40) [0|0] "C" + break; + case 0x2C4: // 708 PCS_logging: not all frames are listed, just ones relating to dcdc + mux = (rx_frame.data.u8[0] & (0x1FU)); + //PCS_logMessageSelect = (rx_frame.data.u8[0] & (0x1FU)); //0|5@1+ (1,0) [0|0] "" + if (mux == 6) { + PCS_dcdcMaxLvOutputCurrent = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //m6 : 28|12@1+ (0.1,0) [0|0] "A" X + PCS_dcdcCurrentLimit = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //m6 : 40|12@1+ (0.1,0) [0|0] "A" X + PCS_dcdcLvOutputCurrentTempLimit = ((rx_frame.data.u8[7] & (0xFFU)) << 4) | + ((rx_frame.data.u8[6] >> 4) & (0x0FU)); //m6 : 52|12@1+ (0.1,0) [0|0] "A" X + } + if (mux == 7) { + PCS_dcdcUnifiedCommand = ((rx_frame.data.u8[1] & (0x7FU)) << 3) | + ((rx_frame.data.u8[0] >> 5) & (0x07U)); //m7 : 5|10@1+ (0.001,0) [0|0] "1" X + PCS_dcdcCLAControllerOutput = ((rx_frame.data.u8[3] & (0x03U)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //m7 : 16|10@1+ (0.001,0) [0|0] "1" X + PCS_dcdcTankVoltage = ((rx_frame.data.u8[4] & (0x1FU)) << 6) | + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //m7 : 26|11@1- (1,0) [0|0] "V" X + PCS_dcdcTankVoltageTarget = ((rx_frame.data.u8[5] & (0x7FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m7 : 37|10@1+ (1,0) [0|0] "V" X + PCS_dcdcClaCurrentFreq = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //P m7 : 48|12@1+ (0.0976563,0) [0|0] "kHz" X + } + if (mux == 8) { + PCS_dcdcTCommMeasured = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m8 : 8|16@1- (0.00195313,0) [0|0] "us" X + PCS_dcdcShortTimeUs = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); // m8 : 24|16@1+ (0.000488281,0) [0|0] "us" X + PCS_dcdcHalfPeriodUs = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); // m8 : 40|16@1+ (0.000488281,0) [0|0] "us" X + } + if (mux == 18) { + PCS_dcdcIntervalMaxFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m18 : 8|12@1+ (1,0) [0|0] "kHz" X + PCS_dcdcIntervalMaxHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //m18 : 24|13@1+ (0.1,0) [0|0] "V" X + PCS_dcdcIntervalMaxLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m18 : 37|9@1+ (0.1,0) [0|0] "V" X + PCS_dcdcIntervalMaxLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //m18 : 48|12@1+ (1,0) [0|0] "A" X + } + if (mux == 19) { + PCS_dcdcIntervalMinFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //m19 : 8|12@1+ (1,0) [0|0] "kHz" X + PCS_dcdcIntervalMinHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //m19 : 24|13@1+ (0.1,0) [0|0] "V" X + PCS_dcdcIntervalMinLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); //m19 : 37|9@1+ (0.1,0) [0|0] "V" X + PCS_dcdcIntervalMinLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); // m19 : 48|12@1+ (1,0) [0|0] "A" X + } + if (mux == 22) { + PCS_dcdc12vSupportLifetimekWh = ((rx_frame.data.u8[3] & (0xFFU)) << 16) | + ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m22 : 8|24@1+ (0.01,0) [0|0] "kWh" X + } + break; case 0x401: // Cell stats //BrickVoltages mux = (rx_frame.data.u8[0]); //MultiplexSelector M : 0|8@1+ (1,0) [0|0] "" //StatusFlags : 8|8@1+ (1,0) [0|0] "" @@ -677,13 +1221,110 @@ void receive_can_battery(CAN_frame rx_frame) { mux = (rx_frame.data.u8[0] & (0xFF)); if (mux == 1) { battery_packConfigMultiplexer = (rx_frame.data.u8[0] & (0xff)); //0|8@1+ (1,0) [0|1] "" - battery_moduleType = (rx_frame.data.u8[1] & (0x07)); //8|3@1+ (1,0) [0|4] "" + battery_moduleType = (rx_frame.data.u8[1] & (0x07)); //8|3@1+ (1,0) [0|4] ""//0 "UNKNOWN" 1 "E3_NCT" 2 "E1_NCT" 3 "E3_CT" 4 "E1_CT" 5 "E1_CP" ;//to datalayer_extended battery_packMass = (rx_frame.data.u8[2]) + 300; //16|8@1+ (1,300) [342|469] "kg" battery_platformMaxBusVoltage = (((rx_frame.data.u8[4] & 0x03) << 8) | (rx_frame.data.u8[3])); //24|10@1+ (0.1,375) [0|0] "V" } if (mux == 0) { - battery_reservedConfig = (rx_frame.data.u8[1] & (0x1F)); //8|5@1+ (1,0) [0|31] "" + battery_reservedConfig = (rx_frame.data.u8[1] & (0x1F)); //8|5@1+ (1,0) [0|31] ""//0 "BMS_CONFIG_0" 1 "BMS_CONFIG_1" 10 "BMS_CONFIG_10" 11 "BMS_CONFIG_11" 12 "BMS_CONFIG_12" 13 "BMS_CONFIG_13" 14 "BMS_CONFIG_14" 15 "BMS_CONFIG_15" 16 "BMS_CONFIG_16" 17 "BMS_CONFIG_17" 18 "BMS_CONFIG_18" 19 "BMS_CONFIG_19" 2 "BMS_CONFIG_2" 20 "BMS_CONFIG_20" 21 "BMS_CONFIG_21" 22 "BMS_CONFIG_22" 23 "BMS_CONFIG_23" 24 "BMS_CONFIG_24" 25 "BMS_CONFIG_25" 26 "BMS_CONFIG_26" 27 "BMS_CONFIG_27" 28 "BMS_CONFIG_28" 29 "BMS_CONFIG_29" 3 "BMS_CONFIG_3" 30 "BMS_CONFIG_30" 31 "BMS_CONFIG_31" 4 "BMS_CONFIG_4" 5 "BMS_CONFIG_5" 6 "BMS_CONFIG_6" 7 "BMS_CONFIG_7" 8 "BMS_CONFIG_8" 9 "BMS_CONFIG_9" ; + } + break; + case 0x7AA: //1962 HVP_debugMessage: + mux = (rx_frame.data.u8[0] & (0x0FU)); + //HVP_debugMessageMultiplexer = (rx_frame.data.u8[0] & (0x0FU)); //0|4@1+ (1,0) [0|6] "" + if (mux == 0) { + HVP_gpioPassivePyroDepl = ((rx_frame.data.u8[0] >> 4) & (0x01U)); //: 4|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPyroIsoEn = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //: 5|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioCpFaultIn = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //: 6|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPackContPowerEn = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //: 7|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioHvCablesOk = (rx_frame.data.u8[1] & (0x01U)); //: 8|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioHvpSelfEnable = ((rx_frame.data.u8[1] >> 1) & (0x01U)); //: 9|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioLed = ((rx_frame.data.u8[1] >> 2) & (0x01U)); //: 10|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioCrashSignal = ((rx_frame.data.u8[1] >> 3) & (0x01U)); //: 11|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioShuntDataReady = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //: 12|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioFcContPosAux = ((rx_frame.data.u8[1] >> 5) & (0x01U)); //: 13|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioFcContNegAux = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //: 14|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioBmsEout = ((rx_frame.data.u8[1] >> 7) & (0x01U)); //: 15|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioCpFaultOut = (rx_frame.data.u8[2] & (0x01U)); //: 16|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPyroPor = ((rx_frame.data.u8[2] >> 1) & (0x01U)); //: 17|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioShuntEn = ((rx_frame.data.u8[2] >> 2) & (0x01U)); //: 18|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioHvpVerEn = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //: 19|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPackCoontPosFlywheel = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //: 20|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioCpLatchEnable = ((rx_frame.data.u8[2] >> 5) & (0x01U)); //: 21|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPcsEnable = ((rx_frame.data.u8[2] >> 6) & (0x01U)); //: 22|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPcsDcdcPwmEnable = ((rx_frame.data.u8[2] >> 7) & (0x01U)); //: 23|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioPcsChargePwmEnable = (rx_frame.data.u8[3] & (0x01U)); //: 24|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioFcContPowerEnable = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //: 25|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioHvilEnable = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //: 26|1@1+ (1,0) [0|1] "" Receiver + HVP_gpioSecDrdy = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //: 27|1@1+ (1,0) [0|1] "" Receiver + HVP_hvp1v5Ref = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|3] "V" Receiver + HVP_shuntCurrentDebug = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + HVP_packCurrentMia = (rx_frame.data.u8[7] & (0x01U)); //: 56|1@1+ (1,0) [0|1] "" Receiver + HVP_auxCurrentMia = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //: 57|1@1+ (1,0) [0|1] "" Receiver + HVP_currentSenseMia = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|1@1+ (1,0) [0|1] "" Receiver + HVP_shuntRefVoltageMismatch = ((rx_frame.data.u8[7] >> 3) & (0x01U)); //: 59|1@1+ (1,0) [0|1] "" Receiver + HVP_shuntThermistorMia = ((rx_frame.data.u8[7] >> 4) & (0x01U)); //: 60|1@1+ (1,0) [0|1] "" Receiver + HVP_shuntHwMia = ((rx_frame.data.u8[7] >> 5) & (0x01U)); //: 61|1@1+ (1,0) [0|1] "" Receiver + } + if (mux == 1) { + HVP_dcLinkVoltage = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + HVP_packVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + HVP_fcLinkVoltage = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + } + if (mux == 2) { + HVP_packContVoltage = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|30] "V" Receiver + HVP_packNegativeV = ((rx_frame.data.u8[3] & (0xFFU)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //: 16|16@1- (0.1,0) [-550|550] "V" Receiver + HVP_packPositiveV = ((rx_frame.data.u8[5] & (0xFFU)) << 8) | + (rx_frame.data.u8[4] & (0xFFU)); //: 32|16@1- (0.1,0) [-550|550] "V" Receiver + HVP_pyroAnalog = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //: 48|12@1+ (0.1,0) [0|3] "V" Receiver + } + if (mux == 3) { + HVP_dcLinkNegativeV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + HVP_dcLinkPositiveV = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-550|550] "V" Receiver + HVP_fcLinkNegativeV = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-550|550] "V" Receiver + } + if (mux == 4) { + HVP_fcContCoilCurrent = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|7.5] "A" Receiver + HVP_fcContVoltage = ((rx_frame.data.u8[3] & (0x0FU)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //: 16|12@1+ (0.1,0) [0|30] "V" Receiver + HVP_hvilInVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|30] "V" Receiver + HVP_hvilOutVoltage = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|12@1+ (0.1,0) [0|30] "V" Receiver + } + if (mux == 5) { + HVP_fcLinkPositiveV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + HVP_packContCoilCurrent = ((rx_frame.data.u8[4] & (0x0FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|12@1+ (0.1,0) [0|7.5] "A" Receiver + HVP_battery12V = ((rx_frame.data.u8[5] & (0xFFU)) << 4) | + ((rx_frame.data.u8[4] >> 4) & (0x0FU)); //: 36|12@1+ (0.1,0) [0|30] "V" Receiver + HVP_shuntRefVoltageDbg = ((rx_frame.data.u8[7] & (0xFFU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //: 48|16@1- (0.001,0) [-32.768|32.767] "V" Receiver + } + if (mux == 6) { + HVP_shuntAuxCurrentDbg = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + HVP_shuntBarTempDbg = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + HVP_shuntAsicTempDbg = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + HVP_shuntAuxCurrentStatus = (rx_frame.data.u8[7] & (0x03U)); //: 56|2@1+ (1,0) [0|3] "" Receiver + HVP_shuntBarTempStatus = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|2@1+ (1,0) [0|3] "" Receiver + HVP_shuntAsicTempStatus = ((rx_frame.data.u8[7] >> 4) & (0x03U)); //: 60|2@1+ (1,0) [0|3] "" Receiver } break; case 0x3aa: //HVP_alertMatrix1 @@ -739,12 +1380,116 @@ void receive_can_battery(CAN_frame rx_frame) { battery_fcCtrCloseFailed = ((rx_frame.data.u8[6] & 0x02) >> 1); battery_shuntThermistorMia = ((rx_frame.data.u8[6] & 0x04) >> 2); break; + case 0x320: //800 BMS_alertMatrix //BMS_alertMatrix 800 BMS_alertMatrix: 8 VEH + mux = (rx_frame.data.u8[0] & (0x0F)); + if (mux == 0) + ; + { //mux0 + battery_BMS_matrixIndex = (rx_frame.data.u8[0] & (0x0F)); // 0|4@1+ (1,0) [0|0] "" X + battery_BMS_a017_SW_Brick_OV = ((rx_frame.data.u8[2] >> 4) & (0x01)); //20|1@1+ (1,0) [0|0] "" X + battery_BMS_a018_SW_Brick_UV = ((rx_frame.data.u8[2] >> 5) & (0x01)); //21|1@1+ (1,0) [0|0] "" X + battery_BMS_a019_SW_Module_OT = ((rx_frame.data.u8[2] >> 6) & (0x01)); //22|1@1+ (1,0) [0|0] "" X + battery_BMS_a021_SW_Dr_Limits_Regulation = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery_BMS_a022_SW_Over_Current = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //25|1@1+ (1,0) [0|0] "" X + battery_BMS_a023_SW_Stack_OV = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|0] "" X + battery_BMS_a024_SW_Islanded_Brick = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery_BMS_a025_SW_PwrBalance_Anomaly = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|0] "" X + battery_BMS_a026_SW_HFCurrent_Anomaly = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|0] "" X + battery_BMS_a034_SW_Passive_Isolation = ((rx_frame.data.u8[4] >> 5) & (0x01U)); //37|1@1+ (1,0) [0|0] "" X ? + battery_BMS_a035_SW_Isolation = ((rx_frame.data.u8[4] >> 6) & (0x01U)); //38|1@1+ (1,0) [0|0] "" X + battery_BMS_a036_SW_HvpHvilFault = ((rx_frame.data.u8[4] >> 6) & (0x01U)); //39|1@1+ (1,0) [0|0] "" X + battery_BMS_a037_SW_Flood_Port_Open = (rx_frame.data.u8[5] & (0x01U)); //40|1@1+ (1,0) [0|0] "" X + battery_BMS_a039_SW_DC_Link_Over_Voltage = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery_BMS_a041_SW_Power_On_Reset = ((rx_frame.data.u8[5] >> 4) & (0x01U)); //44|1@1+ (1,0) [0|0] "" X + battery_BMS_a042_SW_MPU_Error = ((rx_frame.data.u8[5] >> 5) & (0x01U)); //45|1@1+ (1,0) [0|0] "" X + battery_BMS_a043_SW_Watch_Dog_Reset = ((rx_frame.data.u8[5] >> 6) & (0x01U)); //46|1@1+ (1,0) [0|0] "" X + battery_BMS_a044_SW_Assertion = ((rx_frame.data.u8[5] >> 7) & (0x01U)); //47|1@1+ (1,0) [0|0] "" X + battery_BMS_a045_SW_Exception = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery_BMS_a046_SW_Task_Stack_Usage = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery_BMS_a047_SW_Task_Stack_Overflow = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + battery_BMS_a048_SW_Log_Upload_Request = ((rx_frame.data.u8[6] >> 3) & (0x01U)); //51|1@1+ (1,0) [0|0] "" X + battery_BMS_a050_SW_Brick_Voltage_MIA = ((rx_frame.data.u8[6] >> 5) & (0x01U)); //53|1@1+ (1,0) [0|0] "" X + battery_BMS_a051_SW_HVC_Vref_Bad = ((rx_frame.data.u8[6] >> 6) & (0x01U)); //54|1@1+ (1,0) [0|0] "" X + battery_BMS_a052_SW_PCS_MIA = ((rx_frame.data.u8[6] >> 7) & (0x01U)); //55|1@1+ (1,0) [0|0] "" X + battery_BMS_a053_SW_ThermalModel_Sanity = (rx_frame.data.u8[7] & (0x01U)); //56|1@1+ (1,0) [0|0] "" X + battery_BMS_a054_SW_Ver_Supply_Fault = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //57|1@1+ (1,0) [0|0] "" X + battery_BMS_a059_SW_Pack_Voltage_Sensing = ((rx_frame.data.u8[7] >> 6) & (0x01U)); //62|1@1+ (1,0) [0|0] "" X + battery_BMS_a060_SW_Leakage_Test_Failure = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" X + } + if (mux == 1) { //mux1 + battery_BMS_a061_robinBrickOverVoltage = ((rx_frame.data.u8[0] >> 4) & (0x01U)); //4|1@1+ (1,0) [0|0] "" X + battery_BMS_a062_SW_BrickV_Imbalance = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X + battery_BMS_a063_SW_ChargePort_Fault = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X + battery_BMS_a064_SW_SOC_Imbalance = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //7|1@1+ (1,0) [0|0] "" X + battery_BMS_a069_SW_Low_Power = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //12|1@1+ (1,0) [0|0] "" X + battery_BMS_a071_SW_SM_TransCon_Not_Met = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //14|1@1+ (1,0) [0|0] "" X + battery_BMS_a075_SW_Chg_Disable_Failure = ((rx_frame.data.u8[2] >> 2) & (0x01U)); //18|1@1+ (1,0) [0|0] "" X + battery_BMS_a076_SW_Dch_While_Charging = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //19|1@1+ (1,0) [0|0] "" X + battery_BMS_a077_SW_Charger_Regulation = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //20|1@1+ (1,0) [0|0] "" X + battery_BMS_a081_SW_Ctr_Close_Blocked = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery_BMS_a082_SW_Ctr_Force_Open = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //25|1@1+ (1,0) [0|0] "" X + battery_BMS_a083_SW_Ctr_Close_Failure = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|0] "" X + battery_BMS_a084_SW_Sleep_Wake_Aborted = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery_BMS_a087_SW_Feim_Test_Blocked = ((rx_frame.data.u8[3] >> 6) & (0x01U)); //30|1@1+ (1,0) [0|0] "" X + battery_BMS_a088_SW_VcFront_MIA_InDrive = ((rx_frame.data.u8[3] >> 7) & (0x01U)); //31|1@1+ (1,0) [0|0] "" X + battery_BMS_a089_SW_VcFront_MIA = (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|0] "" X + battery_BMS_a090_SW_Gateway_MIA = ((rx_frame.data.u8[4] >> 1) & (0x01U)); //33|1@1+ (1,0) [0|0] "" X + battery_BMS_a091_SW_ChargePort_MIA = ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|0] "" X + battery_BMS_a092_SW_ChargePort_Mia_On_Hv = ((rx_frame.data.u8[4] >> 3) & (0x01U)); //35|1@1+ (1,0) [0|0] "" X + battery_BMS_a094_SW_Drive_Inverter_MIA = ((rx_frame.data.u8[4] >> 5) & (0x01U)); //37|1@1+ (1,0) [0|0] "" X + battery_BMS_a099_SW_BMB_Communication = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery_BMS_a105_SW_One_Module_Tsense = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery_BMS_a106_SW_All_Module_Tsense = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery_BMS_a107_SW_Stack_Voltage_MIA = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + } + if (mux == 2) { //mux2 + battery_BMS_a121_SW_NVRAM_Config_Error = ((rx_frame.data.u8[0] >> 4) & (0x01U)); // 4|1@1+ (1,0) [0|0] "" X + battery_BMS_a122_SW_BMS_Therm_Irrational = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X + battery_BMS_a123_SW_Internal_Isolation = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X + battery_BMS_a127_SW_shunt_SNA = ((rx_frame.data.u8[1] >> 2) & (0x01U)); //10|1@1+ (1,0) [0|0] "" X + battery_BMS_a128_SW_shunt_MIA = ((rx_frame.data.u8[1] >> 3) & (0x01U)); //11|1@1+ (1,0) [0|0] "" X + battery_BMS_a129_SW_VSH_Failure = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //12|1@1+ (1,0) [0|0] "" X + battery_BMS_a130_IO_CAN_Error = ((rx_frame.data.u8[1] >> 5) & (0x01U)); //13|1@1+ (1,0) [0|0] "" X + battery_BMS_a131_Bleed_FET_Failure = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //14|1@1+ (1,0) [0|0] "" X + battery_BMS_a132_HW_BMB_OTP_Uncorrctbl = ((rx_frame.data.u8[1] >> 7) & (0x01U)); //15|1@1+ (1,0) [0|0] "" X + battery_BMS_a134_SW_Delayed_Ctr_Off = ((rx_frame.data.u8[2] >> 1) & (0x01U)); //17|1@1+ (1,0) [0|0] "" X + battery_BMS_a136_SW_Module_OT_Warning = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //19|1@1+ (1,0) [0|0] "" X + battery_BMS_a137_SW_Brick_UV_Warning = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //20|1@1+ (1,0) [0|0] "" X + battery_BMS_a138_SW_Brick_OV_Warning = ((rx_frame.data.u8[2] >> 5) & (0x01U)); //21|1@1+ (1,0) [0|0] "" X + battery_BMS_a139_SW_DC_Link_V_Irrational = ((rx_frame.data.u8[2] >> 6) & (0x01U)); //22|1@1+ (1,0) [0|0] "" X + battery_BMS_a141_SW_BMB_Status_Warning = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery_BMS_a144_Hvp_Config_Mismatch = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery_BMS_a145_SW_SOC_Change = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|0] "" X + battery_BMS_a146_SW_Brick_Overdischarged = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|0] "" X + battery_BMS_a149_SW_Missing_Config_Block = (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|0] "" X + battery_BMS_a151_SW_external_isolation = ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|0] "" X + battery_BMS_a156_SW_BMB_Vref_bad = ((rx_frame.data.u8[4] >> 7) & (0x01U)); //39|1@1+ (1,0) [0|0] "" X + battery_BMS_a157_SW_HVP_HVS_Comms = (rx_frame.data.u8[5] & (0x01U)); //40|1@1+ (1,0) [0|0] "" X + battery_BMS_a158_SW_HVP_HVI_Comms = ((rx_frame.data.u8[5] >> 1) & (0x01U)); //41|1@1+ (1,0) [0|0] "" X + battery_BMS_a159_SW_HVP_ECU_Error = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery_BMS_a161_SW_DI_Open_Request = ((rx_frame.data.u8[5] >> 4) & (0x01U)); //44|1@1+ (1,0) [0|0] "" X + battery_BMS_a162_SW_No_Power_For_Support = ((rx_frame.data.u8[5] >> 5) & (0x01U)); //45|1@1+ (1,0) [0|0] "" X + battery_BMS_a163_SW_Contactor_Mismatch = ((rx_frame.data.u8[5] >> 6) & (0x01U)); //46|1@1+ (1,0) [0|0] "" X + battery_BMS_a164_SW_Uncontrolled_Regen = ((rx_frame.data.u8[5] >> 7) & (0x01U)); //47|1@1+ (1,0) [0|0] "" X + battery_BMS_a165_SW_Pack_Partial_Weld = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery_BMS_a166_SW_Pack_Full_Weld = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery_BMS_a167_SW_FC_Partial_Weld = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + battery_BMS_a168_SW_FC_Full_Weld = ((rx_frame.data.u8[6] >> 3) & (0x01U)); //51|1@1+ (1,0) [0|0] "" X + battery_BMS_a169_SW_FC_Pack_Weld = ((rx_frame.data.u8[6] >> 4) & (0x01U)); //52|1@1+ (1,0) [0|0] "" X + battery_BMS_a170_SW_Limp_Mode = ((rx_frame.data.u8[6] >> 5) & (0x01U)); //53|1@1+ (1,0) [0|0] "" X + battery_BMS_a171_SW_Stack_Voltage_Sense = ((rx_frame.data.u8[6] >> 6) & (0x01U)); //54|1@1+ (1,0) [0|0] "" X + battery_BMS_a174_SW_Charge_Failure = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //57|1@1+ (1,0) [0|0] "" X + battery_BMS_a176_SW_GracefulPowerOff = ((rx_frame.data.u8[7] >> 3) & (0x01U)); //59|1@1+ (1,0) [0|0] "" X + battery_BMS_a179_SW_Hvp_12V_Fault = ((rx_frame.data.u8[7] >> 6) & (0x01U)); //62|1@1+ (1,0) [0|0] "" X + battery_BMS_a180_SW_ECU_reset_blocked = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" X + } + break; default: break; } } -#ifdef DOUBLE_BATTERY +#ifdef DOUBLE_BATTERY //Need to update battery2 void receive_can_battery2(CAN_frame rx_frame) { static uint8_t mux = 0; @@ -1052,7 +1797,7 @@ void update_values_battery2() { //This function maps all the values fetched via datalayer.battery2.status.cell_min_voltage_mV = battery2_cell_min_v; - battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); + datalayer.battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); /* Value mapping is completed. Start to check all safeties */ @@ -1227,14 +1972,14 @@ the first, for a few cycles, then stop all messages which causes the contactor #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) //Send 30ms message - if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { + if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis30 >= INTERVAL_30_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis30)); + if ((currentMillis - previousMillis50 >= INTERVAL_50_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis50)); } else { clear_event(EVENT_CAN_OVERRUN); } - previousMillis30 = currentMillis; + previousMillis50 = currentMillis; if ((datalayer.system.status.inverter_allows_contactor_closing == true) && (datalayer.battery.status.bms_status != FAULT)) { @@ -1292,6 +2037,7 @@ void printFaultCodesIfActive() { "disable the inverter protocol to proceed with contactor closing"); } // Check each symbol and print debug information if its value is 1 + // 0X3AA: 938 HVP_alertMatrix1 printDebugIfActive(battery_WatchdogReset, "ERROR: The processor has experienced a reset due to watchdog reset"); printDebugIfActive(battery_PowerLossReset, "ERROR: The processor has experienced a reset due to power loss"); printDebugIfActive(battery_SwAssertion, "ERROR: An internal software assertion has failed"); @@ -1350,9 +2096,101 @@ void printFaultCodesIfActive() { printDebugIfActive(battery_packCtrCloseFailed, "ERROR: packCtrCloseFailed is active"); printDebugIfActive(battery_fcCtrCloseFailed, "ERROR: fcCtrCloseFailed is active"); printDebugIfActive(battery_shuntThermistorMia, "ERROR: shuntThermistorMia is active"); + // 0x320 800 BMS_alertMatrix + printDebugIfActive(battery_BMS_a017_SW_Brick_OV, "ERROR: BMS_a017_SW_Brick_OV"); + printDebugIfActive(battery_BMS_a018_SW_Brick_UV, "ERROR: BMS_a018_SW_Brick_UV"); + printDebugIfActive(battery_BMS_a019_SW_Module_OT, "ERROR: BMS_a019_SW_Module_OT"); + printDebugIfActive(battery_BMS_a021_SW_Dr_Limits_Regulation, "ERROR: BMS_a021_SW_Dr_Limits_Regulation"); + printDebugIfActive(battery_BMS_a022_SW_Over_Current, "ERROR: BMS_a022_SW_Over_Current"); + printDebugIfActive(battery_BMS_a023_SW_Stack_OV, "ERROR: BMS_a023_SW_Stack_OV"); + printDebugIfActive(battery_BMS_a024_SW_Islanded_Brick, "ERROR: BMS_a024_SW_Islanded_Brick"); + printDebugIfActive(battery_BMS_a025_SW_PwrBalance_Anomaly, "ERROR: BMS_a025_SW_PwrBalance_Anomaly"); + printDebugIfActive(battery_BMS_a026_SW_HFCurrent_Anomaly, "ERROR: BMS_a026_SW_HFCurrent_Anomaly"); + printDebugIfActive(battery_BMS_a034_SW_Passive_Isolation, "ERROR: BMS_a034_SW_Passive_Isolation"); + printDebugIfActive(battery_BMS_a035_SW_Isolation, "ERROR: BMS_a035_SW_Isolation"); + printDebugIfActive(battery_BMS_a036_SW_HvpHvilFault, "ERROR: BMS_a036_SW_HvpHvilFault"); + printDebugIfActive(battery_BMS_a037_SW_Flood_Port_Open, "ERROR: BMS_a037_SW_Flood_Port_Open"); + printDebugIfActive(battery_BMS_a039_SW_DC_Link_Over_Voltage, "ERROR: BMS_a039_SW_DC_Link_Over_Voltage"); + printDebugIfActive(battery_BMS_a041_SW_Power_On_Reset, "ERROR: BMS_a041_SW_Power_On_Reset"); + printDebugIfActive(battery_BMS_a042_SW_MPU_Error, "ERROR: BMS_a042_SW_MPU_Error"); + printDebugIfActive(battery_BMS_a043_SW_Watch_Dog_Reset, "ERROR: BMS_a043_SW_Watch_Dog_Reset"); + printDebugIfActive(battery_BMS_a044_SW_Assertion, "ERROR: BMS_a044_SW_Assertion"); + printDebugIfActive(battery_BMS_a045_SW_Exception, "ERROR: BMS_a045_SW_Exception"); + printDebugIfActive(battery_BMS_a046_SW_Task_Stack_Usage, "ERROR: BMS_a046_SW_Task_Stack_Usage"); + printDebugIfActive(battery_BMS_a047_SW_Task_Stack_Overflow, "ERROR: BMS_a047_SW_Task_Stack_Overflow"); + printDebugIfActive(battery_BMS_a048_SW_Log_Upload_Request, "ERROR: BMS_a048_SW_Log_Upload_Request"); + printDebugIfActive(battery_BMS_a050_SW_Brick_Voltage_MIA, "ERROR: BMS_a050_SW_Brick_Voltage_MIA"); + printDebugIfActive(battery_BMS_a051_SW_HVC_Vref_Bad, "ERROR: BMS_a051_SW_HVC_Vref_Bad"); + printDebugIfActive(battery_BMS_a052_SW_PCS_MIA, "ERROR: BMS_a052_SW_PCS_MIA"); + printDebugIfActive(battery_BMS_a053_SW_ThermalModel_Sanity, "ERROR: BMS_a053_SW_ThermalModel_Sanity"); + printDebugIfActive(battery_BMS_a054_SW_Ver_Supply_Fault, "ERROR: BMS_a054_SW_Ver_Supply_Fault"); + printDebugIfActive(battery_BMS_a059_SW_Pack_Voltage_Sensing, "ERROR: BMS_a059_SW_Pack_Voltage_Sensing"); + printDebugIfActive(battery_BMS_a060_SW_Leakage_Test_Failure, "ERROR: BMS_a060_SW_Leakage_Test_Failure"); + printDebugIfActive(battery_BMS_a061_robinBrickOverVoltage, "ERROR: BMS_a061_robinBrickOverVoltage"); + printDebugIfActive(battery_BMS_a062_SW_BrickV_Imbalance, "ERROR: BMS_a062_SW_BrickV_Imbalance"); + printDebugIfActive(battery_BMS_a063_SW_ChargePort_Fault, "ERROR: BMS_a063_SW_ChargePort_Fault"); + printDebugIfActive(battery_BMS_a064_SW_SOC_Imbalance, "ERROR: BMS_a064_SW_SOC_Imbalance"); + printDebugIfActive(battery_BMS_a069_SW_Low_Power, "ERROR: BMS_a069_SW_Low_Power"); + printDebugIfActive(battery_BMS_a071_SW_SM_TransCon_Not_Met, "ERROR: BMS_a071_SW_SM_TransCon_Not_Met"); + printDebugIfActive(battery_BMS_a075_SW_Chg_Disable_Failure, "ERROR: BMS_a075_SW_Chg_Disable_Failure"); + printDebugIfActive(battery_BMS_a076_SW_Dch_While_Charging, "ERROR: BMS_a076_SW_Dch_While_Charging"); + printDebugIfActive(battery_BMS_a077_SW_Charger_Regulation, "ERROR: BMS_a077_SW_Charger_Regulation"); + printDebugIfActive(battery_BMS_a081_SW_Ctr_Close_Blocked, "ERROR: BMS_a081_SW_Ctr_Close_Blocked"); + printDebugIfActive(battery_BMS_a082_SW_Ctr_Force_Open, "ERROR: BMS_a082_SW_Ctr_Force_Open"); + printDebugIfActive(battery_BMS_a083_SW_Ctr_Close_Failure, "ERROR: BMS_a083_SW_Ctr_Close_Failure"); + printDebugIfActive(battery_BMS_a084_SW_Sleep_Wake_Aborted, "ERROR: BMS_a084_SW_Sleep_Wake_Aborted"); + printDebugIfActive(battery_BMS_a087_SW_Feim_Test_Blocked, "ERROR: BMS_a087_SW_Feim_Test_Blocked"); + printDebugIfActive(battery_BMS_a088_SW_VcFront_MIA_InDrive, "ERROR: BMS_a088_SW_VcFront_MIA_InDrive"); + printDebugIfActive(battery_BMS_a089_SW_VcFront_MIA, "ERROR: BMS_a089_SW_VcFront_MIA"); + printDebugIfActive(battery_BMS_a090_SW_Gateway_MIA, "ERROR: BMS_a090_SW_Gateway_MIA"); + printDebugIfActive(battery_BMS_a091_SW_ChargePort_MIA, "ERROR: BMS_a091_SW_ChargePort_MIA"); + printDebugIfActive(battery_BMS_a092_SW_ChargePort_Mia_On_Hv, "ERROR: BMS_a092_SW_ChargePort_Mia_On_Hv"); + printDebugIfActive(battery_BMS_a094_SW_Drive_Inverter_MIA, "ERROR: BMS_a094_SW_Drive_Inverter_MIA"); + printDebugIfActive(battery_BMS_a099_SW_BMB_Communication, "ERROR: BMS_a099_SW_BMB_Communication"); + printDebugIfActive(battery_BMS_a105_SW_One_Module_Tsense, "ERROR: BMS_a105_SW_One_Module_Tsense"); + printDebugIfActive(battery_BMS_a106_SW_All_Module_Tsense, "ERROR: BMS_a106_SW_All_Module_Tsense"); + printDebugIfActive(battery_BMS_a107_SW_Stack_Voltage_MIA, "ERROR: BMS_a107_SW_Stack_Voltage_MIA"); + printDebugIfActive(battery_BMS_a121_SW_NVRAM_Config_Error, "ERROR: BMS_a121_SW_NVRAM_Config_Error"); + printDebugIfActive(battery_BMS_a122_SW_BMS_Therm_Irrational, "ERROR: BMS_a122_SW_BMS_Therm_Irrational"); + printDebugIfActive(battery_BMS_a123_SW_Internal_Isolation, "ERROR: BMS_a123_SW_Internal_Isolation"); + printDebugIfActive(battery_BMS_a127_SW_shunt_SNA, "ERROR: BMS_a127_SW_shunt_SNA"); + printDebugIfActive(battery_BMS_a128_SW_shunt_MIA, "ERROR: BMS_a128_SW_shunt_MIA"); + printDebugIfActive(battery_BMS_a129_SW_VSH_Failure, "ERROR: BMS_a129_SW_VSH_Failure"); + printDebugIfActive(battery_BMS_a130_IO_CAN_Error, "ERROR: BMS_a130_IO_CAN_Error"); + printDebugIfActive(battery_BMS_a131_Bleed_FET_Failure, "ERROR: BMS_a131_Bleed_FET_Failure"); + printDebugIfActive(battery_BMS_a132_HW_BMB_OTP_Uncorrctbl, "ERROR: BMS_a132_HW_BMB_OTP_Uncorrctbl"); + printDebugIfActive(battery_BMS_a134_SW_Delayed_Ctr_Off, "ERROR: BMS_a134_SW_Delayed_Ctr_Off"); + printDebugIfActive(battery_BMS_a136_SW_Module_OT_Warning, "ERROR: BMS_a136_SW_Module_OT_Warning"); + printDebugIfActive(battery_BMS_a137_SW_Brick_UV_Warning, "ERROR: BMS_a137_SW_Brick_UV_Warning"); + printDebugIfActive(battery_BMS_a139_SW_DC_Link_V_Irrational, "ERROR: BMS_a139_SW_DC_Link_V_Irrational"); + printDebugIfActive(battery_BMS_a141_SW_BMB_Status_Warning, "ERROR: BMS_a141_SW_BMB_Status_Warning"); + printDebugIfActive(battery_BMS_a144_Hvp_Config_Mismatch, "ERROR: BMS_a144_Hvp_Config_Mismatch"); + printDebugIfActive(battery_BMS_a145_SW_SOC_Change, "ERROR: BMS_a145_SW_SOC_Change"); + printDebugIfActive(battery_BMS_a146_SW_Brick_Overdischarged, "ERROR: BMS_a146_SW_Brick_Overdischarged"); + printDebugIfActive(battery_BMS_a149_SW_Missing_Config_Block, "ERROR: BMS_a149_SW_Missing_Config_Block"); + printDebugIfActive(battery_BMS_a151_SW_external_isolation, "ERROR: BMS_a151_SW_external_isolation"); + printDebugIfActive(battery_BMS_a156_SW_BMB_Vref_bad, "ERROR: BMS_a156_SW_BMB_Vref_bad"); + printDebugIfActive(battery_BMS_a157_SW_HVP_HVS_Comms, "ERROR: BMS_a157_SW_HVP_HVS_Comms"); + printDebugIfActive(battery_BMS_a158_SW_HVP_HVI_Comms, "ERROR: BMS_a158_SW_HVP_HVI_Comms"); + printDebugIfActive(battery_BMS_a159_SW_HVP_ECU_Error, "ERROR: BMS_a159_SW_HVP_ECU_Error"); + printDebugIfActive(battery_BMS_a161_SW_DI_Open_Request, "ERROR: BMS_a161_SW_DI_Open_Request"); + printDebugIfActive(battery_BMS_a162_SW_No_Power_For_Support, "ERROR: BMS_a162_SW_No_Power_For_Support"); + printDebugIfActive(battery_BMS_a163_SW_Contactor_Mismatch, "ERROR: BMS_a163_SW_Contactor_Mismatch"); + printDebugIfActive(battery_BMS_a164_SW_Uncontrolled_Regen, "ERROR: BMS_a164_SW_Uncontrolled_Regen"); + printDebugIfActive(battery_BMS_a165_SW_Pack_Partial_Weld, "ERROR: BMS_a165_SW_Pack_Partial_Weld"); + printDebugIfActive(battery_BMS_a166_SW_Pack_Full_Weld, "ERROR: BMS_a166_SW_Pack_Full_Weld"); + printDebugIfActive(battery_BMS_a167_SW_FC_Partial_Weld, "ERROR: BMS_a167_SW_FC_Partial_Weld"); + printDebugIfActive(battery_BMS_a168_SW_FC_Full_Weld, "ERROR: BMS_a168_SW_FC_Full_Weld"); + printDebugIfActive(battery_BMS_a169_SW_FC_Pack_Weld, "ERROR: BMS_a169_SW_FC_Pack_Weld"); + printDebugIfActive(battery_BMS_a170_SW_Limp_Mode, "ERROR: BMS_a170_SW_Limp_Mode"); + printDebugIfActive(battery_BMS_a171_SW_Stack_Voltage_Sense, "ERROR: BMS_a171_SW_Stack_Voltage_Sense"); + printDebugIfActive(battery_BMS_a174_SW_Charge_Failure, "ERROR: BMS_a174_SW_Charge_Failure"); + printDebugIfActive(battery_BMS_a176_SW_GracefulPowerOff, "ERROR: BMS_a176_SW_GracefulPowerOff"); + printDebugIfActive(battery_BMS_a179_SW_Hvp_12V_Fault, "ERROR: BMS_a179_SW_Hvp_12V_Fault"); + printDebugIfActive(battery_BMS_a180_SW_ECU_reset_blocked, "ERROR: BMS_a180_SW_ECU_reset_blocked"); } -#ifdef DOUBLE_BATTERY +#ifdef DOUBLE_BATTERY //need to update battery2 void printFaultCodesIfActive_battery2() { if (battery2_packCtrsClosingAllowed == 0) { Serial.println( From 34f749d864bdf1859b1607e40422e4c30508f10c Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 18 Dec 2024 20:48:28 +1300 Subject: [PATCH 19/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 64 ++++++++++++++------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index dd1273a1..23a7d623 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -23,7 +23,6 @@ CAN_frame TESLA_221_2 = { .ID = 0x221, .data = {0x61, 0x15, 0x01, 0x00, 0x00, 0x00, 0x20, 0xBA}}; //Contactor Frame 221 - hv_up_for_drive - static uint16_t sendContactorClosingMessagesStill = 300; static uint16_t battery_cell_max_v = 3700; static uint16_t battery_cell_min_v = 3700; @@ -47,15 +46,15 @@ static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_full_pack_energy = 600; // Kwh static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt -static uint16_t battery_volts = 0; // V -static int16_t battery_amps = 0; // A -static uint16_t battery_raw_amps = 0; // A -static uint16_t battery_charge_time_remaining = 0; // Minutes +static uint16_t battery_volts = 0; // V +static int16_t battery_amps = 0; // A +static uint16_t battery_raw_amps = 0; // A +static uint16_t battery_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable -static uint16_t BMS_regenerative_limit = 0; //rename from battery_regenerative_limit -static uint16_t BMS_discharge_limit = 0; // rename from battery_discharge_limit -static uint16_t BMS_max_heat_park = 0; //rename from battery_max_heat_park -static uint16_t BMS_hvac_max_power = 0; //rename from battery_hvac_max_power +static uint16_t BMS_regenerative_limit = 0; //rename from battery_regenerative_limit +static uint16_t BMS_discharge_limit = 0; // rename from battery_discharge_limit +static uint16_t BMS_max_heat_park = 0; //rename from battery_max_heat_park +static uint16_t BMS_hvac_max_power = 0; //rename from battery_hvac_max_power //0x2d2: 722 BMSVAlimits static uint16_t battery_max_discharge_current = 0; static uint16_t battery_max_charge_current = 0; @@ -64,9 +63,10 @@ static uint16_t battery_bms_min_voltage = 0; //0x2b4: 692 PCS_dcdcRailStatus static uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt static uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt -static uint16_t battery_dcdcLvOutputCurrent = 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent +static uint16_t battery_dcdcLvOutputCurrent = + 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent //0x292: 658 BMS_socStatus -static uint16_t battery_beginning_of_life = 600; // kWh +static uint16_t battery_beginning_of_life = 600; // kWh static uint16_t battery_soc_min = 0; static uint16_t battery_soc_max = 0; static uint16_t battery_soc_ui = 0; //Change name from battery_soc_vi to reflect DBC battery_soc_ui @@ -79,10 +79,10 @@ static uint32_t battery_packConfigMultiplexer = 0; static uint32_t battery_moduleType = 0; static uint32_t battery_reservedConfig = 0; //0x332: 818 BattBrickMinMax:BMS_bmbMinMax -static int16_t battery_max_temp = 0; // C* -static int16_t battery_min_temp = 0; // C* -static uint16_t battery_BrickVoltageMax = 0; -static uint16_t battery_BrickVoltageMin = 0; +static int16_t battery_max_temp = 0; // C* +static int16_t battery_min_temp = 0; // C* +static uint16_t battery_BrickVoltageMax = 0; +static uint16_t battery_BrickVoltageMin = 0; static uint8_t battery_BrickTempMaxNum = 0; static uint8_t battery_BrickTempMinNum = 0; static uint8_t battery_BrickModelTMax = 0; @@ -403,7 +403,7 @@ static uint8_t battery_BMS_a174_SW_Charge_Failure = 1; static uint8_t battery_BMS_a179_SW_Hvp_12V_Fault = 1; static uint8_t battery_BMS_a180_SW_ECU_reset_blocked = 1; -#ifdef DOUBLE_BATTERY //need to update for battery2 +#ifdef DOUBLE_BATTERY //need to update for battery2 static uint32_t battery2_total_discharge = 0; static uint32_t battery2_total_charge = 0; static uint16_t battery2_volts = 0; // V @@ -852,7 +852,7 @@ void receive_can_battery(CAN_frame rx_frame) { mux = (rx_frame.data.u8[0] & 0x02); //BMS_energyStatusIndex M : 0|2@1+ (1,0) [0|0] "" X if (mux == 0) { - battery_nominal_full_pack_energy_m0 = + battery_nominal_full_pack_energy_m0 = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); //16|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended battery_nominal_energy_remaining_m0 = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); //32|16@1+ (0.02,0) [0|0] "kWh"//to datalayer_extended @@ -958,7 +958,7 @@ void receive_can_battery(CAN_frame rx_frame) { battery_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); battery_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC break; - case 0x224: //548 PCS_dcdcStatus: + case 0x224: //548 PCS_dcdcStatus: battery_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; battery_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" battery_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" @@ -987,15 +987,15 @@ void receive_can_battery(CAN_frame rx_frame) { break; case 0x252: //Limit //BMS_powerAvailable252: BMS_regenerative_limit = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * - 0.01; //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW + 0.01; //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW BMS_discharge_limit = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) * - 0.013; //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? + 0.013; //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? BMS_max_heat_park = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]) * - 0.01; //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW + 0.01; //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW BMS_hvac_max_power = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))) * - 0.02; //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? - //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver - //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] "" Receiver + 0.02; //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? + //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver + //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] "" Receiver break; case 0x132: //battery amps/volts //HVBattAmpVolt battery_volts = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * @@ -1148,7 +1148,7 @@ void receive_can_battery(CAN_frame rx_frame) { ((rx_frame.data.u8[2] & (0xFFU)) << 8) | (rx_frame.data.u8[1] & (0xFFU)); // m22 : 8|24@1+ (0.01,0) [0|0] "kWh" X } - break; + break; case 0x401: // Cell stats //BrickVoltages mux = (rx_frame.data.u8[0]); //MultiplexSelector M : 0|8@1+ (1,0) [0|0] "" //StatusFlags : 8|8@1+ (1,0) [0|0] "" @@ -1221,13 +1221,17 @@ void receive_can_battery(CAN_frame rx_frame) { mux = (rx_frame.data.u8[0] & (0xFF)); if (mux == 1) { battery_packConfigMultiplexer = (rx_frame.data.u8[0] & (0xff)); //0|8@1+ (1,0) [0|1] "" - battery_moduleType = (rx_frame.data.u8[1] & (0x07)); //8|3@1+ (1,0) [0|4] ""//0 "UNKNOWN" 1 "E3_NCT" 2 "E1_NCT" 3 "E3_CT" 4 "E1_CT" 5 "E1_CP" ;//to datalayer_extended - battery_packMass = (rx_frame.data.u8[2]) + 300; //16|8@1+ (1,300) [342|469] "kg" + battery_moduleType = + (rx_frame.data.u8[1] & + (0x07)); //8|3@1+ (1,0) [0|4] ""//0 "UNKNOWN" 1 "E3_NCT" 2 "E1_NCT" 3 "E3_CT" 4 "E1_CT" 5 "E1_CP" ;//to datalayer_extended + battery_packMass = (rx_frame.data.u8[2]) + 300; //16|8@1+ (1,300) [342|469] "kg" battery_platformMaxBusVoltage = (((rx_frame.data.u8[4] & 0x03) << 8) | (rx_frame.data.u8[3])); //24|10@1+ (0.1,375) [0|0] "V" } if (mux == 0) { - battery_reservedConfig = (rx_frame.data.u8[1] & (0x1F)); //8|5@1+ (1,0) [0|31] ""//0 "BMS_CONFIG_0" 1 "BMS_CONFIG_1" 10 "BMS_CONFIG_10" 11 "BMS_CONFIG_11" 12 "BMS_CONFIG_12" 13 "BMS_CONFIG_13" 14 "BMS_CONFIG_14" 15 "BMS_CONFIG_15" 16 "BMS_CONFIG_16" 17 "BMS_CONFIG_17" 18 "BMS_CONFIG_18" 19 "BMS_CONFIG_19" 2 "BMS_CONFIG_2" 20 "BMS_CONFIG_20" 21 "BMS_CONFIG_21" 22 "BMS_CONFIG_22" 23 "BMS_CONFIG_23" 24 "BMS_CONFIG_24" 25 "BMS_CONFIG_25" 26 "BMS_CONFIG_26" 27 "BMS_CONFIG_27" 28 "BMS_CONFIG_28" 29 "BMS_CONFIG_29" 3 "BMS_CONFIG_3" 30 "BMS_CONFIG_30" 31 "BMS_CONFIG_31" 4 "BMS_CONFIG_4" 5 "BMS_CONFIG_5" 6 "BMS_CONFIG_6" 7 "BMS_CONFIG_7" 8 "BMS_CONFIG_8" 9 "BMS_CONFIG_9" ; + battery_reservedConfig = + (rx_frame.data.u8[1] & + (0x1F)); //8|5@1+ (1,0) [0|31] ""//0 "BMS_CONFIG_0" 1 "BMS_CONFIG_1" 10 "BMS_CONFIG_10" 11 "BMS_CONFIG_11" 12 "BMS_CONFIG_12" 13 "BMS_CONFIG_13" 14 "BMS_CONFIG_14" 15 "BMS_CONFIG_15" 16 "BMS_CONFIG_16" 17 "BMS_CONFIG_17" 18 "BMS_CONFIG_18" 19 "BMS_CONFIG_19" 2 "BMS_CONFIG_2" 20 "BMS_CONFIG_20" 21 "BMS_CONFIG_21" 22 "BMS_CONFIG_22" 23 "BMS_CONFIG_23" 24 "BMS_CONFIG_24" 25 "BMS_CONFIG_25" 26 "BMS_CONFIG_26" 27 "BMS_CONFIG_27" 28 "BMS_CONFIG_28" 29 "BMS_CONFIG_29" 3 "BMS_CONFIG_3" 30 "BMS_CONFIG_30" 31 "BMS_CONFIG_31" 4 "BMS_CONFIG_4" 5 "BMS_CONFIG_5" 6 "BMS_CONFIG_6" 7 "BMS_CONFIG_7" 8 "BMS_CONFIG_8" 9 "BMS_CONFIG_9" ; } break; case 0x7AA: //1962 HVP_debugMessage: @@ -1489,7 +1493,7 @@ void receive_can_battery(CAN_frame rx_frame) { } } -#ifdef DOUBLE_BATTERY //Need to update battery2 +#ifdef DOUBLE_BATTERY //Need to update battery2 void receive_can_battery2(CAN_frame rx_frame) { static uint8_t mux = 0; @@ -2190,7 +2194,7 @@ void printFaultCodesIfActive() { printDebugIfActive(battery_BMS_a180_SW_ECU_reset_blocked, "ERROR: BMS_a180_SW_ECU_reset_blocked"); } -#ifdef DOUBLE_BATTERY //need to update battery2 +#ifdef DOUBLE_BATTERY //need to update battery2 void printFaultCodesIfActive_battery2() { if (battery2_packCtrsClosingAllowed == 0) { Serial.println( From 6ed3b7ea089ff647c3f102033b3893ce552e0588 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:05:08 +1300 Subject: [PATCH 20/93] Update TESLA-BATTERY.cpp Update battery2 info to match. --- Software/src/battery/TESLA-BATTERY.cpp | 854 +++++++++++++++++++++++-- 1 file changed, 787 insertions(+), 67 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 23a7d623..26fa6f0b 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -404,13 +404,14 @@ static uint8_t battery_BMS_a179_SW_Hvp_12V_Fault = 1; static uint8_t battery_BMS_a180_SW_ECU_reset_blocked = 1; #ifdef DOUBLE_BATTERY //need to update for battery2 + +static uint16_t battery2_cell_max_v = 3700; +static uint16_t battery2_cell_min_v = 3700; +static uint16_t battery2_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV +//0x3d2: 978 BMS_kwhCounter static uint32_t battery2_total_discharge = 0; static uint32_t battery2_total_charge = 0; -static uint16_t battery2_volts = 0; // V -static int16_t battery2_amps = 0; // A -static uint16_t battery2_raw_amps = 0; // A -static int16_t battery2_max_temp = 0; // C* -static int16_t battery2_min_temp = 0; // C* +//0x352: 850 BMS_energyStatus static uint16_t battery2_energy_buffer = 0; static uint16_t battery2_energy_buffer_m1 = 0; // kWh static uint16_t battery2_energy_to_charge_complete = 0; @@ -425,28 +426,50 @@ static uint16_t battery2_nominal_energy_remaining = 0; static uint16_t battery2_nominal_energy_remaining_m0 = 0; // kWh static uint16_t battery2_nominal_full_pack_energy = 600; static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh -static uint16_t battery2_beginning_of_life = 600; +//0x132 306 HVBattAmpVolt +static uint16_t battery2_volts = 0; // V +static int16_t battery2_amps = 0; // A +static uint16_t battery2_raw_amps = 0; // A static uint16_t battery2_charge_time_remaining = 0; // Minutes -static uint16_t battery2_regenerative_limit = 0; -static uint16_t battery2_discharge_limit = 0; -static uint16_t battery2_max_heat_park = 0; -static uint16_t battery2_hvac_max_power = 0; +//0x252 594 BMS_powerAvailable +static uint16_t BMS2_regenerative_limit = 0; +static uint16_t BMS2_discharge_limit = 0; +static uint16_t BMS2_max_heat_park = 0; +static uint16_t BMS2_hvac_max_power = 0; +//0x2d2: 722 BMSVAlimits static uint16_t battery2_max_discharge_current = 0; static uint16_t battery2_max_charge_current = 0; static uint16_t battery2_bms_max_voltage = 0; static uint16_t battery2_bms_min_voltage = 0; +//0x2b4: 692 PCS_dcdcRailStatus static uint16_t battery2_dcdcHvBusVolt = 0; //update name static uint16_t battery2_dcdcLvBusVolt = 0; //update name static uint16_t battery2_dcdcLvOutputCurrent = 0; //update name +//0x292: 658 BMS_socStatus +static uint16_t battery2_beginning_of_life = 600; static uint16_t battery2_soc_min = 0; static uint16_t battery2_soc_max = 0; static uint16_t battery2_soc_ui = 0; static uint16_t battery2_soc_ave = 0; -static uint16_t battery2_cell_max_v = 3700; -static uint16_t battery2_cell_min_v = 3700; -static uint16_t battery2_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV -static uint8_t battery2_max_vno = 0; -static uint8_t battery2_min_vno = 0; +static uint8_t battery2_battTempPct = 0; +//0x392: BMS_packConfig +static uint32_t battery2_packMass = 0; +static uint32_t battery2_platformMaxBusVoltage = 0; +static uint32_t battery2_packConfigMultiplexer = 0; +static uint32_t battery2_moduleType = 0; +static uint32_t battery2_reservedConfig = 0; +//0x332: 818 BattBrickMinMax:BMS_bmbMinMax +static int16_t battery2_max_temp = 0; // C* +static int16_t battery2_min_temp = 0; // C* +static uint16_t battery2_BrickVoltageMax = 0; +static uint16_t battery2_BrickVoltageMin = 0; +static uint8_t battery2_BrickTempMaxNum = 0; +static uint8_t battery2_BrickTempMinNum = 0; +static uint8_t battery2_BrickModelTMax = 0; +static uint8_t battery2_BrickModelTMin = 0; +static uint8_t battery2_BrickVoltageMaxNum = 0; //rename from battery_max_vno +static uint8_t battery2_BrickVoltageMinNum = 0; //rename from battery_min_vno +//0x20A: 522 HVP_contactorState static uint8_t battery2_contactor = 0; //State of contactor static uint8_t battery2_hvil_status = 0; static uint8_t battery2_packContNegativeState = 0; @@ -454,13 +477,159 @@ static uint8_t battery2_packContPositiveState = 0; static uint8_t battery2_packContactorSetState = 0; static uint8_t battery2_packCtrsClosingAllowed = 0; static uint8_t battery2_pyroTestInProgress = 0; -static uint8_t battery2_battTempPct = 0; -static uint32_t battery2_packMass = 0; -static uint32_t battery2_platformMaxBusVoltage = 0; -static uint32_t battery2_packConfigMultiplexer = 0; -static uint32_t battery2_moduleType = 0; -static uint32_t battery2_reservedConfig = 0; -//Fault codes +static uint8_t battery2_packCtrsOpenNowRequested = 0; +static uint8_t battery2_packCtrsOpenRequested = 0; +static uint8_t battery2_packCtrsRequestStatus = 0; +static uint8_t battery2_packCtrsResetRequestRequired = 0; +static uint8_t battery2_dcLinkAllowedToEnergize = 0; +static uint8_t battery2_fcContNegativeAuxOpen = 0; +static uint8_t battery2_fcContNegativeState = 0; +static uint8_t battery2_fcContPositiveAuxOpen = 0; +static uint8_t battery2_fcContPositiveState = 0; +static uint8_t battery2_fcContactorSetState = 0; +static uint8_t battery2_fcCtrsClosingAllowed = 0; +static uint8_t battery2_fcCtrsOpenNowRequested = 0; +static uint8_t battery2_fcCtrsOpenRequested = 0; +static uint8_t battery2_fcCtrsRequestStatus = 0; +static uint8_t battery2_fcCtrsResetRequestRequired = 0; +static uint8_t battery2_fcLinkAllowedToEnergize = 0; +//0x212: 530 BMS_status +static uint8_t battery2_BMS_hvacPowerRequest = 0; +static uint8_t battery2_BMS_notEnoughPowerForDrive = 0; +static uint8_t battery2_BMS_notEnoughPowerForSupport = 0; +static uint8_t battery2_BMS_preconditionAllowed = 0; +static uint8_t battery2_BMS_updateAllowed = 0; +static uint8_t battery2_BMS_activeHeatingWorthwhile = 0; +static uint8_t battery2_BMS_cpMiaOnHvs = 0; +static uint8_t battery2_BMS_contactorState = 0; +static uint8_t battery2_BMS_state = 0; +static uint8_t battery2_BMS_hvState = 0; +static uint16_t battery2_BMS_isolationResistance = 0; +static uint8_t battery2_BMS_chargeRequest = 0; +static uint8_t battery2_BMS_keepWarmRequest = 0; +static uint8_t battery2_BMS_uiChargeStatus = 0; +static uint8_t battery2_BMS_diLimpRequest = 0; +static uint8_t battery2_BMS_okToShipByAir = 0; +static uint8_t battery2_BMS_okToShipByLand = 0; +static uint32_t battery2_BMS_chgPowerAvailable = 0; +static uint8_t battery2_BMS_chargeRetryCount = 0; +static uint8_t battery2_BMS_pcsPwmEnabled = 0; +static uint8_t battery2_BMS_ecuLogUploadRequest = 0; +static uint8_t battery2_BMS_minPackTemperature = 0; +// 0x224:548 PCS_dcdcStatus +static uint8_t battery2_PCS_dcdcPrechargeStatus = 0; +static uint8_t battery2_PCS_dcdc12VSupportStatus = 0; +static uint8_t battery2_PCS_dcdcHvBusDischargeStatus = 0; +static uint16_t battery2_PCS_dcdcMainState = 0; +static uint8_t battery2_PCS_dcdcSubState = 0; +static uint8_t battery2_PCS_dcdcFaulted = 0; +static uint8_t battery2_PCS_dcdcOutputIsLimited = 0; +static uint32_t battery2_PCS_dcdcMaxOutputCurrentAllowed = 0; +static uint8_t battery2_PCS_dcdcPrechargeRtyCnt = 0; +static uint8_t battery2_PCS_dcdc12VSupportRtyCnt = 0; +static uint8_t battery2_PCS_dcdcDischargeRtyCnt = 0; +static uint8_t battery2_PCS_dcdcPwmEnableLine = 0; +static uint8_t battery2_PCS_dcdcSupportingFixedLvTarget = 0; +static uint8_t battery2_PCS_ecuLogUploadRequest = 0; +static uint8_t battery2_PCS_dcdcPrechargeRestartCnt = 0; +static uint8_t battery2_PCS_dcdcInitialPrechargeSubState = 0; +//0x312: 786 BMS_thermalStatus +static uint16_t BMS2_powerDissipation = 0; +static uint16_t BMS2_flowRequest = 0; +static uint16_t BMS2_inletActiveCoolTargetT = 0; +static uint16_t BMS2_inletPassiveTargetT = 0; +static uint16_t BMS2_inletActiveHeatTargetT = 0; +static uint16_t BMS2_packTMin = 0; +static uint16_t BMS2_packTMax = 0; +static uint16_t BMS2_pcsNoFlowRequest = 0; +static uint16_t BMS2_noFlowRequest = 0; +//0x2A4; 676 PCS_thermalStatus +static uint16_t PCS2_chgPhATemp = 0; +static uint16_t PCS2_chgPhBTemp = 0; +static uint16_t PCS2_chgPhCTemp = 0; +static uint16_t PCS2_dcdcTemp = 0; +static uint16_t PCS2_ambientTemp = 0; +//0x2C4; 708 PCS_logging +static uint16_t PCS2_logMessageSelect = 0; +static uint16_t PCS2_dcdcMaxLvOutputCurrent = 0; +static uint16_t PCS2_dcdcCurrentLimit = 0; +static uint16_t PCS2_dcdcLvOutputCurrentTempLimit = 0; +static uint16_t PCS2_dcdcUnifiedCommand = 0; +static uint16_t PCS2_dcdcCLAControllerOutput = 0; +static uint16_t PCS2_dcdcTankVoltage = 0; +static uint16_t PCS2_dcdcTankVoltageTarget = 0; +static uint16_t PCS2_dcdcClaCurrentFreq = 0; +static uint16_t PCS2_dcdcTCommMeasured = 0; +static uint16_t PCS2_dcdcShortTimeUs = 0; +static uint16_t PCS2_dcdcHalfPeriodUs = 0; +static uint16_t PCS2_dcdcIntervalMaxFrequency = 0; +static uint16_t PCS2_dcdcIntervalMaxHvBusVolt = 0; +static uint16_t PCS2_dcdcIntervalMaxLvBusVolt = 0; +static uint16_t PCS2_dcdcIntervalMaxLvOutputCurr = 0; +static uint16_t PCS2_dcdcIntervalMinFrequency = 0; +static uint16_t PCS2_dcdcIntervalMinHvBusVolt = 0; +static uint16_t PCS2_dcdcIntervalMinLvBusVolt = 0; +static uint16_t PCS2_dcdcIntervalMinLvOutputCurr = 0; +static uint32_t PCS2_dcdc12vSupportLifetimekWh = 0; +//0x7AA: //1962 HVP_debugMessage: +static uint8_t HVP2_debugMessageMultiplexer = 0; +static uint8_t HVP2_gpioPassivePyroDepl = 0; +static uint8_t HVP2_gpioPyroIsoEn = 0; +static uint8_t HVP2_gpioCpFaultIn = 0; +static uint8_t HVP2_gpioPackContPowerEn = 0; +static uint8_t HVP2_gpioHvCablesOk = 0; +static uint8_t HVP2_gpioHVPSelfEnable = 0; +static uint8_t HVP2_gpioLed = 0; +static uint8_t HVP2_gpioCrashSignal = 0; +static uint8_t HVP2_gpioShuntDataReady = 0; +static uint8_t HVP2_gpioFcContPosAux = 0; +static uint8_t HVP2_gpioFcContNegAux = 0; +static uint8_t HVP2_gpioBmsEout = 0; +static uint8_t HVP2_gpioCpFaultOut = 0; +static uint8_t HVP2_gpioPyroPor = 0; +static uint8_t HVP2_gpioShuntEn = 0; +static uint8_t HVP2_gpioHVPVerEn = 0; +static uint8_t HVP2_gpioPackCoontPosFlywheel = 0; +static uint8_t HVP2_gpioCpLatchEnable = 0; +static uint8_t HVP2_gpioPcsEnable = 0; +static uint8_t HVP2_gpioPcsDcdcPwmEnable = 0; +static uint8_t HVP2_gpioPcsChargePwmEnable = 0; +static uint8_t HVP2_gpioFcContPowerEnable = 0; +static uint8_t HVP2_gpioHvilEnable = 0; +static uint8_t HVP2_gpioSecDrdy = 0; +static uint16_t HVP2_hvp1v5Ref = 0; +static uint16_t HVP2_shuntCurrentDebug = 0; +static uint8_t HVP2_packCurrentMia = 0; +static uint8_t HVP2_auxCurrentMia = 0; +static uint8_t HVP2_currentSenseMia = 0; +static uint8_t HVP2_shuntRefVoltageMismatch = 0; +static uint8_t HVP2_shuntThermistorMia = 0; +static uint8_t HVP2_shuntHwMia = 0; +static uint16_t HVP2_dcLinkVoltage = 0; +static uint16_t HVP2_packVoltage = 0; +static uint16_t HVP2_fcLinkVoltage = 0; +static uint16_t HVP2_packContVoltage = 0; +static uint16_t HVP2_packNegativeV = 0; +static uint16_t HVP2_packPositiveV = 0; +static uint16_t HVP2_pyroAnalog = 0; +static uint16_t HVP2_dcLinkNegativeV = 0; +static uint16_t HVP2_dcLinkPositiveV = 0; +static uint16_t HVP2_fcLinkNegativeV = 0; +static uint16_t HVP2_fcContCoilCurrent = 0; +static uint16_t HVP2_fcContVoltage = 0; +static uint16_t HVP2_hvilInVoltage = 0; +static uint16_t HVP2_hvilOutVoltage = 0; +static uint16_t HVP2_fcLinkPositiveV = 0; +static uint16_t HVP2_packContCoilCurrent = 0; +static uint16_t HVP2_battery12V = 0; +static uint16_t HVP2_shuntRefVoltageDbg = 0; +static uint16_t HVP2_shuntAuxCurrentDbg = 0; +static uint16_t HVP2_shuntBarTempDbg = 0; +static uint16_t HVP2_shuntAsicTempDbg = 0; +static uint8_t HVP2_shuntAuxCurrentStatus = 0; +static uint8_t HVP2_shuntBarTempStatus = 0; +static uint8_t HVP2_shuntAsicTempStatus = 0; +//0x3aa: HVP_alertMatrix1 Fault codes static uint8_t battery2_WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset. static uint8_t battery2_PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss. static uint8_t battery2_SwAssertion = 0; //An internal software assertion has failed. @@ -519,6 +688,101 @@ static uint8_t battery2_logUploadRequest = 0; static uint8_t battery2_packCtrCloseFailed = 0; static uint8_t battery2_fcCtrCloseFailed = 0; static uint8_t battery2_shuntThermistorMia = 0; +//0x320: 800 BMS_alertMatrix +static uint8_t battery2_BMS_matrixIndex = 4; +static uint8_t battery2_BMS_a061_robinBrickOverVoltage = 1; +static uint8_t battery2_BMS_a062_SW_BrickV_Imbalance = 1; +static uint8_t battery2_BMS_a063_SW_ChargePort_Fault = 1; +static uint8_t battery2_BMS_a064_SW_SOC_Imbalance = 1; +static uint8_t battery2_BMS_a127_SW_shunt_SNA = 1; +static uint8_t battery2_BMS_a128_SW_shunt_MIA = 1; +static uint8_t battery2_BMS_a069_SW_Low_Power = 1; +static uint8_t battery2_BMS_a130_IO_CAN_Error = 1; +static uint8_t battery2_BMS_a071_SW_SM_TransCon_Not_Met = 1; +static uint8_t battery2_BMS_a132_HW_BMB_OTP_Uncorrctbl = 1; +static uint8_t battery2_BMS_a134_SW_Delayed_Ctr_Off = 1; +static uint8_t battery2_BMS_a075_SW_Chg_Disable_Failure = 1; +static uint8_t battery2_BMS_a076_SW_Dch_While_Charging = 1; +static uint8_t battery2_BMS_a017_SW_Brick_OV = 1; +static uint8_t battery2_BMS_a018_SW_Brick_UV = 1; +static uint8_t battery2_BMS_a019_SW_Module_OT = 1; +static uint8_t battery2_BMS_a021_SW_Dr_Limits_Regulation = 1; +static uint8_t battery2_BMS_a022_SW_Over_Current = 1; +static uint8_t battery2_BMS_a023_SW_Stack_OV = 1; +static uint8_t battery2_BMS_a024_SW_Islanded_Brick = 1; +static uint8_t battery2_BMS_a025_SW_PwrBalance_Anomaly = 1; +static uint8_t battery2_BMS_a026_SW_HFCurrent_Anomaly = 1; +static uint8_t battery2_BMS_a087_SW_Feim_Test_Blocked = 1; +static uint8_t battery2_BMS_a088_SW_VcFront_MIA_InDrive = 1; +static uint8_t battery2_BMS_a089_SW_VcFront_MIA = 1; +static uint8_t battery2_BMS_a090_SW_Gateway_MIA = 1; +static uint8_t battery2_BMS_a091_SW_ChargePort_MIA = 1; +static uint8_t battery2_BMS_a092_SW_ChargePort_Mia_On_Hv = 1; +static uint8_t battery2_BMS_a034_SW_Passive_Isolation = 1; +static uint8_t battery2_BMS_a035_SW_Isolation = 1; +static uint8_t battery2_BMS_a036_SW_HvpHvilFault = 1; +static uint8_t battery2_BMS_a037_SW_Flood_Port_Open = 1; +static uint8_t battery2_BMS_a158_SW_HVP_HVI_Comms = 1; +static uint8_t battery2_BMS_a039_SW_DC_Link_Over_Voltage = 1; +static uint8_t battery2_BMS_a041_SW_Power_On_Reset = 1; +static uint8_t battery2_BMS_a042_SW_MPU_Error = 1; +static uint8_t battery2_BMS_a043_SW_Watch_Dog_Reset = 1; +static uint8_t battery2_BMS_a044_SW_Assertion = 1; +static uint8_t battery2_BMS_a045_SW_Exception = 1; +static uint8_t battery2_BMS_a046_SW_Task_Stack_Usage = 1; +static uint8_t battery2_BMS_a047_SW_Task_Stack_Overflow = 1; +static uint8_t battery2_BMS_a048_SW_Log_Upload_Request = 1; +static uint8_t battery2_BMS_a169_SW_FC_Pack_Weld = 1; +static uint8_t battery2_BMS_a050_SW_Brick_Voltage_MIA = 1; +static uint8_t battery2_BMS_a051_SW_HVC_Vref_Bad = 1; +static uint8_t battery2_BMS_a052_SW_PCS_MIA = 1; +static uint8_t battery2_BMS_a053_SW_ThermalModel_Sanity = 1; +static uint8_t battery2_BMS_a054_SW_Ver_Supply_Fault = 1; +static uint8_t battery2_BMS_a176_SW_GracefulPowerOff = 1; +static uint8_t battery2_BMS_a059_SW_Pack_Voltage_Sensing = 1; +static uint8_t battery2_BMS_a060_SW_Leakage_Test_Failure = 1; +static uint8_t battery2_BMS_a077_SW_Charger_Regulation = 1; +static uint8_t battery2_BMS_a081_SW_Ctr_Close_Blocked = 1; +static uint8_t battery2_BMS_a082_SW_Ctr_Force_Open = 1; +static uint8_t battery2_BMS_a083_SW_Ctr_Close_Failure = 1; +static uint8_t battery2_BMS_a084_SW_Sleep_Wake_Aborted = 1; +static uint8_t battery2_BMS_a094_SW_Drive_Inverter_MIA = 1; +static uint8_t battery2_BMS_a099_SW_BMB_Communication = 1; +static uint8_t battery2_BMS_a105_SW_One_Module_Tsense = 1; +static uint8_t battery2_BMS_a106_SW_All_Module_Tsense = 1; +static uint8_t battery2_BMS_a107_SW_Stack_Voltage_MIA = 1; +static uint8_t battery2_BMS_a121_SW_NVRAM_Config_Error = 1; +static uint8_t battery2_BMS_a122_SW_BMS_Therm_Irrational = 1; +static uint8_t battery2_BMS_a123_SW_Internal_Isolation = 1; +static uint8_t battery2_BMS_a129_SW_VSH_Failure = 1; +static uint8_t battery2_BMS_a131_Bleed_FET_Failure = 1; +static uint8_t battery2_BMS_a136_SW_Module_OT_Warning = 1; +static uint8_t battery2_BMS_a137_SW_Brick_UV_Warning = 1; +static uint8_t battery2_BMS_a138_SW_Brick_OV_Warning = 1; +static uint8_t battery2_BMS_a139_SW_DC_Link_V_Irrational = 1; +static uint8_t battery2_BMS_a141_SW_BMB_Status_Warning = 1; +static uint8_t battery2_BMS_a144_Hvp_Config_Mismatch = 1; +static uint8_t battery2_BMS_a145_SW_SOC_Change = 1; +static uint8_t battery2_BMS_a146_SW_Brick_Overdischarged = 1; +static uint8_t battery2_BMS_a149_SW_Missing_Config_Block = 1; +static uint8_t battery2_BMS_a151_SW_external_isolation = 1; +static uint8_t battery2_BMS_a156_SW_BMB_Vref_bad = 1; +static uint8_t battery2_BMS_a157_SW_HVP_HVS_Comms = 1; +static uint8_t battery2_BMS_a159_SW_HVP_ECU_Error = 1; +static uint8_t battery2_BMS_a161_SW_DI_Open_Request = 1; +static uint8_t battery2_BMS_a162_SW_No_Power_For_Support = 1; +static uint8_t battery2_BMS_a163_SW_Contactor_Mismatch = 1; +static uint8_t battery2_BMS_a164_SW_Uncontrolled_Regen = 1; +static uint8_t battery2_BMS_a165_SW_Pack_Partial_Weld = 1; +static uint8_t battery2_BMS_a166_SW_Pack_Full_Weld = 1; +static uint8_t battery2_BMS_a167_SW_FC_Partial_Weld = 1; +static uint8_t battery2_BMS_a168_SW_FC_Full_Weld = 1; +static uint8_t battery2_BMS_a170_SW_Limp_Mode = 1; +static uint8_t battery2_BMS_a171_SW_Stack_Voltage_Sense = 1; +static uint8_t battery2_BMS_a174_SW_Charge_Failure = 1; +static uint8_t battery2_BMS_a179_SW_Hvp_12V_Fault = 1; +static uint8_t battery2_BMS_a180_SW_ECU_reset_blocked = 1; + #endif //DOUBLE_BATTERY static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", @@ -1519,33 +1783,30 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_energy_buffer_m1 = (rx_frame.data.u8[3] | rx_frame.data.u8[2]); //BMS_energyBuffer m1 : 16|16@1+ (0.01,0) [0|0] "kWh" X battery2_expected_energy_remaining_m1 = - (rx_frame.data.u8[5] | - rx_frame.data.u8[4]); //BMS_expectedEnergyRemaining m1 : 32|16@1+ (0.02,0) [0|0] "kWh" X + (rx_frame.data.u8[5] | rx_frame.data.u8[4]); //BMS_expectedEnergyRemaining m1 : 32|16@1+ (0.02,0) [0|0] "kWh" X battery2_energy_to_charge_complete_m1 = - (rx_frame.data.u8[7] | - rx_frame.data.u8[6]); //BMS_energyToChargeComplete m1 : 48|16@1+ (0.02,0) [0|0] "kWh" X + (rx_frame.data.u8[7] | rx_frame.data.u8[6]); //BMS_energyToChargeComplete m1 : 48|16@1+ (0.02,0) [0|0] "kWh" X } if (mux == 2) {} // Additional information needed on this mux, example frame: 02 26 02 20 02 80 00 00 doesn't change // older BMS <2021 without mux - //battery2_nominal_full_pack_energy = //BMS_nominalFullPackEnergy : 0|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[1] & (0x07U)) << 8) | (_d[0] & (0xFFU)); - (((rx_frame.data.u8[1] & 0x07) << 8) | (rx_frame.data.u8[0])); //Example 752 (75.2kWh) - //battery2_nominal_energy_remaining = //BMS_nominalEnergyRemaining : 11|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[2] & (0x3FU)) << 5) | ((_d[1] >> 3) & (0x1FU)); - (((rx_frame.data.u8[2] & 0x3F) << 5) | ((rx_frame.data.u8[1] & 0x1F) >> 3)); //Example 1247 * 0.1 = 124.7kWh - //battery2_expected_energy_remaining = //BMS_expectedEnergyRemaining : 22|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[4] & (0x01U)) << 10) | ((_d[3] & (0xFFU)) << 2) | ((_d[2] >> 6) & (0x03U)); - (((rx_frame.data.u8[4] & 0x01) << 10) | (rx_frame.data.u8[3] << 2) | - ((rx_frame.data.u8[2] & 0x03) >> 6)); //Example 622 (62.2kWh) - //battery2_ideal_energy_remaining = //BMS_idealEnergyRemaining : 33|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[5] & (0x0FU)) << 7) | ((_d[4] >> 1) & (0x7FU)); - (((rx_frame.data.u8[5] & 0x0F) << 7) | ((rx_frame.data.u8[4] & 0x7F) >> 1)); //Example 311 * 0.1 = 31.1kWh - //battery2_energy_to_charge_complete = // BMS_energyToChargeComplete : 44|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[6] & (0x7FU)) << 4) | ((_d[5] >> 4) & (0x0FU)); - (((rx_frame.data.u8[6] & 0x7F) << 4) | ((rx_frame.data.u8[5] & 0x0F) << 4)); //Example 147 * 0.1 = 14.7kWh - //battery2_energy_buffer = //BMS_energyBuffer : 55|8@1+ (0.1,0) [0|25.4] "KWh"// ((_d[7] & (0x7FU)) << 1) | ((_d[6] >> 7) & (0x01U)); - (((rx_frame.data.u8[7] & 0x7F) << 1) | ((rx_frame.data.u8[6] & 0x01) >> 7)); //Example 1 * 0.1 = 0 - //battery2_full_charge_complete = //BMS_fullChargeComplete : 63|1@1+ (1,0) [0|1] ""//((_d[7] >> 7) & (0x01U)); - ((rx_frame.data.u8[7] & 0x01) >> 7); + battery2_nominal_full_pack_energy = //BMS_nominalFullPackEnergy : 0|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[1] & (0x07U)) << 8) | (_d[0] & (0xFFU)); + (((rx_frame.data.u8[1] & 0x07) << 8) | (rx_frame.data.u8[0])); //Example 752 (75.2kWh) + battery2_nominal_energy_remaining = //BMS_nominalEnergyRemaining : 11|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[2] & (0x3FU)) << 5) | ((_d[1] >> 3) & (0x1FU)); + (((rx_frame.data.u8[2] & 0x3F) << 5) | ((rx_frame.data.u8[1] & 0x1F) >> 3)); //Example 1247 * 0.1 = 124.7kWh + battery2_expected_energy_remaining = //BMS_expectedEnergyRemaining : 22|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[4] & (0x01U)) << 10) | ((_d[3] & (0xFFU)) << 2) | ((_d[2] >> 6) & (0x03U)); + (((rx_frame.data.u8[4] & 0x01) << 10) | (rx_frame.data.u8[3] << 2) | + ((rx_frame.data.u8[2] & 0x03) >> 6)); //Example 622 (62.2kWh) + battery2_ideal_energy_remaining = //BMS_idealEnergyRemaining : 33|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[5] & (0x0FU)) << 7) | ((_d[4] >> 1) & (0x7FU)); + (((rx_frame.data.u8[5] & 0x0F) << 7) | ((rx_frame.data.u8[4] & 0x7F) >> 1)); //Example 311 * 0.1 = 31.1kWh + battery2_energy_to_charge_complete = // BMS_energyToChargeComplete : 44|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[6] & (0x7FU)) << 4) | ((_d[5] >> 4) & (0x0FU)); + (((rx_frame.data.u8[6] & 0x7F) << 4) | ((rx_frame.data.u8[5] & 0x0F) << 4)); //Example 147 * 0.1 = 14.7kWh + battery2_energy_buffer = //BMS_energyBuffer : 55|8@1+ (0.1,0) [0|25.4] "KWh"// ((_d[7] & (0x7FU)) << 1) | ((_d[6] >> 7) & (0x01U)); + (((rx_frame.data.u8[7] & 0x7F) << 1) | ((rx_frame.data.u8[6] & 0x01) >> 7)); //Example 1 * 0.1 = 0 + battery2_full_charge_complete = //BMS_fullChargeComplete : 63|1@1+ (1,0) [0|1] ""//((_d[7] >> 7) & (0x01U)); + ((rx_frame.data.u8[7] & 0x01) >> 7); break; - case 0x20A: - //Contactor state + case 0x20A: //522 HVP_contactorState: battery2_packContNegativeState = (rx_frame.data.u8[0] & 0x07); battery2_packContPositiveState = (rx_frame.data.u8[0] & 0x38) >> 3; battery2_contactor = (rx_frame.data.u8[1] & 0x0F); @@ -1553,22 +1814,89 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_packCtrsClosingAllowed = (rx_frame.data.u8[4] & 0x08) >> 3; battery2_pyroTestInProgress = (rx_frame.data.u8[4] & 0x20) >> 5; battery2_hvil_status = (rx_frame.data.u8[5] & 0x0F); - //HVP_packCtrsOpenNowRequested : 33|1@1+ (1,0) [0|1] "" - //HVP_packCtrsOpenRequested : 34|1@1+ (1,0) [0|1] "" - //HVP_packCtrsRequestStatus : 30|2@1+ (1,0) [0|2] "" - //HVP_packCtrsResetRequestRequired : 32|1@1+ (1,0) [0|1] "" - //HVP_dcLinkAllowedToEnergize : 36|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContNegativeAuxOpen : 7|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContNegativeState : 12|3@1+ (1,0) [0|7] "" Receiver - //HVP_fcContPositiveAuxOpen : 6|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcContPositiveState : 16|3@1+ (1,0) [0|7] "" Receiver - //HVP_fcContactorSetState : 19|4@1+ (1,0) [0|9] "" Receiver - //HVP_fcCtrsClosingAllowed : 29|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsOpenNowRequested : 27|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsOpenRequested : 28|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcCtrsRequestStatus : 24|2@1+ (1,0) [0|2] "" Receiver - //HVP_fcCtrsResetRequestRequired : 26|1@1+ (1,0) [0|1] "" Receiver - //HVP_fcLinkAllowedToEnergize : 44|2@1+ (1,0) [0|2] "" Receiver + battery2_packCtrsOpenNowRequested = + ((rx_frame.data.u8[4] >> 1) & (0x01U)); //33|1@1+ (1,0) [0|1] //to datalayer_extended + battery2_packCtrsOpenRequested = + ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|1] //to datalayer_extended + battery2_packCtrsRequestStatus = + ((rx_frame.data.u8[3] >> 6) & (0x03U)); //30|2@1+ (1,0) [0|2] //to datalayer_extended + battery2_packCtrsResetRequestRequired = + (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|1] //to datalayer_extended + battery2_dcLinkAllowedToEnergize = + ((rx_frame.data.u8[4] >> 4) & (0x01U)); //36|1@1+ (1,0) [0|1] //to datalayer_extended + battery2_fcContNegativeAuxOpen = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //7|1@1+ (1,0) [0|1] "" Receiver + battery2_fcContNegativeState = ((rx_frame.data.u8[1] >> 4) & (0x07U)); //12|3@1+ (1,0) [0|7] "" Receiver + battery2_fcContPositiveAuxOpen = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|1] "" Receiver + battery2_fcContPositiveState = (rx_frame.data.u8[2] & (0x07U)); //16|3@1+ (1,0) [0|7] "" Receiver + battery2_fcContactorSetState = ((rx_frame.data.u8[2] >> 3) & (0x0FU)); //19|4@1+ (1,0) [0|9] "" Receiver + battery2_fcCtrsClosingAllowed = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|1] "" Receiver + battery2_fcCtrsOpenNowRequested = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|1] "" Receiver + battery2_fcCtrsOpenRequested = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|1] "" Receiver + battery2_fcCtrsRequestStatus = (rx_frame.data.u8[3] & (0x03U)); //24|2@1+ (1,0) [0|2] "" Receiver + battery2_fcCtrsResetRequestRequired = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|1] "" Receiver + battery2_fcLinkAllowedToEnergize = ((rx_frame.data.u8[5] >> 4) & (0x03U)); //44|2@1+ (1,0) [0|2] "" Receiver + break; + case 0x212: //530 BMS_status: 8 + battery2_BMS_hvacPowerRequest = (rx_frame.data.u8[0] & (0x01U)); + battery2_BMS_notEnoughPowerForDrive = ((rx_frame.data.u8[0] >> 1) & (0x01U)); + battery2_BMS_notEnoughPowerForSupport = ((rx_frame.data.u8[0] >> 2) & (0x01U)); + battery2_BMS_preconditionAllowed = ((rx_frame.data.u8[0] >> 3) & (0x01U)); + battery2_BMS_updateAllowed = ((rx_frame.data.u8[0] >> 4) & (0x01U)); + battery2_BMS_activeHeatingWorthwhile = ((rx_frame.data.u8[0] >> 5) & (0x01U)); + battery2_BMS_cpMiaOnHvs = ((rx_frame.data.u8[0] >> 6) & (0x01U)); + battery2_BMS_contactorState = + (rx_frame.data.u8[1] & + (0x07U)); //0 "SNA" 1 "OPEN" 2 "OPENING" 3 "CLOSING" 4 "CLOSED" 5 "WELDED" 6 "BLOCKED" ; + battery2_BMS_state = + ((rx_frame.data.u8[1] >> 3) & + (0x0FU)); //0 "STANDBY" 1 "DRIVE" 2 "SUPPORT" 3 "CHARGE" 4 "FEIM" 5 "CLEAR_FAULT" 6 "FAULT" 7 "WELD" 8 "TEST" 9 "SNA" ; + battery2_BMS_hvState = + (rx_frame.data.u8[2] & + (0x07U)); //0 "DOWN" 1 "COMING_UP" 2 "GOING_DOWN" 3 "UP_FOR_DRIVE" 4 "UP_FOR_CHARGE" 5 "UP_FOR_DC_CHARGE" 6 "UP" ; + battery2_BMS_isolationResistance = + ((rx_frame.data.u8[3] & (0x1FU)) << 5) | + ((rx_frame.data.u8[2] >> 3) & (0x1FU)); //19|10@1+ (10,0) [0|0] "kOhm"/to datalayer_extended + battery2_BMS_chargeRequest = ((rx_frame.data.u8[3] >> 5) & (0x01U)); + battery2_BMS_keepWarmRequest = ((rx_frame.data.u8[3] >> 6) & (0x01U)); + battery2_BMS_uiChargeStatus = + (rx_frame.data.u8[4] & + (0x07U)); // 0 "DISCONNECTED" 1 "NO_POWER" 2 "ABOUT_TO_CHARGE" 3 "CHARGING" 4 "CHARGE_COMPLETE" 5 "CHARGE_STOPPED" ; + battery2_BMS_diLimpRequest = ((rx_frame.data.u8[4] >> 3) & (0x01U)); + battery2_BMS_okToShipByAir = ((rx_frame.data.u8[4] >> 4) & (0x01U)); + battery2_BMS_okToShipByLand = ((rx_frame.data.u8[4] >> 5) & (0x01U)); + battery2_BMS_chgPowerAvailable = ((rx_frame.data.u8[6] & (0x01U)) << 10) | ((rx_frame.data.u8[5] & (0xFFU)) << 2) | + ((rx_frame.data.u8[4] >> 6) & (0x03U)); //38|11@1+ (0.125,0) [0|0] "kW" + battery2_BMS_chargeRetryCount = ((rx_frame.data.u8[6] >> 1) & (0x0FU)); + battery2_BMS_pcsPwmEnabled = ((rx_frame.data.u8[6] >> 5) & (0x01U)); + battery2_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); + battery2_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC + break; + case 0x224: //548 PCS_dcdcStatus: + battery2_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; + battery2_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" + battery2_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" + battery2_PCS_dcdcMainState = + ((rx_frame.data.u8[1] & (0x03U)) << 2) | + ((rx_frame.data.u8[0] >> 6) & + (0x03U)); //0 "STANDBY" 1 "12V_SUPPORT_ACTIVE" 2 "PRECHARGE_STARTUP" 3 "PRECHARGE_ACTIVE" 4 "DIS_HVBUS_ACTIVE" 5 "SHUTDOWN" 6 "FAULTED" ; + battery2_PCS_dcdcSubState = + ((rx_frame.data.u8[1] >> 2) & + (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; + battery2_PCS_dcdcFaulted = ((rx_frame.data.u8[1] >> 7) & (0x01U)); + battery2_PCS_dcdcOutputIsLimited = ((rx_frame.data.u8[3] >> 4) & (0x01U)); + battery2_PCS_dcdcMaxOutputCurrentAllowed = ((rx_frame.data.u8[5] & (0x01U)) << 11) | + ((rx_frame.data.u8[4] & (0xFFU)) << 3) | + ((rx_frame.data.u8[3] >> 5) & (0x07U)); //29|12@1+ (0.1,0) [0|0] "A" + battery2_PCS_dcdcPrechargeRtyCnt = ((rx_frame.data.u8[5] >> 1) & (0x07U)); + battery2_PCS_dcdc12VSupportRtyCnt = ((rx_frame.data.u8[5] >> 4) & (0x0FU)); + battery2_PCS_dcdcDischargeRtyCnt = (rx_frame.data.u8[6] & (0x0FU)); + battery2_PCS_dcdcPwmEnableLine = ((rx_frame.data.u8[6] >> 4) & (0x01U)); + battery2_PCS_dcdcSupportingFixedLvTarget = ((rx_frame.data.u8[6] >> 5) & (0x01U)); + battery2_PCS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); + battery2_PCS_dcdcPrechargeRestartCnt = (rx_frame.data.u8[7] & (0x07U)); + battery2_PCS_dcdcInitialPrechargeSubState = + ((rx_frame.data.u8[7] >> 3) & + (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; break; case 0x252: //Limits @@ -1591,10 +1919,8 @@ void receive_can_battery2(CAN_frame rx_frame) { if (battery2_charge_time_remaining == 4095) { battery2_charge_time_remaining = 0; } - break; - case 0x3D2: - // total charge/discharge kwh + case 0x3D2: // total charge/discharge kwh battery2_total_discharge = ((rx_frame.data.u8[3] << 24) | (rx_frame.data.u8[2] << 16) | (rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * 0.001; @@ -1602,8 +1928,7 @@ void receive_can_battery2(CAN_frame rx_frame) { rx_frame.data.u8[4]) * 0.001; break; - case 0x332: - //min/max hist values + case 0x332: //min/max hist values //BattBrickMinMax: mux = (rx_frame.data.u8[0] & 0x03); if (mux == 1) //Cell voltages @@ -1614,14 +1939,116 @@ void receive_can_battery2(CAN_frame rx_frame) { temp = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); temp = (temp & 0xFFF); battery2_cell_min_v = temp * 2; - battery2_max_vno = 1 + (rx_frame.data.u8[4] & 0x7F); //This cell has highest voltage - battery2_min_vno = 1 + (rx_frame.data.u8[5] & 0x7F); //This cell has lowest voltage + //BattBrickVoltageMax m1 : 2|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[1] & (0x3FU)) << 6) | ((_d[0] >> 2) & (0x3FU)); + battery2_BrickVoltageMax = + ((rx_frame.data.u8[1] & (0x3F)) << 6) | ((rx_frame.data.u8[0] >> 2) & (0x3F)); //to datalayer_extended + //BattBrickVoltageMin m1 : 16|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[3] & (0x0FU)) << 8) | (_d[2] & (0xFFU)); + battery2_BrickVoltageMin = + ((rx_frame.data.u8[3] & (0x0F)) << 8) | (rx_frame.data.u8[2] & (0xFF)); //to datalayer_extended + //BattBrickVoltageMaxNum m1 : 32|7@1+ (1,1) [0|0] "" Receiver + battery2_BrickVoltageMaxNum = 1 + (rx_frame.data.u8[4] & 0x7F); //This cell has highest voltage + battery2_BrickVoltageMinNum = 1 + (rx_frame.data.u8[5] & 0x7F); //This cell has lowest voltage } if (mux == 0) //Temperature sensors { battery2_max_temp = (rx_frame.data.u8[2] * 5) - 400; //Temperature values have 40.0*C offset, 0.5*C /bit battery2_min_temp = (rx_frame.data.u8[3] * 5) - 400; //Multiply by 5 and remove offset to get C+1 (0x61*5=485-400=8.5*C) + //BattBrickTempMaxNum m0 : 2|4@1+ (1,0) [0|0] "" ((_d[0] >> 2) & (0x0FU)); + battery2_BrickTempMaxNum = ((rx_frame.data.u8[0] >> 2) & (0x0F)); //to datalayer_extended + //BattBrickTempMinNum m0 : 8|4@1+ (1,0) [0|0] "" (_d[1] & (0x0FU)); + battery2_BrickTempMinNum = (rx_frame.data.u8[1] & (0x0F)); //to datalayer_extended + //BattBrickModelTMax m0 : 32|8@1+ (0.5,-40) [0|0] "C" (_d[4] & (0xFFU)); + battery2_BrickModelTMax = (rx_frame.data.u8[4] & (0xFFU)); //to datalayer_extended + //BattBrickModelTMin m0 : 40|8@1+ (0.5,-40) [0|0] "C" (_d[5] & (0xFFU)); + battery2_BrickModelTMin = (rx_frame.data.u8[5] & (0xFFU)); //to datalayer_extended + } + break; + case 0x312: // 786 BMS_thermalStatus + BMS2_powerDissipation = + ((rx_frame.data.u8[1] & (0x03U)) << 8) | (rx_frame.data.u8[0] & (0xFFU)); //0|10@1+ (0.02,0) [0|0] "kW" + BMS2_flowRequest = ((rx_frame.data.u8[2] & (0x01U)) << 6) | + ((rx_frame.data.u8[1] >> 2) & (0x3FU)); //10|7@1+ (0.3,0) [0|0] "LPM" + BMS2_inletActiveCoolTargetT = ((rx_frame.data.u8[3] & (0x03U)) << 7) | + ((rx_frame.data.u8[2] >> 1) & (0x7FU)); //17|9@1+ (0.25,-25) [0|0] "DegC" + BMS2_inletPassiveTargetT = ((rx_frame.data.u8[4] & (0x07U)) << 6) | + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //26|9@1+ (0.25,-25) [0|0] "DegC" X + BMS2_inletActiveHeatTargetT = ((rx_frame.data.u8[5] & (0x0FU)) << 5) | + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|9@1+ (0.25,-25) [0|0] "DegC" + BMS2_packTMin = ((rx_frame.data.u8[6] & (0x1FU)) << 4) | + ((rx_frame.data.u8[5] >> 4) & (0x0FU)); //44|9@1+ (0.25,-25) [-25|100] "DegC" + BMS2_packTMax = ((rx_frame.data.u8[7] & (0x3FU)) << 3) | + ((rx_frame.data.u8[6] >> 5) & (0x07U)); //53|9@1+ (0.25,-25) [-25|100] "DegC" + BMS2_pcsNoFlowRequest = ((rx_frame.data.u8[7] >> 6) & (0x01U)); // 62|1@1+ (1,0) [0|0] "" + BMS2_noFlowRequest = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" + break; + case 0x2A4: //676 PCS_thermalStatus + PCS2_chgPhATemp = + ((rx_frame.data.u8[1] & (0x07U)) << 8) | (rx_frame.data.u8[0] & (0xFFU)); //0|11@1- (0.1,40) [0|0] "C + PCS2_chgPhBTemp = + ((rx_frame.data.u8[2] & (0x3FU)) << 5) | ((rx_frame.data.u8[1] >> 3) & (0x1FU)); //11|11@1- (0.1,40) [0|0] "C + PCS2_chgPhCTemp = + ((rx_frame.data.u8[4] & (0x07U)) << 8) | (rx_frame.data.u8[3] & (0xFFU)); //24|11@1- (0.1,40) [0|0] "C" + PCS2_dcdcTemp = ((rx_frame.data.u8[5] & (0x3FU)) << 5) | + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|11@1- (0.1,40) [0|0] "C" + PCS2_ambientTemp = + ((rx_frame.data.u8[7] & (0x07U)) << 8) | (rx_frame.data.u8[6] & (0xFFU)); //48|11@1- (0.1,40) [0|0] "C" + break; + case 0x2C4: // 708 PCS_logging: not all frames are listed, just ones relating to dcdc + mux = (rx_frame.data.u8[0] & (0x1FU)); + //PCS_logMessageSelect = (rx_frame.data.u8[0] & (0x1FU)); //0|5@1+ (1,0) [0|0] "" + if (mux == 6) { + PCS2_dcdcMaxLvOutputCurrent = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //m6 : 28|12@1+ (0.1,0) [0|0] "A" X + PCS2_dcdcCurrentLimit = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //m6 : 40|12@1+ (0.1,0) [0|0] "A" X + PCS2_dcdcLvOutputCurrentTempLimit = ((rx_frame.data.u8[7] & (0xFFU)) << 4) | + ((rx_frame.data.u8[6] >> 4) & (0x0FU)); //m6 : 52|12@1+ (0.1,0) [0|0] "A" X + } + if (mux == 7) { + PCS2_dcdcUnifiedCommand = ((rx_frame.data.u8[1] & (0x7FU)) << 3) | + ((rx_frame.data.u8[0] >> 5) & (0x07U)); //m7 : 5|10@1+ (0.001,0) [0|0] "1" X + PCS2_dcdcCLAControllerOutput = ((rx_frame.data.u8[3] & (0x03U)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //m7 : 16|10@1+ (0.001,0) [0|0] "1" X + PCS2_dcdcTankVoltage = ((rx_frame.data.u8[4] & (0x1FU)) << 6) | + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //m7 : 26|11@1- (1,0) [0|0] "V" X + PCS2_dcdcTankVoltageTarget = ((rx_frame.data.u8[5] & (0x7FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m7 : 37|10@1+ (1,0) [0|0] "V" X + PCS2_dcdcClaCurrentFreq = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //P m7 : 48|12@1+ (0.0976563,0) [0|0] "kHz" X + } + if (mux == 8) { + PCS2_dcdcTCommMeasured = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m8 : 8|16@1- (0.00195313,0) [0|0] "us" X + PCS2_dcdcShortTimeUs = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); // m8 : 24|16@1+ (0.000488281,0) [0|0] "us" X + PCS2_dcdcHalfPeriodUs = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); // m8 : 40|16@1+ (0.000488281,0) [0|0] "us" X + } + if (mux == 18) { + PCS2_dcdcIntervalMaxFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m18 : 8|12@1+ (1,0) [0|0] "kHz" X + PCS2_dcdcIntervalMaxHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //m18 : 24|13@1+ (0.1,0) [0|0] "V" X + PCS2_dcdcIntervalMaxLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m18 : 37|9@1+ (0.1,0) [0|0] "V" X + PCS2_dcdcIntervalMaxLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //m18 : 48|12@1+ (1,0) [0|0] "A" X + } + if (mux == 19) { + PCS2_dcdcIntervalMinFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //m19 : 8|12@1+ (1,0) [0|0] "kHz" X + PCS2_dcdcIntervalMinHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //m19 : 24|13@1+ (0.1,0) [0|0] "V" X + PCS2_dcdcIntervalMinLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | + ((rx_frame.data.u8[4] >> 5) & (0x07U)); //m19 : 37|9@1+ (0.1,0) [0|0] "V" X + PCS2_dcdcIntervalMinLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); // m19 : 48|12@1+ (1,0) [0|0] "A" X + } + if (mux == 22) { + PCS2_dcdc12vSupportLifetimekWh = ((rx_frame.data.u8[3] & (0xFFU)) << 16) | + ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m22 : 8|24@1+ (0.01,0) [0|0] "kWh" X } break; case 0x401: // Cell stats @@ -1692,6 +2119,103 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_reservedConfig = (rx_frame.data.u8[1] & (0x1F)); } break; + case 0x7AA: //1962 HVP_debugMessage: + mux = (rx_frame.data.u8[0] & (0x0FU)); + //HVP_debugMessageMultiplexer = (rx_frame.data.u8[0] & (0x0FU)); //0|4@1+ (1,0) [0|6] "" + if (mux == 0) { + HVP2_gpioPassivePyroDepl = ((rx_frame.data.u8[0] >> 4) & (0x01U)); //: 4|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPyroIsoEn = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //: 5|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioCpFaultIn = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //: 6|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPackContPowerEn = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //: 7|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioHvCablesOk = (rx_frame.data.u8[1] & (0x01U)); //: 8|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioHvpSelfEnable = ((rx_frame.data.u8[1] >> 1) & (0x01U)); //: 9|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioLed = ((rx_frame.data.u8[1] >> 2) & (0x01U)); //: 10|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioCrashSignal = ((rx_frame.data.u8[1] >> 3) & (0x01U)); //: 11|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioShuntDataReady = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //: 12|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioFcContPosAux = ((rx_frame.data.u8[1] >> 5) & (0x01U)); //: 13|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioFcContNegAux = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //: 14|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioBmsEout = ((rx_frame.data.u8[1] >> 7) & (0x01U)); //: 15|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioCpFaultOut = (rx_frame.data.u8[2] & (0x01U)); //: 16|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPyroPor = ((rx_frame.data.u8[2] >> 1) & (0x01U)); //: 17|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioShuntEn = ((rx_frame.data.u8[2] >> 2) & (0x01U)); //: 18|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioHvpVerEn = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //: 19|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPackCoontPosFlywheel = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //: 20|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioCpLatchEnable = ((rx_frame.data.u8[2] >> 5) & (0x01U)); //: 21|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPcsEnable = ((rx_frame.data.u8[2] >> 6) & (0x01U)); //: 22|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPcsDcdcPwmEnable = ((rx_frame.data.u8[2] >> 7) & (0x01U)); //: 23|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioPcsChargePwmEnable = (rx_frame.data.u8[3] & (0x01U)); //: 24|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioFcContPowerEnable = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //: 25|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioHvilEnable = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //: 26|1@1+ (1,0) [0|1] "" Receiver + HVP2_gpioSecDrdy = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //: 27|1@1+ (1,0) [0|1] "" Receiver + HVP2_hvp1v5Ref = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|3] "V" Receiver + HVP2_shuntCurrentDebug = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + HVP2_packCurrentMia = (rx_frame.data.u8[7] & (0x01U)); //: 56|1@1+ (1,0) [0|1] "" Receiver + HVP2_auxCurrentMia = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //: 57|1@1+ (1,0) [0|1] "" Receiver + HVP2_currentSenseMia = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|1@1+ (1,0) [0|1] "" Receiver + HVP2_shuntRefVoltageMismatch = ((rx_frame.data.u8[7] >> 3) & (0x01U)); //: 59|1@1+ (1,0) [0|1] "" Receiver + HVP2_shuntThermistorMia = ((rx_frame.data.u8[7] >> 4) & (0x01U)); //: 60|1@1+ (1,0) [0|1] "" Receiver + HVP2_shuntHwMia = ((rx_frame.data.u8[7] >> 5) & (0x01U)); //: 61|1@1+ (1,0) [0|1] "" Receiver + } + if (mux == 1) { + HVP2_dcLinkVoltage = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + HVP2_packVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + HVP2_fcLinkVoltage = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + } + if (mux == 2) { + HVP2_packContVoltage = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|30] "V" Receiver + HVP2_packNegativeV = ((rx_frame.data.u8[3] & (0xFFU)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //: 16|16@1- (0.1,0) [-550|550] "V" Receiver + HVP2_packPositiveV = ((rx_frame.data.u8[5] & (0xFFU)) << 8) | + (rx_frame.data.u8[4] & (0xFFU)); //: 32|16@1- (0.1,0) [-550|550] "V" Receiver + HVP2_pyroAnalog = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //: 48|12@1+ (0.1,0) [0|3] "V" Receiver + } + if (mux == 3) { + HVP2_dcLinkNegativeV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + HVP2_dcLinkPositiveV = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-550|550] "V" Receiver + HVP2_fcLinkNegativeV = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-550|550] "V" Receiver + } + if (mux == 4) { + HVP2_fcContCoilCurrent = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|7.5] "A" Receiver + HVP2_fcContVoltage = ((rx_frame.data.u8[3] & (0x0FU)) << 8) | + (rx_frame.data.u8[2] & (0xFFU)); //: 16|12@1+ (0.1,0) [0|30] "V" Receiver + HVP2_hvilInVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|30] "V" Receiver + HVP2_hvilOutVoltage = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|12@1+ (0.1,0) [0|30] "V" Receiver + } + if (mux == 5) { + HVP2_fcLinkPositiveV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + HVP2_packContCoilCurrent = ((rx_frame.data.u8[4] & (0x0FU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|12@1+ (0.1,0) [0|7.5] "A" Receiver + HVP2_battery12V = ((rx_frame.data.u8[5] & (0xFFU)) << 4) | + ((rx_frame.data.u8[4] >> 4) & (0x0FU)); //: 36|12@1+ (0.1,0) [0|30] "V" Receiver + HVP2_shuntRefVoltageDbg = ((rx_frame.data.u8[7] & (0xFFU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //: 48|16@1- (0.001,0) [-32.768|32.767] "V" Receiver + } + if (mux == 6) { + HVP2_shuntAuxCurrentDbg = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + HVP2_shuntBarTempDbg = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + HVP2_shuntAsicTempDbg = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + HVP2_shuntAuxCurrentStatus = (rx_frame.data.u8[7] & (0x03U)); //: 56|2@1+ (1,0) [0|3] "" Receiver + HVP2_shuntBarTempStatus = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|2@1+ (1,0) [0|3] "" Receiver + HVP2_shuntAsicTempStatus = ((rx_frame.data.u8[7] >> 4) & (0x03U)); //: 60|2@1+ (1,0) [0|3] "" Receiver + } + break; case 0x3aa: //HVP_alertMatrix1 battery2_WatchdogReset = (rx_frame.data.u8[0] & 0x01); battery2_PowerLossReset = ((rx_frame.data.u8[0] & 0x02) >> 1); @@ -1745,6 +2269,110 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_fcCtrCloseFailed = ((rx_frame.data.u8[6] & 0x02) >> 1); battery2_shuntThermistorMia = ((rx_frame.data.u8[6] & 0x04) >> 2); break; + case 0x320: //800 BMS_alertMatrix //BMS_alertMatrix 800 BMS_alertMatrix: 8 VEH + mux = (rx_frame.data.u8[0] & (0x0F)); + if (mux == 0) + ; + { //mux0 + battery2_BMS_matrixIndex = (rx_frame.data.u8[0] & (0x0F)); // 0|4@1+ (1,0) [0|0] "" X + battery2_BMS_a017_SW_Brick_OV = ((rx_frame.data.u8[2] >> 4) & (0x01)); //20|1@1+ (1,0) [0|0] "" X + battery2_BMS_a018_SW_Brick_UV = ((rx_frame.data.u8[2] >> 5) & (0x01)); //21|1@1+ (1,0) [0|0] "" X + battery2_BMS_a019_SW_Module_OT = ((rx_frame.data.u8[2] >> 6) & (0x01)); //22|1@1+ (1,0) [0|0] "" X + battery2_BMS_a021_SW_Dr_Limits_Regulation = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery2_BMS_a022_SW_Over_Current = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //25|1@1+ (1,0) [0|0] "" X + battery2_BMS_a023_SW_Stack_OV = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|0] "" X + battery2_BMS_a024_SW_Islanded_Brick = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery2_BMS_a025_SW_PwrBalance_Anomaly = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|0] "" X + battery2_BMS_a026_SW_HFCurrent_Anomaly = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|0] "" X + battery2_BMS_a034_SW_Passive_Isolation = ((rx_frame.data.u8[4] >> 5) & (0x01U)); //37|1@1+ (1,0) [0|0] "" X ? + battery2_BMS_a035_SW_Isolation = ((rx_frame.data.u8[4] >> 6) & (0x01U)); //38|1@1+ (1,0) [0|0] "" X + battery2_BMS_a036_SW_HvpHvilFault = ((rx_frame.data.u8[4] >> 6) & (0x01U)); //39|1@1+ (1,0) [0|0] "" X + battery2_BMS_a037_SW_Flood_Port_Open = (rx_frame.data.u8[5] & (0x01U)); //40|1@1+ (1,0) [0|0] "" X + battery2_BMS_a039_SW_DC_Link_Over_Voltage = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery2_BMS_a041_SW_Power_On_Reset = ((rx_frame.data.u8[5] >> 4) & (0x01U)); //44|1@1+ (1,0) [0|0] "" X + battery2_BMS_a042_SW_MPU_Error = ((rx_frame.data.u8[5] >> 5) & (0x01U)); //45|1@1+ (1,0) [0|0] "" X + battery2_BMS_a043_SW_Watch_Dog_Reset = ((rx_frame.data.u8[5] >> 6) & (0x01U)); //46|1@1+ (1,0) [0|0] "" X + battery2_BMS_a044_SW_Assertion = ((rx_frame.data.u8[5] >> 7) & (0x01U)); //47|1@1+ (1,0) [0|0] "" X + battery2_BMS_a045_SW_Exception = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery2_BMS_a046_SW_Task_Stack_Usage = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery2_BMS_a047_SW_Task_Stack_Overflow = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + battery2_BMS_a048_SW_Log_Upload_Request = ((rx_frame.data.u8[6] >> 3) & (0x01U)); //51|1@1+ (1,0) [0|0] "" X + battery2_BMS_a050_SW_Brick_Voltage_MIA = ((rx_frame.data.u8[6] >> 5) & (0x01U)); //53|1@1+ (1,0) [0|0] "" X + battery2_BMS_a051_SW_HVC_Vref_Bad = ((rx_frame.data.u8[6] >> 6) & (0x01U)); //54|1@1+ (1,0) [0|0] "" X + battery2_BMS_a052_SW_PCS_MIA = ((rx_frame.data.u8[6] >> 7) & (0x01U)); //55|1@1+ (1,0) [0|0] "" X + battery2_BMS_a053_SW_ThermalModel_Sanity = (rx_frame.data.u8[7] & (0x01U)); //56|1@1+ (1,0) [0|0] "" X + battery2_BMS_a054_SW_Ver_Supply_Fault = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //57|1@1+ (1,0) [0|0] "" X + battery2_BMS_a059_SW_Pack_Voltage_Sensing = ((rx_frame.data.u8[7] >> 6) & (0x01U)); //62|1@1+ (1,0) [0|0] "" X + battery2_BMS_a060_SW_Leakage_Test_Failure = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" X + } + if (mux == 1) { //mux1 + battery2_BMS_a061_robinBrickOverVoltage = ((rx_frame.data.u8[0] >> 4) & (0x01U)); //4|1@1+ (1,0) [0|0] "" X + battery2_BMS_a062_SW_BrickV_Imbalance = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X + battery2_BMS_a063_SW_ChargePort_Fault = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X + battery2_BMS_a064_SW_SOC_Imbalance = ((rx_frame.data.u8[0] >> 7) & (0x01U)); //7|1@1+ (1,0) [0|0] "" X + battery2_BMS_a069_SW_Low_Power = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //12|1@1+ (1,0) [0|0] "" X + battery2_BMS_a071_SW_SM_TransCon_Not_Met = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //14|1@1+ (1,0) [0|0] "" X + battery2_BMS_a075_SW_Chg_Disable_Failure = ((rx_frame.data.u8[2] >> 2) & (0x01U)); //18|1@1+ (1,0) [0|0] "" X + battery2_BMS_a076_SW_Dch_While_Charging = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //19|1@1+ (1,0) [0|0] "" X + battery2_BMS_a077_SW_Charger_Regulation = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //20|1@1+ (1,0) [0|0] "" X + battery2_BMS_a081_SW_Ctr_Close_Blocked = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery2_BMS_a082_SW_Ctr_Force_Open = ((rx_frame.data.u8[3] >> 1) & (0x01U)); //25|1@1+ (1,0) [0|0] "" X + battery2_BMS_a083_SW_Ctr_Close_Failure = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //26|1@1+ (1,0) [0|0] "" X + battery2_BMS_a084_SW_Sleep_Wake_Aborted = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery2_BMS_a087_SW_Feim_Test_Blocked = ((rx_frame.data.u8[3] >> 6) & (0x01U)); //30|1@1+ (1,0) [0|0] "" X + battery2_BMS_a088_SW_VcFront_MIA_InDrive = ((rx_frame.data.u8[3] >> 7) & (0x01U)); //31|1@1+ (1,0) [0|0] "" X + battery2_BMS_a089_SW_VcFront_MIA = (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|0] "" X + battery2_BMS_a090_SW_Gateway_MIA = ((rx_frame.data.u8[4] >> 1) & (0x01U)); //33|1@1+ (1,0) [0|0] "" X + battery2_BMS_a091_SW_ChargePort_MIA = ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|0] "" X + battery2_BMS_a092_SW_ChargePort_Mia_On_Hv = ((rx_frame.data.u8[4] >> 3) & (0x01U)); //35|1@1+ (1,0) [0|0] "" X + battery2_BMS_a094_SW_Drive_Inverter_MIA = ((rx_frame.data.u8[4] >> 5) & (0x01U)); //37|1@1+ (1,0) [0|0] "" X + battery2_BMS_a099_SW_BMB_Communication = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery2_BMS_a105_SW_One_Module_Tsense = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery2_BMS_a106_SW_All_Module_Tsense = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery2_BMS_a107_SW_Stack_Voltage_MIA = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + } + if (mux == 2) { //mux2 + battery2_BMS_a121_SW_NVRAM_Config_Error = ((rx_frame.data.u8[0] >> 4) & (0x01U)); // 4|1@1+ (1,0) [0|0] "" X + battery2_BMS_a122_SW_BMS_Therm_Irrational = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X + battery2_BMS_a123_SW_Internal_Isolation = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X + battery2_BMS_a127_SW_shunt_SNA = ((rx_frame.data.u8[1] >> 2) & (0x01U)); //10|1@1+ (1,0) [0|0] "" X + battery2_BMS_a128_SW_shunt_MIA = ((rx_frame.data.u8[1] >> 3) & (0x01U)); //11|1@1+ (1,0) [0|0] "" X + battery2_BMS_a129_SW_VSH_Failure = ((rx_frame.data.u8[1] >> 4) & (0x01U)); //12|1@1+ (1,0) [0|0] "" X + battery2_BMS_a130_IO_CAN_Error = ((rx_frame.data.u8[1] >> 5) & (0x01U)); //13|1@1+ (1,0) [0|0] "" X + battery2_BMS_a131_Bleed_FET_Failure = ((rx_frame.data.u8[1] >> 6) & (0x01U)); //14|1@1+ (1,0) [0|0] "" X + battery2_BMS_a132_HW_BMB_OTP_Uncorrctbl = ((rx_frame.data.u8[1] >> 7) & (0x01U)); //15|1@1+ (1,0) [0|0] "" X + battery2_BMS_a134_SW_Delayed_Ctr_Off = ((rx_frame.data.u8[2] >> 1) & (0x01U)); //17|1@1+ (1,0) [0|0] "" X + battery2_BMS_a136_SW_Module_OT_Warning = ((rx_frame.data.u8[2] >> 3) & (0x01U)); //19|1@1+ (1,0) [0|0] "" X + battery2_BMS_a137_SW_Brick_UV_Warning = ((rx_frame.data.u8[2] >> 4) & (0x01U)); //20|1@1+ (1,0) [0|0] "" X + battery2_BMS_a138_SW_Brick_OV_Warning = ((rx_frame.data.u8[2] >> 5) & (0x01U)); //21|1@1+ (1,0) [0|0] "" X + battery2_BMS_a139_SW_DC_Link_V_Irrational = ((rx_frame.data.u8[2] >> 6) & (0x01U)); //22|1@1+ (1,0) [0|0] "" X + battery2_BMS_a141_SW_BMB_Status_Warning = (rx_frame.data.u8[3] & (0x01U)); //24|1@1+ (1,0) [0|0] "" X + battery2_BMS_a144_Hvp_Config_Mismatch = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //27|1@1+ (1,0) [0|0] "" X + battery2_BMS_a145_SW_SOC_Change = ((rx_frame.data.u8[3] >> 4) & (0x01U)); //28|1@1+ (1,0) [0|0] "" X + battery2_BMS_a146_SW_Brick_Overdischarged = ((rx_frame.data.u8[3] >> 5) & (0x01U)); //29|1@1+ (1,0) [0|0] "" X + battery2_BMS_a149_SW_Missing_Config_Block = (rx_frame.data.u8[4] & (0x01U)); //32|1@1+ (1,0) [0|0] "" X + battery2_BMS_a151_SW_external_isolation = ((rx_frame.data.u8[4] >> 2) & (0x01U)); //34|1@1+ (1,0) [0|0] "" X + battery2_BMS_a156_SW_BMB_Vref_bad = ((rx_frame.data.u8[4] >> 7) & (0x01U)); //39|1@1+ (1,0) [0|0] "" X + battery2_BMS_a157_SW_HVP_HVS_Comms = (rx_frame.data.u8[5] & (0x01U)); //40|1@1+ (1,0) [0|0] "" X + battery2_BMS_a158_SW_HVP_HVI_Comms = ((rx_frame.data.u8[5] >> 1) & (0x01U)); //41|1@1+ (1,0) [0|0] "" X + battery2_BMS_a159_SW_HVP_ECU_Error = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //42|1@1+ (1,0) [0|0] "" X + battery2_BMS_a161_SW_DI_Open_Request = ((rx_frame.data.u8[5] >> 4) & (0x01U)); //44|1@1+ (1,0) [0|0] "" X + battery2_BMS_a162_SW_No_Power_For_Support = ((rx_frame.data.u8[5] >> 5) & (0x01U)); //45|1@1+ (1,0) [0|0] "" X + battery2_BMS_a163_SW_Contactor_Mismatch = ((rx_frame.data.u8[5] >> 6) & (0x01U)); //46|1@1+ (1,0) [0|0] "" X + battery2_BMS_a164_SW_Uncontrolled_Regen = ((rx_frame.data.u8[5] >> 7) & (0x01U)); //47|1@1+ (1,0) [0|0] "" X + battery2_BMS_a165_SW_Pack_Partial_Weld = (rx_frame.data.u8[6] & (0x01U)); //48|1@1+ (1,0) [0|0] "" X + battery2_BMS_a166_SW_Pack_Full_Weld = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X + battery2_BMS_a167_SW_FC_Partial_Weld = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X + battery2_BMS_a168_SW_FC_Full_Weld = ((rx_frame.data.u8[6] >> 3) & (0x01U)); //51|1@1+ (1,0) [0|0] "" X + battery2_BMS_a169_SW_FC_Pack_Weld = ((rx_frame.data.u8[6] >> 4) & (0x01U)); //52|1@1+ (1,0) [0|0] "" X + battery2_BMS_a170_SW_Limp_Mode = ((rx_frame.data.u8[6] >> 5) & (0x01U)); //53|1@1+ (1,0) [0|0] "" X + battery2_BMS_a171_SW_Stack_Voltage_Sense = ((rx_frame.data.u8[6] >> 6) & (0x01U)); //54|1@1+ (1,0) [0|0] "" X + battery2_BMS_a174_SW_Charge_Failure = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //57|1@1+ (1,0) [0|0] "" X + battery2_BMS_a176_SW_GracefulPowerOff = ((rx_frame.data.u8[7] >> 3) & (0x01U)); //59|1@1+ (1,0) [0|0] "" X + battery2_BMS_a179_SW_Hvp_12V_Fault = ((rx_frame.data.u8[7] >> 6) & (0x01U)); //62|1@1+ (1,0) [0|0] "" X + battery2_BMS_a180_SW_ECU_reset_blocked = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" X + } + break; default: break; } @@ -1801,7 +2429,7 @@ void update_values_battery2() { //This function maps all the values fetched via datalayer.battery2.status.cell_min_voltage_mV = battery2_cell_min_v; - datalayer.battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); + battery2_cell_deviation_mV = (battery2_cell_max_v - battery2_cell_min_v); /* Value mapping is completed. Start to check all safeties */ @@ -2270,6 +2898,98 @@ void printFaultCodesIfActive_battery2() { printDebugIfActive(battery2_packCtrCloseFailed, "ERROR: packCtrCloseFailed is active"); printDebugIfActive(battery2_fcCtrCloseFailed, "ERROR: fcCtrCloseFailed is active"); printDebugIfActive(battery2_shuntThermistorMia, "ERROR: shuntThermistorMia is active"); + // 0x320 800 BMS_alertMatrix + printDebugIfActive(battery2_BMS_a017_SW_Brick_OV, "ERROR: BMS_a017_SW_Brick_OV"); + printDebugIfActive(battery2_BMS_a018_SW_Brick_UV, "ERROR: BMS_a018_SW_Brick_UV"); + printDebugIfActive(battery2_BMS_a019_SW_Module_OT, "ERROR: BMS_a019_SW_Module_OT"); + printDebugIfActive(battery2_BMS_a021_SW_Dr_Limits_Regulation, "ERROR: BMS_a021_SW_Dr_Limits_Regulation"); + printDebugIfActive(battery2_BMS_a022_SW_Over_Current, "ERROR: BMS_a022_SW_Over_Current"); + printDebugIfActive(battery2_BMS_a023_SW_Stack_OV, "ERROR: BMS_a023_SW_Stack_OV"); + printDebugIfActive(battery2_BMS_a024_SW_Islanded_Brick, "ERROR: BMS_a024_SW_Islanded_Brick"); + printDebugIfActive(battery2_BMS_a025_SW_PwrBalance_Anomaly, "ERROR: BMS_a025_SW_PwrBalance_Anomaly"); + printDebugIfActive(battery2_BMS_a026_SW_HFCurrent_Anomaly, "ERROR: BMS_a026_SW_HFCurrent_Anomaly"); + printDebugIfActive(battery2_BMS_a034_SW_Passive_Isolation, "ERROR: BMS_a034_SW_Passive_Isolation"); + printDebugIfActive(battery2_BMS_a035_SW_Isolation, "ERROR: BMS_a035_SW_Isolation"); + printDebugIfActive(battery2_BMS_a036_SW_HvpHvilFault, "ERROR: BMS_a036_SW_HvpHvilFault"); + printDebugIfActive(battery2_BMS_a037_SW_Flood_Port_Open, "ERROR: BMS_a037_SW_Flood_Port_Open"); + printDebugIfActive(battery2_BMS_a039_SW_DC_Link_Over_Voltage, "ERROR: BMS_a039_SW_DC_Link_Over_Voltage"); + printDebugIfActive(battery2_BMS_a041_SW_Power_On_Reset, "ERROR: BMS_a041_SW_Power_On_Reset"); + printDebugIfActive(battery2_BMS_a042_SW_MPU_Error, "ERROR: BMS_a042_SW_MPU_Error"); + printDebugIfActive(battery2_BMS_a043_SW_Watch_Dog_Reset, "ERROR: BMS_a043_SW_Watch_Dog_Reset"); + printDebugIfActive(battery2_BMS_a044_SW_Assertion, "ERROR: BMS_a044_SW_Assertion"); + printDebugIfActive(battery2_BMS_a045_SW_Exception, "ERROR: BMS_a045_SW_Exception"); + printDebugIfActive(battery2_BMS_a046_SW_Task_Stack_Usage, "ERROR: BMS_a046_SW_Task_Stack_Usage"); + printDebugIfActive(battery2_BMS_a047_SW_Task_Stack_Overflow, "ERROR: BMS_a047_SW_Task_Stack_Overflow"); + printDebugIfActive(battery2_BMS_a048_SW_Log_Upload_Request, "ERROR: BMS_a048_SW_Log_Upload_Request"); + printDebugIfActive(battery2_BMS_a050_SW_Brick_Voltage_MIA, "ERROR: BMS_a050_SW_Brick_Voltage_MIA"); + printDebugIfActive(battery2_BMS_a051_SW_HVC_Vref_Bad, "ERROR: BMS_a051_SW_HVC_Vref_Bad"); + printDebugIfActive(battery2_BMS_a052_SW_PCS_MIA, "ERROR: BMS_a052_SW_PCS_MIA"); + printDebugIfActive(battery2_BMS_a053_SW_ThermalModel_Sanity, "ERROR: BMS_a053_SW_ThermalModel_Sanity"); + printDebugIfActive(battery2_BMS_a054_SW_Ver_Supply_Fault, "ERROR: BMS_a054_SW_Ver_Supply_Fault"); + printDebugIfActive(battery2_BMS_a059_SW_Pack_Voltage_Sensing, "ERROR: BMS_a059_SW_Pack_Voltage_Sensing"); + printDebugIfActive(battery2_BMS_a060_SW_Leakage_Test_Failure, "ERROR: BMS_a060_SW_Leakage_Test_Failure"); + printDebugIfActive(battery2_BMS_a061_robinBrickOverVoltage, "ERROR: BMS_a061_robinBrickOverVoltage"); + printDebugIfActive(battery2_BMS_a062_SW_BrickV_Imbalance, "ERROR: BMS_a062_SW_BrickV_Imbalance"); + printDebugIfActive(battery2_BMS_a063_SW_ChargePort_Fault, "ERROR: BMS_a063_SW_ChargePort_Fault"); + printDebugIfActive(battery2_BMS_a064_SW_SOC_Imbalance, "ERROR: BMS_a064_SW_SOC_Imbalance"); + printDebugIfActive(battery2_BMS_a069_SW_Low_Power, "ERROR: BMS_a069_SW_Low_Power"); + printDebugIfActive(battery2_BMS_a071_SW_SM_TransCon_Not_Met, "ERROR: BMS_a071_SW_SM_TransCon_Not_Met"); + printDebugIfActive(battery2_BMS_a075_SW_Chg_Disable_Failure, "ERROR: BMS_a075_SW_Chg_Disable_Failure"); + printDebugIfActive(battery2_BMS_a076_SW_Dch_While_Charging, "ERROR: BMS_a076_SW_Dch_While_Charging"); + printDebugIfActive(battery2_BMS_a077_SW_Charger_Regulation, "ERROR: BMS_a077_SW_Charger_Regulation"); + printDebugIfActive(battery2_BMS_a081_SW_Ctr_Close_Blocked, "ERROR: BMS_a081_SW_Ctr_Close_Blocked"); + printDebugIfActive(battery2_BMS_a082_SW_Ctr_Force_Open, "ERROR: BMS_a082_SW_Ctr_Force_Open"); + printDebugIfActive(battery2_BMS_a083_SW_Ctr_Close_Failure, "ERROR: BMS_a083_SW_Ctr_Close_Failure"); + printDebugIfActive(battery2_BMS_a084_SW_Sleep_Wake_Aborted, "ERROR: BMS_a084_SW_Sleep_Wake_Aborted"); + printDebugIfActive(battery2_BMS_a087_SW_Feim_Test_Blocked, "ERROR: BMS_a087_SW_Feim_Test_Blocked"); + printDebugIfActive(battery2_BMS_a088_SW_VcFront_MIA_InDrive, "ERROR: BMS_a088_SW_VcFront_MIA_InDrive"); + printDebugIfActive(battery2_BMS_a089_SW_VcFront_MIA, "ERROR: BMS_a089_SW_VcFront_MIA"); + printDebugIfActive(battery2_BMS_a090_SW_Gateway_MIA, "ERROR: BMS_a090_SW_Gateway_MIA"); + printDebugIfActive(battery2_BMS_a091_SW_ChargePort_MIA, "ERROR: BMS_a091_SW_ChargePort_MIA"); + printDebugIfActive(battery2_BMS_a092_SW_ChargePort_Mia_On_Hv, "ERROR: BMS_a092_SW_ChargePort_Mia_On_Hv"); + printDebugIfActive(battery2_BMS_a094_SW_Drive_Inverter_MIA, "ERROR: BMS_a094_SW_Drive_Inverter_MIA"); + printDebugIfActive(battery2_BMS_a099_SW_BMB_Communication, "ERROR: BMS_a099_SW_BMB_Communication"); + printDebugIfActive(battery2_BMS_a105_SW_One_Module_Tsense, "ERROR: BMS_a105_SW_One_Module_Tsense"); + printDebugIfActive(battery2_BMS_a106_SW_All_Module_Tsense, "ERROR: BMS_a106_SW_All_Module_Tsense"); + printDebugIfActive(battery2_BMS_a107_SW_Stack_Voltage_MIA, "ERROR: BMS_a107_SW_Stack_Voltage_MIA"); + printDebugIfActive(battery2_BMS_a121_SW_NVRAM_Config_Error, "ERROR: BMS_a121_SW_NVRAM_Config_Error"); + printDebugIfActive(battery2_BMS_a122_SW_BMS_Therm_Irrational, "ERROR: BMS_a122_SW_BMS_Therm_Irrational"); + printDebugIfActive(battery2_BMS_a123_SW_Internal_Isolation, "ERROR: BMS_a123_SW_Internal_Isolation"); + printDebugIfActive(battery2_BMS_a127_SW_shunt_SNA, "ERROR: BMS_a127_SW_shunt_SNA"); + printDebugIfActive(battery2_BMS_a128_SW_shunt_MIA, "ERROR: BMS_a128_SW_shunt_MIA"); + printDebugIfActive(battery2_BMS_a129_SW_VSH_Failure, "ERROR: BMS_a129_SW_VSH_Failure"); + printDebugIfActive(battery2_BMS_a130_IO_CAN_Error, "ERROR: BMS_a130_IO_CAN_Error"); + printDebugIfActive(battery2_BMS_a131_Bleed_FET_Failure, "ERROR: BMS_a131_Bleed_FET_Failure"); + printDebugIfActive(battery2_BMS_a132_HW_BMB_OTP_Uncorrctbl, "ERROR: BMS_a132_HW_BMB_OTP_Uncorrctbl"); + printDebugIfActive(battery2_BMS_a134_SW_Delayed_Ctr_Off, "ERROR: BMS_a134_SW_Delayed_Ctr_Off"); + printDebugIfActive(battery2_BMS_a136_SW_Module_OT_Warning, "ERROR: BMS_a136_SW_Module_OT_Warning"); + printDebugIfActive(battery2_BMS_a137_SW_Brick_UV_Warning, "ERROR: BMS_a137_SW_Brick_UV_Warning"); + printDebugIfActive(battery2_BMS_a139_SW_DC_Link_V_Irrational, "ERROR: BMS_a139_SW_DC_Link_V_Irrational"); + printDebugIfActive(battery2_BMS_a141_SW_BMB_Status_Warning, "ERROR: BMS_a141_SW_BMB_Status_Warning"); + printDebugIfActive(battery2_BMS_a144_Hvp_Config_Mismatch, "ERROR: BMS_a144_Hvp_Config_Mismatch"); + printDebugIfActive(battery2_BMS_a145_SW_SOC_Change, "ERROR: BMS_a145_SW_SOC_Change"); + printDebugIfActive(battery2_BMS_a146_SW_Brick_Overdischarged, "ERROR: BMS_a146_SW_Brick_Overdischarged"); + printDebugIfActive(battery2_BMS_a149_SW_Missing_Config_Block, "ERROR: BMS_a149_SW_Missing_Config_Block"); + printDebugIfActive(battery2_BMS_a151_SW_external_isolation, "ERROR: BMS_a151_SW_external_isolation"); + printDebugIfActive(battery2_BMS_a156_SW_BMB_Vref_bad, "ERROR: BMS_a156_SW_BMB_Vref_bad"); + printDebugIfActive(battery2_BMS_a157_SW_HVP_HVS_Comms, "ERROR: BMS_a157_SW_HVP_HVS_Comms"); + printDebugIfActive(battery2_BMS_a158_SW_HVP_HVI_Comms, "ERROR: BMS_a158_SW_HVP_HVI_Comms"); + printDebugIfActive(battery2_BMS_a159_SW_HVP_ECU_Error, "ERROR: BMS_a159_SW_HVP_ECU_Error"); + printDebugIfActive(battery2_BMS_a161_SW_DI_Open_Request, "ERROR: BMS_a161_SW_DI_Open_Request"); + printDebugIfActive(battery2_BMS_a162_SW_No_Power_For_Support, "ERROR: BMS_a162_SW_No_Power_For_Support"); + printDebugIfActive(battery2_BMS_a163_SW_Contactor_Mismatch, "ERROR: BMS_a163_SW_Contactor_Mismatch"); + printDebugIfActive(battery2_BMS_a164_SW_Uncontrolled_Regen, "ERROR: BMS_a164_SW_Uncontrolled_Regen"); + printDebugIfActive(battery2_BMS_a165_SW_Pack_Partial_Weld, "ERROR: BMS_a165_SW_Pack_Partial_Weld"); + printDebugIfActive(battery2_BMS_a166_SW_Pack_Full_Weld, "ERROR: BMS_a166_SW_Pack_Full_Weld"); + printDebugIfActive(battery2_BMS_a167_SW_FC_Partial_Weld, "ERROR: BMS_a167_SW_FC_Partial_Weld"); + printDebugIfActive(battery2_BMS_a168_SW_FC_Full_Weld, "ERROR: BMS_a168_SW_FC_Full_Weld"); + printDebugIfActive(battery2_BMS_a169_SW_FC_Pack_Weld, "ERROR: BMS_a169_SW_FC_Pack_Weld"); + printDebugIfActive(battery2_BMS_a170_SW_Limp_Mode, "ERROR: BMS_a170_SW_Limp_Mode"); + printDebugIfActive(battery2_BMS_a171_SW_Stack_Voltage_Sense, "ERROR: BMS_a171_SW_Stack_Voltage_Sense"); + printDebugIfActive(battery2_BMS_a174_SW_Charge_Failure, "ERROR: BMS_a174_SW_Charge_Failure"); + printDebugIfActive(battery2_BMS_a176_SW_GracefulPowerOff, "ERROR: BMS_a176_SW_GracefulPowerOff"); + printDebugIfActive(battery2_BMS_a179_SW_Hvp_12V_Fault, "ERROR: BMS_a179_SW_Hvp_12V_Fault"); + printDebugIfActive(battery2_BMS_a180_SW_ECU_reset_blocked, "ERROR: BMS_a180_SW_ECU_reset_blocked"); } #endif //DOUBLE_BATTERY From b4ea3dcf35c18427c26f6a0ae70a35aebd77a76e Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:06:28 +1300 Subject: [PATCH 21/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 155 +++++++++++++------------ 1 file changed, 80 insertions(+), 75 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 26fa6f0b..75781720 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -427,9 +427,9 @@ static uint16_t battery2_nominal_energy_remaining_m0 = 0; // kWh static uint16_t battery2_nominal_full_pack_energy = 600; static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt -static uint16_t battery2_volts = 0; // V -static int16_t battery2_amps = 0; // A -static uint16_t battery2_raw_amps = 0; // A +static uint16_t battery2_volts = 0; // V +static int16_t battery2_amps = 0; // A +static uint16_t battery2_raw_amps = 0; // A static uint16_t battery2_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable static uint16_t BMS2_regenerative_limit = 0; @@ -459,16 +459,16 @@ static uint32_t battery2_packConfigMultiplexer = 0; static uint32_t battery2_moduleType = 0; static uint32_t battery2_reservedConfig = 0; //0x332: 818 BattBrickMinMax:BMS_bmbMinMax -static int16_t battery2_max_temp = 0; // C* -static int16_t battery2_min_temp = 0; // C* +static int16_t battery2_max_temp = 0; // C* +static int16_t battery2_min_temp = 0; // C* static uint16_t battery2_BrickVoltageMax = 0; static uint16_t battery2_BrickVoltageMin = 0; static uint8_t battery2_BrickTempMaxNum = 0; static uint8_t battery2_BrickTempMinNum = 0; static uint8_t battery2_BrickModelTMax = 0; static uint8_t battery2_BrickModelTMin = 0; -static uint8_t battery2_BrickVoltageMaxNum = 0; //rename from battery_max_vno -static uint8_t battery2_BrickVoltageMinNum = 0; //rename from battery_min_vno +static uint8_t battery2_BrickVoltageMaxNum = 0; //rename from battery_max_vno +static uint8_t battery2_BrickVoltageMinNum = 0; //rename from battery_min_vno //0x20A: 522 HVP_contactorState static uint8_t battery2_contactor = 0; //State of contactor static uint8_t battery2_hvil_status = 0; @@ -1783,9 +1783,11 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_energy_buffer_m1 = (rx_frame.data.u8[3] | rx_frame.data.u8[2]); //BMS_energyBuffer m1 : 16|16@1+ (0.01,0) [0|0] "kWh" X battery2_expected_energy_remaining_m1 = - (rx_frame.data.u8[5] | rx_frame.data.u8[4]); //BMS_expectedEnergyRemaining m1 : 32|16@1+ (0.02,0) [0|0] "kWh" X + (rx_frame.data.u8[5] | + rx_frame.data.u8[4]); //BMS_expectedEnergyRemaining m1 : 32|16@1+ (0.02,0) [0|0] "kWh" X battery2_energy_to_charge_complete_m1 = - (rx_frame.data.u8[7] | rx_frame.data.u8[6]); //BMS_energyToChargeComplete m1 : 48|16@1+ (0.02,0) [0|0] "kWh" X + (rx_frame.data.u8[7] | + rx_frame.data.u8[6]); //BMS_energyToChargeComplete m1 : 48|16@1+ (0.02,0) [0|0] "kWh" X } if (mux == 2) {} // Additional information needed on this mux, example frame: 02 26 02 20 02 80 00 00 doesn't change @@ -1796,7 +1798,7 @@ void receive_can_battery2(CAN_frame rx_frame) { (((rx_frame.data.u8[2] & 0x3F) << 5) | ((rx_frame.data.u8[1] & 0x1F) >> 3)); //Example 1247 * 0.1 = 124.7kWh battery2_expected_energy_remaining = //BMS_expectedEnergyRemaining : 22|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[4] & (0x01U)) << 10) | ((_d[3] & (0xFFU)) << 2) | ((_d[2] >> 6) & (0x03U)); (((rx_frame.data.u8[4] & 0x01) << 10) | (rx_frame.data.u8[3] << 2) | - ((rx_frame.data.u8[2] & 0x03) >> 6)); //Example 622 (62.2kWh) + ((rx_frame.data.u8[2] & 0x03) >> 6)); //Example 622 (62.2kWh) battery2_ideal_energy_remaining = //BMS_idealEnergyRemaining : 33|11@1+ (0.1,0) [0|204.6] "KWh" //((_d[5] & (0x0FU)) << 7) | ((_d[4] >> 1) & (0x7FU)); (((rx_frame.data.u8[5] & 0x0F) << 7) | ((rx_frame.data.u8[4] & 0x7F) >> 1)); //Example 311 * 0.1 = 31.1kWh battery2_energy_to_charge_complete = // BMS_energyToChargeComplete : 44|11@1+ (0.1,0) [0|204.6] "KWh"// ((_d[6] & (0x7FU)) << 4) | ((_d[5] >> 4) & (0x0FU)); @@ -1806,7 +1808,7 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_full_charge_complete = //BMS_fullChargeComplete : 63|1@1+ (1,0) [0|1] ""//((_d[7] >> 7) & (0x01U)); ((rx_frame.data.u8[7] & 0x01) >> 7); break; - case 0x20A: //522 HVP_contactorState: + case 0x20A: //522 HVP_contactorState: battery2_packContNegativeState = (rx_frame.data.u8[0] & 0x07); battery2_packContPositiveState = (rx_frame.data.u8[0] & 0x38) >> 3; battery2_contactor = (rx_frame.data.u8[1] & 0x0F); @@ -1864,14 +1866,15 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_BMS_diLimpRequest = ((rx_frame.data.u8[4] >> 3) & (0x01U)); battery2_BMS_okToShipByAir = ((rx_frame.data.u8[4] >> 4) & (0x01U)); battery2_BMS_okToShipByLand = ((rx_frame.data.u8[4] >> 5) & (0x01U)); - battery2_BMS_chgPowerAvailable = ((rx_frame.data.u8[6] & (0x01U)) << 10) | ((rx_frame.data.u8[5] & (0xFFU)) << 2) | - ((rx_frame.data.u8[4] >> 6) & (0x03U)); //38|11@1+ (0.125,0) [0|0] "kW" + battery2_BMS_chgPowerAvailable = ((rx_frame.data.u8[6] & (0x01U)) << 10) | + ((rx_frame.data.u8[5] & (0xFFU)) << 2) | + ((rx_frame.data.u8[4] >> 6) & (0x03U)); //38|11@1+ (0.125,0) [0|0] "kW" battery2_BMS_chargeRetryCount = ((rx_frame.data.u8[6] >> 1) & (0x0FU)); battery2_BMS_pcsPwmEnabled = ((rx_frame.data.u8[6] >> 5) & (0x01U)); battery2_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); battery2_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC break; - case 0x224: //548 PCS_dcdcStatus: + case 0x224: //548 PCS_dcdcStatus: battery2_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; battery2_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" battery2_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" @@ -1885,8 +1888,8 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_PCS_dcdcFaulted = ((rx_frame.data.u8[1] >> 7) & (0x01U)); battery2_PCS_dcdcOutputIsLimited = ((rx_frame.data.u8[3] >> 4) & (0x01U)); battery2_PCS_dcdcMaxOutputCurrentAllowed = ((rx_frame.data.u8[5] & (0x01U)) << 11) | - ((rx_frame.data.u8[4] & (0xFFU)) << 3) | - ((rx_frame.data.u8[3] >> 5) & (0x07U)); //29|12@1+ (0.1,0) [0|0] "A" + ((rx_frame.data.u8[4] & (0xFFU)) << 3) | + ((rx_frame.data.u8[3] >> 5) & (0x07U)); //29|12@1+ (0.1,0) [0|0] "A" battery2_PCS_dcdcPrechargeRtyCnt = ((rx_frame.data.u8[5] >> 1) & (0x07U)); battery2_PCS_dcdc12VSupportRtyCnt = ((rx_frame.data.u8[5] >> 4) & (0x0FU)); battery2_PCS_dcdcDischargeRtyCnt = (rx_frame.data.u8[6] & (0x0FU)); @@ -1920,7 +1923,7 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_charge_time_remaining = 0; } break; - case 0x3D2: // total charge/discharge kwh + case 0x3D2: // total charge/discharge kwh battery2_total_discharge = ((rx_frame.data.u8[3] << 24) | (rx_frame.data.u8[2] << 16) | (rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * 0.001; @@ -1968,17 +1971,17 @@ void receive_can_battery2(CAN_frame rx_frame) { BMS2_powerDissipation = ((rx_frame.data.u8[1] & (0x03U)) << 8) | (rx_frame.data.u8[0] & (0xFFU)); //0|10@1+ (0.02,0) [0|0] "kW" BMS2_flowRequest = ((rx_frame.data.u8[2] & (0x01U)) << 6) | - ((rx_frame.data.u8[1] >> 2) & (0x3FU)); //10|7@1+ (0.3,0) [0|0] "LPM" + ((rx_frame.data.u8[1] >> 2) & (0x3FU)); //10|7@1+ (0.3,0) [0|0] "LPM" BMS2_inletActiveCoolTargetT = ((rx_frame.data.u8[3] & (0x03U)) << 7) | - ((rx_frame.data.u8[2] >> 1) & (0x7FU)); //17|9@1+ (0.25,-25) [0|0] "DegC" + ((rx_frame.data.u8[2] >> 1) & (0x7FU)); //17|9@1+ (0.25,-25) [0|0] "DegC" BMS2_inletPassiveTargetT = ((rx_frame.data.u8[4] & (0x07U)) << 6) | - ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //26|9@1+ (0.25,-25) [0|0] "DegC" X + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //26|9@1+ (0.25,-25) [0|0] "DegC" X BMS2_inletActiveHeatTargetT = ((rx_frame.data.u8[5] & (0x0FU)) << 5) | - ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|9@1+ (0.25,-25) [0|0] "DegC" + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|9@1+ (0.25,-25) [0|0] "DegC" BMS2_packTMin = ((rx_frame.data.u8[6] & (0x1FU)) << 4) | - ((rx_frame.data.u8[5] >> 4) & (0x0FU)); //44|9@1+ (0.25,-25) [-25|100] "DegC" + ((rx_frame.data.u8[5] >> 4) & (0x0FU)); //44|9@1+ (0.25,-25) [-25|100] "DegC" BMS2_packTMax = ((rx_frame.data.u8[7] & (0x3FU)) << 3) | - ((rx_frame.data.u8[6] >> 5) & (0x07U)); //53|9@1+ (0.25,-25) [-25|100] "DegC" + ((rx_frame.data.u8[6] >> 5) & (0x07U)); //53|9@1+ (0.25,-25) [-25|100] "DegC" BMS2_pcsNoFlowRequest = ((rx_frame.data.u8[7] >> 6) & (0x01U)); // 62|1@1+ (1,0) [0|0] "" BMS2_noFlowRequest = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" break; @@ -1990,7 +1993,7 @@ void receive_can_battery2(CAN_frame rx_frame) { PCS2_chgPhCTemp = ((rx_frame.data.u8[4] & (0x07U)) << 8) | (rx_frame.data.u8[3] & (0xFFU)); //24|11@1- (0.1,40) [0|0] "C" PCS2_dcdcTemp = ((rx_frame.data.u8[5] & (0x3FU)) << 5) | - ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|11@1- (0.1,40) [0|0] "C" + ((rx_frame.data.u8[4] >> 3) & (0x1FU)); //35|11@1- (0.1,40) [0|0] "C" PCS2_ambientTemp = ((rx_frame.data.u8[7] & (0x07U)) << 8) | (rx_frame.data.u8[6] & (0xFFU)); //48|11@1- (0.1,40) [0|0] "C" break; @@ -1999,56 +2002,57 @@ void receive_can_battery2(CAN_frame rx_frame) { //PCS_logMessageSelect = (rx_frame.data.u8[0] & (0x1FU)); //0|5@1+ (1,0) [0|0] "" if (mux == 6) { PCS2_dcdcMaxLvOutputCurrent = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | - ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //m6 : 28|12@1+ (0.1,0) [0|0] "A" X + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //m6 : 28|12@1+ (0.1,0) [0|0] "A" X PCS2_dcdcCurrentLimit = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //m6 : 40|12@1+ (0.1,0) [0|0] "A" X - PCS2_dcdcLvOutputCurrentTempLimit = ((rx_frame.data.u8[7] & (0xFFU)) << 4) | - ((rx_frame.data.u8[6] >> 4) & (0x0FU)); //m6 : 52|12@1+ (0.1,0) [0|0] "A" X + (rx_frame.data.u8[5] & (0xFFU)); //m6 : 40|12@1+ (0.1,0) [0|0] "A" X + PCS2_dcdcLvOutputCurrentTempLimit = + ((rx_frame.data.u8[7] & (0xFFU)) << 4) | + ((rx_frame.data.u8[6] >> 4) & (0x0FU)); //m6 : 52|12@1+ (0.1,0) [0|0] "A" X } if (mux == 7) { PCS2_dcdcUnifiedCommand = ((rx_frame.data.u8[1] & (0x7FU)) << 3) | - ((rx_frame.data.u8[0] >> 5) & (0x07U)); //m7 : 5|10@1+ (0.001,0) [0|0] "1" X + ((rx_frame.data.u8[0] >> 5) & (0x07U)); //m7 : 5|10@1+ (0.001,0) [0|0] "1" X PCS2_dcdcCLAControllerOutput = ((rx_frame.data.u8[3] & (0x03U)) << 8) | - (rx_frame.data.u8[2] & (0xFFU)); //m7 : 16|10@1+ (0.001,0) [0|0] "1" X + (rx_frame.data.u8[2] & (0xFFU)); //m7 : 16|10@1+ (0.001,0) [0|0] "1" X PCS2_dcdcTankVoltage = ((rx_frame.data.u8[4] & (0x1FU)) << 6) | - ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //m7 : 26|11@1- (1,0) [0|0] "V" X + ((rx_frame.data.u8[3] >> 2) & (0x3FU)); //m7 : 26|11@1- (1,0) [0|0] "V" X PCS2_dcdcTankVoltageTarget = ((rx_frame.data.u8[5] & (0x7FU)) << 3) | - ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m7 : 37|10@1+ (1,0) [0|0] "V" X + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m7 : 37|10@1+ (1,0) [0|0] "V" X PCS2_dcdcClaCurrentFreq = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | - (rx_frame.data.u8[6] & (0xFFU)); //P m7 : 48|12@1+ (0.0976563,0) [0|0] "kHz" X + (rx_frame.data.u8[6] & (0xFFU)); //P m7 : 48|12@1+ (0.0976563,0) [0|0] "kHz" X } if (mux == 8) { PCS2_dcdcTCommMeasured = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); // m8 : 8|16@1- (0.00195313,0) [0|0] "us" X + (rx_frame.data.u8[1] & (0xFFU)); // m8 : 8|16@1- (0.00195313,0) [0|0] "us" X PCS2_dcdcShortTimeUs = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); // m8 : 24|16@1+ (0.000488281,0) [0|0] "us" X + (rx_frame.data.u8[3] & (0xFFU)); // m8 : 24|16@1+ (0.000488281,0) [0|0] "us" X PCS2_dcdcHalfPeriodUs = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); // m8 : 40|16@1+ (0.000488281,0) [0|0] "us" X + (rx_frame.data.u8[5] & (0xFFU)); // m8 : 40|16@1+ (0.000488281,0) [0|0] "us" X } if (mux == 18) { PCS2_dcdcIntervalMaxFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); // m18 : 8|12@1+ (1,0) [0|0] "kHz" X + (rx_frame.data.u8[1] & (0xFFU)); // m18 : 8|12@1+ (1,0) [0|0] "kHz" X PCS2_dcdcIntervalMaxHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //m18 : 24|13@1+ (0.1,0) [0|0] "V" X + (rx_frame.data.u8[3] & (0xFFU)); //m18 : 24|13@1+ (0.1,0) [0|0] "V" X PCS2_dcdcIntervalMaxLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | - ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m18 : 37|9@1+ (0.1,0) [0|0] "V" X + ((rx_frame.data.u8[4] >> 5) & (0x07U)); // m18 : 37|9@1+ (0.1,0) [0|0] "V" X PCS2_dcdcIntervalMaxLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | - (rx_frame.data.u8[6] & (0xFFU)); //m18 : 48|12@1+ (1,0) [0|0] "A" X + (rx_frame.data.u8[6] & (0xFFU)); //m18 : 48|12@1+ (1,0) [0|0] "A" X } if (mux == 19) { PCS2_dcdcIntervalMinFrequency = ((rx_frame.data.u8[2] & (0x0FU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); //m19 : 8|12@1+ (1,0) [0|0] "kHz" X + (rx_frame.data.u8[1] & (0xFFU)); //m19 : 8|12@1+ (1,0) [0|0] "kHz" X PCS2_dcdcIntervalMinHvBusVolt = ((rx_frame.data.u8[4] & (0x1FU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //m19 : 24|13@1+ (0.1,0) [0|0] "V" X + (rx_frame.data.u8[3] & (0xFFU)); //m19 : 24|13@1+ (0.1,0) [0|0] "V" X PCS2_dcdcIntervalMinLvBusVolt = ((rx_frame.data.u8[5] & (0x3FU)) << 3) | - ((rx_frame.data.u8[4] >> 5) & (0x07U)); //m19 : 37|9@1+ (0.1,0) [0|0] "V" X + ((rx_frame.data.u8[4] >> 5) & (0x07U)); //m19 : 37|9@1+ (0.1,0) [0|0] "V" X PCS2_dcdcIntervalMinLvOutputCurr = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | - (rx_frame.data.u8[6] & (0xFFU)); // m19 : 48|12@1+ (1,0) [0|0] "A" X + (rx_frame.data.u8[6] & (0xFFU)); // m19 : 48|12@1+ (1,0) [0|0] "A" X } if (mux == 22) { PCS2_dcdc12vSupportLifetimekWh = ((rx_frame.data.u8[3] & (0xFFU)) << 16) | - ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); // m22 : 8|24@1+ (0.01,0) [0|0] "kWh" X + ((rx_frame.data.u8[2] & (0xFFU)) << 8) | + (rx_frame.data.u8[1] & (0xFFU)); // m22 : 8|24@1+ (0.01,0) [0|0] "kWh" X } break; case 0x401: // Cell stats @@ -2148,11 +2152,11 @@ void receive_can_battery2(CAN_frame rx_frame) { HVP2_gpioHvilEnable = ((rx_frame.data.u8[3] >> 2) & (0x01U)); //: 26|1@1+ (1,0) [0|1] "" Receiver HVP2_gpioSecDrdy = ((rx_frame.data.u8[3] >> 3) & (0x01U)); //: 27|1@1+ (1,0) [0|1] "" Receiver HVP2_hvp1v5Ref = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | - ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|3] "V" Receiver + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|3] "V" Receiver HVP2_shuntCurrentDebug = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver - HVP2_packCurrentMia = (rx_frame.data.u8[7] & (0x01U)); //: 56|1@1+ (1,0) [0|1] "" Receiver - HVP2_auxCurrentMia = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //: 57|1@1+ (1,0) [0|1] "" Receiver + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + HVP2_packCurrentMia = (rx_frame.data.u8[7] & (0x01U)); //: 56|1@1+ (1,0) [0|1] "" Receiver + HVP2_auxCurrentMia = ((rx_frame.data.u8[7] >> 1) & (0x01U)); //: 57|1@1+ (1,0) [0|1] "" Receiver HVP2_currentSenseMia = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|1@1+ (1,0) [0|1] "" Receiver HVP2_shuntRefVoltageMismatch = ((rx_frame.data.u8[7] >> 3) & (0x01U)); //: 59|1@1+ (1,0) [0|1] "" Receiver HVP2_shuntThermistorMia = ((rx_frame.data.u8[7] >> 4) & (0x01U)); //: 60|1@1+ (1,0) [0|1] "" Receiver @@ -2160,57 +2164,58 @@ void receive_can_battery2(CAN_frame rx_frame) { } if (mux == 1) { HVP2_dcLinkVoltage = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver HVP2_packVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver HVP2_fcLinkVoltage = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-3276.8|3276.7] "V" Receiver } if (mux == 2) { HVP2_packContVoltage = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | - ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|30] "V" Receiver + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|30] "V" Receiver HVP2_packNegativeV = ((rx_frame.data.u8[3] & (0xFFU)) << 8) | - (rx_frame.data.u8[2] & (0xFFU)); //: 16|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[2] & (0xFFU)); //: 16|16@1- (0.1,0) [-550|550] "V" Receiver HVP2_packPositiveV = ((rx_frame.data.u8[5] & (0xFFU)) << 8) | - (rx_frame.data.u8[4] & (0xFFU)); //: 32|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[4] & (0xFFU)); //: 32|16@1- (0.1,0) [-550|550] "V" Receiver HVP2_pyroAnalog = ((rx_frame.data.u8[7] & (0x0FU)) << 8) | - (rx_frame.data.u8[6] & (0xFFU)); //: 48|12@1+ (0.1,0) [0|3] "V" Receiver + (rx_frame.data.u8[6] & (0xFFU)); //: 48|12@1+ (0.1,0) [0|3] "V" Receiver } if (mux == 3) { HVP2_dcLinkNegativeV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver HVP2_dcLinkPositiveV = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.1,0) [-550|550] "V" Receiver HVP2_fcLinkNegativeV = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.1,0) [-550|550] "V" Receiver } if (mux == 4) { HVP2_fcContCoilCurrent = ((rx_frame.data.u8[1] & (0xFFU)) << 4) | - ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|7.5] "A" Receiver + ((rx_frame.data.u8[0] >> 4) & (0x0FU)); //: 4|12@1+ (0.1,0) [0|7.5] "A" Receiver HVP2_fcContVoltage = ((rx_frame.data.u8[3] & (0x0FU)) << 8) | - (rx_frame.data.u8[2] & (0xFFU)); //: 16|12@1+ (0.1,0) [0|30] "V" Receiver + (rx_frame.data.u8[2] & (0xFFU)); //: 16|12@1+ (0.1,0) [0|30] "V" Receiver HVP2_hvilInVoltage = ((rx_frame.data.u8[4] & (0xFFU)) << 4) | - ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|30] "V" Receiver + ((rx_frame.data.u8[3] >> 4) & (0x0FU)); //: 28|12@1+ (0.1,0) [0|30] "V" Receiver HVP2_hvilOutVoltage = ((rx_frame.data.u8[6] & (0x0FU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //: 40|12@1+ (0.1,0) [0|30] "V" Receiver + (rx_frame.data.u8[5] & (0xFFU)); //: 40|12@1+ (0.1,0) [0|30] "V" Receiver } if (mux == 5) { HVP2_fcLinkPositiveV = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-550|550] "V" Receiver HVP2_packContCoilCurrent = ((rx_frame.data.u8[4] & (0x0FU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //: 24|12@1+ (0.1,0) [0|7.5] "A" Receiver + (rx_frame.data.u8[3] & (0xFFU)); //: 24|12@1+ (0.1,0) [0|7.5] "A" Receiver HVP2_battery12V = ((rx_frame.data.u8[5] & (0xFFU)) << 4) | - ((rx_frame.data.u8[4] >> 4) & (0x0FU)); //: 36|12@1+ (0.1,0) [0|30] "V" Receiver - HVP2_shuntRefVoltageDbg = ((rx_frame.data.u8[7] & (0xFFU)) << 8) | - (rx_frame.data.u8[6] & (0xFFU)); //: 48|16@1- (0.001,0) [-32.768|32.767] "V" Receiver + ((rx_frame.data.u8[4] >> 4) & (0x0FU)); //: 36|12@1+ (0.1,0) [0|30] "V" Receiver + HVP2_shuntRefVoltageDbg = + ((rx_frame.data.u8[7] & (0xFFU)) << 8) | + (rx_frame.data.u8[6] & (0xFFU)); //: 48|16@1- (0.001,0) [-32.768|32.767] "V" Receiver } if (mux == 6) { HVP2_shuntAuxCurrentDbg = ((rx_frame.data.u8[2] & (0xFFU)) << 8) | - (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver + (rx_frame.data.u8[1] & (0xFFU)); //: 8|16@1- (0.1,0) [-3276.8|3276.7] "A" Receiver HVP2_shuntBarTempDbg = ((rx_frame.data.u8[4] & (0xFFU)) << 8) | - (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + (rx_frame.data.u8[3] & (0xFFU)); //: 24|16@1- (0.01,0) [-327.67|327.67] "C" Receiver HVP2_shuntAsicTempDbg = ((rx_frame.data.u8[6] & (0xFFU)) << 8) | - (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.01,0) [-327.67|327.67] "C" Receiver + (rx_frame.data.u8[5] & (0xFFU)); //: 40|16@1- (0.01,0) [-327.67|327.67] "C" Receiver HVP2_shuntAuxCurrentStatus = (rx_frame.data.u8[7] & (0x03U)); //: 56|2@1+ (1,0) [0|3] "" Receiver HVP2_shuntBarTempStatus = ((rx_frame.data.u8[7] >> 2) & (0x03U)); //: 58|2@1+ (1,0) [0|3] "" Receiver HVP2_shuntAsicTempStatus = ((rx_frame.data.u8[7] >> 4) & (0x03U)); //: 60|2@1+ (1,0) [0|3] "" Receiver @@ -2273,7 +2278,7 @@ void receive_can_battery2(CAN_frame rx_frame) { mux = (rx_frame.data.u8[0] & (0x0F)); if (mux == 0) ; - { //mux0 + { //mux0 battery2_BMS_matrixIndex = (rx_frame.data.u8[0] & (0x0F)); // 0|4@1+ (1,0) [0|0] "" X battery2_BMS_a017_SW_Brick_OV = ((rx_frame.data.u8[2] >> 4) & (0x01)); //20|1@1+ (1,0) [0|0] "" X battery2_BMS_a018_SW_Brick_UV = ((rx_frame.data.u8[2] >> 5) & (0x01)); //21|1@1+ (1,0) [0|0] "" X @@ -2305,7 +2310,7 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_BMS_a059_SW_Pack_Voltage_Sensing = ((rx_frame.data.u8[7] >> 6) & (0x01U)); //62|1@1+ (1,0) [0|0] "" X battery2_BMS_a060_SW_Leakage_Test_Failure = ((rx_frame.data.u8[7] >> 7) & (0x01U)); //63|1@1+ (1,0) [0|0] "" X } - if (mux == 1) { //mux1 + if (mux == 1) { //mux1 battery2_BMS_a061_robinBrickOverVoltage = ((rx_frame.data.u8[0] >> 4) & (0x01U)); //4|1@1+ (1,0) [0|0] "" X battery2_BMS_a062_SW_BrickV_Imbalance = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X battery2_BMS_a063_SW_ChargePort_Fault = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X @@ -2331,7 +2336,7 @@ void receive_can_battery2(CAN_frame rx_frame) { battery2_BMS_a106_SW_All_Module_Tsense = ((rx_frame.data.u8[6] >> 1) & (0x01U)); //49|1@1+ (1,0) [0|0] "" X battery2_BMS_a107_SW_Stack_Voltage_MIA = ((rx_frame.data.u8[6] >> 2) & (0x01U)); //50|1@1+ (1,0) [0|0] "" X } - if (mux == 2) { //mux2 + if (mux == 2) { //mux2 battery2_BMS_a121_SW_NVRAM_Config_Error = ((rx_frame.data.u8[0] >> 4) & (0x01U)); // 4|1@1+ (1,0) [0|0] "" X battery2_BMS_a122_SW_BMS_Therm_Irrational = ((rx_frame.data.u8[0] >> 5) & (0x01U)); //5|1@1+ (1,0) [0|0] "" X battery2_BMS_a123_SW_Internal_Isolation = ((rx_frame.data.u8[0] >> 6) & (0x01U)); //6|1@1+ (1,0) [0|0] "" X From dd510f40ca3386f14072bea6540f2aacbfc08414 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sat, 21 Dec 2024 21:51:15 +1300 Subject: [PATCH 22/93] Update TESLA-BATTERY.cpp Update advanced_battery_html.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 79 ++-- .../webserver/advanced_battery_html.cpp | 341 ++++++++++++++---- 2 files changed, 320 insertions(+), 100 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 75781720..7a46d065 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -51,10 +51,13 @@ static int16_t battery_amps = 0; // A static uint16_t battery_raw_amps = 0; // A static uint16_t battery_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable -static uint16_t BMS_regenerative_limit = 0; //rename from battery_regenerative_limit -static uint16_t BMS_discharge_limit = 0; // rename from battery_discharge_limit -static uint16_t BMS_max_heat_park = 0; //rename from battery_max_heat_park -static uint16_t BMS_hvac_max_power = 0; //rename from battery_hvac_max_power +static uint16_t BMS_maxRegenPower = 0; //rename from battery_regenerative_limit +static uint16_t BMS_maxDischargePower = 0; // rename from battery_discharge_limit +static uint16_t BMS_maxStationaryHeatPower = 0; //rename from battery_max_heat_park +static uint16_t BMS_hvacPowerBudget = 0; //rename from battery_hvac_max_power +static uint8_t BMS_notEnoughPowerForHeatPump = 0; +static uint8_t BMS_powerLimitState = 0; +static uint8_t BMS_inverterTQF = 0; //0x2d2: 722 BMSVAlimits static uint16_t battery_max_discharge_current = 0; static uint16_t battery_max_charge_current = 0; @@ -923,10 +926,12 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.battery_energy_to_charge_complete_m1 = battery_energy_to_charge_complete_m1; datalayer_extended.tesla.battery_energy_buffer = battery_energy_buffer; datalayer_extended.tesla.battery_energy_buffer_m1 = battery_energy_buffer_m1; + datalayer_extended.tesla.battery_expected_energy_remaining_m1 = battery_expected_energy_remaining_m1; datalayer_extended.tesla.battery_full_charge_complete = battery_full_charge_complete; + datalayer_extended.tesla.battery_fully_charged = battery_fully_charged; + //0x3D2 datalayer_extended.tesla.battery_total_discharge = battery_total_discharge; datalayer_extended.tesla.battery_total_charge = battery_total_charge; - datalayer_extended.tesla.battery_fully_charged = battery_fully_charged; //0x392 datalayer_extended.tesla.battery_moduleType = battery_moduleType; datalayer_extended.tesla.battery_packMass = battery_packMass; @@ -976,10 +981,13 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt = battery_PCS_dcdcPrechargeRestartCnt; datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState = battery_PCS_dcdcInitialPrechargeSubState; //0x252 - datalayer_extended.tesla.BMS_regenerative_limit = BMS_regenerative_limit; - datalayer_extended.tesla.BMS_discharge_limit = BMS_discharge_limit; - datalayer_extended.tesla.BMS_max_heat_park = BMS_max_heat_park; - datalayer_extended.tesla.BMS_hvac_max_power = BMS_hvac_max_power; + datalayer_extended.tesla.BMS_maxRegenPower = BMS_maxRegenPower; + datalayer_extended.tesla.BMS_maxDischargePower = BMS_maxDischargePower; + datalayer_extended.tesla.BMS_maxStationaryHeatPower = BMS_maxStationaryHeatPower; + datalayer_extended.tesla.BMS_hvacPowerBudget = BMS_hvacPowerBudget; + datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump = BMS_notEnoughPowerForHeatPump; + datalayer_extended.tesla.BMS_powerLimitState = BMS_powerLimitState; + datalayer_extended.tesla.BMS_inverterTQF = BMS_inverterTQF; //0x312 datalayer_extended.tesla.BMS_powerDissipation = BMS_powerDissipation; datalayer_extended.tesla.BMS_flowRequest = BMS_flowRequest; @@ -1015,8 +1023,38 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.PCS_dcdcIntervalMinLvOutputCurr = PCS_dcdcIntervalMinLvOutputCurr; datalayer_extended.tesla.PCS_dcdc12vSupportLifetimekWh = PCS_dcdc12vSupportLifetimekWh; //0x7AA + datalayer_extended.tesla.HVP_gpioPassivePyroDepl = HVP_gpioPassivePyroDepl; + datalayer_extended.tesla.HVP_gpioPyroIsoEn = HVP_gpioPyroIsoEn; + datalayer_extended.tesla.HVP_gpioCpFaultIn = HVP_gpioCpFaultIn; + datalayer_extended.tesla.HVP_gpioPackContPowerEn = HVP_gpioPackContPowerEn; + datalayer_extended.tesla.HVP_gpioHvCablesOk = HVP_gpioHvCablesOk; + datalayer_extended.tesla.HVP_gpioHvpSelfEnable = HVP_gpioHvpSelfEnable; + datalayer_extended.tesla.HVP_gpioLed = HVP_gpioLed; + datalayer_extended.tesla.HVP_gpioCrashSignal = HVP_gpioCrashSignal; + datalayer_extended.tesla.HVP_gpioShuntDataReady = HVP_gpioShuntDataReady; + datalayer_extended.tesla.HVP_gpioFcContPosAux = HVP_gpioFcContPosAux; + datalayer_extended.tesla.HVP_gpioFcContNegAux = HVP_gpioFcContNegAux; + datalayer_extended.tesla.HVP_gpioBmsEout = HVP_gpioBmsEout; + datalayer_extended.tesla.HVP_gpioCpFaultOut = HVP_gpioCpFaultOut; + datalayer_extended.tesla.HVP_gpioPyroPor = HVP_gpioPyroPor; + datalayer_extended.tesla.HVP_gpioShuntEn = HVP_gpioShuntEn; + datalayer_extended.tesla.HVP_gpioHvpVerEn = HVP_gpioHvpVerEn; + datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel = HVP_gpioPackCoontPosFlywheel; + datalayer_extended.tesla.HVP_gpioCpLatchEnable = HVP_gpioCpLatchEnable; + datalayer_extended.tesla.HVP_gpioPcsEnable = HVP_gpioPcsEnable; + datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable = HVP_gpioPcsDcdcPwmEnable; + datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable = HVP_gpioPcsChargePwmEnable; + datalayer_extended.tesla.HVP_gpioFcContPowerEnable = HVP_gpioFcContPowerEnable; + datalayer_extended.tesla.HVP_gpioHvilEnable = HVP_gpioHvilEnable; + datalayer_extended.tesla.HVP_gpioSecDrdy = HVP_gpioSecDrdy; datalayer_extended.tesla.HVP_hvp1v5Ref = HVP_hvp1v5Ref; datalayer_extended.tesla.HVP_shuntCurrentDebug = HVP_shuntCurrentDebug; + datalayer_extended.tesla.HVP_packCurrentMia = HVP_packCurrentMia; + datalayer_extended.tesla.HVP_auxCurrentMia = HVP_auxCurrentMia; + datalayer_extended.tesla.HVP_currentSenseMia = HVP_currentSenseMia; + datalayer_extended.tesla.HVP_shuntRefVoltageMismatch = HVP_shuntRefVoltageMismatch; + datalayer_extended.tesla.HVP_shuntThermistorMia = HVP_shuntThermistorMia; + datalayer_extended.tesla.HVP_shuntHwMia = HVP_shuntHwMia; datalayer_extended.tesla.HVP_dcLinkVoltage = HVP_dcLinkVoltage; datalayer_extended.tesla.HVP_packVoltage = HVP_packVoltage; datalayer_extended.tesla.HVP_fcLinkVoltage = HVP_fcLinkVoltage; @@ -1112,7 +1150,7 @@ void receive_can_battery(CAN_frame rx_frame) { static uint16_t temp = 0; switch (rx_frame.ID) { - case 0x352: // BMS_energyStatus // newer BMS >2021 + case 0x352: // 850 BMS_energyStatus newer BMS mux = (rx_frame.data.u8[0] & 0x02); //BMS_energyStatusIndex M : 0|2@1+ (1,0) [0|0] "" X if (mux == 0) { @@ -1222,7 +1260,7 @@ void receive_can_battery(CAN_frame rx_frame) { battery_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); battery_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC break; - case 0x224: //548 PCS_dcdcStatus: + case 0x224: //548 PCS_dcdcStatus: battery_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; battery_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" battery_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" @@ -1249,17 +1287,14 @@ void receive_can_battery(CAN_frame rx_frame) { ((rx_frame.data.u8[7] >> 3) & (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; break; - case 0x252: //Limit //BMS_powerAvailable252: - BMS_regenerative_limit = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * - 0.01; //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW - BMS_discharge_limit = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]) * - 0.013; //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? - BMS_max_heat_park = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]) * - 0.01; //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW - BMS_hvac_max_power = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))) * - 0.02; //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? - //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver - //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] "" Receiver + case 0x252: //Limit //594 BMS_powerAvailable: + BMS_maxRegenPower = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]); //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW + BMS_maxDischargePower = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? + BMS_maxStationaryHeatPower = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]); //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW + BMS_hvacPowerBudget = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))); //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? + BMS_notEnoughPowerForHeatPump = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver + BMS_powerLimitState = (rx_frame.data.u8[6] & (0x01U)); //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] 0 "NOT_CALCULATED_FOR_DRIVE" 1 "CALCULATED_FOR_DRIVE" + BMS_inverterTQF = ((rx_frame.data.u8[7] >> 4) & (0x03U)); break; case 0x132: //battery amps/volts //HVBattAmpVolt battery_volts = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]) * diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 5806bb32..5959e761 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -294,28 +294,21 @@ String advanced_battery_processor(const String& var) { float dcdcLvBusVolt = static_cast(datalayer_extended.tesla.battery_dcdcLvBusVolt) * 0.0390625; float dcdcHvBusVolt = static_cast(datalayer_extended.tesla.battery_dcdcHvBusVolt) * 0.146484; float dcdcLvOutputCurrent = static_cast(datalayer_extended.tesla.battery_dcdcLvOutputCurrent) * 0.1; - float nominal_full_pack_energy = - static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy) * 0.1; - float nominal_full_pack_energy_m0 = - static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy_m0) * 0.02; - float nominal_energy_remaining = - static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining) * 0.1; - float nominal_energy_remaining_m0 = - static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining_m0) * 0.02; + float nominal_full_pack_energy = static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy) * 0.1; + float nominal_full_pack_energy_m0 = static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy_m0) * 0.02; + float nominal_energy_remaining = static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining) * 0.1; + float nominal_energy_remaining_m0 = static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining_m0) * 0.02; float ideal_energy_remaining = static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining) * 0.1; - float ideal_energy_remaining_m0 = - static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining_m0) * 0.02; - float energy_to_charge_complete = - static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete) * 0.1; - float energy_to_charge_complete_m1 = - static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete_m1) * 0.02; + float ideal_energy_remaining_m0 = static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining_m0) * 0.02; + float energy_to_charge_complete = static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete) * 0.1; + float energy_to_charge_complete_m1 = static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete_m1) * 0.02; float energy_buffer = static_cast(datalayer_extended.tesla.battery_energy_buffer) * 0.1; float energy_buffer_m1 = static_cast(datalayer_extended.tesla.battery_energy_buffer_m1) * 0.01; + float expected_energy_remaining_m1 = static_cast(datalayer_extended.tesla.battery_expected_energy_remaining_m1) * 0.02; float total_discharge = static_cast(datalayer_extended.tesla.battery_total_discharge); float total_charge = static_cast(datalayer_extended.tesla.battery_total_charge); float packMass = static_cast(datalayer_extended.tesla.battery_packMass); - float platformMaxBusVoltage = - static_cast(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375; + float platformMaxBusVoltage = static_cast(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375; float bms_min_voltage = static_cast(datalayer_extended.tesla.battery_bms_min_voltage) * 0.01 * 2; float bms_max_voltage = static_cast(datalayer_extended.tesla.battery_bms_max_voltage) * 0.01 * 2; float max_charge_current = static_cast(datalayer_extended.tesla.battery_max_charge_current); @@ -324,76 +317,268 @@ String advanced_battery_processor(const String& var) { float soc_max = static_cast(datalayer_extended.tesla.battery_soc_max) * 0.1; float soc_min = static_cast(datalayer_extended.tesla.battery_soc_min) * 0.1; float soc_ui = static_cast(datalayer_extended.tesla.battery_soc_ui) * 0.1; + float BrickVoltageMax = static_cast(datalayer_extended.tesla.battery_BrickVoltageMax) * 0.002; + float BrickVoltageMin = static_cast(datalayer_extended.tesla.battery_BrickVoltageMin) * 0.002; + float BrickModelTMax = static_cast(datalayer_extended.tesla.battery_BrickTempMinNum) * 0.5 - 40; + float BrickModelTMin = static_cast(datalayer_extended.tesla.battery_BrickModelTMin) * 0.5 - 40; + float isolationResistance = static_cast(datalayer_extended.tesla.battery_BMS_isolationResistance) * 10; + float PCS_dcdcMaxOutputCurrentAllowed = static_cast(datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed) * 0.1; + float PCS_dcdcTemp = static_cast(datalayer_extended.tesla.PCS_dcdcTemp * 0.1 + 40); + float PCS_ambientTemp = static_cast(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 + 40; + float BMS_maxRegenPower = static_cast(datalayer_extended.tesla.BMS_maxRegenPower) * 0.01; + float BMS_maxDischargePower = static_cast(datalayer_extended.tesla.BMS_maxDischargePower) * 0.013; + float BMS_maxStationaryHeatPower = static_cast(datalayer_extended.tesla.BMS_maxStationaryHeatPower) * 0.01; + float BMS_hvacPowerBudget = static_cast(datalayer_extended.tesla.BMS_hvacPowerBudget) * 0.02; + float BMS_powerDissipation = static_cast(datalayer_extended.tesla.BMS_powerDissipation) * 0.02; + float BMS_flowRequest = static_cast(datalayer_extended.tesla.BMS_flowRequest) * 0.3; + float BMS_inletActiveCoolTargetT = static_cast(datalayer_extended.tesla.BMS_inletActiveCoolTargetT) * 0.25 - 25; + float BMS_inletPassiveTargetT = static_cast(datalayer_extended.tesla.BMS_inletPassiveTargetT) * 0.25 - 25; + float BMS_inletActiveHeatTargetT = static_cast(datalayer_extended.tesla.BMS_inletActiveHeatTargetT) * 0.25 - 25; + float BMS_packTMin = static_cast(datalayer_extended.tesla.BMS_packTMin); + float BMS_packTMax = static_cast(datalayer_extended.tesla.BMS_packTMax); + float PCS_dcdcMaxLvOutputCurrent = static_cast(datalayer_extended.tesla.PCS_dcdcMaxLvOutputCurrent) * 0.1; + float PCS_dcdcCurrentLimit = static_cast(datalayer_extended.tesla.PCS_dcdcCurrentLimit) * 0.1; + float PCS_dcdcLvOutputCurrentTempLimit = static_cast(datalayer_extended.tesla.PCS_dcdcLvOutputCurrentTempLimit) * 0.1; + float PCS_dcdcUnifiedCommand = static_cast(datalayer_extended.tesla.PCS_dcdcUnifiedCommand) * 0.001; + float PCS_dcdcCLAControllerOutput = static_cast(datalayer_extended.tesla.PCS_dcdcCLAControllerOutput * 0.001); + float PCS_dcdcTankVoltage = static_cast(datalayer_extended.tesla.PCS_dcdcTankVoltage); + float PCS_dcdcTankVoltageTarget = static_cast(datalayer_extended.tesla.PCS_dcdcTankVoltageTarget); + float PCS_dcdcClaCurrentFreq = static_cast(datalayer_extended.tesla.PCS_dcdcClaCurrentFreq) * 0.0976563; + float PCS_dcdcTCommMeasured = static_cast(datalayer_extended.tesla.PCS_dcdcTCommMeasured) * 0.00195313; + float PCS_dcdcShortTimeUs = static_cast(datalayer_extended.tesla.PCS_dcdcShortTimeUs) * 0.000488281; + float PCS_dcdcHalfPeriodUs = static_cast(datalayer_extended.tesla.PCS_dcdcHalfPeriodUs) * 0.000488281; + float PCS_dcdcIntervalMaxFrequency = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxFrequency); + float PCS_dcdcIntervalMaxHvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxHvBusVolt) * 0.1; + float PCS_dcdcIntervalMaxLvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvBusVolt) * 0.1; + float PCS_dcdcIntervalMaxLvOutputCurr = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvOutputCurr); + float PCS_dcdcIntervalMinFrequency = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinFrequency); + float PCS_dcdcIntervalMinHvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinHvBusVolt) * 0.1; + float PCS_dcdcIntervalMinLvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvBusVolt) * 0.1; + float PCS_dcdcIntervalMinLvOutputCurr = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvOutputCurr); + float PCS_dcdc12vSupportLifetimekWh = static_cast(datalayer_extended.tesla.PCS_dcdc12vSupportLifetimekWh) * 0.01; + float HVP_hvp1v5Ref = static_cast(datalayer_extended.tesla.HVP_hvp1v5Ref) * 0.1; + float HVP_shuntCurrentDebug = static_cast(datalayer_extended.tesla.HVP_shuntCurrentDebug) * 0.1; + float HVP_dcLinkVoltage = static_cast(datalayer_extended.tesla.HVP_dcLinkVoltage) * 0.1; + float HVP_packVoltage = static_cast(datalayer_extended.tesla.HVP_packVoltage) * 0.1; + float HVP_fcLinkVoltage = static_cast(datalayer_extended.tesla.HVP_fcLinkVoltage) * 0.1; + float HVP_packContVoltage = static_cast(datalayer_extended.tesla.HVP_packContVoltage) * 0.1; + float HVP_packNegativeV = static_cast(datalayer_extended.tesla.HVP_packNegativeV) * 0.1; + float HVP_packPositiveV = static_cast(datalayer_extended.tesla.HVP_packPositiveV) * 0.1; + float HVP_pyroAnalog = static_cast(datalayer_extended.tesla.HVP_pyroAnalog) * 0.1; + float HVP_dcLinkNegativeV = static_cast(datalayer_extended.tesla.HVP_dcLinkNegativeV) * 0.1; + float HVP_dcLinkPositiveV = static_cast(datalayer_extended.tesla.HVP_dcLinkPositiveV) * 0.1; + float HVP_fcLinkNegativeV = static_cast(datalayer_extended.tesla.HVP_fcLinkNegativeV) * 0.1; + float HVP_fcContCoilCurrent = static_cast(datalayer_extended.tesla.HVP_fcContCoilCurrent) * 0.1; + float HVP_fcContVoltage = static_cast(datalayer_extended.tesla.HVP_fcContVoltage) * 0.1; + float HVP_hvilInVoltage = static_cast(datalayer_extended.tesla.HVP_hvilInVoltage) * 0.1; + float HVP_hvilOutVoltage = static_cast(datalayer_extended.tesla.HVP_hvilOutVoltage) * 0.1; + float HVP_fcLinkPositiveV = static_cast(datalayer_extended.tesla.HVP_fcLinkPositiveV) * 0.1; + float HVP_packContCoilCurrent = static_cast(datalayer_extended.tesla.HVP_packContCoilCurrent) * 0.1; + float HVP_battery12V = static_cast(datalayer_extended.tesla.HVP_battery12V) * 0.1; + float HVP_shuntRefVoltageDbg = static_cast(datalayer_extended.tesla.HVP_shuntRefVoltageDbg) * 0.001; + float HVP_shuntAuxCurrentDbg = static_cast(datalayer_extended.tesla.HVP_shuntAuxCurrentDbg) * 0.1; + float HVP_shuntBarTempDbg = static_cast(datalayer_extended.tesla.HVP_shuntBarTempDbg) * 0.01; + float HVP_shuntAsicTempDbg = static_cast(datalayer_extended.tesla.HVP_shuntAsicTempDbg) * 0.01; + static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", "CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL", "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"}; + static const char* hvilStatusState[] = {"NOT Ok", "STATUS_OK", "CURRENT_SOURCE_FAULT", "INTERNAL_OPEN_FAULT", "VEHICLE_OPEN_FAULT", "PENTHOUSE_LID_OPEN_FAULT", "UNKNOWN_LOCATION_OPEN_FAULT", "VEHICLE_NODE_FAULT", "NO_12V_SUPPLY", "VEHICLE_OR_PENTHOUSE_LID_OPENFAULT", "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)", "UNKNOWN(13)", "UNKNOWN(14)", "UNKNOWN(15)"}; + static const char* contactorState[] = {"SNA", "OPEN", "PRECHARGE", "BLOCKED", "PULLED_IN", "OPENING", "ECONOMIZED", "WELDED", "UNKNOWN(8)", "UNKNOWN(9)", "UNKNOWN(10)", "UNKNOWN(11)"}; + static const char* BMS_state[] = {"STANDBY", "DRIVE", "SUPPORT", "CHARGE", "FEIM", "CLEAR_FAULT", "FAULT", "WELD", "TEST", "SNA"}; + static const char* BMS_contactorState[] = {"SNA", "OPEN", "OPENING", "CLOSING", "CLOSED", "WELDED", "BLOCKED"}; + static const char* BMS_hvState[] = {"DOWN", "COMING_UP", "GOING_DOWN", "UP_FOR_DRIVE", "UP_FOR_CHARGE", "UP_FOR_DC_CHARGE", "UP"}; + static const char* BMS_uiChargeStatus[] = {"DISCONNECTED", "NO_POWER", "ABOUT_TO_CHARGE", "CHARGING", "CHARGE_COMPLETE", "CHARGE_STOPPED"}; + static const char* PCS_dcdcStatus[] = {"IDLE", "ACTIVE", "FAULTED"}; + static const char* PCS_dcdcMainState[] = {"STANDBY", "12V_SUPPORT_ACTIVE", "PRECHARGE_STARTUP", "PRECHARGE_ACTIVE", "DIS_HVBUS_ACTIVE", "SHUTDOWN", "FAULTED"}; + static const char* PCS_dcdcSubState[] = {"PWR_UP_INIT", "STANDBY", "12V_SUPPORT_ACTIVE", "DIS_HVBUS", "PCHG_FAST_DIS_HVBUS", "PCHG_SLOW_DIS_HVBUS", "PCHG_DWELL_CHARGE", "PCHG_DWELL_WAIT", "PCHG_DI_RECOVERY_WAIT", "PCHG_ACTIVE", "PCHG_FLT_FAST_DIS_HVBUS", "SHUTDOWN", "12V_SUPPORT_FAULTED", "DIS_HVBUS_FAULTED", "PCHG_FAULTED", "CLEAR_FAULTS", "FAULTED", "NUM"}; + static const char* BMS_powerLimitState[] = {"NOT_CALCULATED_FOR_DRIVE", "CALCULATED_FOR_DRIVE"}; + static const char* HVP_status[] = {"INVALID", "NOT_AVAILABLE", "STALE", "VALID"}; + static const char* falseTrue[] = {"False", "True"}; + static const char* noYes[] = {"No", "Yes"}; + //0x20A 522 HVP_contatorState + content += "

Contactor Status: " + String(contactorText[datalayer_extended.tesla.status_contactor]) + "

"; + content += "

HVIL: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "

"; + content += "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; + content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; + content += "

Closing allowed?: " + String(falseTrue[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; + content += "

Pyrotest in Progress: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; + content += "

Contactors Open Now Requested: " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; + content += "

Contactors Open Requested; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; + content += "

Contactors Request Status; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; + content += "

Contactors Reset Request Required; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; + content += "

DC Link Allowed to Energize;" + String(falseTrue[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; // Comment what data you would like to dislay, order can be changed. - content += "

Battery Beginning of Life: " + String(beginning_of_life) + " kWh

"; + //0x292 658 BMS_socStates + content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; content += "

BattTempPct: " + String(battTempPct) + "

"; - content += "

PCS Lv Bus: " + String(dcdcLvBusVolt) + " V

"; - content += "

PCS Hv Bus: " + String(dcdcHvBusVolt) + " V

"; - content += "

PCS Lv Output: " + String(dcdcLvOutputCurrent) + " A

"; - - //if using older BMS <2021 and comment 0x352 without MUX - //content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy) + " kWh

"; - //content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " kWh

"; - //content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " kWh

"; - //content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " kWh

"; - //content += "

Energy Buffer: " + String(energy_buffer) + " kWh

"; - - //if using newer BMS >2021 and comment 0x352 with MUX - content += "

Nominal Full Pack Energy m0: " + String(nominal_full_pack_energy_m0) + " kWh

"; - content += "

Nominal Energy Remaining m0: " + String(nominal_energy_remaining_m0) + " kWh

"; - content += "

Ideal Energy Remaining m0: " + String(ideal_energy_remaining_m0) + " kWh

"; - content += "

Energy to Charge Complete m1: " + String(energy_to_charge_complete_m1) + " kWh

"; - content += "

Energy Buffer m1: " + String(energy_buffer_m1) + " kWh

"; - - content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; - content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; - content += "

reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "

"; - content += "

Full Charge Complete: " + String(datalayer_extended.tesla.battery_full_charge_complete) + "

"; - content += "

Total Discharge: " + String(total_discharge) + " kWh

"; - content += "

Total Charge: " + String(total_charge) + " kWh

"; - content += "

Battery Pack Mass: " + String(packMass) + " KG

"; - content += "

Platform Max Bus Voltage: " + String(platformMaxBusVoltage) + " V

"; - content += "

BMS Min Voltage: " + String(bms_min_voltage) + " V

"; - content += "

BMS Max Voltage: " + String(bms_max_voltage) + " V

"; - content += "

Max Charge Current: " + String(max_charge_current) + " A

"; - content += "

Max Discharge Current: " + String(max_discharge_current) + " A

"; content += "

Battery SOC Ave: " + String(soc_ave) + "

"; content += "

Battery SOC Max: " + String(soc_max) + "

"; content += "

Battery SOC Min: " + String(soc_min) + "

"; content += "

Battery SOC UI: " + String(soc_ui) + "

"; + //0x2B4 PCS_dcdcRailStatus + content += "

PCS Lv Bus: " + String(dcdcLvBusVolt) + " V

"; + content += "

PCS Hv Bus: " + String(dcdcHvBusVolt) + " V

"; + content += "

PCS Lv Output: " + String(dcdcLvOutputCurrent) + " A

"; + //0x2A4 676 PCS_thermalStatus + content += "

PCS dcdc Temp: " + String(PCS_dcdcTemp) + " DegC

"; + content += "

PCS Ambient Temp: " + String(PCS_ambientTemp) + " DegC

"; + //0x224 548 PCS_dcdcStatus + content += "

Precharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcPrechargeStatus]) + "

"; + content += "

12V Support Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdc12VSupportStatus]) + "

"; + content += "

HV Bus Discharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcHvBusDischargeStatus]) + "

"; + content += "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; + content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; + content += "

PCS Faulted: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "

"; + content += "

Output Is Limited: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; + content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; + content += "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + "

"; + content += "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + "

"; + content += "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + "

"; + content += "

PWM Enable Line: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; + content += "

Supporting Fixed LV Target: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; + content += "

Precharge Restart Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; + content += "

Initial Precharge Substate: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; + //0x2C4 708 PCS_logging + content += "

PCS_dcdcMaxLvOutputCurrent: " + String(PCS_dcdcMaxLvOutputCurrent) + " A

"; + content += "

PCS_dcdcCurrentLimit: " + String(PCS_dcdcCurrentLimit) + " A

"; + content += "

PCS_dcdcLvOutputCurrentTempLimit: " + String(PCS_dcdcLvOutputCurrentTempLimit) + " A

"; + content += "

PCS_dcdcUnifiedCommand: " + String(PCS_dcdcUnifiedCommand) + "

"; + content += "

PCS_dcdcCLAControllerOutput: " + String(PCS_dcdcCLAControllerOutput) + "

"; + content += "

PCS_dcdcTankVoltage: " + String(PCS_dcdcTankVoltage) + " V

"; + content += "

PCS_dcdcTankVoltageTarget: " + String(PCS_dcdcTankVoltageTarget) + " V

"; + content += "

PCS_dcdcClaCurrentFreq: " + String(PCS_dcdcClaCurrentFreq) + " kHz

"; + content += "

PCS_dcdcTCommMeasured: " + String(PCS_dcdcTCommMeasured) + " us

"; + content += "

PCS_dcdcShortTimeUs: " + String(PCS_dcdcShortTimeUs) + " us

"; + content += "

PCS_dcdcHalfPeriodUs: " + String(PCS_dcdcHalfPeriodUs) + " us

"; + content += "

PCS_dcdcIntervalMaxFrequency: " + String(PCS_dcdcIntervalMaxFrequency) + " kHz

"; + content += "

PCS_dcdcIntervalMaxHvBusVolt: " + String(PCS_dcdcIntervalMaxHvBusVolt) + " V

"; + content += "

PCS_dcdcIntervalMaxLvBusVolt: " + String(PCS_dcdcIntervalMaxLvBusVolt) + " V

"; + content += "

PCS_dcdcIntervalMaxLvOutputCurr: " + String(PCS_dcdcIntervalMaxLvOutputCurr) + " A

"; + content += "

PCS_dcdcIntervalMinFrequency: " + String(PCS_dcdcIntervalMinFrequency) + " kHz

"; + content += "

PCS_dcdcIntervalMinHvBusVolt: " + String(PCS_dcdcIntervalMinHvBusVolt) + " V

"; + content += "

PCS_dcdcIntervalMinLvBusVolt: " + String(PCS_dcdcIntervalMinLvBusVolt) + " V

"; + content += "

PCS_dcdcIntervalMinLvOutputCurr: " + String(PCS_dcdcIntervalMinLvOutputCurr) + " A

"; + content += "

PCS_dcdc12vSupportLifetimekWh: " + String(PCS_dcdc12vSupportLifetimekWh) + " kWh

"; + //0x3D2 978 BMS_kwhCounter + content += "

Total Discharge: " + String(total_discharge) + " KWh

"; + content += "

Total Charge: " + String(total_charge) + " KWh

"; + //0x212 530 BMS_status + content += "

Isolation Resistance: " + String(isolationResistance) + " kOhms

"; + content += "

BMS Contactor State: " + String(BMS_contactorState[datalayer_extended.tesla.battery_BMS_contactorState]) + "

"; + content += "

BMS State: " + String(BMS_state[datalayer_extended.tesla.battery_BMS_state]) + "

"; + content += "

BMS HV State: " + String(BMS_hvState[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; + content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; + content += "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; + //0x352 850 BMS_energyStatus + content += "

Early BMS 0x352"; + content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh

"; + content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh

"; + content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; + content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; + content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; + //0x352 850 BMS_energyStatus + content += "

Late BMS 0x352 with Mux2021 and comment 0x352 with MUX + content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; + content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; + content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " KWh

"; + content += "

Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh

"; + content += "

Energy Buffer: " + String(energy_buffer_m1) + " KWh

"; + content += "

Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh

"; + content += "

Fully Charged: " + String(noYes[datalayer_extended.battery_fully_charged]) + "

"; + //0x392 BMS_packConfig + content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; + content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; + content += "

reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "

"; + content += "

Battery Pack Mass: " + String(packMass) + " KG

"; + content += "

Platform Max Bus Voltage: " + String(platformMaxBusVoltage) + " V

"; + //0x2D2 722 BMSVAlimits + content += "

BMS Min Voltage: " + String(bms_min_voltage) + " V

"; + content += "

BMS Max Voltage: " + String(bms_max_voltage) + " V

"; + content += "

Max Charge Current: " + String(max_charge_current) + " A

"; + content += "

Max Discharge Current: " + String(max_discharge_current) + " A

"; + //0x332 818 BMS_bmbMinMax + content += "

Brick Voltage Max: " + String(BrickVoltageMax) + " V

"; + content += "

Brick Voltage Min: " + String(BrickVoltageMin) + " V

"; + content += "

Brick Temp Max Num: " + String(datalayer_extended.tesla.battery_BrickTempMaxNum) + "

"; + content += "

Brick Temp Min Num: " + String(datalayer_extended.tesla.battery_BrickTempMinNum) + "

"; + content += "

Brick Temp Max: " + String(BrickModelTMax) + " C

"; + content += "

Brick Temp Min: " + String(BrickModelTMin) + " C

"; + //0x252 594 BMS_powerAvailable + content += "

Max Regen Power: " + String(BMS_maxRegenPower) + " KW

"; + content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; + content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; + content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; + content += "

Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + " KW

"; + content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; + content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; + //0x312 786 BMS_thermalStatus + content += "

Power Dissipation: " + String(BMS_powerDissipation) + " kW

"; + content += "

Flow Request: " + String(BMS_flowRequest) + " LPM

"; + content += "

Inlet Active Cool Target Temp: " + String(BMS_inletActiveCoolTargetT) + " DegC

"; + content += "

Inlet Passive Target Temp: " + String(BMS_inletPassiveTargetT) + " DegC

"; + content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; + content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; + content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; + content += "

PCS No Flow Request: " + String(falseTrue[ datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; + content += "

BMS No Flow Request: " + String(falseTrue[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; + //0x7AA 1962 HVP_debugMessage + content += "

HVP_gpioPassivePyroDepl: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; + content += "

HVP_gpioPyroIsoEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; + content += "

HVP_gpioCpFaultIn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; + content += "

HVP_gpioPackContPowerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; + content += "

HVP_gpioHvCablesOk: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; + content += "

HVP_gpioHvpSelfEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; + content += "

HVP_gpioLed: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioLed]) + "

"; + content += "

HVP_gpioCrashSignal: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; + content += "

HVP_gpioShuntDataReady: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; + content += "

HVP_gpioFcContPosAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; + content += "

HVP_gpioFcContNegAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; + content += "

HVP_gpioBmsEout: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; + content += "

HVP_gpioCpFaultOut: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; + content += "

HVP_gpioPyroPor: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; + content += "

HVP_gpioShuntEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; + content += "

HVP_gpioHvpVerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; + content += "

HVP_gpioPackCoontPosFlywheel: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + "

"; + content += "

HVP_gpioCpLatchEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; + content += "

HVP_gpioPcsEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; + content += "

HVP_gpioPcsDcdcPwmEnable: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + "

"; + content += "

HVP_gpioPcsChargePwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + "

"; + content += "

HVP_gpioFcContPowerEnable: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + "

"; + content += "

HVP_gpioHvilEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; + content += "

HVP_gpioSecDrdy: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; + content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; + content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; + content += "

HVP_packCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; + content += "

HVP_auxCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; + content += "

HVP_currentSenseMia: " + String(falseTrue[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; + content += "

HVP_shuntRefVoltageMismatch: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + "

"; + content += "

HVP_shuntThermistorMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; + content += "

HVP_shuntHwMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; + content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; + content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; + content += "

HVP_fcLinkVoltage: " + String(HVP_fcLinkVoltage) + " V

"; + content += "

HVP_packContVoltage: " + String(HVP_packContVoltage) + " V

"; + content += "

HVP_packNegativeV: " + String(HVP_packNegativeV) + " V

"; + content += "

HVP_packPositiveV: " + String(HVP_packPositiveV) + " V

"; + content += "

HVP_pyroAnalog: " + String(HVP_pyroAnalog) + " V

"; + content += "

HVP_dcLinkNegativeV: " + String(HVP_dcLinkNegativeV) + " V

"; + content += "

HVP_dcLinkPositiveV: " + String(HVP_dcLinkPositiveV) + " V

"; + content += "

HVP_fcLinkNegativeV: " + String(HVP_fcLinkNegativeV) + " V

"; + content += "

HVP_fcContCoilCurrent: " + String(HVP_fcContCoilCurrent) + " A

"; + content += "

HVP_fcContVoltage: " + String(HVP_fcContVoltage) + " V

"; + content += "

HVP_hvilInVoltage: " + String(HVP_hvilInVoltage) + " V

"; + content += "

HVP_hvilOutVoltage: " + String(HVP_hvilOutVoltage) + " V

"; + content += "

HVP_fcLinkPositiveV: " + String(HVP_fcLinkPositiveV) + " V

"; + content += "

HVP_packContCoilCurrent: " + String(HVP_packContCoilCurrent) + " A

"; + content += "

HVP_battery12V: " + String(HVP_battery12V) + " V

"; + content += "

HVP_shuntRefVoltageDbg: " + String(HVP_shuntRefVoltageDbg) + " V

"; + content += "

HVP_shuntAuxCurrentDbg: " + String(HVP_shuntAuxCurrentDbg) + " A

"; + content += "

HVP_shuntBarTempDbg: " + String(HVP_shuntBarTempDbg) + " DegC

"; + content += "

HVP_shuntAsicTempDbg: " + String(HVP_shuntAsicTempDbg) + " DegC

"; + content += "

HVP_shuntAuxCurrentStatus: " + String(HVP_status) + "

"; + content += "

HVP_shuntBarTempStatus: " + String(HVP_status) + "

"; + content += "

HVP_shuntAsicTempStatus: " + String(HVP_status) + "

"; - static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", - "CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL", - "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"}; - content += "

Contactor Status: " + String(contactorText[datalayer_extended.tesla.status_contactor]) + "

"; - static const char* hvilStatusState[] = {"NOT OK", - "STATUS_OK", - "CURRENT_SOURCE_FAULT", - "INTERNAL_OPEN_FAULT", - "VEHICLE_OPEN_FAULT", - "PENTHOUSE_LID_OPEN_FAULT", - "UNKNOWN_LOCATION_OPEN_FAULT", - "VEHICLE_NODE_FAULT", - "NO_12V_SUPPLY", - "VEHICLE_OR_PENTHOUSE_LID_OPENFAULT", - "UNKNOWN(10)", - "UNKNOWN(11)", - "UNKNOWN(12)", - "UNKNOWN(13)", - "UNKNOWN(14)", - "UNKNOWN(15)"}; - content += "

HVIL: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "

"; - static const char* contactorState[] = {"SNA", "OPEN", "PRECHARGE", "BLOCKED", - "PULLED_IN", "OPENING", "ECONOMIZED", "WELDED", - "UNKNOWN(8)", "UNKNOWN(9)", "UNKNOWN(10)", "UNKNOWN(11)"}; - content += - "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; - content += - "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; - static const char* falseTrue[] = {"False", "True"}; - content += "

Closing allowed?: " + String(falseTrue[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; - content += "

Pyrotest: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; #endif #ifdef NISSAN_LEAF_BATTERY From 320416e20458d7a5ad122a7fda4596c395902ba8 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sat, 21 Dec 2024 21:54:14 +1300 Subject: [PATCH 23/93] Update TESLA-BATTERY.cpp Update advance_battery_html.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 38 ++- .../webserver/advanced_battery_html.cpp | 253 +++++++++++++----- 2 files changed, 205 insertions(+), 86 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 7a46d065..a9160a90 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -51,10 +51,10 @@ static int16_t battery_amps = 0; // A static uint16_t battery_raw_amps = 0; // A static uint16_t battery_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable -static uint16_t BMS_maxRegenPower = 0; //rename from battery_regenerative_limit -static uint16_t BMS_maxDischargePower = 0; // rename from battery_discharge_limit -static uint16_t BMS_maxStationaryHeatPower = 0; //rename from battery_max_heat_park -static uint16_t BMS_hvacPowerBudget = 0; //rename from battery_hvac_max_power +static uint16_t BMS_maxRegenPower = 0; //rename from battery_regenerative_limit +static uint16_t BMS_maxDischargePower = 0; // rename from battery_discharge_limit +static uint16_t BMS_maxStationaryHeatPower = 0; //rename from battery_max_heat_park +static uint16_t BMS_hvacPowerBudget = 0; //rename from battery_hvac_max_power static uint8_t BMS_notEnoughPowerForHeatPump = 0; static uint8_t BMS_powerLimitState = 0; static uint8_t BMS_inverterTQF = 0; @@ -929,7 +929,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.battery_expected_energy_remaining_m1 = battery_expected_energy_remaining_m1; datalayer_extended.tesla.battery_full_charge_complete = battery_full_charge_complete; datalayer_extended.tesla.battery_fully_charged = battery_fully_charged; - //0x3D2 + //0x3D2 datalayer_extended.tesla.battery_total_discharge = battery_total_discharge; datalayer_extended.tesla.battery_total_charge = battery_total_charge; //0x392 @@ -987,7 +987,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.BMS_hvacPowerBudget = BMS_hvacPowerBudget; datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump = BMS_notEnoughPowerForHeatPump; datalayer_extended.tesla.BMS_powerLimitState = BMS_powerLimitState; - datalayer_extended.tesla.BMS_inverterTQF = BMS_inverterTQF; + datalayer_extended.tesla.BMS_inverterTQF = BMS_inverterTQF; //0x312 datalayer_extended.tesla.BMS_powerDissipation = BMS_powerDissipation; datalayer_extended.tesla.BMS_flowRequest = BMS_flowRequest; @@ -1150,7 +1150,7 @@ void receive_can_battery(CAN_frame rx_frame) { static uint16_t temp = 0; switch (rx_frame.ID) { - case 0x352: // 850 BMS_energyStatus newer BMS + case 0x352: // 850 BMS_energyStatus newer BMS mux = (rx_frame.data.u8[0] & 0x02); //BMS_energyStatusIndex M : 0|2@1+ (1,0) [0|0] "" X if (mux == 0) { @@ -1260,7 +1260,7 @@ void receive_can_battery(CAN_frame rx_frame) { battery_BMS_ecuLogUploadRequest = ((rx_frame.data.u8[6] >> 6) & (0x03U)); battery_BMS_minPackTemperature = (rx_frame.data.u8[7] & (0xFFU)); //56|8@1+ (0.5,-40) [0|0] "DegC break; - case 0x224: //548 PCS_dcdcStatus: + case 0x224: //548 PCS_dcdcStatus: battery_PCS_dcdcPrechargeStatus = (rx_frame.data.u8[0] & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" ; battery_PCS_dcdc12VSupportStatus = ((rx_frame.data.u8[0] >> 2) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" battery_PCS_dcdcHvBusDischargeStatus = ((rx_frame.data.u8[0] >> 4) & (0x03U)); //0 "IDLE" 1 "ACTIVE" 2 "FAULTED" @@ -1288,12 +1288,22 @@ void receive_can_battery(CAN_frame rx_frame) { (0x1FU)); //0 "PWR_UP_INIT" 1 "STANDBY" 2 "12V_SUPPORT_ACTIVE" 3 "DIS_HVBUS" 4 "PCHG_FAST_DIS_HVBUS" 5 "PCHG_SLOW_DIS_HVBUS" 6 "PCHG_DWELL_CHARGE" 7 "PCHG_DWELL_WAIT" 8 "PCHG_DI_RECOVERY_WAIT" 9 "PCHG_ACTIVE" 10 "PCHG_FLT_FAST_DIS_HVBUS" 11 "SHUTDOWN" 12 "12V_SUPPORT_FAULTED" 13 "DIS_HVBUS_FAULTED" 14 "PCHG_FAULTED" 15 "CLEAR_FAULTS" 16 "FAULTED" 17 "NUM" ; break; case 0x252: //Limit //594 BMS_powerAvailable: - BMS_maxRegenPower = ((rx_frame.data.u8[1] << 8) | rx_frame.data.u8[0]); //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW - BMS_maxDischargePower = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? - BMS_maxStationaryHeatPower = (((rx_frame.data.u8[5] & 0x03) << 8) | rx_frame.data.u8[4]); //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW - BMS_hvacPowerBudget = (((rx_frame.data.u8[7] << 6) | ((rx_frame.data.u8[6] & 0xFC) >> 2))); //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? - BMS_notEnoughPowerForHeatPump = ((rx_frame.data.u8[5] >> 2) & (0x01U)); //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver - BMS_powerLimitState = (rx_frame.data.u8[6] & (0x01U)); //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] 0 "NOT_CALCULATED_FOR_DRIVE" 1 "CALCULATED_FOR_DRIVE" + BMS_maxRegenPower = ((rx_frame.data.u8[1] << 8) | + rx_frame.data.u8[0]); //0|16@1+ (0.01,0) [0|655.35] "kW" //Example 4715 * 0.01 = 47.15kW + BMS_maxDischargePower = + ((rx_frame.data.u8[3] << 8) | + rx_frame.data.u8[2]); //16|16@1+ (0.013,0) [0|655.35] "kW" //Example 2009 * 0.013 = 26.117??? + BMS_maxStationaryHeatPower = + (((rx_frame.data.u8[5] & 0x03) << 8) | + rx_frame.data.u8[4]); //32|10@1+ (0.01,0) [0|10.23] "kW" //Example 500 * 0.01 = 5kW + BMS_hvacPowerBudget = + (((rx_frame.data.u8[7] << 6) | + ((rx_frame.data.u8[6] & 0xFC) >> 2))); //50|10@1+ (0.02,0) [0|20.46] "kW" //Example 1000 * 0.02 = 20kW? + BMS_notEnoughPowerForHeatPump = + ((rx_frame.data.u8[5] >> 2) & (0x01U)); //BMS_notEnoughPowerForHeatPump : 42|1@1+ (1,0) [0|1] "" Receiver + BMS_powerLimitState = + (rx_frame.data.u8[6] & + (0x01U)); //BMS_powerLimitsState : 48|1@1+ (1,0) [0|1] 0 "NOT_CALCULATED_FOR_DRIVE" 1 "CALCULATED_FOR_DRIVE" BMS_inverterTQF = ((rx_frame.data.u8[7] >> 4) & (0x03U)); break; case 0x132: //battery amps/volts //HVBattAmpVolt diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 5959e761..50d02dd8 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -294,21 +294,30 @@ String advanced_battery_processor(const String& var) { float dcdcLvBusVolt = static_cast(datalayer_extended.tesla.battery_dcdcLvBusVolt) * 0.0390625; float dcdcHvBusVolt = static_cast(datalayer_extended.tesla.battery_dcdcHvBusVolt) * 0.146484; float dcdcLvOutputCurrent = static_cast(datalayer_extended.tesla.battery_dcdcLvOutputCurrent) * 0.1; - float nominal_full_pack_energy = static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy) * 0.1; - float nominal_full_pack_energy_m0 = static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy_m0) * 0.02; - float nominal_energy_remaining = static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining) * 0.1; - float nominal_energy_remaining_m0 = static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining_m0) * 0.02; + float nominal_full_pack_energy = + static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy) * 0.1; + float nominal_full_pack_energy_m0 = + static_cast(datalayer_extended.tesla.battery_nominal_full_pack_energy_m0) * 0.02; + float nominal_energy_remaining = + static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining) * 0.1; + float nominal_energy_remaining_m0 = + static_cast(datalayer_extended.tesla.battery_nominal_energy_remaining_m0) * 0.02; float ideal_energy_remaining = static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining) * 0.1; - float ideal_energy_remaining_m0 = static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining_m0) * 0.02; - float energy_to_charge_complete = static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete) * 0.1; - float energy_to_charge_complete_m1 = static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete_m1) * 0.02; + float ideal_energy_remaining_m0 = + static_cast(datalayer_extended.tesla.battery_ideal_energy_remaining_m0) * 0.02; + float energy_to_charge_complete = + static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete) * 0.1; + float energy_to_charge_complete_m1 = + static_cast(datalayer_extended.tesla.battery_energy_to_charge_complete_m1) * 0.02; float energy_buffer = static_cast(datalayer_extended.tesla.battery_energy_buffer) * 0.1; float energy_buffer_m1 = static_cast(datalayer_extended.tesla.battery_energy_buffer_m1) * 0.01; - float expected_energy_remaining_m1 = static_cast(datalayer_extended.tesla.battery_expected_energy_remaining_m1) * 0.02; + float expected_energy_remaining_m1 = + static_cast(datalayer_extended.tesla.battery_expected_energy_remaining_m1) * 0.02; float total_discharge = static_cast(datalayer_extended.tesla.battery_total_discharge); float total_charge = static_cast(datalayer_extended.tesla.battery_total_charge); float packMass = static_cast(datalayer_extended.tesla.battery_packMass); - float platformMaxBusVoltage = static_cast(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375; + float platformMaxBusVoltage = + static_cast(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375; float bms_min_voltage = static_cast(datalayer_extended.tesla.battery_bms_min_voltage) * 0.01 * 2; float bms_max_voltage = static_cast(datalayer_extended.tesla.battery_bms_max_voltage) * 0.01 * 2; float max_charge_current = static_cast(datalayer_extended.tesla.battery_max_charge_current); @@ -322,25 +331,30 @@ String advanced_battery_processor(const String& var) { float BrickModelTMax = static_cast(datalayer_extended.tesla.battery_BrickTempMinNum) * 0.5 - 40; float BrickModelTMin = static_cast(datalayer_extended.tesla.battery_BrickModelTMin) * 0.5 - 40; float isolationResistance = static_cast(datalayer_extended.tesla.battery_BMS_isolationResistance) * 10; - float PCS_dcdcMaxOutputCurrentAllowed = static_cast(datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed) * 0.1; + float PCS_dcdcMaxOutputCurrentAllowed = + static_cast(datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed) * 0.1; float PCS_dcdcTemp = static_cast(datalayer_extended.tesla.PCS_dcdcTemp * 0.1 + 40); float PCS_ambientTemp = static_cast(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 + 40; float BMS_maxRegenPower = static_cast(datalayer_extended.tesla.BMS_maxRegenPower) * 0.01; float BMS_maxDischargePower = static_cast(datalayer_extended.tesla.BMS_maxDischargePower) * 0.013; float BMS_maxStationaryHeatPower = static_cast(datalayer_extended.tesla.BMS_maxStationaryHeatPower) * 0.01; float BMS_hvacPowerBudget = static_cast(datalayer_extended.tesla.BMS_hvacPowerBudget) * 0.02; - float BMS_powerDissipation = static_cast(datalayer_extended.tesla.BMS_powerDissipation) * 0.02; + float BMS_powerDissipation = static_cast(datalayer_extended.tesla.BMS_powerDissipation) * 0.02; float BMS_flowRequest = static_cast(datalayer_extended.tesla.BMS_flowRequest) * 0.3; - float BMS_inletActiveCoolTargetT = static_cast(datalayer_extended.tesla.BMS_inletActiveCoolTargetT) * 0.25 - 25; + float BMS_inletActiveCoolTargetT = + static_cast(datalayer_extended.tesla.BMS_inletActiveCoolTargetT) * 0.25 - 25; float BMS_inletPassiveTargetT = static_cast(datalayer_extended.tesla.BMS_inletPassiveTargetT) * 0.25 - 25; - float BMS_inletActiveHeatTargetT = static_cast(datalayer_extended.tesla.BMS_inletActiveHeatTargetT) * 0.25 - 25; + float BMS_inletActiveHeatTargetT = + static_cast(datalayer_extended.tesla.BMS_inletActiveHeatTargetT) * 0.25 - 25; float BMS_packTMin = static_cast(datalayer_extended.tesla.BMS_packTMin); float BMS_packTMax = static_cast(datalayer_extended.tesla.BMS_packTMax); float PCS_dcdcMaxLvOutputCurrent = static_cast(datalayer_extended.tesla.PCS_dcdcMaxLvOutputCurrent) * 0.1; float PCS_dcdcCurrentLimit = static_cast(datalayer_extended.tesla.PCS_dcdcCurrentLimit) * 0.1; - float PCS_dcdcLvOutputCurrentTempLimit = static_cast(datalayer_extended.tesla.PCS_dcdcLvOutputCurrentTempLimit) * 0.1; + float PCS_dcdcLvOutputCurrentTempLimit = + static_cast(datalayer_extended.tesla.PCS_dcdcLvOutputCurrentTempLimit) * 0.1; float PCS_dcdcUnifiedCommand = static_cast(datalayer_extended.tesla.PCS_dcdcUnifiedCommand) * 0.001; - float PCS_dcdcCLAControllerOutput = static_cast(datalayer_extended.tesla.PCS_dcdcCLAControllerOutput * 0.001); + float PCS_dcdcCLAControllerOutput = + static_cast(datalayer_extended.tesla.PCS_dcdcCLAControllerOutput * 0.001); float PCS_dcdcTankVoltage = static_cast(datalayer_extended.tesla.PCS_dcdcTankVoltage); float PCS_dcdcTankVoltageTarget = static_cast(datalayer_extended.tesla.PCS_dcdcTankVoltageTarget); float PCS_dcdcClaCurrentFreq = static_cast(datalayer_extended.tesla.PCS_dcdcClaCurrentFreq) * 0.0976563; @@ -348,14 +362,21 @@ String advanced_battery_processor(const String& var) { float PCS_dcdcShortTimeUs = static_cast(datalayer_extended.tesla.PCS_dcdcShortTimeUs) * 0.000488281; float PCS_dcdcHalfPeriodUs = static_cast(datalayer_extended.tesla.PCS_dcdcHalfPeriodUs) * 0.000488281; float PCS_dcdcIntervalMaxFrequency = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxFrequency); - float PCS_dcdcIntervalMaxHvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxHvBusVolt) * 0.1; - float PCS_dcdcIntervalMaxLvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvBusVolt) * 0.1; - float PCS_dcdcIntervalMaxLvOutputCurr = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvOutputCurr); + float PCS_dcdcIntervalMaxHvBusVolt = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxHvBusVolt) * 0.1; + float PCS_dcdcIntervalMaxLvBusVolt = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvBusVolt) * 0.1; + float PCS_dcdcIntervalMaxLvOutputCurr = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMaxLvOutputCurr); float PCS_dcdcIntervalMinFrequency = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinFrequency); - float PCS_dcdcIntervalMinHvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinHvBusVolt) * 0.1; - float PCS_dcdcIntervalMinLvBusVolt = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvBusVolt) * 0.1; - float PCS_dcdcIntervalMinLvOutputCurr = static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvOutputCurr); - float PCS_dcdc12vSupportLifetimekWh = static_cast(datalayer_extended.tesla.PCS_dcdc12vSupportLifetimekWh) * 0.01; + float PCS_dcdcIntervalMinHvBusVolt = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinHvBusVolt) * 0.1; + float PCS_dcdcIntervalMinLvBusVolt = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvBusVolt) * 0.1; + float PCS_dcdcIntervalMinLvOutputCurr = + static_cast(datalayer_extended.tesla.PCS_dcdcIntervalMinLvOutputCurr); + float PCS_dcdc12vSupportLifetimekWh = + static_cast(datalayer_extended.tesla.PCS_dcdc12vSupportLifetimekWh) * 0.01; float HVP_hvp1v5Ref = static_cast(datalayer_extended.tesla.HVP_hvp1v5Ref) * 0.1; float HVP_shuntCurrentDebug = static_cast(datalayer_extended.tesla.HVP_shuntCurrentDebug) * 0.1; float HVP_dcLinkVoltage = static_cast(datalayer_extended.tesla.HVP_dcLinkVoltage) * 0.1; @@ -380,16 +401,57 @@ String advanced_battery_processor(const String& var) { float HVP_shuntBarTempDbg = static_cast(datalayer_extended.tesla.HVP_shuntBarTempDbg) * 0.01; float HVP_shuntAsicTempDbg = static_cast(datalayer_extended.tesla.HVP_shuntAsicTempDbg) * 0.01; - static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", "CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL", "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"}; - static const char* hvilStatusState[] = {"NOT Ok", "STATUS_OK", "CURRENT_SOURCE_FAULT", "INTERNAL_OPEN_FAULT", "VEHICLE_OPEN_FAULT", "PENTHOUSE_LID_OPEN_FAULT", "UNKNOWN_LOCATION_OPEN_FAULT", "VEHICLE_NODE_FAULT", "NO_12V_SUPPLY", "VEHICLE_OR_PENTHOUSE_LID_OPENFAULT", "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)", "UNKNOWN(13)", "UNKNOWN(14)", "UNKNOWN(15)"}; - static const char* contactorState[] = {"SNA", "OPEN", "PRECHARGE", "BLOCKED", "PULLED_IN", "OPENING", "ECONOMIZED", "WELDED", "UNKNOWN(8)", "UNKNOWN(9)", "UNKNOWN(10)", "UNKNOWN(11)"}; - static const char* BMS_state[] = {"STANDBY", "DRIVE", "SUPPORT", "CHARGE", "FEIM", "CLEAR_FAULT", "FAULT", "WELD", "TEST", "SNA"}; + static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", + "CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL", + "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"}; + static const char* hvilStatusState[] = {"NOT Ok", + "STATUS_OK", + "CURRENT_SOURCE_FAULT", + "INTERNAL_OPEN_FAULT", + "VEHICLE_OPEN_FAULT", + "PENTHOUSE_LID_OPEN_FAULT", + "UNKNOWN_LOCATION_OPEN_FAULT", + "VEHICLE_NODE_FAULT", + "NO_12V_SUPPLY", + "VEHICLE_OR_PENTHOUSE_LID_OPENFAULT", + "UNKNOWN(10)", + "UNKNOWN(11)", + "UNKNOWN(12)", + "UNKNOWN(13)", + "UNKNOWN(14)", + "UNKNOWN(15)"}; + static const char* contactorState[] = {"SNA", "OPEN", "PRECHARGE", "BLOCKED", + "PULLED_IN", "OPENING", "ECONOMIZED", "WELDED", + "UNKNOWN(8)", "UNKNOWN(9)", "UNKNOWN(10)", "UNKNOWN(11)"}; + static const char* BMS_state[] = {"STANDBY", "DRIVE", "SUPPORT", "CHARGE", "FEIM", + "CLEAR_FAULT", "FAULT", "WELD", "TEST", "SNA"}; static const char* BMS_contactorState[] = {"SNA", "OPEN", "OPENING", "CLOSING", "CLOSED", "WELDED", "BLOCKED"}; - static const char* BMS_hvState[] = {"DOWN", "COMING_UP", "GOING_DOWN", "UP_FOR_DRIVE", "UP_FOR_CHARGE", "UP_FOR_DC_CHARGE", "UP"}; - static const char* BMS_uiChargeStatus[] = {"DISCONNECTED", "NO_POWER", "ABOUT_TO_CHARGE", "CHARGING", "CHARGE_COMPLETE", "CHARGE_STOPPED"}; + static const char* BMS_hvState[] = {"DOWN", "COMING_UP", "GOING_DOWN", "UP_FOR_DRIVE", + "UP_FOR_CHARGE", "UP_FOR_DC_CHARGE", "UP"}; + static const char* BMS_uiChargeStatus[] = {"DISCONNECTED", "NO_POWER", "ABOUT_TO_CHARGE", + "CHARGING", "CHARGE_COMPLETE", "CHARGE_STOPPED"}; static const char* PCS_dcdcStatus[] = {"IDLE", "ACTIVE", "FAULTED"}; - static const char* PCS_dcdcMainState[] = {"STANDBY", "12V_SUPPORT_ACTIVE", "PRECHARGE_STARTUP", "PRECHARGE_ACTIVE", "DIS_HVBUS_ACTIVE", "SHUTDOWN", "FAULTED"}; - static const char* PCS_dcdcSubState[] = {"PWR_UP_INIT", "STANDBY", "12V_SUPPORT_ACTIVE", "DIS_HVBUS", "PCHG_FAST_DIS_HVBUS", "PCHG_SLOW_DIS_HVBUS", "PCHG_DWELL_CHARGE", "PCHG_DWELL_WAIT", "PCHG_DI_RECOVERY_WAIT", "PCHG_ACTIVE", "PCHG_FLT_FAST_DIS_HVBUS", "SHUTDOWN", "12V_SUPPORT_FAULTED", "DIS_HVBUS_FAULTED", "PCHG_FAULTED", "CLEAR_FAULTS", "FAULTED", "NUM"}; + static const char* PCS_dcdcMainState[] = {"STANDBY", "12V_SUPPORT_ACTIVE", "PRECHARGE_STARTUP", + "PRECHARGE_ACTIVE", "DIS_HVBUS_ACTIVE", "SHUTDOWN", + "FAULTED"}; + static const char* PCS_dcdcSubState[] = {"PWR_UP_INIT", + "STANDBY", + "12V_SUPPORT_ACTIVE", + "DIS_HVBUS", + "PCHG_FAST_DIS_HVBUS", + "PCHG_SLOW_DIS_HVBUS", + "PCHG_DWELL_CHARGE", + "PCHG_DWELL_WAIT", + "PCHG_DI_RECOVERY_WAIT", + "PCHG_ACTIVE", + "PCHG_FLT_FAST_DIS_HVBUS", + "SHUTDOWN", + "12V_SUPPORT_FAULTED", + "DIS_HVBUS_FAULTED", + "PCHG_FAULTED", + "CLEAR_FAULTS", + "FAULTED", + "NUM"}; static const char* BMS_powerLimitState[] = {"NOT_CALCULATED_FOR_DRIVE", "CALCULATED_FOR_DRIVE"}; static const char* HVP_status[] = {"INVALID", "NOT_AVAILABLE", "STALE", "VALID"}; static const char* falseTrue[] = {"False", "True"}; @@ -397,15 +459,22 @@ String advanced_battery_processor(const String& var) { //0x20A 522 HVP_contatorState content += "

Contactor Status: " + String(contactorText[datalayer_extended.tesla.status_contactor]) + "

"; content += "

HVIL: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "

"; - content += "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; - content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; + content += + "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; + content += + "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; content += "

Closing allowed?: " + String(falseTrue[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; content += "

Pyrotest in Progress: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; - content += "

Contactors Open Now Requested: " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; - content += "

Contactors Open Requested; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; - content += "

Contactors Request Status; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; - content += "

Contactors Reset Request Required; " + String(falseTrue[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; - content += "

DC Link Allowed to Energize;" + String(falseTrue[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; + content += "

Contactors Open Now Requested: " + + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; + content += "

Contactors Open Requested; " + + String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; + content += "

Contactors Request Status; " + + String(falseTrue[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; + content += "

Contactors Reset Request Required; " + + String(falseTrue[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; + content += "

DC Link Allowed to Energize;" + + String(falseTrue[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -422,21 +491,37 @@ String advanced_battery_processor(const String& var) { content += "

PCS dcdc Temp: " + String(PCS_dcdcTemp) + " DegC

"; content += "

PCS Ambient Temp: " + String(PCS_ambientTemp) + " DegC

"; //0x224 548 PCS_dcdcStatus - content += "

Precharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcPrechargeStatus]) + "

"; - content += "

12V Support Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdc12VSupportStatus]) + "

"; - content += "

HV Bus Discharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcHvBusDischargeStatus]) + "

"; - content += "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; - content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; + content += + "

Precharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcPrechargeStatus]) + + "

"; + content += + "

12V Support Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdc12VSupportStatus]) + + "

"; + content += "

HV Bus Discharge Status: " + + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcHvBusDischargeStatus]) + "

"; + content += + "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; + content += + "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; content += "

PCS Faulted: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "

"; - content += "

Output Is Limited: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; + content += + "

Output Is Limited: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; - content += "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + "

"; - content += "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + "

"; - content += "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + "

"; - content += "

PWM Enable Line: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; - content += "

Supporting Fixed LV Target: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; - content += "

Precharge Restart Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; - content += "

Initial Precharge Substate: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; + content += "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + + "

"; + content += + "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + + "

"; + content += "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + + "

"; + content += + "

PWM Enable Line: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; + content += "

Supporting Fixed LV Target: " + + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; + content += "

Precharge Restart Cnt: " + + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; + content += "

Initial Precharge Substate: " + + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; //0x2C4 708 PCS_logging content += "

PCS_dcdcMaxLvOutputCurrent: " + String(PCS_dcdcMaxLvOutputCurrent) + " A

"; content += "

PCS_dcdcCurrentLimit: " + String(PCS_dcdcCurrentLimit) + " A

"; @@ -463,21 +548,26 @@ String advanced_battery_processor(const String& var) { content += "

Total Charge: " + String(total_charge) + " KWh

"; //0x212 530 BMS_status content += "

Isolation Resistance: " + String(isolationResistance) + " kOhms

"; - content += "

BMS Contactor State: " + String(BMS_contactorState[datalayer_extended.tesla.battery_BMS_contactorState]) + "

"; + content += + "

BMS Contactor State: " + String(BMS_contactorState[datalayer_extended.tesla.battery_BMS_contactorState]) + + "

"; content += "

BMS State: " + String(BMS_state[datalayer_extended.tesla.battery_BMS_state]) + "

"; content += "

BMS HV State: " + String(BMS_hvState[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; - content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; - content += "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; + content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + + "

"; + content += + "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //0x352 850 BMS_energyStatus - content += "

Early BMS 0x352"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh

"; content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; - content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; + content += + "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //0x352 850 BMS_energyStatus - content += "

Late BMS 0x352 with Mux2021 and comment 0x352 with MUX + content += "

Late BMS 0x352 with Mux2021 and comment 0x352 with MUX content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " KWh

"; @@ -508,8 +598,11 @@ String advanced_battery_processor(const String& var) { content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; - content += "

Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + " KW

"; - content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; + content += + "

Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + + " KW

"; + content += + "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; //0x312 786 BMS_thermalStatus content += "

Power Dissipation: " + String(BMS_powerDissipation) + " kW

"; @@ -519,31 +612,44 @@ String advanced_battery_processor(const String& var) { content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; - content += "

PCS No Flow Request: " + String(falseTrue[ datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; + content += "

PCS No Flow Request: " + String(falseTrue[datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; content += "

BMS No Flow Request: " + String(falseTrue[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; //0x7AA 1962 HVP_debugMessage - content += "

HVP_gpioPassivePyroDepl: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; + content += + "

HVP_gpioPassivePyroDepl: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; content += "

HVP_gpioPyroIsoEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; content += "

HVP_gpioCpFaultIn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; - content += "

HVP_gpioPackContPowerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; + content += + "

HVP_gpioPackContPowerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; content += "

HVP_gpioHvCablesOk: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; - content += "

HVP_gpioHvpSelfEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; + content += + "

HVP_gpioHvpSelfEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; content += "

HVP_gpioLed: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioLed]) + "

"; content += "

HVP_gpioCrashSignal: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; - content += "

HVP_gpioShuntDataReady: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; - content += "

HVP_gpioFcContPosAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; - content += "

HVP_gpioFcContNegAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; + content += + "

HVP_gpioShuntDataReady: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; + content += + "

HVP_gpioFcContPosAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; + content += + "

HVP_gpioFcContNegAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; content += "

HVP_gpioBmsEout: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; content += "

HVP_gpioCpFaultOut: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; content += "

HVP_gpioPyroPor: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; content += "

HVP_gpioShuntEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; content += "

HVP_gpioHvpVerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; - content += "

HVP_gpioPackCoontPosFlywheel: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + "

"; - content += "

HVP_gpioCpLatchEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; + content += "

HVP_gpioPackCoontPosFlywheel: " + + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + "

"; + content += + "

HVP_gpioCpLatchEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; content += "

HVP_gpioPcsEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; - content += "

HVP_gpioPcsDcdcPwmEnable: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + "

"; - content += "

HVP_gpioPcsChargePwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + "

"; - content += "

HVP_gpioFcContPowerEnable: " + String(falseTrue[ datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + "

"; + content += "

HVP_gpioPcsDcdcPwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + + "

"; + content += + "

HVP_gpioPcsChargePwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + + "

"; + content += + "

HVP_gpioFcContPowerEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + + "

"; content += "

HVP_gpioHvilEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; content += "

HVP_gpioSecDrdy: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; @@ -551,8 +657,11 @@ String advanced_battery_processor(const String& var) { content += "

HVP_packCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; content += "

HVP_auxCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; content += "

HVP_currentSenseMia: " + String(falseTrue[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; - content += "

HVP_shuntRefVoltageMismatch: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + "

"; - content += "

HVP_shuntThermistorMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; + content += + "

HVP_shuntRefVoltageMismatch: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + + "

"; + content += + "

HVP_shuntThermistorMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; content += "

HVP_shuntHwMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; From 1ea1746e326cb8b8edf5ce260caa0cd100ce936e Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sat, 21 Dec 2024 23:33:34 +1300 Subject: [PATCH 24/93] Update datalayer_extended.h --- Software/src/datalayer/datalayer_extended.h | 132 ++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index 0d9b2d3f..5bbedb29 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -180,6 +180,11 @@ typedef struct { /** uint8_t */ /** Pyro test in progress */ uint8_t pyroTestInProgress = 0; + uint8_t battery_packCtrsOpenNowRequested = 0; + uint8_t battery_packCtrsOpenRequested = 0; + uint8_t battery_packCtrsRequestStatus = 0; + uint8_t battery_packCtrsResetRequestRequired = 0; + uint8_t battery_dcLinkAllowedToEnergize = 0; uint8_t battery_beginning_of_life = 0; uint8_t battery_battTempPct = 0; uint16_t battery_dcdcLvBusVolt = 0; @@ -195,10 +200,20 @@ typedef struct { uint16_t battery_energy_to_charge_complete_m1 = 0; uint16_t battery_energy_buffer = 0; uint16_t battery_energy_buffer_m1 = 0; + uint16_t battery_expected_energy_remaining = 0; + uint16_t battery_expected_energy_remaining_m1 = 0; uint16_t battery_full_charge_complete = 0; uint8_t battery_fully_charged = 0; uint16_t battery_total_discharge = 0; uint16_t battery_total_charge = 0; + uint16_t battery_BrickVoltageMax = 0; + uint16_t battery_BrickVoltageMin = 0; + uint8_t battery_BrickVoltageMaxNum = 0; + uint8_t battery_BrickVoltageMinNum = 0; + uint8_t battery_BrickTempMaxNum = 0; + uint8_t battery_BrickTempMinNum = 0; + uint8_t battery_BrickModelTMax = 0; + uint8_t battery_BrickModelTMin = 0; uint16_t battery_packConfigMultiplexer = 0; uint16_t battery_moduleType = 0; uint16_t battery_reservedConfig = 0; @@ -212,6 +227,123 @@ typedef struct { uint32_t battery_soc_max = 0; uint32_t battery_soc_ave = 0; uint32_t battery_soc_ui = 0; + uint8_t battery_BMS_contactorState = 0; + uint8_t battery_BMS_state = 0; + uint8_t battery_BMS_hvState = 0; + uint16_t battery_BMS_isolationResistance = 0; + uint8_t battery_BMS_uiChargeStatus = 0; + uint8_t battery_BMS_diLimpRequest = 0; + uint16_t battery_BMS_chgPowerAvailable = 0; + uint8_t battery_BMS_pcsPwmEnabled = 0; + uint8_t battery_PCS_dcdcPrechargeStatus = 0; + uint8_t battery_PCS_dcdc12VSupportStatus = 0; + uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; + uint8_t battery_PCS_dcdcMainState = 0; + uint8_t battery_PCS_dcdcSubState = 0; + uint8_t battery_PCS_dcdcFaulted = 0; + uint8_t battery_PCS_dcdcOutputIsLimited = 0; + uint16_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; + uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; + uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0; + uint8_t battery_PCS_dcdcDischargeRtyCnt = 0; + uint8_t battery_PCS_dcdcPwmEnableLine = 0; + uint8_t battery_PCS_dcdcSupportingFixedLvTarget = 0; + uint8_t battery_PCS_dcdcPrechargeRestartCnt = 0; + uint8_t battery_PCS_dcdcInitialPrechargeSubState = 0; + uint16_t BMS_maxRegenPower = 0; + uint16_t BMS_maxDischargePower = 0; + uint16_t BMS_maxStationaryHeatPower = 0; + uint16_t BMS_hvacPowerBudget = 0; + uint8_t BMS_notEnoughPowerForHeatPump = 0; + uint8_t BMS_powerLimitState = 0; + uint8_t BMS_inverterTQF = 0; + uint16_t BMS_powerDissipation = 0; + uint8_t BMS_flowRequest = 0; + uint16_t BMS_inletActiveCoolTargetT = 0; + uint16_t BMS_inletPassiveTargetT = 0; + uint16_t BMS_inletActiveHeatTargetT = 0; + uint16_t BMS_packTMin = 0; + uint16_t BMS_packTMax = 0; + uint8_t BMS_pcsNoFlowRequest = 0; + uint8_t BMS_noFlowRequest = 0; + uint16_t PCS_dcdcTemp = 0; + uint16_t PCS_ambientTemp = 0; + uint16_t PCS_dcdcMaxLvOutputCurrent = 0; + uint16_t PCS_dcdcCurrentLimit = 0; + uint16_t PCS_dcdcLvOutputCurrentTempLimit = 0; + uint16_t PCS_dcdcUnifiedCommand = 0; + uint16_t PCS_dcdcCLAControllerOutput = 0; + uint16_t PCS_dcdcTankVoltage = 0; + uint16_t PCS_dcdcTankVoltageTarget = 0; + uint16_t PCS_dcdcClaCurrentFreq = 0; + uint16_t PCS_dcdcTCommMeasured = 0; + uint16_t PCS_dcdcShortTimeUs = 0; + uint16_t PCS_dcdcHalfPeriodUs = 0; + uint16_t PCS_dcdcIntervalMaxFrequency = 0; + uint16_t PCS_dcdcIntervalMaxHvBusVolt = 0; + uint16_t PCS_dcdcIntervalMaxLvBusVolt = 0; + uint16_t PCS_dcdcIntervalMaxLvOutputCurr = 0; + uint16_t PCS_dcdcIntervalMinFrequency = 0; + uint16_t PCS_dcdcIntervalMinHvBusVolt = 0; + uint16_t PCS_dcdcIntervalMinLvBusVolt = 0; + uint16_t PCS_dcdcIntervalMinLvOutputCurr = 0; + uint32_t PCS_dcdc12vSupportLifetimekWh = 0; + uint8_t HVP_gpioPassivePyroDepl = 0; + uint8_t HVP_gpioPyroIsoEn = 0; + uint8_t HVP_gpioCpFaultIn = 0; + uint8_t HVP_gpioPackContPowerEn = 0; + uint8_t HVP_gpioHvCablesOk = 0; + uint8_t HVP_gpioHvpSelfEnable = 0; + uint8_t HVP_gpioLed = 0; + uint8_t HVP_gpioCrashSignal = 0; + uint8_t HVP_gpioShuntDataReady = 0; + uint8_t HVP_gpioFcContPosAux = 0; + uint8_t HVP_gpioFcContNegAux = 0; + uint8_t HVP_gpioBmsEout = 0; + uint8_t HVP_gpioCpFaultOut = 0; + uint8_t HVP_gpioPyroPor = 0; + uint8_t HVP_gpioShuntEn = 0; + uint8_t HVP_gpioHvpVerEn = 0; + uint8_t HVP_gpioPackCoontPosFlywheel = 0; + uint8_t HVP_gpioCpLatchEnable = 0; + uint8_t HVP_gpioPcsEnable = 0; + uint8_t HVP_gpioPcsDcdcPwmEnable = 0; + uint8_t HVP_gpioPcsChargePwmEnable = 0; + uint8_t HVP_gpioFcContPowerEnable = 0; + uint8_t HVP_gpioHvilEnable = 0; + uint8_t HVP_gpioSecDrdy = 0; + uint16_t HVP_hvp1v5Ref = 0; + uint16_t HVP_shuntCurrentDebug = 0; + uint8_t HVP_packCurrentMia = 0; + uint8_t HVP_auxCurrentMia = 0; + uint8_t HVP_currentSenseMia = 0; + uint8_t HVP_shuntRefVoltageMismatch = 0; + uint8_t HVP_shuntThermistorMia = 0; + uint8_t HVP_shuntHwMia = 0; + uint16_t HVP_dcLinkVoltage = 0; + uint16_t HVP_packVoltage = 0; + uint16_t HVP_fcLinkVoltage = 0; + uint16_t HVP_packContVoltage = 0; + uint16_t HVP_packNegativeV = 0; + uint16_t HVP_packPositiveV = 0; + uint16_t HVP_pyroAnalog = 0; + uint16_t HVP_dcLinkNegativeV = 0; + uint16_t HVP_dcLinkPositiveV = 0; + uint16_t HVP_fcLinkNegativeV = 0; + uint16_t HVP_fcContCoilCurrent = 0; + uint16_t HVP_fcContVoltage = 0; + uint16_t HVP_hvilInVoltage = 0; + uint16_t HVP_hvilOutVoltage = 0; + uint16_t HVP_fcLinkPositiveV = 0; + uint16_t HVP_packContCoilCurrent = 0; + uint16_t HVP_battery12V = 0; + uint16_t HVP_shuntRefVoltageDbg = 0; + uint16_t HVP_shuntAuxCurrentDbg = 0; + uint16_t HVP_shuntBarTempDbg = 0; + uint16_t HVP_shuntAsicTempDbg = 0; + uint8_t HVP_shuntAuxCurrentStatus = 0; + uint8_t HVP_shuntBarTempStatus = 0; + uint8_t HVP_shuntAsicTempStatus = 0; } DATALAYER_INFO_TESLA; typedef struct { From ff6727da113431ec3c89643c7e42b408d95429fb Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 00:00:41 +1300 Subject: [PATCH 25/93] Update advanced_battery_html.cpp --- Software/src/devboard/webserver/advanced_battery_html.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 64958929..01b84c6b 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -574,7 +574,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer_m1) + " KWh

"; content += "

Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh

"; - content += "

Fully Charged: " + String(noYes[datalayer_extended.battery_fully_charged]) + "

"; + content += "

Fully Charged: " + String(noYes[datalayer_extended.tesla.battery_fully_charged]) + "

"; //0x392 BMS_packConfig content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; @@ -684,9 +684,9 @@ String advanced_battery_processor(const String& var) { content += "

HVP_shuntAuxCurrentDbg: " + String(HVP_shuntAuxCurrentDbg) + " A

"; content += "

HVP_shuntBarTempDbg: " + String(HVP_shuntBarTempDbg) + " DegC

"; content += "

HVP_shuntAsicTempDbg: " + String(HVP_shuntAsicTempDbg) + " DegC

"; - content += "

HVP_shuntAuxCurrentStatus: " + String(HVP_status) + "

"; - content += "

HVP_shuntBarTempStatus: " + String(HVP_status) + "

"; - content += "

HVP_shuntAsicTempStatus: " + String(HVP_status) + "

"; + content += "

HVP_shuntAuxCurrentStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAuxCurrentStatus]) + "

"; + content += "

HVP_shuntBarTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntBarTempStatus]) + "

"; + content += "

HVP_shuntAsicTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAsicTempStatus]) + "

"; #endif From 333bcef917fa91871887401d708931cdbee30e9a Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 00:00:59 +1300 Subject: [PATCH 26/93] Update advanced_battery_html.cpp --- .../src/devboard/webserver/advanced_battery_html.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 01b84c6b..c8fc14c3 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -684,9 +684,13 @@ String advanced_battery_processor(const String& var) { content += "

HVP_shuntAuxCurrentDbg: " + String(HVP_shuntAuxCurrentDbg) + " A

"; content += "

HVP_shuntBarTempDbg: " + String(HVP_shuntBarTempDbg) + " DegC

"; content += "

HVP_shuntAsicTempDbg: " + String(HVP_shuntAsicTempDbg) + " DegC

"; - content += "

HVP_shuntAuxCurrentStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAuxCurrentStatus]) + "

"; - content += "

HVP_shuntBarTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntBarTempStatus]) + "

"; - content += "

HVP_shuntAsicTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAsicTempStatus]) + "

"; + content += + "

HVP_shuntAuxCurrentStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAuxCurrentStatus]) + + "

"; + content += + "

HVP_shuntBarTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntBarTempStatus]) + "

"; + content += "

HVP_shuntAsicTempStatus: " + String(HVP_status[datalayer_extended.tesla.HVP_shuntAsicTempStatus]) + + "

"; #endif From 8870027d75770ae76bfe744b377200eb0b7731bf Mon Sep 17 00:00:00 2001 From: No-Signal Date: Sun, 8 Dec 2024 11:30:10 +0000 Subject: [PATCH 27/93] Moving secrets from USER_SETTINGS to USER_SECRETS.h --- .gitignore | 3 +++ README.md | 3 ++- Software/USER_SECRETS.TEMPLATE.h | 8 ++++++++ Software/USER_SETTINGS.cpp | 21 +++++++++++---------- Software/USER_SETTINGS.h | 1 - Software/src/devboard/mqtt/mqtt.cpp | 1 + 6 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 Software/USER_SECRETS.TEMPLATE.h diff --git a/.gitignore b/.gitignore index f4dd4582..f0e530d2 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ compile.bat # Ignore binary files *.bin + +# Ignore secret file +USER_SECRETS.h \ No newline at end of file diff --git a/README.md b/README.md index c2d9630c..d3acd4be 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,8 @@ For more examples showing wiring, see each battery types own Wiki page. For inst 5. The Arduino board should be set to `ESP32 Dev Module` (under `Tools` -> `Board` -> `ESP32 Arduino`) with the following settings: ![alt text](https://github.com/Xinyuan-LilyGO/T-CAN485/blob/main/img/arduino_setting.png) 6. Select which battery type you will use, along with other optional settings. This is done in the `USER_SETTINGS.h` file. -7. Press `Verify` and `Upload` to send the sketch to the board. +7. Copy the `USER_SECRETS.TEMPLATE.h` file to `USER_SECRETS.h` and update relevant secrets. +8. Press `Verify` and `Upload` to send the sketch to the board. NOTE: In some cases, the LilyGo must be powered through the main power connector instead of USB-C when performing the initial firmware upload. NOTE: On Mac, the following USB driver may need to be installed: https://github.com/WCHSoftGroup/ch34xser_macos diff --git a/Software/USER_SECRETS.TEMPLATE.h b/Software/USER_SECRETS.TEMPLATE.h new file mode 100644 index 00000000..eaf5ced1 --- /dev/null +++ b/Software/USER_SECRETS.TEMPLATE.h @@ -0,0 +1,8 @@ +#define WIFI_SSID "REPLACE_WITH_YOUR_SSID" // Maximum of 63 characters +#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" // Minimum of 8 characters +#define AP_PASSWORD "123456789" // Minimum of 8 characters; set to blank if you want the access point to be open +#define HTTP_USERNAME "admin" // username to webserver authentication; +#define HTTP_PASSWORD "admin" // password to webserver authentication; +#define MQTT_SERVER "192.168.xxx.yyy" // mqtt server address +#define MQTT_USER NULL // mqtt username, leave blank for no authentication +#define MQTT_PASSWORD NULL // mqtt password, leave blank for no authentication diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index 7c2309b4..7c406893 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -1,5 +1,6 @@ #include "USER_SETTINGS.h" #include +#include "USER_SECRETS.h" #include "src/devboard/hal/hal.h" /* This file contains all the battery settings and limits */ @@ -21,12 +22,12 @@ volatile CAN_Configuration can_config = { #ifdef WIFI -volatile uint8_t AccessPointEnabled = true; //Set to either true/false to enable direct wifi access point -std::string ssid = "REPLACE_WITH_YOUR_SSID"; // Maximum of 63 characters -std::string password = "REPLACE_WITH_YOUR_PASSWORD"; // Minimum of 8 characters -const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface -const char* passwordAP = "123456789"; // Minimum of 8 characters; set to NULL if you want the access point to be open -const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection +volatile uint8_t AccessPointEnabled = true; //Set to either true/false to enable direct wifi access point +std::string ssid = WIFI_SSID; // Set in USER_SECRETS.h +std::string password = WIFI_PASSWORD; // Set in USER_SECRETS.h +const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface +const char* passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h +const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection #ifdef WIFICONFIG // Set your Static IP address @@ -37,14 +38,14 @@ IPAddress gateway(192, 168, 10, 1); IPAddress subnet(255, 255, 255, 0); #endif #ifdef WEBSERVER -const char* http_username = "admin"; // username to webserver authentication; -const char* http_password = "admin"; // password to webserver authentication; +const char* http_username = HTTP_USERNAME; // Set in USER_SECRETS.h +const char* http_password = HTTP_PASSWORD; // Set in USER_SECRETS.h #endif // WEBSERVER // MQTT #ifdef MQTT -const char* mqtt_user = "REDACTED"; // Set NULL for no username -const char* mqtt_password = "REDACTED"; // Set NULL for no password +const char* mqtt_user = MQTT_USER; // Set in USER_SECRETS.h +const char* mqtt_password = MQTT_PASSWORD; // Set in USER_SECRETS.h #ifdef MQTT_MANUAL_TOPIC_OBJECT_NAME const char* mqtt_topic_name = "BE"; // Custom MQTT topic name. Previously, the name was automatically set to "battery-emulator_esp32-XXXXXX" diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index d31582dd..823d46a0 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -92,7 +92,6 @@ /* MQTT options */ // #define MQTT // Enable this line to enable MQTT -#define MQTT_SERVER "192.168.xxx.yyy" #define MQTT_PORT 1883 #define MQTT_MANUAL_TOPIC_OBJECT_NAME // Enable this to use custom MQTT topic, object ID prefix, and device name. \ // WARNING: If this is not defined, the previous default naming format \ diff --git a/Software/src/devboard/mqtt/mqtt.cpp b/Software/src/devboard/mqtt/mqtt.cpp index 95f5444a..0779711c 100644 --- a/Software/src/devboard/mqtt/mqtt.cpp +++ b/Software/src/devboard/mqtt/mqtt.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "../../../USER_SECRETS.h" #include "../../../USER_SETTINGS.h" #include "../../battery/BATTERIES.h" #include "../../datalayer/datalayer.h" From 4f53a3b358990046e9232000017d02c9dcca672f Mon Sep 17 00:00:00 2001 From: No-Signal Date: Sat, 21 Dec 2024 10:48:39 +0000 Subject: [PATCH 28/93] Updating github workflows to copy template secrets file --- .github/workflows/compile-all-batteries.yml | 4 ++++ .../compile-all-combinations-part1-batteries-A-to-M.yml | 4 ++++ .../compile-all-combinations-part2-batteries-N-to-Z.yml | 4 ++++ .github/workflows/compile-all-inverters.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/workflows/compile-all-batteries.yml b/.github/workflows/compile-all-batteries.yml index 3e04e5d4..80466e52 100644 --- a/.github/workflows/compile-all-batteries.yml +++ b/.github/workflows/compile-all-batteries.yml @@ -86,6 +86,10 @@ jobs: # First we clone the repo using the `checkout` action. - name: Checkout uses: actions/checkout@v4 + + # Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + - name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h # We use the `arduino/setup-arduino-cli` action to install and # configure the Arduino CLI on the system. diff --git a/.github/workflows/compile-all-combinations-part1-batteries-A-to-M.yml b/.github/workflows/compile-all-combinations-part1-batteries-A-to-M.yml index 3fc07734..f9eda5bf 100644 --- a/.github/workflows/compile-all-combinations-part1-batteries-A-to-M.yml +++ b/.github/workflows/compile-all-combinations-part1-batteries-A-to-M.yml @@ -92,6 +92,10 @@ jobs: # First we clone the repo using the `checkout` action. - name: Checkout uses: actions/checkout@v4 + + # Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + - name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h # We use the `arduino/setup-arduino-cli` action to install and # configure the Arduino CLI on the system. diff --git a/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml b/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml index 668f6db3..8c77e237 100644 --- a/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml +++ b/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml @@ -93,6 +93,10 @@ jobs: # First we clone the repo using the `checkout` action. - name: Checkout uses: actions/checkout@v4 + + # Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + - name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h # We use the `arduino/setup-arduino-cli` action to install and # configure the Arduino CLI on the system. diff --git a/.github/workflows/compile-all-inverters.yml b/.github/workflows/compile-all-inverters.yml index 6723c803..b1f2afa1 100644 --- a/.github/workflows/compile-all-inverters.yml +++ b/.github/workflows/compile-all-inverters.yml @@ -78,6 +78,10 @@ jobs: # First we clone the repo using the `checkout` action. - name: Checkout uses: actions/checkout@v4 + + # Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + - name: Copy USER_SECRETS.TEMPLATE.h to USER_SECRETS.h + run: cp ./Software/USER_SECRETS.TEMPLATE.h ./Software/USER_SECRETS.h # We use the `arduino/setup-arduino-cli` action to install and # configure the Arduino CLI on the system. From fcedc4bb733512e61fd16c236aca1874b2c2fb34 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:28:40 +1300 Subject: [PATCH 29/93] Update advanced_battery_html.cpp --- .../webserver/advanced_battery_html.cpp | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index c8fc14c3..fbb2f29e 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -333,8 +333,8 @@ String advanced_battery_processor(const String& var) { float isolationResistance = static_cast(datalayer_extended.tesla.battery_BMS_isolationResistance) * 10; float PCS_dcdcMaxOutputCurrentAllowed = static_cast(datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed) * 0.1; - float PCS_dcdcTemp = static_cast(datalayer_extended.tesla.PCS_dcdcTemp * 0.1 + 40); - float PCS_ambientTemp = static_cast(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 + 40; + float PCS_dcdcTemp = static_cast(datalayer_extended.tesla.PCS_dcdcTemp) * 0.1 - 40; + float PCS_ambientTemp = static_cast(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 - 40; float BMS_maxRegenPower = static_cast(datalayer_extended.tesla.BMS_maxRegenPower) * 0.01; float BMS_maxDischargePower = static_cast(datalayer_extended.tesla.BMS_maxDischargePower) * 0.013; float BMS_maxStationaryHeatPower = static_cast(datalayer_extended.tesla.BMS_maxStationaryHeatPower) * 0.01; @@ -346,8 +346,8 @@ String advanced_battery_processor(const String& var) { float BMS_inletPassiveTargetT = static_cast(datalayer_extended.tesla.BMS_inletPassiveTargetT) * 0.25 - 25; float BMS_inletActiveHeatTargetT = static_cast(datalayer_extended.tesla.BMS_inletActiveHeatTargetT) * 0.25 - 25; - float BMS_packTMin = static_cast(datalayer_extended.tesla.BMS_packTMin); - float BMS_packTMax = static_cast(datalayer_extended.tesla.BMS_packTMax); + float BMS_packTMin = static_cast(datalayer_extended.tesla.BMS_packTMin) * 0.25 - 25; + float BMS_packTMax = static_cast(datalayer_extended.tesla.BMS_packTMax) * 0.25 - 25; float PCS_dcdcMaxLvOutputCurrent = static_cast(datalayer_extended.tesla.PCS_dcdcMaxLvOutputCurrent) * 0.1; float PCS_dcdcCurrentLimit = static_cast(datalayer_extended.tesla.PCS_dcdcCurrentLimit) * 0.1; float PCS_dcdcLvOutputCurrentTempLimit = @@ -454,6 +454,7 @@ String advanced_battery_processor(const String& var) { "NUM"}; static const char* BMS_powerLimitState[] = {"NOT_CALCULATED_FOR_DRIVE", "CALCULATED_FOR_DRIVE"}; static const char* HVP_status[] = {"INVALID", "NOT_AVAILABLE", "STALE", "VALID"}; + static const char* HVP_contactor[] = {"NOT_ACTIVE", "ACTIVE", "COMPLETED"}; static const char* falseTrue[] = {"False", "True"}; static const char* noYes[] = {"No", "Yes"}; //0x20A 522 HVP_contatorState @@ -466,15 +467,15 @@ String advanced_battery_processor(const String& var) { content += "

Closing allowed?: " + String(falseTrue[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; content += "

Pyrotest in Progress: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; content += "

Contactors Open Now Requested: " + - String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; - content += "

Contactors Open Requested; " + - String(falseTrue[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; - content += "

Contactors Request Status; " + - String(falseTrue[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; - content += "

Contactors Reset Request Required; " + - String(falseTrue[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; - content += "

DC Link Allowed to Energize;" + - String(falseTrue[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + ""; + content += "

Contactors Open Requested: " + + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; + content += "

Contactors Request Status: " + + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; + content += "

Contactors Reset Request Required: " + + String(noYes[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; + content += "

DC Link Allowed to Energize:" + + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -558,7 +559,8 @@ String advanced_battery_processor(const String& var) { content += "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //0x352 850 BMS_energyStatus - content += "

Early BMS 0x352"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh

"; @@ -567,7 +569,8 @@ String advanced_battery_processor(const String& var) { content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //0x352 850 BMS_energyStatus - content += "

Late BMS 0x352 with Mux2021 and comment 0x352 with MUX + content += "

Late BMS 0x352 with Mux:""2021 and comment 0x352 with MUX + content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0) * 100 / (beginning_of_life); content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " KWh

"; @@ -600,7 +603,7 @@ String advanced_battery_processor(const String& var) { content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; content += "

Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + - " KW

"; + ""; content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; From f55cad92f1cb32fdf2df863413eb58504b91b03c Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:29:06 +1300 Subject: [PATCH 30/93] Update advanced_battery_html.cpp --- .../webserver/advanced_battery_html.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index fbb2f29e..e457f6bf 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -468,14 +468,16 @@ String advanced_battery_processor(const String& var) { content += "

Pyrotest in Progress: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; content += "

Contactors Open Now Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; - content += "

Contactors Open Requested: " + - String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; + content += + "

Contactors Open Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + + "

"; content += "

Contactors Request Status: " + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; content += "

Contactors Reset Request Required: " + String(noYes[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; - content += "

DC Link Allowed to Energize:" + - String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; + content += + "

DC Link Allowed to Energize:" + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + + "

"; // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -559,7 +561,9 @@ String advanced_battery_processor(const String& var) { content += "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //0x352 850 BMS_energyStatus - content += "

Early BMS 0x352:""Early BMS 0x352:" + ""; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh

"; @@ -569,7 +573,9 @@ String advanced_battery_processor(const String& var) { content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //0x352 850 BMS_energyStatus - content += "

Late BMS 0x352 with Mux:""2021 and comment 0x352 with MUX + content += + "

Late BMS 0x352 with Mux:" + "2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0) * 100 / (beginning_of_life); content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; From 6d96808de44c66af83f65edf2c8176f7dc3f6cba Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:35:12 +1300 Subject: [PATCH 31/93] factoring changes --- Software/src/battery/TESLA-BATTERY.cpp | 88 +++++++++---------- .../webserver/advanced_battery_html.cpp | 15 ++-- 2 files changed, 50 insertions(+), 53 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index a9160a90..3d3daf7e 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -48,7 +48,7 @@ static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery_volts = 0; // V static int16_t battery_amps = 0; // A -static uint16_t battery_raw_amps = 0; // A +static int16_t battery_raw_amps = 0; // A static uint16_t battery_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable static uint16_t BMS_maxRegenPower = 0; //rename from battery_regenerative_limit @@ -167,11 +167,11 @@ static uint16_t BMS_packTMax = 0; static uint16_t BMS_pcsNoFlowRequest = 0; static uint16_t BMS_noFlowRequest = 0; //0x2A4; 676 PCS_thermalStatus -static uint16_t PCS_chgPhATemp = 0; -static uint16_t PCS_chgPhBTemp = 0; -static uint16_t PCS_chgPhCTemp = 0; -static uint16_t PCS_dcdcTemp = 0; -static uint16_t PCS_ambientTemp = 0; +static int16_t PCS_chgPhATemp = 0; +static int16_t PCS_chgPhBTemp = 0; +static int16_t PCS_chgPhCTemp = 0; +static int16_t PCS_dcdcTemp = 0; +static int16_t PCS_ambientTemp = 0; //0x2C4; 708 PCS_logging static uint16_t PCS_logMessageSelect = 0; static uint16_t PCS_dcdcMaxLvOutputCurrent = 0; @@ -179,10 +179,10 @@ static uint16_t PCS_dcdcCurrentLimit = 0; static uint16_t PCS_dcdcLvOutputCurrentTempLimit = 0; static uint16_t PCS_dcdcUnifiedCommand = 0; static uint16_t PCS_dcdcCLAControllerOutput = 0; -static uint16_t PCS_dcdcTankVoltage = 0; +static int16_t PCS_dcdcTankVoltage = 0; static uint16_t PCS_dcdcTankVoltageTarget = 0; static uint16_t PCS_dcdcClaCurrentFreq = 0; -static uint16_t PCS_dcdcTCommMeasured = 0; +static int16_t PCS_dcdcTCommMeasured = 0; static uint16_t PCS_dcdcShortTimeUs = 0; static uint16_t PCS_dcdcHalfPeriodUs = 0; static uint16_t PCS_dcdcIntervalMaxFrequency = 0; @@ -221,34 +221,34 @@ static uint8_t HVP_gpioFcContPowerEnable = 0; static uint8_t HVP_gpioHvilEnable = 0; static uint8_t HVP_gpioSecDrdy = 0; static uint16_t HVP_hvp1v5Ref = 0; -static uint16_t HVP_shuntCurrentDebug = 0; +static int16_t HVP_shuntCurrentDebug = 0; static uint8_t HVP_packCurrentMia = 0; static uint8_t HVP_auxCurrentMia = 0; static uint8_t HVP_currentSenseMia = 0; static uint8_t HVP_shuntRefVoltageMismatch = 0; static uint8_t HVP_shuntThermistorMia = 0; static uint8_t HVP_shuntHwMia = 0; -static uint16_t HVP_dcLinkVoltage = 0; -static uint16_t HVP_packVoltage = 0; -static uint16_t HVP_fcLinkVoltage = 0; +static int16_t HVP_dcLinkVoltage = 0; +static int16_t HVP_packVoltage = 0; +static int16_t HVP_fcLinkVoltage = 0; static uint16_t HVP_packContVoltage = 0; -static uint16_t HVP_packNegativeV = 0; -static uint16_t HVP_packPositiveV = 0; +static int16_t HVP_packNegativeV = 0; +static int16_t HVP_packPositiveV = 0; static uint16_t HVP_pyroAnalog = 0; -static uint16_t HVP_dcLinkNegativeV = 0; -static uint16_t HVP_dcLinkPositiveV = 0; -static uint16_t HVP_fcLinkNegativeV = 0; +static int16_t HVP_dcLinkNegativeV = 0; +static int16_t HVP_dcLinkPositiveV = 0; +static int16_t HVP_fcLinkNegativeV = 0; static uint16_t HVP_fcContCoilCurrent = 0; static uint16_t HVP_fcContVoltage = 0; static uint16_t HVP_hvilInVoltage = 0; static uint16_t HVP_hvilOutVoltage = 0; -static uint16_t HVP_fcLinkPositiveV = 0; +static int16_t HVP_fcLinkPositiveV = 0; static uint16_t HVP_packContCoilCurrent = 0; static uint16_t HVP_battery12V = 0; -static uint16_t HVP_shuntRefVoltageDbg = 0; -static uint16_t HVP_shuntAuxCurrentDbg = 0; -static uint16_t HVP_shuntBarTempDbg = 0; -static uint16_t HVP_shuntAsicTempDbg = 0; +static int16_t HVP_shuntRefVoltageDbg = 0; +static int16_t HVP_shuntAuxCurrentDbg = 0; +static int16_t HVP_shuntBarTempDbg = 0; +static int16_t HVP_shuntAsicTempDbg = 0; static uint8_t HVP_shuntAuxCurrentStatus = 0; static uint8_t HVP_shuntBarTempStatus = 0; static uint8_t HVP_shuntAsicTempStatus = 0; @@ -432,7 +432,7 @@ static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery2_volts = 0; // V static int16_t battery2_amps = 0; // A -static uint16_t battery2_raw_amps = 0; // A +static int16_t battery2_raw_amps = 0; // A static uint16_t battery2_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable static uint16_t BMS2_regenerative_limit = 0; @@ -547,11 +547,11 @@ static uint16_t BMS2_packTMax = 0; static uint16_t BMS2_pcsNoFlowRequest = 0; static uint16_t BMS2_noFlowRequest = 0; //0x2A4; 676 PCS_thermalStatus -static uint16_t PCS2_chgPhATemp = 0; -static uint16_t PCS2_chgPhBTemp = 0; -static uint16_t PCS2_chgPhCTemp = 0; -static uint16_t PCS2_dcdcTemp = 0; -static uint16_t PCS2_ambientTemp = 0; +static int16_t PCS2_chgPhATemp = 0; +static int16_t PCS2_chgPhBTemp = 0; +static int16_t PCS2_chgPhCTemp = 0; +static int16_t PCS2_dcdcTemp = 0; +static int16_t PCS2_ambientTemp = 0; //0x2C4; 708 PCS_logging static uint16_t PCS2_logMessageSelect = 0; static uint16_t PCS2_dcdcMaxLvOutputCurrent = 0; @@ -559,10 +559,10 @@ static uint16_t PCS2_dcdcCurrentLimit = 0; static uint16_t PCS2_dcdcLvOutputCurrentTempLimit = 0; static uint16_t PCS2_dcdcUnifiedCommand = 0; static uint16_t PCS2_dcdcCLAControllerOutput = 0; -static uint16_t PCS2_dcdcTankVoltage = 0; +static int16_t PCS2_dcdcTankVoltage = 0; static uint16_t PCS2_dcdcTankVoltageTarget = 0; static uint16_t PCS2_dcdcClaCurrentFreq = 0; -static uint16_t PCS2_dcdcTCommMeasured = 0; +static int16_t PCS2_dcdcTCommMeasured = 0; static uint16_t PCS2_dcdcShortTimeUs = 0; static uint16_t PCS2_dcdcHalfPeriodUs = 0; static uint16_t PCS2_dcdcIntervalMaxFrequency = 0; @@ -601,34 +601,34 @@ static uint8_t HVP2_gpioFcContPowerEnable = 0; static uint8_t HVP2_gpioHvilEnable = 0; static uint8_t HVP2_gpioSecDrdy = 0; static uint16_t HVP2_hvp1v5Ref = 0; -static uint16_t HVP2_shuntCurrentDebug = 0; +static int16_t HVP2_shuntCurrentDebug = 0; static uint8_t HVP2_packCurrentMia = 0; static uint8_t HVP2_auxCurrentMia = 0; static uint8_t HVP2_currentSenseMia = 0; static uint8_t HVP2_shuntRefVoltageMismatch = 0; static uint8_t HVP2_shuntThermistorMia = 0; static uint8_t HVP2_shuntHwMia = 0; -static uint16_t HVP2_dcLinkVoltage = 0; -static uint16_t HVP2_packVoltage = 0; -static uint16_t HVP2_fcLinkVoltage = 0; +static int16_t HVP2_dcLinkVoltage = 0; +static int16_t HVP2_packVoltage = 0; +static int16_t HVP2_fcLinkVoltage = 0; static uint16_t HVP2_packContVoltage = 0; -static uint16_t HVP2_packNegativeV = 0; -static uint16_t HVP2_packPositiveV = 0; +static int16_t HVP2_packNegativeV = 0; +static int16_t HVP2_packPositiveV = 0; static uint16_t HVP2_pyroAnalog = 0; -static uint16_t HVP2_dcLinkNegativeV = 0; -static uint16_t HVP2_dcLinkPositiveV = 0; -static uint16_t HVP2_fcLinkNegativeV = 0; +static int16_t HVP2_dcLinkNegativeV = 0; +static int16_t HVP2_dcLinkPositiveV = 0; +static int16_t HVP2_fcLinkNegativeV = 0; static uint16_t HVP2_fcContCoilCurrent = 0; static uint16_t HVP2_fcContVoltage = 0; static uint16_t HVP2_hvilInVoltage = 0; static uint16_t HVP2_hvilOutVoltage = 0; -static uint16_t HVP2_fcLinkPositiveV = 0; +static int16_t HVP2_fcLinkPositiveV = 0; static uint16_t HVP2_packContCoilCurrent = 0; static uint16_t HVP2_battery12V = 0; -static uint16_t HVP2_shuntRefVoltageDbg = 0; -static uint16_t HVP2_shuntAuxCurrentDbg = 0; -static uint16_t HVP2_shuntBarTempDbg = 0; -static uint16_t HVP2_shuntAsicTempDbg = 0; +static int16_t HVP2_shuntRefVoltageDbg = 0; +static int16_t HVP2_shuntAuxCurrentDbg = 0; +static int16_t HVP2_shuntBarTempDbg = 0; +static int16_t HVP2_shuntAsicTempDbg = 0; static uint8_t HVP2_shuntAuxCurrentStatus = 0; static uint8_t HVP2_shuntBarTempStatus = 0; static uint8_t HVP2_shuntAsicTempStatus = 0; diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index e457f6bf..a20e96f6 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -561,10 +561,8 @@ String advanced_battery_processor(const String& var) { content += "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //0x352 850 BMS_energyStatus - content += - "

Early BMS 0x352:" - ""; content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh

"; @@ -574,9 +572,8 @@ String advanced_battery_processor(const String& var) { "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //0x352 850 BMS_energyStatus content += - "

Late BMS 0x352 with Mux:" - "2021 and comment 0x352 with MUX - content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0) * 100 / (beginning_of_life); + "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX + content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " KWh

"; @@ -600,8 +597,8 @@ String advanced_battery_processor(const String& var) { content += "

Brick Voltage Min: " + String(BrickVoltageMin) + " V

"; content += "

Brick Temp Max Num: " + String(datalayer_extended.tesla.battery_BrickTempMaxNum) + "

"; content += "

Brick Temp Min Num: " + String(datalayer_extended.tesla.battery_BrickTempMinNum) + "

"; - content += "

Brick Temp Max: " + String(BrickModelTMax) + " C

"; - content += "

Brick Temp Min: " + String(BrickModelTMin) + " C

"; + content += "

Brick Model Temp Max: " + String(BrickModelTMax) + " C

"; + content += "

Brick Model Temp Min: " + String(BrickModelTMin) + " C

"; //0x252 594 BMS_powerAvailable content += "

Max Regen Power: " + String(BMS_maxRegenPower) + " KW

"; content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; From ad215a0a061a6decaaf27b5c0d90af06edffccca Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 22 Dec 2024 18:35:48 +1300 Subject: [PATCH 32/93] Factoring changes --- Software/src/battery/TESLA-BATTERY.cpp | 4 ++-- Software/src/devboard/webserver/advanced_battery_html.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 3d3daf7e..5ecd958e 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -48,7 +48,7 @@ static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery_volts = 0; // V static int16_t battery_amps = 0; // A -static int16_t battery_raw_amps = 0; // A +static int16_t battery_raw_amps = 0; // A static uint16_t battery_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable static uint16_t BMS_maxRegenPower = 0; //rename from battery_regenerative_limit @@ -432,7 +432,7 @@ static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery2_volts = 0; // V static int16_t battery2_amps = 0; // A -static int16_t battery2_raw_amps = 0; // A +static int16_t battery2_raw_amps = 0; // A static uint16_t battery2_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable static uint16_t BMS2_regenerative_limit = 0; diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index a20e96f6..92d42020 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -571,8 +571,7 @@ String advanced_battery_processor(const String& var) { content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //0x352 850 BMS_energyStatus - content += - "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX + content += "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; content += "

Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh

"; content += "

Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh

"; From 11752833c5e56b4b9fc2d5c3846dff5a6fdf1b7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 22 Dec 2024 11:46:53 +0200 Subject: [PATCH 33/93] Change to use regen allowed value --- Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp index 84a8463f..22035cc5 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN1-BATTERY.cpp @@ -90,7 +90,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.max_discharge_power_W = LB_Discharge_allowed_W; - datalayer.battery.status.max_charge_power_W = LB_Charging_Power_W; + datalayer.battery.status.max_charge_power_W = LB_Regen_allowed_W; int16_t temperatures[] = {cell_1_temperature_polled, cell_2_temperature_polled, cell_3_temperature_polled, cell_4_temperature_polled, cell_5_temperature_polled, cell_6_temperature_polled, From b4474e504d38d65f2fc01affcf8599b1cbab0799 Mon Sep 17 00:00:00 2001 From: No-Signal Date: Sun, 22 Dec 2024 10:46:54 +0000 Subject: [PATCH 34/93] Moving additional sensitive settings to USER_SECRETS.h --- Software/USER_SECRETS.TEMPLATE.h | 11 ++++++++--- Software/USER_SETTINGS.h | 3 --- Software/src/devboard/webserver/webserver.cpp | 1 + 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Software/USER_SECRETS.TEMPLATE.h b/Software/USER_SECRETS.TEMPLATE.h index eaf5ced1..1d1b0569 100644 --- a/Software/USER_SECRETS.TEMPLATE.h +++ b/Software/USER_SECRETS.TEMPLATE.h @@ -1,8 +1,13 @@ #define WIFI_SSID "REPLACE_WITH_YOUR_SSID" // Maximum of 63 characters #define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" // Minimum of 8 characters -#define AP_PASSWORD "123456789" // Minimum of 8 characters; set to blank if you want the access point to be open -#define HTTP_USERNAME "admin" // username to webserver authentication; -#define HTTP_PASSWORD "admin" // password to webserver authentication; +#define AP_PASSWORD "123456789" // Minimum of 8 characters; set to blank if you want the access point to be open + +#define WEBSERVER_AUTH_REQUIRED \ + false //Set this line to true to activate webserver authentication (this line must not be commented). +#define HTTP_USERNAME "admin" // username to webserver authentication; +#define HTTP_PASSWORD "admin" // password to webserver authentication; + #define MQTT_SERVER "192.168.xxx.yyy" // mqtt server address +#define MQTT_PORT 1883 // mqtt server port #define MQTT_USER NULL // mqtt username, leave blank for no authentication #define MQTT_PASSWORD NULL // mqtt password, leave blank for no authentication diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 823d46a0..73e475c9 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -82,8 +82,6 @@ #define WIFI //#define WIFICONFIG //Enable this line to set a static IP address / gateway /subnet mask for the device. see USER_SETTINGS.cpp for the settings #define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. -#define WEBSERVER_AUTH_REQUIRED \ - false //Set this line to true to activate webserver authentication (this line must not be commented). Refer to USER_SETTINGS.cpp for setting the credentials. #define WIFIAP //Disable this line to permanently disable WIFI AP mode (make sure to hardcode ssid and password of you home wifi network). When enabled WIFI AP can still be disabled by a setting in the future. #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) @@ -92,7 +90,6 @@ /* MQTT options */ // #define MQTT // Enable this line to enable MQTT -#define MQTT_PORT 1883 #define MQTT_MANUAL_TOPIC_OBJECT_NAME // Enable this to use custom MQTT topic, object ID prefix, and device name. \ // WARNING: If this is not defined, the previous default naming format \ // 'battery-emulator_esp32-XXXXXX' (based on hardware ID) will be used. \ diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 5468c704..d5f3a3b2 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -1,6 +1,7 @@ #include "webserver.h" #include #include +#include "../../../USER_SECRETS.h" #include "../../datalayer/datalayer.h" #include "../../datalayer/datalayer_extended.h" #include "../../lib/bblanchon-ArduinoJson/ArduinoJson.h" From c713d0a94ece00210bd7a090ce1025eaa5b5bbf5 Mon Sep 17 00:00:00 2001 From: mvgalen Date: Sun, 22 Dec 2024 22:48:35 +0100 Subject: [PATCH 35/93] Change Serial logging to flexible logging (#690) * Add Logging class Add Logging class which inherits from Print class, to be able to route logging to USB Serial or to memory for display in the webpage. Adds a log webpage only visible when DEBUG_VIA_WEB is defined. --- Software/Software.ino | 3 + Software/USER_SETTINGS.h | 5 + Software/src/battery/BMW-IX-BATTERY.cpp | 4 +- Software/src/battery/CHADEMO-BATTERY.cpp | 174 +++++++-------- Software/src/battery/CHADEMO-SHUNTS.cpp | 46 ++-- .../src/battery/IMIEV-CZERO-ION-BATTERY.cpp | 40 ++-- Software/src/battery/JAGUAR-IPACE-BATTERY.cpp | 30 +-- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 102 ++++----- .../src/battery/KIA-HYUNDAI-64-BATTERY.cpp | 100 ++++----- Software/src/battery/MG-5-BATTERY.cpp | 4 - .../src/battery/RENAULT-KANGOO-BATTERY.cpp | 58 ++--- .../src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp | 4 - Software/src/battery/RJXZS-BMS.cpp | 18 +- .../SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp | 112 +++++----- Software/src/battery/TESLA-BATTERY.cpp | 204 +++++++++--------- Software/src/battery/TEST-FAKE-BATTERY.cpp | 18 +- Software/src/battery/VOLVO-SPA-BATTERY.cpp | 122 +++++------ Software/src/charger/CHEVY-VOLT-CHARGER.cpp | 16 +- Software/src/communication/can/comm_can.cpp | 72 ++++--- Software/src/devboard/mqtt/mqtt.cpp | 56 ++--- Software/src/devboard/utils/events.cpp | 32 +-- .../devboard/utils/events_test_on_target.cpp | 66 +++--- Software/src/devboard/utils/logging.cpp | 86 ++++++++ Software/src/devboard/utils/logging.h | 16 ++ .../devboard/webserver/can_logging_html.cpp | 10 +- .../devboard/webserver/debug_logging_html.cpp | 36 ++++ .../devboard/webserver/debug_logging_html.h | 16 ++ .../src/devboard/webserver/events_html.cpp | 10 +- Software/src/devboard/webserver/webserver.cpp | 110 +++++++--- Software/src/devboard/wifi/wifi.cpp | 71 +++--- Software/src/include.h | 1 + Software/src/inverter/BYD-CAN.cpp | 8 +- Software/src/inverter/FOXESS-CAN.cpp | 32 +-- Software/src/inverter/KOSTAL-RS485.cpp | 18 +- .../SERIAL-LINK-TRANSMITTER-INVERTER.cpp | 102 ++++----- Software/src/inverter/SOLAX-CAN.cpp | 16 +- 36 files changed, 1020 insertions(+), 798 deletions(-) create mode 100644 Software/src/devboard/utils/logging.cpp create mode 100644 Software/src/devboard/utils/logging.h create mode 100644 Software/src/devboard/webserver/debug_logging_html.cpp create mode 100644 Software/src/devboard/webserver/debug_logging_html.h diff --git a/Software/Software.ino b/Software/Software.ino index efcb4051..60cc30d2 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -20,6 +20,7 @@ #include "src/datalayer/datalayer.h" #include "src/devboard/utils/events.h" #include "src/devboard/utils/led_handler.h" +#include "src/devboard/utils/logging.h" #include "src/devboard/utils/value_mapping.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h" @@ -84,6 +85,8 @@ MyTimer check_pause_2s(INTERVAL_2_S); TaskHandle_t main_loop_task; TaskHandle_t connectivity_loop_task; +Logging logging; + // Initialization void setup() { init_serial(); diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index d31582dd..2cefdb7a 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -66,6 +66,11 @@ /* Other options */ //#define DEBUG_VIA_USB //Enable this line to have the USB port output serial diagnostic data while program runs (WARNING, raises CPU load, do not use for production) +//#define DEBUG_VIA_WEB //Enable this line to log diagnostic data while program runs, which can be viewed via webpage (WARNING, slightly raises CPU load, do not use for production) +#if defined(DEBUG_VIA_USB) || defined(DEBUG_VIA_WEB) +#define DEBUG_LOG +#endif + //#define DEBUG_CAN_DATA //Enable this line to print incoming/outgoing CAN & CAN-FD messages to USB serial (WARNING, raises CPU load, do not use for production) //#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting //#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery) diff --git a/Software/src/battery/BMW-IX-BATTERY.cpp b/Software/src/battery/BMW-IX-BATTERY.cpp index bcd22983..ebecb6da 100644 --- a/Software/src/battery/BMW-IX-BATTERY.cpp +++ b/Software/src/battery/BMW-IX-BATTERY.cpp @@ -670,8 +670,8 @@ void receive_can_battery(CAN_frame rx_frame) { if ((rx_frame.data.u8[6] << 8 | rx_frame.data.u8[7]) == 10000 || (rx_frame.data.u8[8] << 8 | rx_frame.data.u8[9]) == 10000) { //Qualifier Invalid Mode - Request Reboot -#ifdef DEBUG_VIA_USB - Serial.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset"); +#ifdef DEBUG_LOG + logging.println("Cell MinMax Qualifier Invalid - Requesting BMS Reset"); #endif //set_event(EVENT_BATTERY_VALUE_UNAVAILABLE, (millis())); //Eventually need new Info level event type transmit_can(&BMWiX_6F4_REQUEST_HARD_RESET, can_config.battery); diff --git a/Software/src/battery/CHADEMO-BATTERY.cpp b/Software/src/battery/CHADEMO-BATTERY.cpp index 14720065..a8faddfc 100644 --- a/Software/src/battery/CHADEMO-BATTERY.cpp +++ b/Software/src/battery/CHADEMO-BATTERY.cpp @@ -197,13 +197,13 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) { x102_chg_session.ChargingCurrentRequest = newChargingCurrentRequest; x102_chg_session.TargetBatteryVoltage = newTargetBatteryVoltage; -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG //Note on p131 uint8_t chargingrate = 0; if (x100_chg_lim.ConstantOfChargingRateIndication > 0) { chargingrate = x102_chg_session.StateOfCharge / x100_chg_lim.ConstantOfChargingRateIndication * 100; - Serial.print("Charge Rate (kW): "); - Serial.println(chargingrate); + logging.print("Charge Rate (kW): "); + logging.println(chargingrate); } #endif @@ -217,40 +217,40 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) { */ if ((CHADEMO_Status == CHADEMO_INIT && vehicle_permission) || (x102_chg_session.s.status.StatusVehicleChargingEnabled && !vehicle_permission)) { -#ifdef DEBUG_VIA_USB - Serial.println("Inconsistent charge/discharge state."); +#ifdef DEBUG_LOG + logging.println("Inconsistent charge/discharge state."); #endif CHADEMO_Status = CHADEMO_FAULT; return; } if (x102_chg_session.f.fault.FaultBatteryOverVoltage) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle indicates fault, battery over voltage."); +#ifdef DEBUG_LOG + logging.println("Vehicle indicates fault, battery over voltage."); #endif CHADEMO_Status = CHADEMO_STOP; return; } if (x102_chg_session.f.fault.FaultBatteryUnderVoltage) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle indicates fault, battery under voltage."); +#ifdef DEBUG_LOG + logging.println("Vehicle indicates fault, battery under voltage."); #endif CHADEMO_Status = CHADEMO_STOP; return; } if (x102_chg_session.f.fault.FaultBatteryCurrentDeviation) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?"); +#ifdef DEBUG_LOG + logging.println("Vehicle indicates fault, battery current deviation. Possible EVSE issue?"); #endif CHADEMO_Status = CHADEMO_STOP; return; } if (x102_chg_session.f.fault.FaultBatteryVoltageDeviation) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?"); +#ifdef DEBUG_LOG + logging.println("Vehicle indicates fault, battery voltage deviation. Possible EVSE issue?"); #endif CHADEMO_Status = CHADEMO_STOP; return; @@ -264,8 +264,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) { //FIXME condition nesting or more stanzas needed here for clear determination of cessation reason if (CHADEMO_Status == CHADEMO_POWERFLOW && EVSE_mode == CHADEMO_CHARGE && !vehicle_permission) { -#ifdef DEBUG_VIA_USB - Serial.println("State of charge ceiling reached or charging interrupted, stop charging"); +#ifdef DEBUG_LOG + logging.println("State of charge ceiling reached or charging interrupted, stop charging"); #endif CHADEMO_Status = CHADEMO_STOP; return; @@ -273,8 +273,8 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) { if (vehicle_permission && CHADEMO_Status == CHADEMO_NEGOTIATE) { CHADEMO_Status = CHADEMO_EV_ALLOWED; -#ifdef DEBUG_VIA_USB - Serial.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()"); +#ifdef DEBUG_LOG + logging.println("STATE shift to CHADEMO_EV_ALLOWED in process_vehicle_charging_session()"); #endif return; } @@ -284,22 +284,22 @@ inline void process_vehicle_charging_session(CAN_frame rx_frame) { // consider relocating if (vehicle_permission && CHADEMO_Status == CHADEMO_EVSE_PREPARE && priorTargetBatteryVoltage == 0 && newTargetBatteryVoltage > 0 && x102_chg_session.s.status.StatusVehicleChargingEnabled) { -#ifdef DEBUG_VIA_USB - Serial.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()"); +#ifdef DEBUG_LOG + logging.println("STATE SHIFT to EVSE_START reached in process_vehicle_charging_session()"); #endif CHADEMO_Status = CHADEMO_EVSE_START; return; } if (vehicle_permission && evse_permission && CHADEMO_Status == CHADEMO_POWERFLOW) { -#ifdef DEBUG_VIA_USB - Serial.println("updating vehicle request in process_vehicle_charging_session()"); +#ifdef DEBUG_LOG + logging.println("updating vehicle request in process_vehicle_charging_session()"); #endif return; } -#ifdef DEBUG_VIA_USB - Serial.println("UNHANDLED STATE IN process_vehicle_charging_session()"); +#ifdef DEBUG_LOG + logging.println("UNHANDLED STATE IN process_vehicle_charging_session()"); #endif return; } @@ -312,20 +312,20 @@ inline void process_vehicle_charging_limits(CAN_frame rx_frame) { x200_discharge_limits.MinimumBatteryDischargeLevel = rx_frame.data.u8[6]; x200_discharge_limits.MaxRemainingCapacityForCharging = rx_frame.data.u8[7]; -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG /* unsigned long currentMillis = millis(); if (currentMillis - previousMillis5000 >= INTERVAL_5_S) { previousMillis5000 = currentMillis; - Serial.println("x200 Max remaining capacity for charging/discharging:"); + logging.println("x200 Max remaining capacity for charging/discharging:"); // initially this is set to 0, which is represented as 0xFF - Serial.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging); + logging.println(0xFF - x200_discharge_limits.MaxRemainingCapacityForCharging); } */ #endif if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage && CHADEMO_Status > CHADEMO_NEGOTIATE) { -#ifdef DEBUG_VIA_USB - Serial.println("x200 minimum discharge voltage met or exceeded, stopping."); +#ifdef DEBUG_LOG + logging.println("x200 minimum discharge voltage met or exceeded, stopping."); #endif CHADEMO_Status = CHADEMO_STOP; } @@ -341,13 +341,13 @@ inline void process_vehicle_discharge_estimate(CAN_frame rx_frame) { x201_discharge_estimate.ApproxDischargeCompletionTime = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[1]); x201_discharge_estimate.AvailableVehicleEnergy = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[3]); -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG if (currentMillis - previousMillis5000 >= INTERVAL_5_S) { previousMillis5000 = currentMillis; - Serial.print("x201 availabile vehicle energy, completion time: "); - Serial.println(x201_discharge_estimate.AvailableVehicleEnergy); - Serial.print("x201 approx vehicle completion time: "); - Serial.println(x201_discharge_estimate.ApproxDischargeCompletionTime); + logging.print("x201 availabile vehicle energy, completion time: "); + logging.println(x201_discharge_estimate.AvailableVehicleEnergy); + logging.print("x201 approx vehicle completion time: "); + logging.println(x201_discharge_estimate.ApproxDischargeCompletionTime); } #endif } @@ -369,17 +369,17 @@ inline void process_vehicle_vendor_ID(CAN_frame rx_frame) { void receive_can_battery(CAN_frame rx_frame) { #ifdef CH_CAN_DEBUG - Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D - Serial.print(" "); - Serial.print(rx_frame.ID, HEX); - Serial.print(" "); - Serial.print(rx_frame.DLC); - Serial.print(" "); + logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D + logging.print(" "); + logging.print(rx_frame.ID, HEX); + logging.print(" "); + logging.print(rx_frame.DLC); + logging.print(" "); for (int i = 0; i < rx_frame.DLC; ++i) { - Serial.print(rx_frame.data.u8[i], HEX); - Serial.print(" "); + logging.print(rx_frame.data.u8[i], HEX); + logging.print(" "); } - Serial.println(""); + logging.println(""); #endif // CHADEMO coexists with a CAN-based shunt. Only process CHADEMO-specific IDs @@ -713,9 +713,9 @@ void send_can_battery() { // TODO need an update_evse_dynamic_control(..) function above before we send 118 // 110.0.0 if (x102_chg_session.ControlProtocolNumberEV >= 0x03) { //Only send the following on Chademo 2.0 vehicles? -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG //FIXME REMOVE - Serial.println("REMOVE: proto 2.0"); + logging.println("REMOVE: proto 2.0"); #endif transmit_can(&CHADEMO_118, can_config.battery); } @@ -753,15 +753,15 @@ void handle_chademo_sequence() { /* ------------------- State override conditions checks ------------------- */ /* ------------------------------------------------------------------------------ */ if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && x102_chg_session.s.status.StatusVehicleShifterPosition) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle is not parked, abort."); +#ifdef DEBUG_LOG + logging.println("Vehicle is not parked, abort."); #endif CHADEMO_Status = CHADEMO_STOP; } if (CHADEMO_Status >= CHADEMO_EV_ALLOWED && !vehicle_permission) { -#ifdef DEBUG_VIA_USB - Serial.println("Vehicle charge/discharge permission ended, stop."); +#ifdef DEBUG_LOG + logging.println("Vehicle charge/discharge permission ended, stop."); #endif CHADEMO_Status = CHADEMO_STOP; } @@ -775,24 +775,24 @@ void handle_chademo_sequence() { plug_inserted = digitalRead(CHADEMO_PIN_7); if (!plug_inserted) { -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug -// Serial.println("CHADEMO plug is not inserted."); +// logging.println("CHADEMO plug is not inserted."); #endif return; } CHADEMO_Status = CHADEMO_CONNECTED; -#ifdef DEBUG_VIA_USB - Serial.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization."); +#ifdef DEBUG_LOG + logging.println("CHADEMO plug is inserted. Provide EVSE power to vehicle to trigger initialization."); #endif break; case CHADEMO_CONNECTED: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - //Serial.println("CHADEMO_CONNECTED State"); + //logging.println("CHADEMO_CONNECTED State"); #endif /* plug_inserted is .. essentially a volatile of sorts, so verify */ if (plug_inserted) { @@ -810,8 +810,8 @@ void handle_chademo_sequence() { * with timers to have higher confidence of certain conditions hitting * a steady state */ -#ifdef DEBUG_VIA_USB - Serial.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization."); +#ifdef DEBUG_LOG + logging.println("CHADEMO plug is not inserted, cannot connect d2 relay to begin initialization."); #endif CHADEMO_Status = CHADEMO_IDLE; } @@ -821,8 +821,8 @@ void handle_chademo_sequence() { * Used for triggers/error handling elsewhere; * State change to CHADEMO_NEGOTIATE occurs in receive_can_battery(..) */ -#ifdef DEBUG_VIA_USB -// Serial.println("Awaiting initial vehicle CAN to trigger negotiation"); +#ifdef DEBUG_LOG +// logging.println("Awaiting initial vehicle CAN to trigger negotiation"); #endif evse_init(); break; @@ -830,16 +830,16 @@ void handle_chademo_sequence() { /* Vehicle and EVSE dance */ //TODO if pin 4 / j goes high, -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug -// Serial.println("CHADEMO_NEGOTIATE State"); +// logging.println("CHADEMO_NEGOTIATE State"); #endif x109_evse_state.s.status.ChgDischStopControl = 1; break; case CHADEMO_EV_ALLOWED: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_EV_ALLOWED State"); + logging.println("CHADEMO_EV_ALLOWED State"); #endif // If we are in this state, vehicle_permission was already set to true...but re-verify // that pin 4 (j) reads high @@ -855,9 +855,9 @@ void handle_chademo_sequence() { } break; case CHADEMO_EVSE_PREPARE: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_EVSE_PREPARE State"); + logging.println("CHADEMO_EVSE_PREPARE State"); #endif /* TODO voltage check of output < 20v * insulation test hypothetically happens here before triggering PIN 10 high @@ -878,7 +878,7 @@ void handle_chademo_sequence() { digitalWrite(CHADEMO_PIN_10, HIGH); evse_permission = true; } else { - Serial.println("Insulation check measures > 20v "); + logging.println("Insulation check measures > 20v "); } // likely unnecessary but just to be sure. consider removal @@ -891,9 +891,9 @@ void handle_chademo_sequence() { //state changes to CHADEMO_EVSE_START only upon receipt of charging session request break; case CHADEMO_EVSE_START: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_EVSE_START State"); + logging.println("CHADEMO_EVSE_START State"); #endif datalayer.system.status.battery_allows_contactor_closing = true; x109_evse_state.s.status.ChgDischStopControl = 1; @@ -901,8 +901,8 @@ void handle_chademo_sequence() { CHADEMO_Status = CHADEMO_EVSE_CONTACTORS_ENABLED; -#ifdef DEBUG_VIA_USB - Serial.println("Initiating contactors"); +#ifdef DEBUG_LOG + logging.println("Initiating contactors"); #endif /* break rather than fall through because contactors are not instantaneous; @@ -911,17 +911,17 @@ void handle_chademo_sequence() { break; case CHADEMO_EVSE_CONTACTORS_ENABLED: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_EVSE_CONTACTORS State"); + logging.println("CHADEMO_EVSE_CONTACTORS State"); #endif /* check whether contactors ready, because externally dependent upon inverter allow during discharge */ if (contactors_ready) { -#ifdef DEBUG_VIA_USB - Serial.println("Contactors ready"); - Serial.print("Voltage: "); - Serial.println(get_measured_voltage()); +#ifdef DEBUG_LOG + logging.println("Contactors ready"); + logging.print("Voltage: "); + logging.println(get_measured_voltage()); #endif /* transition to POWERFLOW state if discharge compatible on both sides */ if (x109_evse_state.discharge_compatible && x102_chg_session.s.status.StatusVehicleDischargeCompatible && @@ -941,9 +941,9 @@ void handle_chademo_sequence() { /* break or fall through ? TODO */ break; case CHADEMO_POWERFLOW: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_POWERFLOW State"); + logging.println("CHADEMO_POWERFLOW State"); #endif /* POWERFLOW for charging, discharging, and bidirectional */ /* Interpretation */ @@ -961,8 +961,8 @@ void handle_chademo_sequence() { } if (get_measured_voltage() <= x200_discharge_limits.MinimumDischargeVoltage) { -#ifdef DEBUG_VIA_USB - Serial.println("x200 minimum discharge voltage met or exceeded, stopping."); +#ifdef DEBUG_LOG + logging.println("x200 minimum discharge voltage met or exceeded, stopping."); #endif CHADEMO_Status = CHADEMO_STOP; } @@ -972,9 +972,9 @@ void handle_chademo_sequence() { x109_evse_state.s.status.EVSE_status = 1; break; case CHADEMO_STOP: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_STOP State"); + logging.println("CHADEMO_STOP State"); #endif /* back to CHADEMO_IDLE after teardown */ x109_evse_state.s.status.ChgDischStopControl = 1; @@ -1000,16 +1000,16 @@ void handle_chademo_sequence() { break; case CHADEMO_FAULT: -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG // Commented unless needed for debug - Serial.println("CHADEMO_FAULT State"); + logging.println("CHADEMO_FAULT State"); #endif /* Once faulted, never departs CHADEMO_FAULT state unless device is power cycled as a safety measure */ x109_evse_state.s.status.EVSE_error = 1; x109_evse_state.s.status.ChgDischError = 1; x109_evse_state.s.status.ChgDischStopControl = 1; -#ifdef DEBUG_VIA_USB - Serial.println("CHADEMO fault encountered, tearing down to make safe"); +#ifdef DEBUG_LOG + logging.println("CHADEMO fault encountered, tearing down to make safe"); #endif digitalWrite(CHADEMO_PIN_10, LOW); digitalWrite(CHADEMO_PIN_2, LOW); @@ -1020,8 +1020,8 @@ void handle_chademo_sequence() { break; default: -#ifdef DEBUG_VIA_USB - Serial.println("UNHANDLED CHADEMO_STATE, setting FAULT"); +#ifdef DEBUG_LOG + logging.println("UNHANDLED CHADEMO_STATE, setting FAULT"); #endif CHADEMO_Status = CHADEMO_FAULT; break; diff --git a/Software/src/battery/CHADEMO-SHUNTS.cpp b/Software/src/battery/CHADEMO-SHUNTS.cpp index 6ca55ca7..92c0da68 100644 --- a/Software/src/battery/CHADEMO-SHUNTS.cpp +++ b/Software/src/battery/CHADEMO-SHUNTS.cpp @@ -91,17 +91,17 @@ void ISA_handleFrame(CAN_frame* frame) { case 0x510: case 0x511: - Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D - Serial.print(" "); - Serial.print(frame->ID, HEX); - Serial.print(" "); - Serial.print(frame->DLC); - Serial.print(" "); + logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D + logging.print(" "); + logging.print(frame->ID, HEX); + logging.print(" "); + logging.print(frame->DLC); + logging.print(" "); for (int i = 0; i < frame->DLC; ++i) { - Serial.print(frame->data.u8[i], HEX); - Serial.print(" "); + logging.print(frame->data.u8[i], HEX); + logging.print(" "); } - Serial.println(""); + logging.println(""); break; case 0x521: @@ -245,8 +245,8 @@ void ISA_initialize() { ISA_STOP(); delay(500); for (int i = 0; i < 8; i++) { - Serial.print("ISA Initialization "); - Serial.println(i); + logging.print("ISA Initialization "); + logging.println(i); outframe.data.u8[0] = (0x20 + i); outframe.data.u8[1] = 0x02; @@ -271,7 +271,7 @@ void ISA_initialize() { } void ISA_STOP() { - Serial.println("ISA STOP"); + logging.println("ISA STOP"); outframe.data.u8[0] = 0x34; outframe.data.u8[1] = 0x00; @@ -286,7 +286,7 @@ void ISA_STOP() { } void ISA_sendSTORE() { - Serial.println("ISA send STORE"); + logging.println("ISA send STORE"); outframe.data.u8[0] = 0x32; outframe.data.u8[1] = 0x00; @@ -301,7 +301,7 @@ void ISA_sendSTORE() { } void ISA_START() { - Serial.println("ISA START"); + logging.println("ISA START"); outframe.data.u8[0] = 0x34; outframe.data.u8[1] = 0x01; @@ -317,7 +317,7 @@ void ISA_START() { void ISA_RESTART() { //Has the effect of zeroing AH and KWH - Serial.println("ISA RESTART"); + logging.println("ISA RESTART"); outframe.data.u8[0] = 0x3F; outframe.data.u8[1] = 0x00; @@ -336,7 +336,7 @@ void ISA_deFAULT() { ISA_STOP(); delay(500); - Serial.println("ISA RESTART to default"); + logging.println("ISA RESTART to default"); outframe.data.u8[0] = 0x3D; outframe.data.u8[1] = 0x00; @@ -358,7 +358,7 @@ void ISA_initCurrent() { ISA_STOP(); delay(500); - Serial.println("ISA Initialization Current"); + logging.println("ISA Initialization Current"); outframe.data.u8[0] = 0x21; outframe.data.u8[1] = 0x02; @@ -382,8 +382,8 @@ void ISA_initCurrent() { } void ISA_getCONFIG(uint8_t i) { - Serial.print("ISA Get Config "); - Serial.println(i); + logging.print("ISA Get Config "); + logging.println(i); outframe.data.u8[0] = (0x60 + i); outframe.data.u8[1] = 0x00; @@ -398,8 +398,8 @@ void ISA_getCONFIG(uint8_t i) { } void ISA_getCAN_ID(uint8_t i) { - Serial.print("ISA Get CAN ID "); - Serial.println(i); + logging.print("ISA Get CAN ID "); + logging.println(i); outframe.data.u8[0] = (0x50 + i); if (i == 8) @@ -418,8 +418,8 @@ void ISA_getCAN_ID(uint8_t i) { } void ISA_getINFO(uint8_t i) { - Serial.print("ISA Get INFO "); - Serial.println(i, HEX); + logging.print("ISA Get INFO "); + logging.println(i, HEX); outframe.data.u8[0] = (0x70 + i); outframe.data.u8[1] = 0x00; diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp index 05e6e7c6..64a75e6c 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp @@ -103,29 +103,29 @@ void update_values_battery() { //This function maps all the values fetched via } if (!BMU_Detected) { -#ifdef DEBUG_VIA_USB - Serial.println("BMU not detected, check wiring!"); +#ifdef DEBUG_LOG + logging.println("BMU not detected, check wiring!"); #endif } -#ifdef DEBUG_VIA_USB - Serial.println("Battery Values"); - Serial.print("BMU SOC: "); - Serial.print(BMU_SOC); - Serial.print(" BMU Current: "); - Serial.print(BMU_Current); - Serial.print(" BMU Battery Voltage: "); - Serial.print(BMU_PackVoltage); - Serial.print(" BMU_Power: "); - Serial.print(BMU_Power); - Serial.print(" Cell max voltage: "); - Serial.print(max_volt_cel); - Serial.print(" Cell min voltage: "); - Serial.print(min_volt_cel); - Serial.print(" Cell max temp: "); - Serial.print(max_temp_cel); - Serial.print(" Cell min temp: "); - Serial.println(min_temp_cel); +#ifdef DEBUG_LOG + logging.println("Battery Values"); + logging.print("BMU SOC: "); + logging.print(BMU_SOC); + logging.print(" BMU Current: "); + logging.print(BMU_Current); + logging.print(" BMU Battery Voltage: "); + logging.print(BMU_PackVoltage); + logging.print(" BMU_Power: "); + logging.print(BMU_Power); + logging.print(" Cell max voltage: "); + logging.print(max_volt_cel); + logging.print(" Cell min voltage: "); + logging.print(min_volt_cel); + logging.print(" Cell max temp: "); + logging.print(max_temp_cel); + logging.print(" Cell min temp: "); + logging.println(min_temp_cel); #endif } diff --git a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp index eb13017c..1292f0cc 100644 --- a/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp +++ b/Software/src/battery/JAGUAR-IPACE-BATTERY.cpp @@ -57,9 +57,9 @@ CAN_frame ipace_keep_alive = {.FD = false, .data = {0x9E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};*/ void print_units(char* header, int value, char* units) { - Serial.print(header); - Serial.print(value); - Serial.print(units); + logging.print(header); + logging.print(value); + logging.print(units); } void update_values_battery() { @@ -104,8 +104,8 @@ void update_values_battery() { } /*Finally print out values to serial if configured to do so*/ -#ifdef DEBUG_VIA_USB - Serial.println("Values going to inverter"); +#ifdef DEBUG_LOG + logging.println("Values going to inverter"); print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% "); print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% "); print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V "); @@ -115,7 +115,7 @@ void update_values_battery() { print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C "); print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV "); print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV "); - Serial.println(""); + logging.println(""); #endif } @@ -229,17 +229,17 @@ void receive_can_battery(CAN_frame rx_frame) { } // All CAN messages recieved will be logged via serial - Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D - Serial.print(" "); - Serial.print(rx_frame.ID, HEX); - Serial.print(" "); - Serial.print(rx_frame.DLC); - Serial.print(" "); + logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D + logging.print(" "); + logging.print(rx_frame.ID, HEX); + logging.print(" "); + logging.print(rx_frame.DLC); + logging.print(" "); for (int i = 0; i < rx_frame.DLC; ++i) { - Serial.print(rx_frame.data.u8[i], HEX); - Serial.print(" "); + logging.print(rx_frame.data.u8[i], HEX); + logging.print(" "); } - Serial.println(""); + logging.println(""); } void send_can_battery() { diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index a0715a26..476459aa 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -690,63 +690,63 @@ void update_values_battery() { //This function maps all the values fetched via /* Safeties verified. Perform USB serial printout if configured to do so */ -#ifdef DEBUG_VIA_USB - Serial.println(); //sepatator - Serial.println("Values from battery: "); - Serial.print("SOC BMS: "); - Serial.print((uint16_t)SOC_BMS / 10.0, 1); - Serial.print("% | SOC Display: "); - Serial.print((uint16_t)SOC_Display / 10.0, 1); - Serial.print("% | SOH "); - Serial.print((uint16_t)batterySOH / 10.0, 1); - Serial.println("%"); - Serial.print((int16_t)batteryAmps / 10.0, 1); - Serial.print(" Amps | "); - Serial.print((uint16_t)batteryVoltage / 10.0, 1); - Serial.print(" Volts | "); - Serial.print((int16_t)datalayer.battery.status.active_power_W); - Serial.println(" Watts"); - Serial.print("Allowed Charge "); - Serial.print((uint16_t)allowedChargePower * 10); - Serial.print(" W | Allowed Discharge "); - Serial.print((uint16_t)allowedDischargePower * 10); - Serial.println(" W"); - Serial.print("MaxCellVolt "); - Serial.print(CellVoltMax_mV); - Serial.print(" mV No "); - Serial.print(CellVmaxNo); - Serial.print(" | MinCellVolt "); - Serial.print(CellVoltMin_mV); - Serial.print(" mV No "); - Serial.println(CellVminNo); - Serial.print("TempHi "); - Serial.print((int16_t)temperatureMax); - Serial.print("°C TempLo "); - Serial.print((int16_t)temperatureMin); - Serial.print("°C WaterInlet "); - Serial.print((int8_t)temperature_water_inlet); - Serial.print("°C PowerRelay "); - Serial.print((int8_t)powerRelayTemperature * 2); - Serial.println("°C"); - Serial.print("Aux12volt: "); - Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1); - Serial.println("V | "); - Serial.print("BmsManagementMode "); - Serial.print((uint8_t)batteryManagementMode, BIN); +#ifdef DEBUG_LOG + logging.println(); //sepatator + logging.println("Values from battery: "); + logging.print("SOC BMS: "); + logging.print((uint16_t)SOC_BMS / 10.0, 1); + logging.print("% | SOC Display: "); + logging.print((uint16_t)SOC_Display / 10.0, 1); + logging.print("% | SOH "); + logging.print((uint16_t)batterySOH / 10.0, 1); + logging.println("%"); + logging.print((int16_t)batteryAmps / 10.0, 1); + logging.print(" Amps | "); + logging.print((uint16_t)batteryVoltage / 10.0, 1); + logging.print(" Volts | "); + logging.print((int16_t)datalayer.battery.status.active_power_W); + logging.println(" Watts"); + logging.print("Allowed Charge "); + logging.print((uint16_t)allowedChargePower * 10); + logging.print(" W | Allowed Discharge "); + logging.print((uint16_t)allowedDischargePower * 10); + logging.println(" W"); + logging.print("MaxCellVolt "); + logging.print(CellVoltMax_mV); + logging.print(" mV No "); + logging.print(CellVmaxNo); + logging.print(" | MinCellVolt "); + logging.print(CellVoltMin_mV); + logging.print(" mV No "); + logging.println(CellVminNo); + logging.print("TempHi "); + logging.print((int16_t)temperatureMax); + logging.print("°C TempLo "); + logging.print((int16_t)temperatureMin); + logging.print("°C WaterInlet "); + logging.print((int8_t)temperature_water_inlet); + logging.print("°C PowerRelay "); + logging.print((int8_t)powerRelayTemperature * 2); + logging.println("°C"); + logging.print("Aux12volt: "); + logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1); + logging.println("V | "); + logging.print("BmsManagementMode "); + logging.print((uint8_t)batteryManagementMode, BIN); if (bitRead((uint8_t)BMS_ign, 2) == 1) { - Serial.print(" | BmsIgnition ON"); + logging.print(" | BmsIgnition ON"); } else { - Serial.print(" | BmsIgnition OFF"); + logging.print(" | BmsIgnition OFF"); } if (bitRead((uint8_t)batteryRelay, 0) == 1) { - Serial.print(" | PowerRelay ON"); + logging.print(" | PowerRelay ON"); } else { - Serial.print(" | PowerRelay OFF"); + logging.print(" | PowerRelay OFF"); } - Serial.print(" | Inverter "); - Serial.print(inverterVoltage); - Serial.println(" Volts"); + logging.print(" | Inverter "); + logging.print(inverterVoltage); + logging.println(" Volts"); #endif } @@ -808,7 +808,7 @@ void receive_can_battery(CAN_frame rx_frame) { // print_canfd_frame(frame); switch (rx_frame.data.u8[0]) { case 0x10: //"PID Header" - // Serial.println ("Send ack"); + // logging.println ("Send ack"); poll_data_pid = rx_frame.data.u8[4]; // if (rx_frame.data.u8[4] == poll_data_pid) { transmit_can(&EGMP_7E4_ack, can_config.battery); //Send ack to BMS if the same frame is sent as polled diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp index 3a6663c6..ea55a988 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp @@ -142,63 +142,63 @@ void update_values_battery() { //This function maps all the values fetched via /* Safeties verified. Perform USB serial printout if configured to do so */ -#ifdef DEBUG_VIA_USB - Serial.println(); //sepatator - Serial.println("Values from battery: "); - Serial.print("SOC BMS: "); - Serial.print((uint16_t)SOC_BMS / 10.0, 1); - Serial.print("% | SOC Display: "); - Serial.print((uint16_t)SOC_Display / 10.0, 1); - Serial.print("% | SOH "); - Serial.print((uint16_t)batterySOH / 10.0, 1); - Serial.println("%"); - Serial.print((int16_t)batteryAmps / 10.0, 1); - Serial.print(" Amps | "); - Serial.print((uint16_t)batteryVoltage / 10.0, 1); - Serial.print(" Volts | "); - Serial.print((int16_t)datalayer.battery.status.active_power_W); - Serial.println(" Watts"); - Serial.print("Allowed Charge "); - Serial.print((uint16_t)allowedChargePower * 10); - Serial.print(" W | Allowed Discharge "); - Serial.print((uint16_t)allowedDischargePower * 10); - Serial.println(" W"); - Serial.print("MaxCellVolt "); - Serial.print(CellVoltMax_mV); - Serial.print(" mV No "); - Serial.print(CellVmaxNo); - Serial.print(" | MinCellVolt "); - Serial.print(CellVoltMin_mV); - Serial.print(" mV No "); - Serial.println(CellVminNo); - Serial.print("TempHi "); - Serial.print((int16_t)temperatureMax); - Serial.print("°C TempLo "); - Serial.print((int16_t)temperatureMin); - Serial.print("°C WaterInlet "); - Serial.print((int8_t)temperature_water_inlet); - Serial.print("°C PowerRelay "); - Serial.print((int8_t)powerRelayTemperature * 2); - Serial.println("°C"); - Serial.print("Aux12volt: "); - Serial.print((int16_t)leadAcidBatteryVoltage / 10.0, 1); - Serial.println("V | "); - Serial.print("BmsManagementMode "); - Serial.print((uint8_t)batteryManagementMode, BIN); +#ifdef DEBUG_LOG + logging.println(); //sepatator + logging.println("Values from battery: "); + logging.print("SOC BMS: "); + logging.print((uint16_t)SOC_BMS / 10.0, 1); + logging.print("% | SOC Display: "); + logging.print((uint16_t)SOC_Display / 10.0, 1); + logging.print("% | SOH "); + logging.print((uint16_t)batterySOH / 10.0, 1); + logging.println("%"); + logging.print((int16_t)batteryAmps / 10.0, 1); + logging.print(" Amps | "); + logging.print((uint16_t)batteryVoltage / 10.0, 1); + logging.print(" Volts | "); + logging.print((int16_t)datalayer.battery.status.active_power_W); + logging.println(" Watts"); + logging.print("Allowed Charge "); + logging.print((uint16_t)allowedChargePower * 10); + logging.print(" W | Allowed Discharge "); + logging.print((uint16_t)allowedDischargePower * 10); + logging.println(" W"); + logging.print("MaxCellVolt "); + logging.print(CellVoltMax_mV); + logging.print(" mV No "); + logging.print(CellVmaxNo); + logging.print(" | MinCellVolt "); + logging.print(CellVoltMin_mV); + logging.print(" mV No "); + logging.println(CellVminNo); + logging.print("TempHi "); + logging.print((int16_t)temperatureMax); + logging.print("°C TempLo "); + logging.print((int16_t)temperatureMin); + logging.print("°C WaterInlet "); + logging.print((int8_t)temperature_water_inlet); + logging.print("°C PowerRelay "); + logging.print((int8_t)powerRelayTemperature * 2); + logging.println("°C"); + logging.print("Aux12volt: "); + logging.print((int16_t)leadAcidBatteryVoltage / 10.0, 1); + logging.println("V | "); + logging.print("BmsManagementMode "); + logging.print((uint8_t)batteryManagementMode, BIN); if (bitRead((uint8_t)BMS_ign, 2) == 1) { - Serial.print(" | BmsIgnition ON"); + logging.print(" | BmsIgnition ON"); } else { - Serial.print(" | BmsIgnition OFF"); + logging.print(" | BmsIgnition OFF"); } if (bitRead((uint8_t)batteryRelay, 0) == 1) { - Serial.print(" | PowerRelay ON"); + logging.print(" | PowerRelay ON"); } else { - Serial.print(" | PowerRelay OFF"); + logging.print(" | PowerRelay OFF"); } - Serial.print(" | Inverter "); - Serial.print(inverterVoltage); - Serial.println(" Volts"); + logging.print(" | Inverter "); + logging.print(inverterVoltage); + logging.println(" Volts"); #endif } diff --git a/Software/src/battery/MG-5-BATTERY.cpp b/Software/src/battery/MG-5-BATTERY.cpp index 35c8ee96..006634ab 100644 --- a/Software/src/battery/MG-5-BATTERY.cpp +++ b/Software/src/battery/MG-5-BATTERY.cpp @@ -42,10 +42,6 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_min_dC; datalayer.battery.status.temperature_max_dC; - -#ifdef DEBUG_VIA_USB - -#endif } void receive_can_battery(CAN_frame rx_frame) { diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp index 096cb629..6b3e35c3 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp @@ -103,36 +103,36 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_max_voltage_mV = LB_Cell_Max_Voltage; -#ifdef DEBUG_VIA_USB - Serial.println("Values going to inverter:"); - Serial.print("SOH%: "); - Serial.print(datalayer.battery.status.soh_pptt); - Serial.print(", SOC% scaled: "); - Serial.print(datalayer.battery.status.reported_soc); - Serial.print(", Voltage: "); - Serial.print(datalayer.battery.status.voltage_dV); - Serial.print(", Max discharge power: "); - Serial.print(datalayer.battery.status.max_discharge_power_W); - Serial.print(", Max charge power: "); - Serial.print(datalayer.battery.status.max_charge_power_W); - Serial.print(", Max temp: "); - Serial.print(datalayer.battery.status.temperature_max_dC); - Serial.print(", Min temp: "); - Serial.print(datalayer.battery.status.temperature_min_dC); - Serial.print(", BMS Status (3=OK): "); - Serial.print(datalayer.battery.status.bms_status); +#ifdef DEBUG_LOG + logging.println("Values going to inverter:"); + logging.print("SOH%: "); + logging.print(datalayer.battery.status.soh_pptt); + logging.print(", SOC% scaled: "); + logging.print(datalayer.battery.status.reported_soc); + logging.print(", Voltage: "); + logging.print(datalayer.battery.status.voltage_dV); + logging.print(", Max discharge power: "); + logging.print(datalayer.battery.status.max_discharge_power_W); + logging.print(", Max charge power: "); + logging.print(datalayer.battery.status.max_charge_power_W); + logging.print(", Max temp: "); + logging.print(datalayer.battery.status.temperature_max_dC); + logging.print(", Min temp: "); + logging.print(datalayer.battery.status.temperature_min_dC); + logging.print(", BMS Status (3=OK): "); + logging.print(datalayer.battery.status.bms_status); - Serial.println("Battery values: "); - Serial.print("Real SOC: "); - Serial.print(LB_SOC); - Serial.print(", Current: "); - Serial.print(LB_Current); - Serial.print(", kWh remain: "); - Serial.print(LB_kWh_Remaining); - Serial.print(", max mV: "); - Serial.print(LB_Cell_Max_Voltage); - Serial.print(", min mV: "); - Serial.print(LB_Cell_Min_Voltage); + logging.println("Battery values: "); + logging.print("Real SOC: "); + logging.print(LB_SOC); + logging.print(", Current: "); + logging.print(LB_Current); + logging.print(", kWh remain: "); + logging.print(LB_kWh_Remaining); + logging.print(", max mV: "); + logging.print(LB_Cell_Max_Voltage); + logging.print(", min mV: "); + logging.print(LB_Cell_Min_Voltage); #endif } diff --git a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp index 08ac57bf..9c35d7da 100644 --- a/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-GEN2-BATTERY.cpp @@ -216,10 +216,6 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.zoePH2.battery_pack_time = battery_pack_time; datalayer_extended.zoePH2.battery_soc_min = battery_soc_min; datalayer_extended.zoePH2.battery_soc_max = battery_soc_max; - -#ifdef DEBUG_VIA_USB - -#endif } void receive_can_battery(CAN_frame rx_frame) { diff --git a/Software/src/battery/RJXZS-BMS.cpp b/Software/src/battery/RJXZS-BMS.cpp index 85b96434..c59a99f1 100644 --- a/Software/src/battery/RJXZS-BMS.cpp +++ b/Software/src/battery/RJXZS-BMS.cpp @@ -162,17 +162,17 @@ void receive_can_battery(CAN_frame rx_frame) { /* // All CAN messages recieved will be logged via serial - Serial.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D - Serial.print(" "); - Serial.print(rx_frame.ID, HEX); - Serial.print(" "); - Serial.print(rx_frame.DLC); - Serial.print(" "); + logging.print(millis()); // Example printout, time, ID, length, data: 7553 1DB 8 FF C0 B9 EA 0 0 2 5D + logging.print(" "); + logging.print(rx_frame.ID, HEX); + logging.print(" "); + logging.print(rx_frame.DLC); + logging.print(" "); for (int i = 0; i < rx_frame.DLC; ++i) { - Serial.print(rx_frame.data.u8[i], HEX); - Serial.print(" "); + logging.print(rx_frame.data.u8[i], HEX); + logging.print(" "); } - Serial.println(""); + logging.println(""); */ switch (rx_frame.ID) { case 0xF5: // This is the only message is sent from BMS diff --git a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp index 41697c33..349f4d82 100644 --- a/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp +++ b/Software/src/battery/SERIAL-LINK-RECEIVER-FROM-BATTERY.cpp @@ -94,8 +94,8 @@ void manageSerialLinkReceiver() { bool readError = dataLinkReceive.checkReadError(true); // check for error & clear error flag if (readError) { - Serial.print(currentTime); - Serial.println(" - ERROR: SerialDataLink - Read Error"); + logging.print(currentTime); + logging.println(" - ERROR: SerialDataLink - Read Error"); lasterror = true; errors++; } @@ -112,8 +112,8 @@ void manageSerialLinkReceiver() { //bms_status = ACTIVE; // just testing if (lasterror) { lasterror = false; - Serial.print(currentTime); - Serial.println(" - RECOVERY: SerialDataLink - Read GOOD"); + logging.print(currentTime); + logging.println(" - RECOVERY: SerialDataLink - Read GOOD"); } } @@ -134,34 +134,34 @@ void manageSerialLinkReceiver() { // report Lost data & Max charge / Discharge reductions if (minutesLost != last_minutesLost) { last_minutesLost = minutesLost; - Serial.print(currentTime); + logging.print(currentTime); if (batteryFault) { - Serial.print("Battery Fault (minutes) : "); + logging.print("Battery Fault (minutes) : "); } else { - Serial.print(" - Minutes without data : "); + logging.print(" - Minutes without data : "); } - Serial.print(minutesLost); - Serial.print(", max Charge = "); - Serial.print(datalayer.battery.status.max_charge_power_W); - Serial.print(", max Discharge = "); - Serial.println(datalayer.battery.status.max_discharge_power_W); + logging.print(minutesLost); + logging.print(", max Charge = "); + logging.print(datalayer.battery.status.max_charge_power_W); + logging.print(", max Discharge = "); + logging.println(datalayer.battery.status.max_discharge_power_W); } } if (currentTime - reportTime > 59999) { reportTime = currentTime; - Serial.print(currentTime); - Serial.print(" SerialDataLink-Receiver - NewData :"); - Serial.print(reads); - Serial.print(" Errors : "); - Serial.println(errors); + logging.print(currentTime); + logging.print(" SerialDataLink-Receiver - NewData :"); + logging.print(reads); + logging.print(" Errors : "); + logging.println(errors); reads = 0; errors = 0; // --- printUsefullData(); -//Serial.print("SOC = "); -//Serial.println(SOC); -#ifdef DEBUG_VIA_USB +//logging.print("SOC = "); +//logging.println(SOC); +#ifdef DEBUG_LOG update_values_serial_link(); #endif } @@ -179,43 +179,43 @@ void manageSerialLinkReceiver() { } void update_values_serial_link() { - Serial.println("Values from battery: "); - Serial.print("SOC: "); - Serial.print(datalayer.battery.status.real_soc); - Serial.print(" SOH: "); - Serial.print(datalayer.battery.status.soh_pptt); - Serial.print(" Voltage: "); - Serial.print(datalayer.battery.status.voltage_dV); - Serial.print(" Current: "); - Serial.print(datalayer.battery.status.current_dA); - Serial.print(" Capacity: "); - Serial.print(datalayer.battery.info.total_capacity_Wh); - Serial.print(" Remain cap: "); - Serial.print(datalayer.battery.status.remaining_capacity_Wh); - Serial.print(" Max discharge W: "); - Serial.print(datalayer.battery.status.max_discharge_power_W); - Serial.print(" Max charge W: "); - Serial.print(datalayer.battery.status.max_charge_power_W); - Serial.print(" BMS status: "); - Serial.print(datalayer.battery.status.bms_status); - Serial.print(" Power: "); - Serial.print(datalayer.battery.status.active_power_W); - Serial.print(" Temp min: "); - Serial.print(datalayer.battery.status.temperature_min_dC); - Serial.print(" Temp max: "); - Serial.print(datalayer.battery.status.temperature_max_dC); - Serial.print(" Cell max: "); - Serial.print(datalayer.battery.status.cell_max_voltage_mV); - Serial.print(" Cell min: "); - Serial.print(datalayer.battery.status.cell_min_voltage_mV); - Serial.print(" LFP : "); - Serial.print(datalayer.battery.info.chemistry); - Serial.print(" Battery Allows Contactor Closing: "); - Serial.print(datalayer.system.status.battery_allows_contactor_closing); - Serial.print(" Inverter Allows Contactor Closing: "); - Serial.print(datalayer.system.status.inverter_allows_contactor_closing); + logging.println("Values from battery: "); + logging.print("SOC: "); + logging.print(datalayer.battery.status.real_soc); + logging.print(" SOH: "); + logging.print(datalayer.battery.status.soh_pptt); + logging.print(" Voltage: "); + logging.print(datalayer.battery.status.voltage_dV); + logging.print(" Current: "); + logging.print(datalayer.battery.status.current_dA); + logging.print(" Capacity: "); + logging.print(datalayer.battery.info.total_capacity_Wh); + logging.print(" Remain cap: "); + logging.print(datalayer.battery.status.remaining_capacity_Wh); + logging.print(" Max discharge W: "); + logging.print(datalayer.battery.status.max_discharge_power_W); + logging.print(" Max charge W: "); + logging.print(datalayer.battery.status.max_charge_power_W); + logging.print(" BMS status: "); + logging.print(datalayer.battery.status.bms_status); + logging.print(" Power: "); + logging.print(datalayer.battery.status.active_power_W); + logging.print(" Temp min: "); + logging.print(datalayer.battery.status.temperature_min_dC); + logging.print(" Temp max: "); + logging.print(datalayer.battery.status.temperature_max_dC); + logging.print(" Cell max: "); + logging.print(datalayer.battery.status.cell_max_voltage_mV); + logging.print(" Cell min: "); + logging.print(datalayer.battery.status.cell_min_voltage_mV); + logging.print(" LFP : "); + logging.print(datalayer.battery.info.chemistry); + logging.print(" Battery Allows Contactor Closing: "); + logging.print(datalayer.system.status.battery_allows_contactor_closing); + logging.print(" Inverter Allows Contactor Closing: "); + logging.print(datalayer.system.status.inverter_allows_contactor_closing); - Serial.println(""); + logging.println(""); } void setup_battery(void) { diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index f6db10a8..cd6afd08 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -408,69 +408,69 @@ void update_values_battery() { //This function maps all the values fetched via datalayer_extended.tesla.battery_soc_min = battery_soc_min; datalayer_extended.tesla.battery_soc_ui = battery_soc_ui; -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG printFaultCodesIfActive(); - Serial.print("STATUS: Contactor: "); - Serial.print(contactorText[battery_contactor]); //Display what state the contactor is in - Serial.print(", HVIL: "); - Serial.print(hvilStatusState[battery_hvil_status]); - Serial.print(", NegativeState: "); - Serial.print(contactorState[battery_packContNegativeState]); - Serial.print(", PositiveState: "); - Serial.print(contactorState[battery_packContPositiveState]); - Serial.print(", setState: "); - Serial.print(contactorState[battery_packContactorSetState]); - Serial.print(", close allowed: "); - Serial.print(battery_packCtrsClosingAllowed); - Serial.print(", Pyrotest: "); - Serial.println(battery_pyroTestInProgress); + logging.print("STATUS: Contactor: "); + logging.print(contactorText[battery_contactor]); //Display what state the contactor is in + logging.print(", HVIL: "); + logging.print(hvilStatusState[battery_hvil_status]); + logging.print(", NegativeState: "); + logging.print(contactorState[battery_packContNegativeState]); + logging.print(", PositiveState: "); + logging.print(contactorState[battery_packContPositiveState]); + logging.print(", setState: "); + logging.print(contactorState[battery_packContactorSetState]); + logging.print(", close allowed: "); + logging.print(battery_packCtrsClosingAllowed); + logging.print(", Pyrotest: "); + logging.println(battery_pyroTestInProgress); - Serial.print("Battery values: "); - Serial.print("Real SOC: "); - Serial.print(battery_soc_ui / 10.0, 1); + logging.print("Battery values: "); + logging.print("Real SOC: "); + logging.print(battery_soc_ui / 10.0, 1); print_int_with_units(", Battery voltage: ", battery_volts, "V"); print_int_with_units(", Battery HV current: ", (battery_amps * 0.1), "A"); - Serial.print(", Fully charged?: "); + logging.print(", Fully charged?: "); if (battery_full_charge_complete) - Serial.print("YES, "); + logging.print("YES, "); else - Serial.print("NO, "); + logging.print("NO, "); if (datalayer.battery.info.chemistry == battery_chemistry_enum::LFP) { - Serial.print("LFP chemistry detected!"); + logging.print("LFP chemistry detected!"); } - Serial.println(""); - Serial.print("Cellstats, Max: "); - Serial.print(battery_cell_max_v); - Serial.print("mV (cell "); - Serial.print(battery_max_vno); - Serial.print("), Min: "); - Serial.print(battery_cell_min_v); - Serial.print("mV (cell "); - Serial.print(battery_min_vno); - Serial.print("), Imbalance: "); - Serial.print(battery_cell_deviation_mV); - Serial.println("mV."); + logging.println(""); + logging.print("Cellstats, Max: "); + logging.print(battery_cell_max_v); + logging.print("mV (cell "); + logging.print(battery_max_vno); + logging.print("), Min: "); + logging.print(battery_cell_min_v); + logging.print("mV (cell "); + logging.print(battery_min_vno); + logging.print("), Imbalance: "); + logging.print(battery_cell_deviation_mV); + logging.println("mV."); print_int_with_units("High Voltage Output Pins: ", battery_dcdcHvBusVolt, "V"); - Serial.print(", "); + logging.print(", "); print_int_with_units("Low Voltage: ", battery_dcdcLvBusVolt, "V"); - Serial.println(""); + logging.println(""); print_int_with_units("DC/DC 12V current: ", battery_dcdcLvOutputCurrent, "A"); - Serial.println(""); + logging.println(""); - Serial.println("Values passed to the inverter: "); + logging.println("Values passed to the inverter: "); print_SOC(" SOC: ", datalayer.battery.status.reported_soc); print_int_with_units(" Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W"); - Serial.print(", "); + logging.print(", "); print_int_with_units(" Max charge power: ", datalayer.battery.status.max_charge_power_W, "W"); - Serial.println(""); + logging.println(""); print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery.status.temperature_min_dC * 0.1), "°C"); - Serial.print(", "); + logging.print(", "); print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery.status.temperature_max_dC * 0.1), "°C"); - Serial.println(""); -#endif //DEBUG_VIA_USB + logging.println(""); +#endif //DEBUG_LOG } void receive_can_battery(CAN_frame rx_frame) { @@ -1087,69 +1087,69 @@ void update_values_battery2() { //This function maps all the values fetched via } #endif // TESLA_MODEL_3Y_BATTERY -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG printFaultCodesIfActive_battery2(); - Serial.print("STATUS: Contactor: "); - Serial.print(contactorText[battery2_contactor]); //Display what state the contactor is in - Serial.print(", HVIL: "); - Serial.print(hvilStatusState[battery2_hvil_status]); - Serial.print(", NegativeState: "); - Serial.print(contactorState[battery2_packContNegativeState]); - Serial.print(", PositiveState: "); - Serial.print(contactorState[battery2_packContPositiveState]); - Serial.print(", setState: "); - Serial.print(contactorState[battery2_packContactorSetState]); - Serial.print(", close allowed: "); - Serial.print(battery2_packCtrsClosingAllowed); - Serial.print(", Pyrotest: "); - Serial.println(battery2_pyroTestInProgress); + logging.print("STATUS: Contactor: "); + logging.print(contactorText[battery2_contactor]); //Display what state the contactor is in + logging.print(", HVIL: "); + logging.print(hvilStatusState[battery2_hvil_status]); + logging.print(", NegativeState: "); + logging.print(contactorState[battery2_packContNegativeState]); + logging.print(", PositiveState: "); + logging.print(contactorState[battery2_packContPositiveState]); + logging.print(", setState: "); + logging.print(contactorState[battery2_packContactorSetState]); + logging.print(", close allowed: "); + logging.print(battery2_packCtrsClosingAllowed); + logging.print(", Pyrotest: "); + logging.println(battery2_pyroTestInProgress); - Serial.print("Battery2 values: "); - Serial.print("Real SOC: "); - Serial.print(battery2_soc_ui / 10.0, 1); + logging.print("Battery2 values: "); + logging.print("Real SOC: "); + logging.print(battery2_soc_ui / 10.0, 1); print_int_with_units(", Battery2 voltage: ", battery2_volts, "V"); print_int_with_units(", Battery2 HV current: ", (battery2_amps * 0.1), "A"); - Serial.print(", Fully charged?: "); + logging.print(", Fully charged?: "); if (battery2_full_charge_complete) - Serial.print("YES, "); + logging.print("YES, "); else - Serial.print("NO, "); + logging.print("NO, "); if (datalayer.battery2.info.chemistry == battery_chemistry_enum::LFP) { - Serial.print("LFP chemistry detected!"); + logging.print("LFP chemistry detected!"); } - Serial.println(""); - Serial.print("Cellstats, Max: "); - Serial.print(battery2_cell_max_v); - Serial.print("mV (cell "); - Serial.print(battery2_max_vno); - Serial.print("), Min: "); - Serial.print(battery2_cell_min_v); - Serial.print("mV (cell "); - Serial.print(battery2_min_vno); - Serial.print("), Imbalance: "); - Serial.print(battery2_cell_deviation_mV); - Serial.println("mV."); + logging.println(""); + logging.print("Cellstats, Max: "); + logging.print(battery2_cell_max_v); + logging.print("mV (cell "); + logging.print(battery2_max_vno); + logging.print("), Min: "); + logging.print(battery2_cell_min_v); + logging.print("mV (cell "); + logging.print(battery2_min_vno); + logging.print("), Imbalance: "); + logging.print(battery2_cell_deviation_mV); + logging.println("mV."); print_int_with_units("High Voltage Output Pins: ", battery2_dcdcHvBusVolt, "V"); - Serial.print(", "); + logging.print(", "); print_int_with_units("Low Voltage: ", battery2_dcdcLvBusVolt, "V"); - Serial.println(""); + logging.println(""); print_int_with_units("DC/DC 12V current: ", battery2_dcdcLvOutputCurrent, "A"); - Serial.println(""); + logging.println(""); - Serial.println("Values passed to the inverter: "); + logging.println("Values passed to the inverter: "); print_SOC(" SOC: ", datalayer.battery2.status.reported_soc); print_int_with_units(" Max discharge power: ", datalayer.battery2.status.max_discharge_power_W, "W"); - Serial.print(", "); + logging.print(", "); print_int_with_units(" Max charge power: ", datalayer.battery2.status.max_charge_power_W, "W"); - Serial.println(""); + logging.println(""); print_int_with_units(" Max temperature: ", ((int16_t)datalayer.battery2.status.temperature_min_dC * 0.1), "°C"); - Serial.print(", "); + logging.print(", "); print_int_with_units(" Min temperature: ", ((int16_t)datalayer.battery2.status.temperature_max_dC * 0.1), "°C"); - Serial.println(""); -#endif // DEBUG_VIA_USB + logging.println(""); +#endif // DEBUG_LOG } #endif //DOUBLE_BATTERY @@ -1261,32 +1261,32 @@ the first, for a few cycles, then stop all messages which causes the contactor } void print_int_with_units(char* header, int value, char* units) { - Serial.print(header); - Serial.print(value); - Serial.print(units); + logging.print(header); + logging.print(value); + logging.print(units); } void print_SOC(char* header, int SOC) { - Serial.print(header); - Serial.print(SOC / 100); - Serial.print("."); + logging.print(header); + logging.print(SOC / 100); + logging.print("."); int hundredth = SOC % 100; if (hundredth < 10) - Serial.print(0); - Serial.print(hundredth); - Serial.println("%"); + logging.print(0); + logging.print(hundredth); + logging.println("%"); } void printFaultCodesIfActive() { if (battery_packCtrsClosingAllowed == 0) { - Serial.println( + logging.println( "ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: "); } if (battery_pyroTestInProgress == 1) { - Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!"); + logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!"); } if (datalayer.system.status.inverter_allows_contactor_closing == false) { - Serial.println( + logging.println( "ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter " "OR " "disable the inverter protocol to proceed with contactor closing"); @@ -1355,14 +1355,14 @@ void printFaultCodesIfActive() { #ifdef DOUBLE_BATTERY void printFaultCodesIfActive_battery2() { if (battery2_packCtrsClosingAllowed == 0) { - Serial.println( + logging.println( "ERROR: Check high voltage connectors and interlock circuit! Closing contactor not allowed! Values: "); } if (battery2_pyroTestInProgress == 1) { - Serial.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!"); + logging.println("ERROR: Please wait for Pyro Connection check to finish, HV cables successfully seated!"); } if (datalayer.system.status.inverter_allows_contactor_closing == false) { - Serial.println( + logging.println( "ERROR: Solar inverter does not allow for contactor closing. Check communication connection to the inverter " "OR " "disable the inverter protocol to proceed with contactor closing"); @@ -1433,7 +1433,7 @@ void printFaultCodesIfActive_battery2() { void printDebugIfActive(uint8_t symbol, const char* message) { if (symbol == 1) { - Serial.println(message); + logging.println(message); } } diff --git a/Software/src/battery/TEST-FAKE-BATTERY.cpp b/Software/src/battery/TEST-FAKE-BATTERY.cpp index 30d9119d..52b19b32 100644 --- a/Software/src/battery/TEST-FAKE-BATTERY.cpp +++ b/Software/src/battery/TEST-FAKE-BATTERY.cpp @@ -15,9 +15,9 @@ CAN_frame TEST = {.FD = false, .data = {0x10, 0x64, 0x00, 0xB0, 0x00, 0x1E, 0x00, 0x8F}}; void print_units(char* header, int value, char* units) { - Serial.print(header); - Serial.print(value); - Serial.print(units); + logging.print(header); + logging.print(value); + logging.print(units); } void update_values_battery() { /* This function puts fake values onto the parameters sent towards the inverter */ @@ -54,8 +54,8 @@ void update_values_battery() { /* This function puts fake values onto the parame datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; /*Finally print out values to serial if configured to do so*/ -#ifdef DEBUG_VIA_USB - Serial.println("FAKE Values going to inverter"); +#ifdef DEBUG_LOG + logging.println("FAKE Values going to inverter"); print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% "); print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% "); print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V "); @@ -65,7 +65,7 @@ void update_values_battery() { /* This function puts fake values onto the parame print_units(", Min temp: ", (datalayer.battery.status.temperature_min_dC * 0.1), "°C "); print_units(", Max cell voltage: ", datalayer.battery.status.cell_max_voltage_mV, "mV "); print_units(", Min cell voltage: ", datalayer.battery.status.cell_min_voltage_mV, "mV "); - Serial.println(""); + logging.println(""); #endif } @@ -107,8 +107,8 @@ void update_values_battery2() { // Handle the values coming in from battery #2 datalayer.battery2.status.CAN_battery_still_alive = CAN_STILL_ALIVE; /*Finally print out values to serial if configured to do so*/ -#ifdef DEBUG_VIA_USB - Serial.println("FAKE Values battery 2 going to inverter"); +#ifdef DEBUG_LOG + logging.println("FAKE Values battery 2 going to inverter"); print_units("SOH 2 %: ", (datalayer.battery2.status.soh_pptt * 0.01), "% "); print_units(", SOC 2 %: ", (datalayer.battery2.status.reported_soc * 0.01), "% "); print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V "); @@ -118,7 +118,7 @@ void update_values_battery2() { // Handle the values coming in from battery #2 print_units(", Min temp 2: ", (datalayer.battery2.status.temperature_min_dC * 0.1), "°C "); print_units(", Max cell voltage 2: ", datalayer.battery2.status.cell_max_voltage_mV, "mV "); print_units(", Min cell voltage 2: ", datalayer.battery2.status.cell_min_voltage_mV, "mV "); - Serial.println(""); + logging.println(""); #endif } diff --git a/Software/src/battery/VOLVO-SPA-BATTERY.cpp b/Software/src/battery/VOLVO-SPA-BATTERY.cpp index 839665c8..0c8b4e85 100644 --- a/Software/src/battery/VOLVO-SPA-BATTERY.cpp +++ b/Software/src/battery/VOLVO-SPA-BATTERY.cpp @@ -94,49 +94,49 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_voltages_mV[i] = cell_voltages[i]; } -#ifdef DEBUG_VIA_USB - Serial.print("BMS reported SOC%: "); - Serial.println(SOC_BMS); - Serial.print("Calculated SOC%: "); - Serial.println(SOC_CALC); - Serial.print("Rescaled SOC%: "); - Serial.println(datalayer.battery.status.reported_soc / 100); - Serial.print("Battery current: "); - Serial.println(BATT_I); - Serial.print("Battery voltage: "); - Serial.println(BATT_U); - Serial.print("Battery maximum voltage limit: "); - Serial.println(MAX_U); - Serial.print("Battery minimum voltage limit: "); - Serial.println(MIN_U); - Serial.print("Remaining Energy: "); - Serial.println(remaining_capacity); - Serial.print("Discharge limit: "); - Serial.println(HvBattPwrLimDchaSoft); - Serial.print("Battery Error Indication: "); - Serial.println(BATT_ERR_INDICATION); - Serial.print("Maximum battery temperature: "); - Serial.println(BATT_T_MAX / 10); - Serial.print("Minimum battery temperature: "); - Serial.println(BATT_T_MIN / 10); - Serial.print("Average battery temperature: "); - Serial.println(BATT_T_AVG / 10); - Serial.print("BMS Highest cell voltage: "); - Serial.println(CELL_U_MAX * 10); - Serial.print("BMS Lowest cell voltage: "); - Serial.println(CELL_U_MIN * 10); - Serial.print("BMS Highest cell nr: "); - Serial.println(CELL_ID_U_MAX); - Serial.print("Highest cell voltage: "); - Serial.println(min_max_voltage[1]); - Serial.print("Lowest cell voltage: "); - Serial.println(min_max_voltage[0]); - Serial.print("Cell voltage,"); +#ifdef DEBUG_LOG + logging.print("BMS reported SOC%: "); + logging.println(SOC_BMS); + logging.print("Calculated SOC%: "); + logging.println(SOC_CALC); + logging.print("Rescaled SOC%: "); + logging.println(datalayer.battery.status.reported_soc / 100); + logging.print("Battery current: "); + logging.println(BATT_I); + logging.print("Battery voltage: "); + logging.println(BATT_U); + logging.print("Battery maximum voltage limit: "); + logging.println(MAX_U); + logging.print("Battery minimum voltage limit: "); + logging.println(MIN_U); + logging.print("Remaining Energy: "); + logging.println(remaining_capacity); + logging.print("Discharge limit: "); + logging.println(HvBattPwrLimDchaSoft); + logging.print("Battery Error Indication: "); + logging.println(BATT_ERR_INDICATION); + logging.print("Maximum battery temperature: "); + logging.println(BATT_T_MAX / 10); + logging.print("Minimum battery temperature: "); + logging.println(BATT_T_MIN / 10); + logging.print("Average battery temperature: "); + logging.println(BATT_T_AVG / 10); + logging.print("BMS Highest cell voltage: "); + logging.println(CELL_U_MAX * 10); + logging.print("BMS Lowest cell voltage: "); + logging.println(CELL_U_MIN * 10); + logging.print("BMS Highest cell nr: "); + logging.println(CELL_ID_U_MAX); + logging.print("Highest cell voltage: "); + logging.println(min_max_voltage[1]); + logging.print("Lowest cell voltage: "); + logging.println(min_max_voltage[0]); + logging.print("Cell voltage,"); while (cnt < 108) { - Serial.print(cell_voltages[cnt++]); - Serial.print(","); + logging.print(cell_voltages[cnt++]); + logging.print(","); } - Serial.println(";"); + logging.println(";"); #endif } @@ -148,8 +148,8 @@ void receive_can_battery(CAN_frame rx_frame) { BATT_I = (0 - ((((rx_frame.data.u8[6] & 0x7F) * 256.0 + rx_frame.data.u8[7]) * 0.1) - 1638)); else { BATT_I = 0; -#ifdef DEBUG_VIA_USB - Serial.println("BATT_I not valid"); +#ifdef DEBUG_LOG + logging.println("BATT_I not valid"); #endif } @@ -157,22 +157,22 @@ void receive_can_battery(CAN_frame rx_frame) { MAX_U = (((rx_frame.data.u8[2] & 0x07) * 256.0 + rx_frame.data.u8[3]) * 0.25); else { //MAX_U = 0; - //Serial.println("MAX_U not valid"); // Value toggles between true/false from BMS + //logging.println("MAX_U not valid"); // Value toggles between true/false from BMS } if ((rx_frame.data.u8[4] & 0x08) == 0x08) MIN_U = (((rx_frame.data.u8[4] & 0x07) * 256.0 + rx_frame.data.u8[5]) * 0.25); else { //MIN_U = 0; - //Serial.println("MIN_U not valid"); // Value toggles between true/false from BMS + //logging.println("MIN_U not valid"); // Value toggles between true/false from BMS } if ((rx_frame.data.u8[0] & 0x08) == 0x08) BATT_U = (((rx_frame.data.u8[0] & 0x07) * 256.0 + rx_frame.data.u8[1]) * 0.25); else { BATT_U = 0; -#ifdef DEBUG_VIA_USB - Serial.println("BATT_U not valid"); +#ifdef DEBUG_LOG + logging.println("BATT_U not valid"); #endif } break; @@ -189,8 +189,8 @@ void receive_can_battery(CAN_frame rx_frame) { BATT_ERR_INDICATION = ((rx_frame.data.u8[0] & 0x40) >> 6); else { BATT_ERR_INDICATION = 0; -#ifdef DEBUG_VIA_USB - Serial.println("BATT_ERR_INDICATION not valid"); +#ifdef DEBUG_LOG + logging.println("BATT_ERR_INDICATION not valid"); #endif } if ((rx_frame.data.u8[0] & 0x20) == 0x20) { @@ -201,8 +201,8 @@ void receive_can_battery(CAN_frame rx_frame) { BATT_T_MAX = 0; BATT_T_MIN = 0; BATT_T_AVG = 0; -#ifdef DEBUG_VIA_USB - Serial.println("BATT_T not valid"); +#ifdef DEBUG_LOG + logging.println("BATT_T not valid"); #endif } break; @@ -211,8 +211,8 @@ void receive_can_battery(CAN_frame rx_frame) { HvBattPwrLimDchaSoft = (((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[6]) >> 2); } else { HvBattPwrLimDchaSoft = 0; -#ifdef DEBUG_VIA_USB - Serial.println("HvBattPwrLimDchaSoft not valid"); +#ifdef DEBUG_LOG + logging.println("HvBattPwrLimDchaSoft not valid"); #endif } break; @@ -221,8 +221,8 @@ void receive_can_battery(CAN_frame rx_frame) { SOC_BMS = ((rx_frame.data.u8[6] & 0x03) * 256 + rx_frame.data.u8[7]); } else { SOC_BMS = 0; -#ifdef DEBUG_VIA_USB - Serial.println("SOC_BMS not valid"); +#ifdef DEBUG_LOG + logging.println("SOC_BMS not valid"); #endif } @@ -230,8 +230,8 @@ void receive_can_battery(CAN_frame rx_frame) { CELL_U_MAX = ((rx_frame.data.u8[2] & 0x01) * 256 + rx_frame.data.u8[3]); else { CELL_U_MAX = 0; -#ifdef DEBUG_VIA_USB - Serial.println("CELL_U_MAX not valid"); +#ifdef DEBUG_LOG + logging.println("CELL_U_MAX not valid"); #endif } @@ -239,8 +239,8 @@ void receive_can_battery(CAN_frame rx_frame) { CELL_U_MIN = ((rx_frame.data.u8[0] & 0x01) * 256.0 + rx_frame.data.u8[1]); else { CELL_U_MIN = 0; -#ifdef DEBUG_VIA_USB - Serial.println("CELL_U_MIN not valid"); +#ifdef DEBUG_LOG + logging.println("CELL_U_MIN not valid"); #endif } @@ -248,8 +248,8 @@ void receive_can_battery(CAN_frame rx_frame) { CELL_ID_U_MAX = ((rx_frame.data.u8[4] & 0x01) * 256.0 + rx_frame.data.u8[5]); else { CELL_ID_U_MAX = 0; -#ifdef DEBUG_VIA_USB - Serial.println("CELL_ID_U_MAX not valid"); +#ifdef DEBUG_LOG + logging.println("CELL_ID_U_MAX not valid"); #endif } break; diff --git a/Software/src/charger/CHEVY-VOLT-CHARGER.cpp b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp index 75cfd021..3b947d2d 100644 --- a/Software/src/charger/CHEVY-VOLT-CHARGER.cpp +++ b/Software/src/charger/CHEVY-VOLT-CHARGER.cpp @@ -101,8 +101,8 @@ void receive_can_charger(CAN_frame rx_frame) { case 0x308: break; default: -#ifdef DEBUG_VIA_USB - Serial.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID); +#ifdef DEBUG_LOG + logging.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID); #endif break; } @@ -177,15 +177,15 @@ void send_can_charger() { transmit_can(&charger_set_targets, can_config.charger); } -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG /* Serial echo every 5s of charger stats */ if (currentMillis - previousMillis5000ms >= INTERVAL_5_S) { previousMillis5000ms = currentMillis; - Serial.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol); - Serial.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol); - Serial.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol); - Serial.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled"); - Serial.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END); + logging.printf("Charger AC in IAC=%fA VAC=%fV\n", charger_stat_ACcur, charger_stat_ACvol); + logging.printf("Charger HV out IDC=%fA VDC=%fV\n", charger_stat_HVcur, charger_stat_HVvol); + logging.printf("Charger LV out IDC=%fA VDC=%fV\n", charger_stat_LVcur, charger_stat_LVvol); + logging.printf("Charger mode=%s\n", (charger_mode > MODE_DISABLED) ? "Enabled" : "Disabled"); + logging.printf("Charger HVset=%uV,%uA finishCurrent=%uA\n", setpoint_HV_VDC, setpoint_HV_IDC, setpoint_HV_IDC_END); } #endif } diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index 8d7923fd..8fa2ab3d 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -35,31 +35,31 @@ void init_CAN() { ESP32Can.CANInit(); #ifdef CAN_ADDON -#ifdef DEBUG_VIA_USB - Serial.println("Dual CAN Bus (ESP32+MCP2515) selected"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Dual CAN Bus (ESP32+MCP2515) selected"); +#endif // DEBUG_LOG gBuffer.initWithSize(25); SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI); ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s settings.mRequestedMode = ACAN2515Settings::NormalMode; const uint16_t errorCodeMCP = can.begin(settings, [] { can.isr(); }); if (errorCodeMCP == 0) { -#ifdef DEBUG_VIA_USB - Serial.println("Can ok"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Can ok"); +#endif // DEBUG_LOG } else { -#ifdef DEBUG_VIA_USB - Serial.print("Error Can: 0x"); - Serial.println(errorCodeMCP, HEX); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.print("Error Can: 0x"); + logging.println(errorCodeMCP, HEX); +#endif // DEBUG_LOG set_event(EVENT_CANMCP_INIT_FAILURE, (uint8_t)errorCodeMCP); } #endif // CAN_ADDON #ifdef CANFD_ADDON -#ifdef DEBUG_VIA_USB - Serial.println("CAN FD add-on (ESP32+MCP2517) selected"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("CAN FD add-on (ESP32+MCP2517) selected"); +#endif // DEBUG_LOG SPI.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI); ACAN2517FDSettings settings(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000, DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s @@ -71,29 +71,29 @@ void init_CAN() { const uint32_t errorCode = canfd.begin(settings, [] { canfd.isr(); }); canfd.poll(); if (errorCode == 0) { -#ifdef DEBUG_VIA_USB - Serial.print("Bit Rate prescaler: "); - Serial.println(settings.mBitRatePrescaler); - Serial.print("Arbitration Phase segment 1: "); - Serial.println(settings.mArbitrationPhaseSegment1); - Serial.print("Arbitration Phase segment 2: "); - Serial.println(settings.mArbitrationPhaseSegment2); - Serial.print("Arbitration SJW:"); - Serial.println(settings.mArbitrationSJW); - Serial.print("Actual Arbitration Bit Rate: "); - Serial.print(settings.actualArbitrationBitRate()); - Serial.println(" bit/s"); - Serial.print("Exact Arbitration Bit Rate ? "); - Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no"); - Serial.print("Arbitration Sample point: "); - Serial.print(settings.arbitrationSamplePointFromBitStart()); - Serial.println("%"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.print("Bit Rate prescaler: "); + logging.println(settings.mBitRatePrescaler); + logging.print("Arbitration Phase segment 1: "); + logging.print(settings.mArbitrationPhaseSegment1); + logging.print(" segment 2: "); + logging.print(settings.mArbitrationPhaseSegment2); + logging.print(" SJW: "); + logging.println(settings.mArbitrationSJW); + logging.print("Actual Arbitration Bit Rate: "); + logging.print(settings.actualArbitrationBitRate()); + logging.print(" bit/s"); + logging.print(" (Exact:"); + logging.println(settings.exactArbitrationBitRate() ? "yes)" : "no)"); + logging.print("Arbitration Sample point: "); + logging.print(settings.arbitrationSamplePointFromBitStart()); + logging.println("%"); +#endif // DEBUG_LOG } else { -#ifdef DEBUG_VIA_USB - Serial.print("CAN-FD Configuration error 0x"); - Serial.println(errorCode, HEX); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.print("CAN-FD Configuration error 0x"); + logging.println(errorCode, HEX); +#endif // DEBUG_LOG set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode); } #endif // CANFD_ADDON @@ -153,6 +153,8 @@ void transmit_can(CAN_frame* tx_frame, int interface) { send_ok = canfd.tryToSend(MCP2518Frame); if (!send_ok) { set_event(EVENT_CANFD_BUFFER_FULL, interface); + } else { + clear_event(EVENT_CANFD_BUFFER_FULL); } #else // Interface not compiled, and settings try to use it set_event(EVENT_INTERFACE_MISSING, interface); diff --git a/Software/src/devboard/mqtt/mqtt.cpp b/Software/src/devboard/mqtt/mqtt.cpp index 95f5444a..6e1b6bd1 100644 --- a/Software/src/devboard/mqtt/mqtt.cpp +++ b/Software/src/devboard/mqtt/mqtt.cpp @@ -194,9 +194,9 @@ static void publish_common_info(void) { #endif // DOUBLE_BATTERY serializeJson(doc, mqtt_msg); if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) { -#ifdef DEBUG_VIA_USB - Serial.println("Common info MQTT msg could not be sent"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Common info MQTT msg could not be sent"); +#endif // DEBUG_LOG } doc.clear(); #ifdef HA_AUTODISCOVERY @@ -292,9 +292,9 @@ static void publish_cell_voltages(void) { serializeJson(doc, mqtt_msg, sizeof(mqtt_msg)); if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) { -#ifdef DEBUG_VIA_USB - Serial.println("Cell voltage MQTT msg could not be sent"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Cell voltage MQTT msg could not be sent"); +#endif // DEBUG_LOG } doc.clear(); } @@ -312,9 +312,9 @@ static void publish_cell_voltages(void) { serializeJson(doc, mqtt_msg, sizeof(mqtt_msg)); if (!mqtt_publish(state_topic_2.c_str(), mqtt_msg, false)) { -#ifdef DEBUG_VIA_USB - Serial.println("Cell voltage MQTT msg could not be sent"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Cell voltage MQTT msg could not be sent"); +#endif // DEBUG_LOG } doc.clear(); } @@ -384,9 +384,9 @@ void publish_events() { serializeJson(doc, mqtt_msg); if (!mqtt_publish(state_topic.c_str(), mqtt_msg, false)) { -#ifdef DEBUG_VIA_USB - Serial.println("Common info MQTT msg could not be sent"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("Common info MQTT msg could not be sent"); +#endif // DEBUG_LOG } else { set_event_MQTTpublished(event_handle); } @@ -402,9 +402,9 @@ void publish_events() { /* If we lose the connection, get it back */ static bool reconnect() { // attempt one reconnection -#ifdef DEBUG_VIA_USB - Serial.print("Attempting MQTT connection... "); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.print("Attempting MQTT connection... "); +#endif // DEBUG_LOG char clientId[64]; // Adjust the size as needed snprintf(clientId, sizeof(clientId), "BatteryEmulatorClient-%s", WiFi.getHostname()); // Attempt to connect @@ -413,19 +413,19 @@ static bool reconnect() { clear_event(EVENT_MQTT_DISCONNECT); set_event(EVENT_MQTT_CONNECT, 0); reconnectAttempts = 0; // Reset attempts on successful connection -#ifdef DEBUG_VIA_USB - Serial.println("connected"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("connected"); +#endif // DEBUG_LOG clear_event(EVENT_MQTT_CONNECT); } else { if (connected_once) set_event(EVENT_MQTT_DISCONNECT, 0); reconnectAttempts++; // Count failed attempts -#ifdef DEBUG_VIA_USB - Serial.print("failed, rc="); - Serial.print(client.state()); - Serial.println(" try again in 5 seconds"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.print("failed, rc="); + logging.print(client.state()); + logging.println(" try again in 5 seconds"); +#endif // DEBUG_LOG // Wait 5 seconds before retrying } return client.connected(); @@ -449,9 +449,9 @@ void init_mqtt(void) { #endif client.setServer(MQTT_SERVER, MQTT_PORT); -#ifdef DEBUG_VIA_USB - Serial.println("MQTT initialized"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("MQTT initialized"); +#endif // DEBUG_LOG client.setKeepAlive(30); // Increase keepalive to manage network latency better. default is 15 @@ -478,8 +478,8 @@ void mqtt_loop(void) { if (reconnect()) { lastReconnectAttempt = 0; } else if (reconnectAttempts >= maxReconnectAttempts) { -#ifdef DEBUG_VIA_USB - Serial.println("Too many failed reconnect attempts, restarting client."); +#ifdef DEBUG_LOG + logging.println("Too many failed reconnect attempts, restarting client."); #endif client.disconnect(); // Force close the MQTT client connection reconnectAttempts = 0; // Reset attempts to avoid infinite loop diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index d51bd1c4..021b1660 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -118,15 +118,15 @@ void init_events(void) { // Push changes to eeprom EEPROM.commit(); -#ifdef DEBUG_VIA_USB - Serial.println("EEPROM wasn't ready"); +#ifdef DEBUG_LOG + logging.println("EEPROM wasn't ready"); #endif } else { events.event_log_head_index = EEPROM.readUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS); events.event_log_tail_index = EEPROM.readUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS); -#ifdef DEBUG_VIA_USB - Serial.println("EEPROM was initialized for event logging"); - Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index)); +#ifdef DEBUG_LOG + logging.println("EEPROM was initialized for event logging"); + logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index)); #endif print_event_log(); } @@ -471,6 +471,10 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { if (events.entries[event].log) { log_event(event, events.entries[event].millisrolloverCount, events.entries[event].timestamp, data); } +#ifdef DEBUG_LOG + logging.print("Event: "); + logging.println(get_event_message_string(event)); +#endif } // We should set the event, update event info @@ -484,10 +488,6 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { events.level = max(events.level, events.entries[event].level); update_bms_status(); - -#ifdef DEBUG_VIA_USB - Serial.println(get_event_message_string(event)); -#endif } static void update_bms_status(void) { @@ -561,8 +561,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3 // Store the new indices EEPROM.writeUShort(EE_EVENT_LOG_HEAD_INDEX_ADDRESS, events.event_log_head_index); EEPROM.writeUShort(EE_EVENT_LOG_TAIL_INDEX_ADDRESS, events.event_log_tail_index); - //Serial.println("Wrote event " + String(event) + " to " + String(entry_address)); - //Serial.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index)); + //logging.println("Wrote event " + String(event) + " to " + String(entry_address)); + //logging.println("head: " + String(events.event_log_head_index) + ", tail: " + String(events.event_log_tail_index)); // We don't need the exact number, it's just for deciding to store or not events.nof_logged_events += (events.nof_logged_events < 255) ? 1 : 0; @@ -571,8 +571,8 @@ static void log_event(EVENTS_ENUM_TYPE event, uint8_t millisrolloverCount, uint3 static void print_event_log(void) { // If the head actually points to the tail, the log is probably blank if (events.event_log_head_index == events.event_log_tail_index) { -#ifdef DEBUG_VIA_USB - Serial.println("No events in log"); +#ifdef DEBUG_LOG + logging.println("No events in log"); #endif return; } @@ -588,9 +588,9 @@ static void print_event_log(void) { // The entry is a blank that has been left behind somehow continue; } -#ifdef DEBUG_VIA_USB - Serial.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) + - ", time: " + String(entry.timestamp)); +#ifdef DEBUG_LOG + logging.println("Event: " + String(get_event_enum_string(entry.event)) + ", data: " + String(entry.data) + + ", time: " + String(entry.timestamp)); #endif if (index == events.event_log_head_index) { break; diff --git a/Software/src/devboard/utils/events_test_on_target.cpp b/Software/src/devboard/utils/events_test_on_target.cpp index 9f91e8df..980c3f1f 100644 --- a/Software/src/devboard/utils/events_test_on_target.cpp +++ b/Software/src/devboard/utils/events_test_on_target.cpp @@ -25,9 +25,9 @@ void run_sequence_on_target(void) { case ETOT_INIT: timer.set_interval(10000); events_test_state = ETOT_FIRST_WAIT; - Serial.println("Events test: initialized"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test: initialized"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); break; case ETOT_FIRST_WAIT: if (timer.elapsed()) { @@ -35,9 +35,9 @@ void run_sequence_on_target(void) { events_test_state = ETOT_INFO; set_event(EVENT_DUMMY_INFO, 123); set_event(EVENT_DUMMY_INFO, 234); // 234 should show, occurrence 1 - Serial.println("Events test: info event set, data: 234"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test: info event set, data: 234"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_INFO: @@ -45,9 +45,9 @@ void run_sequence_on_target(void) { timer.set_interval(8000); clear_event(EVENT_DUMMY_INFO); events_test_state = ETOT_INFO_CLEAR; - Serial.println("Events test : info event cleared"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : info event cleared"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_INFO_CLEAR: @@ -56,9 +56,9 @@ void run_sequence_on_target(void) { events_test_state = ETOT_DEBUG; set_event(EVENT_DUMMY_DEBUG, 111); set_event(EVENT_DUMMY_DEBUG, 222); // 222 should show, occurrence 1 - Serial.println("Events test : debug event set, data: 222"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : debug event set, data: 222"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_DEBUG: @@ -66,9 +66,9 @@ void run_sequence_on_target(void) { timer.set_interval(8000); clear_event(EVENT_DUMMY_DEBUG); events_test_state = ETOT_DEBUG_CLEAR; - Serial.println("Events test : info event cleared"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : info event cleared"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_DEBUG_CLEAR: @@ -77,9 +77,9 @@ void run_sequence_on_target(void) { events_test_state = ETOT_WARNING; set_event(EVENT_DUMMY_WARNING, 234); set_event(EVENT_DUMMY_WARNING, 121); // 121 should show, occurrence 1 - Serial.println("Events test : warning event set, data: 121"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : warning event set, data: 121"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_WARNING: @@ -87,9 +87,9 @@ void run_sequence_on_target(void) { timer.set_interval(8000); clear_event(EVENT_DUMMY_WARNING); events_test_state = ETOT_WARNING_CLEAR; - Serial.println("Events test : warning event cleared"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : warning event cleared"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_WARNING_CLEAR: @@ -98,9 +98,9 @@ void run_sequence_on_target(void) { events_test_state = ETOT_ERROR; set_event(EVENT_DUMMY_ERROR, 221); set_event(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1 - Serial.println("Events test : error event set, data: 133"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : error event set, data: 133"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_ERROR: @@ -108,9 +108,9 @@ void run_sequence_on_target(void) { timer.set_interval(8000); clear_event(EVENT_DUMMY_ERROR); events_test_state = ETOT_ERROR_CLEAR; - Serial.println("Events test : error event cleared"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : error event cleared"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_ERROR_CLEAR: @@ -119,9 +119,9 @@ void run_sequence_on_target(void) { events_test_state = ETOT_ERROR_LATCHED; set_event_latched(EVENT_DUMMY_ERROR, 221); set_event_latched(EVENT_DUMMY_ERROR, 133); // 133 should show, occurrence 1 - Serial.println("Events test : latched error event set, data: 133"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : latched error event set, data: 133"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_ERROR_LATCHED: @@ -129,9 +129,9 @@ void run_sequence_on_target(void) { timer.set_interval(8000); clear_event(EVENT_DUMMY_ERROR); events_test_state = ETOT_DONE; - Serial.println("Events test : latched error event cleared?"); - Serial.print("datalayer.battery.status.bms_status: "); - Serial.println(datalayer.battery.status.bms_status); + logging.println("Events test : latched error event cleared?"); + logging.print("datalayer.battery.status.bms_status: "); + logging.println(datalayer.battery.status.bms_status); } break; case ETOT_DONE: diff --git a/Software/src/devboard/utils/logging.cpp b/Software/src/devboard/utils/logging.cpp new file mode 100644 index 00000000..0f78956f --- /dev/null +++ b/Software/src/devboard/utils/logging.cpp @@ -0,0 +1,86 @@ +#include "logging.h" +#include "../../datalayer/datalayer.h" + +size_t Logging::write(const uint8_t* buffer, size_t size) { +#ifdef DEBUG_LOG + char* message_string = datalayer.system.info.logged_can_messages; + int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer + size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages); + unsigned long currentTime = millis(); +#ifdef DEBUG_VIA_USB + size_t n = 0; + while (size--) { + if (Serial.write(*buffer++)) + n++; + else + break; + } + return n; +#endif +#ifdef DEBUG_VIA_WEB + if (datalayer.system.info.can_logging_active) { + return 0; + } + if (offset + size + 13 > sizeof(datalayer.system.info.logged_can_messages)) { + offset = 0; + } + if (buffer[0] != '\r' && buffer[0] != '\n' && + (offset == 0 || message_string[offset - 1] == '\r' || message_string[offset - 1] == '\n')) { + offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000, + currentTime % 1000); + } + memcpy(message_string + offset, buffer, size); + datalayer.system.info.logged_can_messages_offset = offset + size; // Update offset in buffer + return size; +#endif // DEBUG_VIA_WEB +#endif // DEBUG_LOG + return 0; +} + +void Logging::printf(const char* fmt, ...) { +#ifdef DEBUG_LOG + char* message_string = datalayer.system.info.logged_can_messages; + int offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer + size_t message_string_size = sizeof(datalayer.system.info.logged_can_messages); +#ifdef DEBUG_VIA_USB + static char buf[128]; + message_string = buf; + offset = 0; + message_string_size = sizeof(buf); +#endif +#ifdef DEBUG_VIA_WEB + if (datalayer.system.info.can_logging_active) { + return; + } + message_string = datalayer.system.info.logged_can_messages; + offset = datalayer.system.info.logged_can_messages_offset; // Keeps track of the current position in the buffer + message_string_size = sizeof(datalayer.system.info.logged_can_messages); +#endif + if (offset + 128 > sizeof(datalayer.system.info.logged_can_messages)) { + // Not enough space, reset and start from the beginning + offset = 0; + } + unsigned long currentTime = millis(); + // Add timestamp + offset += snprintf(message_string + offset, message_string_size - offset - 1, "%8lu.%03lu ", currentTime / 1000, + currentTime % 1000); + + va_list(args); + va_start(args, fmt); + offset += vsnprintf(message_string + offset, message_string_size - offset - 1, fmt, args); + va_end(args); + + if (datalayer.system.info.can_logging_active) { + size_t size = offset; + size_t n = 0; + while (size--) { + if (Serial.write(*message_string++)) + n++; + else + break; + } + } else { + datalayer.system.info.logged_can_messages_offset = offset; // Update offset in buffer + } +#endif // DEBUG_LOG +} diff --git a/Software/src/devboard/utils/logging.h b/Software/src/devboard/utils/logging.h new file mode 100644 index 00000000..09b91458 --- /dev/null +++ b/Software/src/devboard/utils/logging.h @@ -0,0 +1,16 @@ +#ifndef __LOGGING_H__ +#define __LOGGING_H__ + +#include +#include "Print.h" + +class Logging : public Print { + public: + virtual size_t write(const uint8_t* buffer, size_t size); + virtual size_t write(uint8_t) { return 0; } + void printf(const char* fmt, ...); + Logging() {} +}; + +extern Logging logging; +#endif // __LOGGING_H__ diff --git a/Software/src/devboard/webserver/can_logging_html.cpp b/Software/src/devboard/webserver/can_logging_html.cpp index 59f03823..77f1975e 100644 --- a/Software/src/devboard/webserver/can_logging_html.cpp +++ b/Software/src/devboard/webserver/can_logging_html.cpp @@ -4,6 +4,10 @@ String can_logger_processor(const String& var) { if (var == "X") { + if (!datalayer.system.info.can_logging_active) { + datalayer.system.info.logged_can_messages_offset = 0; + datalayer.system.info.logged_can_messages[0] = '\0'; + } datalayer.system.info.can_logging_active = true; // Signal to main loop that we should log messages. Disabled by default for performance reasons String content = ""; @@ -19,7 +23,7 @@ String can_logger_processor(const String& var) { "monospace; }"; content += ""; content += " "; - content += " "; + content += " "; content += ""; // Start a new block for the CAN messages @@ -47,9 +51,9 @@ String can_logger_processor(const String& var) { // Add JavaScript for navigation content += ""; return content; diff --git a/Software/src/devboard/webserver/debug_logging_html.cpp b/Software/src/devboard/webserver/debug_logging_html.cpp new file mode 100644 index 00000000..7dd9ede4 --- /dev/null +++ b/Software/src/devboard/webserver/debug_logging_html.cpp @@ -0,0 +1,36 @@ +#include "debug_logging_html.h" +#include +#include "../../datalayer/datalayer.h" + +#ifdef DEBUG_VIA_WEB +String debug_logger_processor(const String& var) { + String content = ""; + // Page format + content += ""; + content += " "; + content += " "; + content += ""; + + // Start a new block for the debug log messages + content += "
";
+  content += String(datalayer.system.info.logged_can_messages);
+  content += "
"; + + // Add JavaScript for navigation + content += ""; + return content; +} +#endif // DEBUG_VIA_WEB diff --git a/Software/src/devboard/webserver/debug_logging_html.h b/Software/src/devboard/webserver/debug_logging_html.h new file mode 100644 index 00000000..0b6ebc69 --- /dev/null +++ b/Software/src/devboard/webserver/debug_logging_html.h @@ -0,0 +1,16 @@ +#ifndef DEBUGLOGGER_H +#define DEBUGLOGGER_H + +#include +#include + +/** + * @brief Replaces placeholder with content section in web page + * + * @param[in] var + * + * @return String + */ +String debug_logger_processor(const String& var); + +#endif diff --git a/Software/src/devboard/webserver/events_html.cpp b/Software/src/devboard/webserver/events_html.cpp index 3cb3edbe..a602b938 100644 --- a/Software/src/devboard/webserver/events_html.cpp +++ b/Software/src/devboard/webserver/events_html.cpp @@ -39,11 +39,11 @@ String events_processor(const String& var) { for (const auto& event : order_events) { EVENTS_ENUM_TYPE event_handle = event.event_handle; event_pointer = event.event_pointer; -#ifdef DEBUG_VIA_USB - Serial.println("Event: " + String(get_event_enum_string(event_handle)) + - " count: " + String(event_pointer->occurences) + " seconds: " + String(event_pointer->timestamp) + - " data: " + String(event_pointer->data) + - " level: " + String(get_event_level_string(event_handle))); +#ifdef DEBUG_LOG + logging.println("Showing Event: " + String(get_event_enum_string(event_handle)) + + " count: " + String(event_pointer->occurences) + " seconds: " + String(event_pointer->timestamp) + + " data: " + String(event_pointer->data) + + " level: " + String(get_event_level_string(event_handle))); #endif content.concat("
"); content.concat("
" + String(get_event_enum_string(event_handle)) + "
"); diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 5468c704..290657db 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -17,6 +17,7 @@ unsigned long ota_progress_millis = 0; #include "advanced_battery_html.h" #include "can_logging_html.h" #include "cellmonitor_html.h" +#include "debug_logging_html.h" #include "events_html.h" #include "index_html.cpp" #include "settings_html.h" @@ -63,14 +64,21 @@ void init_webserver() { request->send_P(200, "text/html", index_html, can_logger_processor); }); - // Define the handler to stop logging - server.on("/stop_logging", HTTP_GET, [](AsyncWebServerRequest* request) { +#ifdef DEBUG_VIA_WEB + // Route for going to debug logging web page + server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send_P(200, "text/html", index_html, debug_logger_processor); + }); +#endif // DEBUG_VIA_WEB + + // Define the handler to stop can logging + server.on("/stop_can_logging", HTTP_GET, [](AsyncWebServerRequest* request) { datalayer.system.info.can_logging_active = false; request->send_P(200, "text/plain", "Logging stopped"); }); - // Define the handler to export logs - server.on("/export_logs", HTTP_GET, [](AsyncWebServerRequest* request) { + // Define the handler to export can log + server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) { String logs = String(datalayer.system.info.logged_can_messages); if (logs.length() == 0) { logs = "No logs available."; @@ -96,6 +104,33 @@ void init_webserver() { request->send(response); }); + // Define the handler to export debug log + server.on("/export_log", HTTP_GET, [](AsyncWebServerRequest* request) { + String logs = String(datalayer.system.info.logged_can_messages); + if (logs.length() == 0) { + logs = "No logs available."; + } + + // Get the current time + time_t now = time(nullptr); + struct tm timeinfo; + localtime_r(&now, &timeinfo); + + // Ensure time retrieval was successful + char filename[32]; + if (strftime(filename, sizeof(filename), "log_%H-%M-%S.txt", &timeinfo)) { + // Valid filename created + } else { + // Fallback filename if automatic timestamping failed + strcpy(filename, "battery_emulator_log.txt"); + } + + // Use request->send with dynamic headers + AsyncWebServerResponse* response = request->beginResponse(200, "text/plain", logs); + response->addHeader("Content-Disposition", String("attachment; filename=\"") + String(filename) + "\""); + request->send(response); + }); + // Route for going to cellmonitor web page server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) { if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) @@ -535,14 +570,15 @@ String processor(const String& var) { content += "
"; // Show version number - content += "

Software: " + String(version_number) + "

"; + content += "

Software: " + String(version_number); // Show hardware used: #ifdef HW_LILYGO - content += "

Hardware: LilyGo T-CAN485

"; + content += " Hardware: LilyGo T-CAN485"; #endif // HW_LILYGO #ifdef HW_STARK - content += "

Hardware: Stark CMR Module

"; + content += " Hardware: Stark CMR Module"; #endif // HW_STARK + content += ""; content += "

Uptime: " + uptime_formatter::getUptime() + "

"; #ifdef FUNCTION_TIME_MEASUREMENT // Load information @@ -566,11 +602,14 @@ String processor(const String& var) { wl_status_t status = WiFi.status(); // Display ssid of network connected to and, if connected to the WiFi, its own IP - content += "

SSID: " + String(ssid.c_str()) + "

"; + content += "

SSID: " + String(ssid.c_str()); + if (status == WL_CONNECTED) { + // Get and display the signal strength (RSSI) and channel + content += " RSSI:" + String(WiFi.RSSI()) + " dBm Ch: " + String(WiFi.channel()); + } + content += "

"; if (status == WL_CONNECTED) { content += "

IP: " + WiFi.localIP().toString() + "

"; - // Get and display the signal strength (RSSI) and channel - content += "

Signal strength: " + String(WiFi.RSSI()) + " dBm, at channel " + String(WiFi.channel()) + "

"; } else { content += "

Wifi state: " + getConnectResultString(status) + "

"; } @@ -692,13 +731,30 @@ String processor(const String& var) { } content += "

Temperature max: " + String(tempMaxFloat, 1) + " C

"; content += "

Temperature min: " + String(tempMinFloat, 1) + " C

"; - if (datalayer.battery.status.bms_status == ACTIVE) { - content += "

System status: OK

"; - } else if (datalayer.battery.status.bms_status == UPDATING) { - content += "

System status: UPDATING

"; - } else { - content += "

System status: FAULT

"; + + content += "

System status: "; + switch (datalayer.battery.status.bms_status) { + case ACTIVE: + content += String("OK"); + break; + case UPDATING: + content += String("UPDATING"); + break; + case FAULT: + content += String("FAULT"); + break; + case INACTIVE: + content += String("INACTIVE"); + break; + case STANDBY: + content += String("STANDBY"); + break; + default: + content += String("??"); + break; } + content += "

"; + if (datalayer.battery.status.current_dA == 0) { content += "

Battery idle

"; } else if (datalayer.battery.status.current_dA < 0) { @@ -977,6 +1033,9 @@ String processor(const String& var) { content += " "; content += " "; content += " "; +#ifdef DEBUG_VIA_WEB + content += " "; +#endif // DEBUG_VIA_WEB content += " "; content += " "; content += ""; @@ -1002,6 +1061,7 @@ String processor(const String& var) { content += "function Settings() { window.location.href = '/settings'; }"; content += "function Advanced() { window.location.href = '/advanced'; }"; content += "function CANlog() { window.location.href = '/canlog'; }"; + content += "function Log() { window.location.href = '/log'; }"; content += "function Events() { window.location.href = '/events'; }"; content += "function askReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If " @@ -1062,9 +1122,9 @@ void onOTAProgress(size_t current, size_t final) { // Log every 1 second if (millis() - ota_progress_millis > 1000) { ota_progress_millis = millis(); -#ifdef DEBUG_VIA_USB - Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final); +#endif // DEBUG_LOG // Reset the "watchdog" ota_timeout_timer.reset(); } @@ -1081,13 +1141,13 @@ void onOTAEnd(bool success) { // Max Charge/Discharge = 0; CAN = stop; contactors = open setBatteryPause(true, true, true, false); // a reboot will be done by the OTA library. no need to do anything here -#ifdef DEBUG_VIA_USB - Serial.println("OTA update finished successfully!"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("OTA update finished successfully!"); +#endif // DEBUG_LOG } else { -#ifdef DEBUG_VIA_USB - Serial.println("There was an error during OTA update!"); -#endif // DEBUG_VIA_USB +#ifdef DEBUG_LOG + logging.println("There was an error during OTA update!"); +#endif // DEBUG_LOG //try to Resume the battery pause and CAN communication setBatteryPause(false, false); } diff --git a/Software/src/devboard/wifi/wifi.cpp b/Software/src/devboard/wifi/wifi.cpp index 91862e2a..3dba4b72 100644 --- a/Software/src/devboard/wifi/wifi.cpp +++ b/Software/src/devboard/wifi/wifi.cpp @@ -72,28 +72,28 @@ void wifi_monitor() { // Increase the current check interval if it's not at the maximum if (current_check_interval + STEP_WIFI_CHECK_INTERVAL <= MAX_STEP_WIFI_CHECK_INTERVAL) current_check_interval += STEP_WIFI_CHECK_INTERVAL; -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi not connected, attempting to reconnect..."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi not connected, attempting to reconnect..."); #endif // Try WiFi.reconnect() if it was successfully connected at least once if (hasConnectedBefore) { lastReconnectAttempt = millis(); // Reset reconnection attempt timer -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi reconnect attempt..."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi reconnect attempt..."); #endif if (WiFi.reconnect()) { -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi reconnect attempt sucess..."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi reconnect attempt sucess..."); #endif reconnectAttempts = 0; // Reset the attempt counter on successful reconnect } else { -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi reconnect attempt error..."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi reconnect attempt error..."); #endif reconnectAttempts++; if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) { -#ifdef DEBUG_VIA_USB - Serial.println("Failed to reconnect multiple times, forcing a full connection attempt..."); +#ifdef DEBUG_LOG + logging.println("Failed to reconnect multiple times, forcing a full connection attempt..."); #endif FullReconnectToWiFi(); } @@ -101,8 +101,8 @@ void wifi_monitor() { } else { // If no previous connection, force a full connection attempt if (currentMillis - lastReconnectAttempt > current_full_reconnect_interval) { -#ifdef DEBUG_VIA_USB - Serial.println("No previous OK connection, force a full connection attempt..."); +#ifdef DEBUG_LOG + logging.println("No previous OK connection, force a full connection attempt..."); #endif FullReconnectToWiFi(); } @@ -127,13 +127,13 @@ static void FullReconnectToWiFi() { static void connectToWiFi() { if (WiFi.status() != WL_CONNECTED) { lastReconnectAttempt = millis(); // Reset the reconnect attempt timer -#ifdef DEBUG_VIA_USB - Serial.println("Connecting to Wi-Fi..."); +#ifdef DEBUG_LOG + logging.println("Connecting to Wi-Fi..."); #endif WiFi.begin(ssid.c_str(), password.c_str(), wifi_channel); } else { -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi already connected."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi already connected."); #endif } } @@ -143,10 +143,11 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) { clear_event(EVENT_WIFI_DISCONNECT); set_event(EVENT_WIFI_CONNECT, 0); connected_once = true; -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi connected."); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); +#ifdef DEBUG_LOG + logging.print("Wi-Fi connected. RSSI: "); + logging.print(-WiFi.RSSI()); + logging.print(" dBm, IP address: "); + logging.println(WiFi.localIP().toString()); #endif hasConnectedBefore = true; // Mark as successfully connected at least once reconnectAttempts = 0; // Reset the attempt counter @@ -159,10 +160,10 @@ static void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) { static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { //clear disconnects events if we got a IP clear_event(EVENT_WIFI_DISCONNECT); -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi Got IP."); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); +#ifdef DEBUG_LOG + logging.print("Wi-Fi Got IP. "); + logging.print("IP address: "); + logging.println(WiFi.localIP().toString()); #endif } @@ -170,8 +171,8 @@ static void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { static void onWifiDisconnect(WiFiEvent_t event, WiFiEventInfo_t info) { if (connected_once) set_event(EVENT_WIFI_DISCONNECT, 0); -#ifdef DEBUG_VIA_USB - Serial.println("Wi-Fi disconnected."); +#ifdef DEBUG_LOG + logging.println("Wi-Fi disconnected."); #endif //we dont do anything here, the reconnect will be handled by the monitor //too many events received when the connection is lost @@ -188,8 +189,8 @@ void init_mDNS() { // Initialize mDNS .local resolution if (!MDNS.begin(mdnsHost)) { -#ifdef DEBUG_VIA_USB - Serial.println("Error setting up MDNS responder!"); +#ifdef DEBUG_LOG + logging.println("Error setting up MDNS responder!"); #endif } else { // Advertise via bonjour the service so we can auto discover these battery emulators on the local network. @@ -200,16 +201,16 @@ void init_mDNS() { #ifdef WIFIAP void init_WiFi_AP() { -#ifdef DEBUG_VIA_USB - Serial.println("Creating Access Point: " + String(ssidAP)); - Serial.println("With password: " + String(passwordAP)); +#ifdef DEBUG_LOG + logging.println("Creating Access Point: " + String(ssidAP)); + logging.println("With password: " + String(passwordAP)); #endif WiFi.softAP(ssidAP, passwordAP); IPAddress IP = WiFi.softAPIP(); -#ifdef DEBUG_VIA_USB - Serial.println("Access Point created."); - Serial.print("IP address: "); - Serial.println(IP); +#ifdef DEBUG_LOG + logging.println("Access Point created."); + logging.print("IP address: "); + logging.println(IP); #endif } #endif // WIFIAP diff --git a/Software/src/include.h b/Software/src/include.h index 5d5520d8..c8ae60df 100644 --- a/Software/src/include.h +++ b/Software/src/include.h @@ -9,6 +9,7 @@ #include "devboard/hal/hal.h" #include "devboard/safety/safety.h" +#include "devboard/utils/logging.h" #include "devboard/utils/time_meas.h" #include "devboard/utils/types.h" diff --git a/Software/src/inverter/BYD-CAN.cpp b/Software/src/inverter/BYD-CAN.cpp index d7a4028f..6d558edb 100644 --- a/Software/src/inverter/BYD-CAN.cpp +++ b/Software/src/inverter/BYD-CAN.cpp @@ -153,13 +153,13 @@ void update_values_can_inverter() { //This function maps all the values fetched BYD_210.data.u8[2] = (datalayer.battery.status.temperature_min_dC >> 8); BYD_210.data.u8[3] = (datalayer.battery.status.temperature_min_dC & 0x00FF); -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG if (inverter_name[0] != 0) { - Serial.print("Detected inverter: "); + logging.print("Detected inverter: "); for (uint8_t i = 0; i < 7; i++) { - Serial.print((char)inverter_name[i]); + logging.print((char)inverter_name[i]); } - Serial.println(); + logging.println(); } #endif } diff --git a/Software/src/inverter/FOXESS-CAN.cpp b/Software/src/inverter/FOXESS-CAN.cpp index e23f9006..9522a6a0 100644 --- a/Software/src/inverter/FOXESS-CAN.cpp +++ b/Software/src/inverter/FOXESS-CAN.cpp @@ -595,8 +595,8 @@ void send_can_inverter() { // This function loops as fast as possible // Send a subset of messages per iteration to avoid overloading the CAN bus / transmit buffer switch (can_message_cellvolt_index) { case 0: -#ifdef DEBUG_VIA_USB - Serial.println("Sending large batch"); +#ifdef DEBUG_LOG + logging.println("Sending large batch"); #endif transmit_can(&FOXESS_0C1D, can_config.inverter); transmit_can(&FOXESS_0C21, can_config.inverter); @@ -655,8 +655,8 @@ void send_can_inverter() { // This function loops as fast as possible transmit_can(&FOXESS_0D49, can_config.inverter); transmit_can(&FOXESS_0D51, can_config.inverter); transmit_can(&FOXESS_0D59, can_config.inverter); -#ifdef DEBUG_VIA_USB - Serial.println("Sending completed"); +#ifdef DEBUG_LOG + logging.println("Sending completed"); #endif send_cellvoltages = false; break; @@ -679,14 +679,14 @@ void receive_can_inverter(CAN_frame rx_frame) { if (rx_frame.data.u8[0] == 0x03) { //0x1871 [0x03, 0x06, 0x17, 0x05, 0x09, 0x09, 0x28, 0x22] //This message is sent by the inverter every '6' seconds (0.5s after the pack serial numbers) //and contains a timestamp in bytes 2-7 i.e. ,,
,,, -#ifdef DEBUG_VIA_USB - Serial.println("Inverter sends current time and date"); +#ifdef DEBUG_LOG + logging.println("Inverter sends current time and date"); #endif } else if (rx_frame.data.u8[0] == 0x01) { if (rx_frame.data.u8[4] == 0x00) { // Inverter wants to know bms info (every 1s) -#ifdef DEBUG_VIA_USB - Serial.println("Inverter requests 1s BMS info, we reply"); +#ifdef DEBUG_LOG + logging.println("Inverter requests 1s BMS info, we reply"); #endif transmit_can(&FOXESS_1872, can_config.inverter); transmit_can(&FOXESS_1873, can_config.inverter); @@ -698,8 +698,8 @@ void receive_can_inverter(CAN_frame rx_frame) { transmit_can(&FOXESS_1879, can_config.inverter); } else if (rx_frame.data.u8[4] == 0x01) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00] //Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply) -#ifdef DEBUG_VIA_USB - Serial.println("Inverter requests individual battery pack status, we reply"); +#ifdef DEBUG_LOG + logging.println("Inverter requests individual battery pack status, we reply"); #endif transmit_can(&FOXESS_0C05, can_config.inverter); //TODO, should we limit this incase NUMBER_OF_PACKS =! 8? transmit_can(&FOXESS_0C06, can_config.inverter); @@ -711,19 +711,19 @@ void receive_can_inverter(CAN_frame rx_frame) { transmit_can(&FOXESS_0C0C, can_config.inverter); } else if (rx_frame.data.u8[4] == 0x04) { // b4 0x01 , 0x1871 [0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00] //Inverter wants to know all individual cellvoltages (occurs 6 seconds after valid BMS reply) -#ifdef DEBUG_VIA_USB - Serial.println("Inverter requests cellvoltages and temps, we reply"); +#ifdef DEBUG_LOG + logging.println("Inverter requests cellvoltages and temps, we reply"); #endif send_cellvoltages = true; } } else if (rx_frame.data.u8[0] == 0x02) { //0x1871 [0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00] // Ack message -#ifdef DEBUG_VIA_USB - Serial.println("Inverter acks, no reply needed"); +#ifdef DEBUG_LOG + logging.println("Inverter acks, no reply needed"); #endif } else if (rx_frame.data.u8[0] == 0x05) { //0x1871 [0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00] -#ifdef DEBUG_VIA_USB - Serial.println("Inverter wants to know serial numbers, we reply"); +#ifdef DEBUG_LOG + logging.println("Inverter wants to know serial numbers, we reply"); #endif for (uint8_t i = 0; i < (NUMBER_OF_PACKS + 1); i++) { FOXESS_1881.data.u8[0] = (uint8_t)i; diff --git a/Software/src/inverter/KOSTAL-RS485.cpp b/Software/src/inverter/KOSTAL-RS485.cpp index 7df23ff1..fc45c1b9 100644 --- a/Software/src/inverter/KOSTAL-RS485.cpp +++ b/Software/src/inverter/KOSTAL-RS485.cpp @@ -119,15 +119,15 @@ void float2frameMSB(byte* arr, float value, byte framepointer) { void send_kostal(byte* arr, int alen) { #ifdef DEBUG_KOSTAL_RS485_DATA - Serial.print("TX: "); + logging.print("TX: "); for (int i = 0; i < alen; i++) { if (arr[i] < 0x10) { - Serial.print("0"); + logging.print("0"); } - Serial.print(arr[i], HEX); - Serial.print(" "); + logging.print(arr[i], HEX); + logging.print(" "); } - Serial.println("\n"); + logging.println("\n"); #endif Serial2.write(arr, alen); } @@ -274,12 +274,12 @@ void receive_RS485() // Runs as fast as possible to handle the serial stream if (RS485_RXFRAME[rx_index - 1] == 0x00) { if ((rx_index == 10) && (RS485_RXFRAME[0] == 0x09) && register_content_ok) { #ifdef DEBUG_KOSTAL_RS485_DATA - Serial.print("RX: "); + logging.print("RX: "); for (uint8_t i = 0; i < 10; i++) { - Serial.print(RS485_RXFRAME[i], HEX); - Serial.print(" "); + logging.print(RS485_RXFRAME[i], HEX); + logging.print(" "); } - Serial.println(""); + logging.println(""); #endif rx_index = 0; if (check_kostal_frame_crc()) { diff --git a/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp b/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp index a61ea7dc..35772e4a 100644 --- a/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp +++ b/Software/src/inverter/SERIAL-LINK-TRANSMITTER-INVERTER.cpp @@ -60,8 +60,8 @@ void manageSerialLinkTransmitter() { } bool sendError = dataLinkTransmit.checkTransmissionError(true); if (sendError) { - Serial.print(currentTime); - Serial.println(" - ERROR: Serial Data Link - SEND Error"); + logging.print(currentTime); + logging.println(" - ERROR: Serial Data Link - SEND Error"); lasterror = true; transmitGoodSince = currentTime; } @@ -82,17 +82,17 @@ void manageSerialLinkTransmitter() { if (lasterror && (ackReceived > 0)) { lasterror = false; - Serial.print(currentTime); - Serial.println(" - RECOVERY: Serial Data Link - Send GOOD"); + logging.print(currentTime); + logging.println(" - RECOVERY: Serial Data Link - Send GOOD"); } //--- reporting every 60 seconds that transmission is good if (currentTime - transmitGoodSince > INTERVAL_60_S) { transmitGoodSince = currentTime; - Serial.print(currentTime); - Serial.println(" - Transmit Good"); + logging.print(currentTime); + logging.println(" - Transmit Good"); // printUsefullData(); -#ifdef DEBUG_VIA_USB +#ifdef DEBUG_LOG void printSendingValues(); #endif } @@ -100,13 +100,13 @@ void manageSerialLinkTransmitter() { //--- report that Errors been ocurring for > 60 seconds if (currentTime - lastGood > INTERVAL_60_S) { lastGood = currentTime; - Serial.print(currentTime); - Serial.println(" - Transmit Failed : 60 seconds"); + logging.print(currentTime); + logging.println(" - Transmit Failed : 60 seconds"); // print the max_ data - Serial.println("SerialDataLink : bms_status=4"); - Serial.println("SerialDataLink : LEDcolor = RED"); - Serial.println("SerialDataLink : max_target_discharge_power = 0"); - Serial.println("SerialDataLink : max_target_charge_power = 0"); + logging.println("SerialDataLink : bms_status=4"); + logging.println("SerialDataLink : LEDcolor = RED"); + logging.println("SerialDataLink : max_target_discharge_power = 0"); + logging.println("SerialDataLink : max_target_charge_power = 0"); datalayer.battery.status.max_discharge_power_W = 0; datalayer.battery.status.max_charge_power_W = 0; @@ -117,8 +117,8 @@ void manageSerialLinkTransmitter() { // lastMessageReceived from CAN bus (Battery) if (currentTime - lastMessageReceived > (5 * 60000) ) // 5 minutes { - Serial.print(millis()); - Serial.println(" - Data Stale : 5 minutes"); + logging.print(millis()); + logging.println(" - Data Stale : 5 minutes"); // throw error // stop transmitting until fresh @@ -154,42 +154,42 @@ void manageSerialLinkTransmitter() { } void printSendingValues() { - Serial.println("Values from battery: "); - Serial.print("SOC: "); - Serial.print(datalayer.battery.status.real_soc); - Serial.print(" SOH: "); - Serial.print(datalayer.battery.status.soh_pptt); - Serial.print(" Voltage: "); - Serial.print(datalayer.battery.status.voltage_dV); - Serial.print(" Current: "); - Serial.print(datalayer.battery.status.current_dA); - Serial.print(" Capacity: "); - Serial.print(datalayer.battery.info.total_capacity_Wh); - Serial.print(" Remain cap: "); - Serial.print(datalayer.battery.status.remaining_capacity_Wh); - Serial.print(" Max discharge W: "); - Serial.print(datalayer.battery.status.max_discharge_power_W); - Serial.print(" Max charge W: "); - Serial.print(datalayer.battery.status.max_charge_power_W); - Serial.print(" BMS status: "); - Serial.print(datalayer.battery.status.bms_status); - Serial.print(" Power: "); - Serial.print(datalayer.battery.status.active_power_W); - Serial.print(" Temp min: "); - Serial.print(datalayer.battery.status.temperature_min_dC); - Serial.print(" Temp max: "); - Serial.print(datalayer.battery.status.temperature_max_dC); - Serial.print(" Cell max: "); - Serial.print(datalayer.battery.status.cell_max_voltage_mV); - Serial.print(" Cell min: "); - Serial.print(datalayer.battery.status.cell_min_voltage_mV); - Serial.print(" LFP : "); - Serial.print(datalayer.battery.info.chemistry); - Serial.print(" Battery Allows Contactor Closing: "); - Serial.print(datalayer.system.status.battery_allows_contactor_closing); - Serial.print(" Inverter Allows Contactor Closing: "); - Serial.print(datalayer.system.status.inverter_allows_contactor_closing); + logging.println("Values from battery: "); + logging.print("SOC: "); + logging.print(datalayer.battery.status.real_soc); + logging.print(" SOH: "); + logging.print(datalayer.battery.status.soh_pptt); + logging.print(" Voltage: "); + logging.print(datalayer.battery.status.voltage_dV); + logging.print(" Current: "); + logging.print(datalayer.battery.status.current_dA); + logging.print(" Capacity: "); + logging.print(datalayer.battery.info.total_capacity_Wh); + logging.print(" Remain cap: "); + logging.print(datalayer.battery.status.remaining_capacity_Wh); + logging.print(" Max discharge W: "); + logging.print(datalayer.battery.status.max_discharge_power_W); + logging.print(" Max charge W: "); + logging.print(datalayer.battery.status.max_charge_power_W); + logging.print(" BMS status: "); + logging.print(datalayer.battery.status.bms_status); + logging.print(" Power: "); + logging.print(datalayer.battery.status.active_power_W); + logging.print(" Temp min: "); + logging.print(datalayer.battery.status.temperature_min_dC); + logging.print(" Temp max: "); + logging.print(datalayer.battery.status.temperature_max_dC); + logging.print(" Cell max: "); + logging.print(datalayer.battery.status.cell_max_voltage_mV); + logging.print(" Cell min: "); + logging.print(datalayer.battery.status.cell_min_voltage_mV); + logging.print(" LFP : "); + logging.print(datalayer.battery.info.chemistry); + logging.print(" Battery Allows Contactor Closing: "); + logging.print(datalayer.system.status.battery_allows_contactor_closing); + logging.print(" Inverter Allows Contactor Closing: "); + logging.print(datalayer.system.status.inverter_allows_contactor_closing); - Serial.println(""); + logging.println(""); } #endif diff --git a/Software/src/inverter/SOLAX-CAN.cpp b/Software/src/inverter/SOLAX-CAN.cpp index da036517..60f684b9 100644 --- a/Software/src/inverter/SOLAX-CAN.cpp +++ b/Software/src/inverter/SOLAX-CAN.cpp @@ -207,8 +207,8 @@ void receive_can_inverter(CAN_frame rx_frame) { LastFrameTime = millis(); switch (STATE) { case (BATTERY_ANNOUNCE): -#ifdef DEBUG_VIA_USB - Serial.println("Solax Battery State: Announce"); +#ifdef DEBUG_LOG + logging.println("Solax Battery State: Announce"); #endif datalayer.system.status.inverter_allows_contactor_closing = false; SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on. @@ -239,8 +239,8 @@ void receive_can_inverter(CAN_frame rx_frame) { transmit_can(&SOLAX_1878, can_config.inverter); transmit_can(&SOLAX_1801, can_config.inverter); // Announce that the battery will be connected STATE = CONTACTOR_CLOSED; // Jump to Contactor Closed State -#ifdef DEBUG_VIA_USB - Serial.println("Solax Battery State: Contactor Closed"); +#ifdef DEBUG_LOG + logging.println("Solax Battery State: Contactor Closed"); #endif break; @@ -267,13 +267,13 @@ void receive_can_inverter(CAN_frame rx_frame) { if (rx_frame.ID == 0x1871 && rx_frame.data.u64 == __builtin_bswap64(0x0500010000000000)) { transmit_can(&SOLAX_1881, can_config.inverter); transmit_can(&SOLAX_1882, can_config.inverter); -#ifdef DEBUG_VIA_USB - Serial.println("1871 05-frame received from inverter"); +#ifdef DEBUG_LOG + logging.println("1871 05-frame received from inverter"); #endif } if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x03)) { -#ifdef DEBUG_VIA_USB - Serial.println("1871 03-frame received from inverter"); +#ifdef DEBUG_LOG + logging.println("1871 03-frame received from inverter"); #endif } } From ce2b714d30699b4570aa02b45ed74e13ad146972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Dec 2024 15:35:38 +0200 Subject: [PATCH 36/93] Restore Async lib, implement Mutex locking --- README.md | 2 +- Software/USER_SETTINGS.h | 6 +- Software/src/devboard/webserver/webserver.h | 2 +- .../ayushsharma82-ElegantOTA/src/ElegantOTA.h | 2 +- .../mathieucarbou-AsyncTCP/CODE_OF_CONDUCT.md | 129 -- .../src/lib/mathieucarbou-AsyncTCP/README.md | 62 - .../lib/mathieucarbou-AsyncTCP/library.json | 38 - .../mathieucarbou-AsyncTCP/library.properties | 10 - .../lib/mathieucarbou-AsyncTCP/platformio.ini | 43 - .../mathieucarbou-AsyncTCP/src/AsyncTCP.cpp | 1661 ----------------- .../lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h | 347 ---- .../src/lib/me-no-dev-AsyncTCP/.gitignore | 2 + .../src/lib/me-no-dev-AsyncTCP/.travis.yml | 34 + .../CMakeLists.txt | 0 .../lib/me-no-dev-AsyncTCP/Kconfig.projbuild | 30 + .../LICENSE | 0 Software/src/lib/me-no-dev-AsyncTCP/README.md | 15 + .../component.mk | 0 .../src/lib/me-no-dev-AsyncTCP/library.json | 22 + .../lib/me-no-dev-AsyncTCP/library.properties | 9 + .../lib/me-no-dev-AsyncTCP/src/AsyncTCP.cpp | 1387 ++++++++++++++ .../src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.h | 220 +++ .../src/AsyncEventSource.h | 2 +- .../src/AsyncWebSocket.h | 2 +- .../src/ESPAsyncWebServer.h | 4 +- 25 files changed, 1729 insertions(+), 2300 deletions(-) delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/CODE_OF_CONDUCT.md delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/README.md delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/library.json delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/library.properties delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/platformio.ini delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.cpp delete mode 100644 Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/.gitignore create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/.travis.yml rename Software/src/lib/{mathieucarbou-AsyncTCP => me-no-dev-AsyncTCP}/CMakeLists.txt (100%) create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/Kconfig.projbuild rename Software/src/lib/{mathieucarbou-AsyncTCP => me-no-dev-AsyncTCP}/LICENSE (100%) create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/README.md rename Software/src/lib/{mathieucarbou-AsyncTCP => me-no-dev-AsyncTCP}/component.mk (100%) create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/library.json create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/library.properties create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.cpp create mode 100644 Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.h diff --git a/README.md b/README.md index c2d9630c..3d86f120 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ This code uses the following excellent libraries: - [eModbus/eModbus](https://github.com/eModbus/eModbus) MIT-License - [knolleary/pubsubclient](https://github.com/knolleary/pubsubclient) MIT-License - [mackelec/SerialDataLink](https://github.com/mackelec/SerialDataLink) -- [mathieucarbou/AsyncTCP](https://github.com/mathieucarbou/AsyncTCP) LGPL-3.0 license +- [me-no-dev/AsyncTCP](https://github.com/me-no-dev/AsyncTCP) LGPL-3.0 license - [me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) - [miwagner/ESP32-Arduino-CAN](https://github.com/miwagner/ESP32-Arduino-CAN/) MIT-License - [pierremolinaro/acan2515](https://github.com/pierremolinaro/acan2515) MIT-License diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 2cefdb7a..90cb37f7 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -33,7 +33,7 @@ //#define TESLA_MODEL_3Y_BATTERY //#define TESLA_MODEL_SX_BATTERY //#define VOLVO_SPA_BATTERY -//#define TEST_FAKE_BATTERY +#define TEST_FAKE_BATTERY //#define DOUBLE_BATTERY //Enable this line if you use two identical batteries at the same time (requires CAN_ADDON setup) /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ @@ -53,8 +53,8 @@ //#define SOLAX_CAN //Enable this line to emulate a "SolaX Triple Power LFP" over CAN bus /* Select hardware used for Battery-Emulator */ -#define HW_LILYGO -//#define HW_STARK +//#define HW_LILYGO +#define HW_STARK //#define HW_3LB /* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */ diff --git a/Software/src/devboard/webserver/webserver.h b/Software/src/devboard/webserver/webserver.h index 86b5a763..a75ef8fb 100644 --- a/Software/src/devboard/webserver/webserver.h +++ b/Software/src/devboard/webserver/webserver.h @@ -6,7 +6,7 @@ #include "../../include.h" #include "../../lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h" #include "../../lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h" -#include "../../lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h" +#include "../../lib/me-no-dev-AsyncTCP/src/AsyncTCP.h" #include "../../lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h" #include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" diff --git a/Software/src/lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h b/Software/src/lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h index 48833d99..f8770a07 100644 --- a/Software/src/lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h +++ b/Software/src/lib/ayushsharma82-ElegantOTA/src/ElegantOTA.h @@ -64,7 +64,7 @@ _____ _ _ ___ _____ _ #include "Update.h" #include "StreamString.h" #if ELEGANTOTA_USE_ASYNC_WEBSERVER == 1 - #include "../../mathieucarbou-AsyncTCP/src/AsyncTCP.h" + #include "../../me-no-dev-AsyncTCP/src/AsyncTCP.h" #include "../../me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h" #define ELEGANTOTA_WEBSERVER AsyncWebServer #else diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/CODE_OF_CONDUCT.md b/Software/src/lib/mathieucarbou-AsyncTCP/CODE_OF_CONDUCT.md deleted file mode 100644 index 0a5f9141..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,129 +0,0 @@ - -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -https://sidweb.nl/cms3/en/contact. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/README.md b/Software/src/lib/mathieucarbou-AsyncTCP/README.md deleted file mode 100644 index d90814a1..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# AsyncTCP - -[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) -[![Continuous Integration](https://github.com/mathieucarbou/AsyncTCP/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/AsyncTCP/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/AsyncTCP.svg)](https://registry.platformio.org/libraries/mathieucarbou/AsyncTCP) - -A fork of the [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) library by [@me-no-dev](https://github.com/me-no-dev). - -### Async TCP Library for ESP32 Arduino - -This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs. - -This library is the base for [ESPAsyncWebServer](https://github.com/mathieucarbou/ESPAsyncWebServer) - -## AsyncClient and AsyncServer - -The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use. - -## Changes in this fork - -- Based on [ESPHome fork](https://github.com/esphome/AsyncTCP) - -- `library.properties` for Arduino IDE users -- Add `CONFIG_ASYNC_TCP_MAX_ACK_TIME` -- Add `CONFIG_ASYNC_TCP_PRIORITY` -- Add `CONFIG_ASYNC_TCP_QUEUE_SIZE` -- Add `setKeepAlive()` -- Arduino 3 / ESP-IDF 5 compatibility -- Better CI -- Better example -- Customizable macros -- Fix for "Required to lock TCPIP core functionality". Ref: https://github.com/mathieucarbou/AsyncTCP/issues/27 and https://github.com/espressif/arduino-esp32/issues/10526 -- Fix for "ack timeout 4" client disconnects. -- Fix from https://github.com/me-no-dev/AsyncTCP/pull/173 (partially applied) -- Fix from https://github.com/me-no-dev/AsyncTCP/pull/184 -- IPv6 -- LIBRETINY support -- LibreTuya -- Reduce logging of non critical messages -- Use IPADDR6_INIT() macro to set connecting IPv6 address -- xTaskCreateUniversal function - -## Coordinates - -``` -mathieucarbou/AsyncTCP @ ^3.3.1 -``` - -## Important recommendations - -Most of the crashes are caused by improper configuration of the library for the project. -Here are some recommendations to avoid them. - -I personally use the following configuration in my projects: - -```c++ - -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 // (keep default) - -D CONFIG_ASYNC_TCP_PRIORITY=10 // (keep default) - -D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 // (keep default) - -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 // force async_tcp task to be on same core as the app (default is core 0) - -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K) -``` diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/library.json b/Software/src/lib/mathieucarbou-AsyncTCP/library.json deleted file mode 100644 index 5d6e228b..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/library.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "AsyncTCP", - "version": "3.3.1", - "description": "Asynchronous TCP Library for ESP32", - "keywords": "async,tcp", - "repository": { - "type": "git", - "url": "https://github.com/mathieucarbou/AsyncTCP.git" - }, - "authors": [ - { - "name": "Hristo Gochkov" - }, - { - "name": "Mathieu Carbou", - "maintainer": true - } - ], - "license": "LGPL-3.0", - "frameworks": "arduino", - "platforms": [ - "espressif32", - "libretiny" - ], - "build": { - "libCompatMode": 2 - }, - "export": { - "include": [ - "examples", - "src", - "library.json", - "library.properties", - "LICENSE", - "README.md" - ] - } -} \ No newline at end of file diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/library.properties b/Software/src/lib/mathieucarbou-AsyncTCP/library.properties deleted file mode 100644 index dd945f8d..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Async TCP -includes=AsyncTCP.h -version=3.3.1 -author=Me-No-Dev -maintainer=Mathieu Carbou -sentence=Async TCP Library for ESP32 -paragraph=Async TCP Library for ESP32 -category=Other -url=https://github.com/mathieucarbou/AsyncTCP.git -architectures=* diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/platformio.ini b/Software/src/lib/mathieucarbou-AsyncTCP/platformio.ini deleted file mode 100644 index ec65a367..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/platformio.ini +++ /dev/null @@ -1,43 +0,0 @@ -[platformio] -default_envs = arduino-2, arduino-3, arduino-310 -lib_dir = . -src_dir = examples/Client - -[env] -framework = arduino -build_flags = - -Wall -Wextra - -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 - -D CONFIG_ASYNC_TCP_PRIORITY=10 - -D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 - -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 - -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 - -D CONFIG_ARDUHAL_LOG_COLORS - -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -upload_protocol = esptool -monitor_speed = 115200 -monitor_filters = esp32_exception_decoder, log2file -board = esp32dev - -[env:arduino-2] -platform = espressif32@6.9.0 - -[env:arduino-3] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip - -[env:arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip - -; CI - -[env:ci-arduino-2] -platform = espressif32@6.9.0 -board = ${sysenv.PIO_BOARD} - -[env:ci-arduino-3] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip -board = ${sysenv.PIO_BOARD} - -[env:ci-arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip -board = ${sysenv.PIO_BOARD} diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.cpp b/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.cpp deleted file mode 100644 index 9addb135..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.cpp +++ /dev/null @@ -1,1661 +0,0 @@ -/* - Asynchronous TCP library for Espressif MCUs - - Copyright (c) 2016 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "Arduino.h" - -#include "AsyncTCP.h" - -extern "C" { -#include "lwip/dns.h" -#include "lwip/err.h" -#include "lwip/inet.h" -#include "lwip/opt.h" -#include "lwip/tcp.h" -} - -#if CONFIG_ASYNC_TCP_USE_WDT - #include "esp_task_wdt.h" -#endif - -// Required for: -// https://github.com/espressif/arduino-esp32/blob/3.0.3/libraries/Network/src/NetworkInterface.cpp#L37-L47 -#if ESP_IDF_VERSION_MAJOR >= 5 - #include -#endif - -#define TAG "AsyncTCP" - -// https://github.com/espressif/arduino-esp32/issues/10526 -#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING - #define TCP_MUTEX_LOCK() \ - if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \ - LOCK_TCPIP_CORE(); \ - } - - #define TCP_MUTEX_UNLOCK() \ - if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \ - UNLOCK_TCPIP_CORE(); \ - } -#else // CONFIG_LWIP_TCPIP_CORE_LOCKING - #define TCP_MUTEX_LOCK() - #define TCP_MUTEX_UNLOCK() -#endif // CONFIG_LWIP_TCPIP_CORE_LOCKING - -#define INVALID_CLOSED_SLOT -1 - -/* - TCP poll interval is specified in terms of the TCP coarse timer interval, which is called twice a second - https://github.com/espressif/esp-lwip/blob/2acf959a2bb559313cd2bf9306c24612ba3d0e19/src/core/tcp.c#L1895 -*/ -#define CONFIG_ASYNC_TCP_POLL_TIMER 1 - -/* - * TCP/IP Event Task - * */ - -typedef enum { - LWIP_TCP_SENT, - LWIP_TCP_RECV, - LWIP_TCP_FIN, - LWIP_TCP_ERROR, - LWIP_TCP_POLL, - LWIP_TCP_CLEAR, - LWIP_TCP_ACCEPT, - LWIP_TCP_CONNECTED, - LWIP_TCP_DNS -} lwip_event_t; - -typedef struct { - lwip_event_t event; - void* arg; - union { - struct { - tcp_pcb* pcb; - int8_t err; - } connected; - struct { - int8_t err; - } error; - struct { - tcp_pcb* pcb; - uint16_t len; - } sent; - struct { - tcp_pcb* pcb; - pbuf* pb; - int8_t err; - } recv; - struct { - tcp_pcb* pcb; - int8_t err; - } fin; - struct { - tcp_pcb* pcb; - } poll; - struct { - AsyncClient* client; - } accept; - struct { - const char* name; - ip_addr_t addr; - } dns; - }; -} lwip_event_packet_t; - -static QueueHandle_t _async_queue; -static TaskHandle_t _async_service_task_handle = NULL; - -SemaphoreHandle_t _slots_lock; -const int _number_of_closed_slots = CONFIG_LWIP_MAX_ACTIVE_TCP; -static uint32_t _closed_slots[_number_of_closed_slots]; -static uint32_t _closed_index = []() { - _slots_lock = xSemaphoreCreateBinary(); - xSemaphoreGive(_slots_lock); - for (int i = 0; i < _number_of_closed_slots; ++i) { - _closed_slots[i] = 1; - } - return 1; -}(); - -static inline bool _init_async_event_queue() { - if (!_async_queue) { - _async_queue = xQueueCreate(CONFIG_ASYNC_TCP_QUEUE_SIZE, sizeof(lwip_event_packet_t*)); - if (!_async_queue) { - return false; - } - } - return true; -} - -static inline bool _send_async_event(lwip_event_packet_t** e, TickType_t wait = portMAX_DELAY) { - return _async_queue && xQueueSend(_async_queue, e, wait) == pdPASS; -} - -static inline bool _prepend_async_event(lwip_event_packet_t** e, TickType_t wait = portMAX_DELAY) { - return _async_queue && xQueueSendToFront(_async_queue, e, wait) == pdPASS; -} - -static inline bool _get_async_event(lwip_event_packet_t** e) { - if (!_async_queue) { - return false; - } - -#if CONFIG_ASYNC_TCP_USE_WDT - // need to return periodically to feed the dog - if (xQueueReceive(_async_queue, e, pdMS_TO_TICKS(1000)) != pdPASS) - return false; -#else - if (xQueueReceive(_async_queue, e, portMAX_DELAY) != pdPASS) - return false; -#endif - - if ((*e)->event != LWIP_TCP_POLL) - return true; - - /* - Let's try to coalesce two (or more) consecutive poll events into one - this usually happens with poor implemented user-callbacks that are runs too long and makes poll events to stack in the queue - if consecutive user callback for a same connection runs longer that poll time then it will fill the queue with events until it deadlocks. - This is a workaround to mitigate such poor designs and won't let other events/connections to starve the task time. - It won't be effective if user would run multiple simultaneous long running callbacks due to message interleaving. - todo: implement some kind of fair dequeing or (better) simply punish user for a bad designed callbacks by resetting hog connections - */ - lwip_event_packet_t* next_pkt = NULL; - while (xQueuePeek(_async_queue, &next_pkt, 0) == pdPASS) { - if (next_pkt->arg == (*e)->arg && next_pkt->event == LWIP_TCP_POLL) { - if (xQueueReceive(_async_queue, &next_pkt, 0) == pdPASS) { - free(next_pkt); - next_pkt = NULL; - log_d("coalescing polls, network congestion or async callbacks might be too slow!"); - continue; - } - } - - // quit while loop if next event can't be discarded - break; - } - - /* - now we have to decide if to proceed with poll callback handler or discard it? - poor designed apps using asynctcp without proper dataflow control could flood the queue with interleaved pool/ack events. - I.e. on each poll app would try to generate more data to send, which in turn results in additional ack event triggering chain effect - for long connections. Or poll callback could take long time starving other connections. Anyway our goal is to keep the queue length - grows under control (if possible) and poll events are the safest to discard. - Let's discard poll events processing using linear-increasing probability curve when queue size grows over 3/4 - Poll events are periodic and connection could get another chance next time - */ - if (uxQueueMessagesWaiting(_async_queue) > (rand() % CONFIG_ASYNC_TCP_QUEUE_SIZE / 4 + CONFIG_ASYNC_TCP_QUEUE_SIZE * 3 / 4)) { - free(*e); - *e = NULL; - log_d("discarding poll due to queue congestion"); - // evict next event from a queue - return _get_async_event(e); - } - - // last resort return - return true; -} - -static bool _remove_events_with_arg(void* arg) { - if (!_async_queue) { - return false; - } - - lwip_event_packet_t* first_packet = NULL; - lwip_event_packet_t* packet = NULL; - - // figure out which is the first non-matching packet so we can keep the order - while (!first_packet) { - if (xQueueReceive(_async_queue, &first_packet, 0) != pdPASS) { - return false; - } - // discard packet if matching - if ((int)first_packet->arg == (int)arg) { - free(first_packet); - first_packet = NULL; - } else if (xQueueSend(_async_queue, &first_packet, 0) != pdPASS) { - // try to return first packet to the back of the queue - // we can't wait here if queue is full, because this call has been done from the only consumer task of this queue - // otherwise it would deadlock, we have to discard the event - free(first_packet); - first_packet = NULL; - return false; - } - } - - while (xQueuePeek(_async_queue, &packet, 0) == pdPASS && packet != first_packet) { - if (xQueueReceive(_async_queue, &packet, 0) != pdPASS) { - return false; - } - if ((int)packet->arg == (int)arg) { - // remove matching event - free(packet); - packet = NULL; - // otherwise try to requeue it - } else if (xQueueSend(_async_queue, &packet, 0) != pdPASS) { - // we can't wait here if queue is full, because this call has been done from the only consumer task of this queue - // otherwise it would deadlock, we have to discard the event - free(packet); - packet = NULL; - return false; - } - } - return true; -} - -static void _handle_async_event(lwip_event_packet_t* e) { - if (e->arg == NULL) { - // do nothing when arg is NULL - // ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb); - } else if (e->event == LWIP_TCP_CLEAR) { - _remove_events_with_arg(e->arg); - } else if (e->event == LWIP_TCP_RECV) { - // ets_printf("-R: 0x%08x\n", e->recv.pcb); - AsyncClient::_s_recv(e->arg, e->recv.pcb, e->recv.pb, e->recv.err); - } else if (e->event == LWIP_TCP_FIN) { - // ets_printf("-F: 0x%08x\n", e->fin.pcb); - AsyncClient::_s_fin(e->arg, e->fin.pcb, e->fin.err); - } else if (e->event == LWIP_TCP_SENT) { - // ets_printf("-S: 0x%08x\n", e->sent.pcb); - AsyncClient::_s_sent(e->arg, e->sent.pcb, e->sent.len); - } else if (e->event == LWIP_TCP_POLL) { - // ets_printf("-P: 0x%08x\n", e->poll.pcb); - AsyncClient::_s_poll(e->arg, e->poll.pcb); - } else if (e->event == LWIP_TCP_ERROR) { - // ets_printf("-E: 0x%08x %d\n", e->arg, e->error.err); - AsyncClient::_s_error(e->arg, e->error.err); - } else if (e->event == LWIP_TCP_CONNECTED) { - // ets_printf("C: 0x%08x 0x%08x %d\n", e->arg, e->connected.pcb, e->connected.err); - AsyncClient::_s_connected(e->arg, e->connected.pcb, e->connected.err); - } else if (e->event == LWIP_TCP_ACCEPT) { - // ets_printf("A: 0x%08x 0x%08x\n", e->arg, e->accept.client); - AsyncServer::_s_accepted(e->arg, e->accept.client); - } else if (e->event == LWIP_TCP_DNS) { - // ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr)); - AsyncClient::_s_dns_found(e->dns.name, &e->dns.addr, e->arg); - } - free((void*)(e)); -} - -static void _async_service_task(void* pvParameters) { -#if CONFIG_ASYNC_TCP_USE_WDT - if (esp_task_wdt_add(NULL) != ESP_OK) { - log_w("Failed to add async task to WDT"); - } -#endif - lwip_event_packet_t* packet = NULL; - for (;;) { - if (_get_async_event(&packet)) { - _handle_async_event(packet); - } -#if CONFIG_ASYNC_TCP_USE_WDT - esp_task_wdt_reset(); -#endif - } -#if CONFIG_ASYNC_TCP_USE_WDT - esp_task_wdt_delete(NULL); -#endif - vTaskDelete(NULL); - _async_service_task_handle = NULL; -} -/* -static void _stop_async_task(){ - if(_async_service_task_handle){ - vTaskDelete(_async_service_task_handle); - _async_service_task_handle = NULL; - } -} -*/ - -static bool customTaskCreateUniversal( - TaskFunction_t pxTaskCode, - const char* const pcName, - const uint32_t usStackDepth, - void* const pvParameters, - UBaseType_t uxPriority, - TaskHandle_t* const pxCreatedTask, - const BaseType_t xCoreID) { -#ifndef CONFIG_FREERTOS_UNICORE - if (xCoreID >= 0 && xCoreID < 2) { - return xTaskCreatePinnedToCore(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID); - } else { -#endif - return xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask); -#ifndef CONFIG_FREERTOS_UNICORE - } -#endif -} - -static bool _start_async_task() { - if (!_init_async_event_queue()) { - return false; - } - if (!_async_service_task_handle) { - customTaskCreateUniversal(_async_service_task, "async_tcp", CONFIG_ASYNC_TCP_STACK_SIZE, NULL, TASK_CONNECTIVITY_PRIO, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); - if (!_async_service_task_handle) { - return false; - } - } - return true; -} - -/* - * LwIP Callbacks - * */ - -static int8_t _tcp_clear_events(void* arg) { - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_CLEAR; - e->arg = arg; - if (!_prepend_async_event(&e)) { - free((void*)(e)); - } - return ERR_OK; -} - -static int8_t _tcp_connected(void* arg, tcp_pcb* pcb, int8_t err) { - // ets_printf("+C: 0x%08x\n", pcb); - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_CONNECTED; - e->arg = arg; - e->connected.pcb = pcb; - e->connected.err = err; - if (!_prepend_async_event(&e)) { - free((void*)(e)); - } - return ERR_OK; -} - -static int8_t _tcp_poll(void* arg, struct tcp_pcb* pcb) { - // throttle polling events queing when event queue is getting filled up, let it handle _onack's - // log_d("qs:%u", uxQueueMessagesWaiting(_async_queue)); - if (uxQueueMessagesWaiting(_async_queue) > (rand() % CONFIG_ASYNC_TCP_QUEUE_SIZE / 2 + CONFIG_ASYNC_TCP_QUEUE_SIZE / 4)) { - log_d("throttling"); - return ERR_OK; - } - - // ets_printf("+P: 0x%08x\n", pcb); - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_POLL; - e->arg = arg; - e->poll.pcb = pcb; - // poll events are not critical 'cause those are repetitive, so we may not wait the queue in any case - if (!_send_async_event(&e, 0)) { - free((void*)(e)); - } - return ERR_OK; -} - -static int8_t _tcp_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* pb, int8_t err) { - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->arg = arg; - if (pb) { - // ets_printf("+R: 0x%08x\n", pcb); - e->event = LWIP_TCP_RECV; - e->recv.pcb = pcb; - e->recv.pb = pb; - e->recv.err = err; - } else { - // ets_printf("+F: 0x%08x\n", pcb); - e->event = LWIP_TCP_FIN; - e->fin.pcb = pcb; - e->fin.err = err; - // close the PCB in LwIP thread - AsyncClient::_s_lwip_fin(e->arg, e->fin.pcb, e->fin.err); - } - if (!_send_async_event(&e)) { - free((void*)(e)); - } - return ERR_OK; -} - -static int8_t _tcp_sent(void* arg, struct tcp_pcb* pcb, uint16_t len) { - // ets_printf("+S: 0x%08x\n", pcb); - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_SENT; - e->arg = arg; - e->sent.pcb = pcb; - e->sent.len = len; - if (!_send_async_event(&e)) { - free((void*)(e)); - } - return ERR_OK; -} - -static void _tcp_error(void* arg, int8_t err) { - // ets_printf("+E: 0x%08x\n", arg); - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_ERROR; - e->arg = arg; - e->error.err = err; - if (!_send_async_event(&e)) { - free((void*)(e)); - } -} - -static void _tcp_dns_found(const char* name, struct ip_addr* ipaddr, void* arg) { - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - // ets_printf("+DNS: name=%s ipaddr=0x%08x arg=%x\n", name, ipaddr, arg); - e->event = LWIP_TCP_DNS; - e->arg = arg; - e->dns.name = name; - if (ipaddr) { - memcpy(&e->dns.addr, ipaddr, sizeof(struct ip_addr)); - } else { - memset(&e->dns.addr, 0, sizeof(e->dns.addr)); - } - if (!_send_async_event(&e)) { - free((void*)(e)); - } -} - -// Used to switch out from LwIP thread -static int8_t _tcp_accept(void* arg, AsyncClient* client) { - lwip_event_packet_t* e = (lwip_event_packet_t*)malloc(sizeof(lwip_event_packet_t)); - e->event = LWIP_TCP_ACCEPT; - e->arg = arg; - e->accept.client = client; - if (!_prepend_async_event(&e)) { - free((void*)(e)); - } - return ERR_OK; -} - -/* - * TCP/IP API Calls - * */ - -#include "lwip/priv/tcpip_priv.h" - -typedef struct { - struct tcpip_api_call_data call; - tcp_pcb* pcb; - int8_t closed_slot; - int8_t err; - union { - struct { - const char* data; - size_t size; - uint8_t apiflags; - } write; - size_t received; - struct { - ip_addr_t* addr; - uint16_t port; - tcp_connected_fn cb; - } connect; - struct { - ip_addr_t* addr; - uint16_t port; - } bind; - uint8_t backlog; - }; -} tcp_api_call_t; - -static err_t _tcp_output_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = ERR_CONN; - if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { - msg->err = tcp_output(msg->pcb); - } - return msg->err; -} - -static esp_err_t _tcp_output(tcp_pcb* pcb, int8_t closed_slot) { - if (!pcb) { - return ERR_CONN; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_write_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = ERR_CONN; - if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { - msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags); - } - return msg->err; -} - -static esp_err_t _tcp_write(tcp_pcb* pcb, int8_t closed_slot, const char* data, size_t size, uint8_t apiflags) { - if (!pcb) { - return ERR_CONN; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - msg.write.data = data; - msg.write.size = size; - msg.write.apiflags = apiflags; - tcpip_api_call(_tcp_write_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_recved_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = ERR_CONN; - if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { - // if(msg->closed_slot != INVALID_CLOSED_SLOT && !_closed_slots[msg->closed_slot]) { - // if(msg->closed_slot != INVALID_CLOSED_SLOT) { - msg->err = 0; - tcp_recved(msg->pcb, msg->received); - } - return msg->err; -} - -static esp_err_t _tcp_recved(tcp_pcb* pcb, int8_t closed_slot, size_t len) { - if (!pcb) { - return ERR_CONN; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - msg.received = len; - tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_close_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = ERR_CONN; - if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { - msg->err = tcp_close(msg->pcb); - } - return msg->err; -} - -static esp_err_t _tcp_close(tcp_pcb* pcb, int8_t closed_slot) { - if (!pcb) { - return ERR_CONN; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_abort_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = ERR_CONN; - if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { - tcp_abort(msg->pcb); - } - return msg->err; -} - -static esp_err_t _tcp_abort(tcp_pcb* pcb, int8_t closed_slot) { - if (!pcb) { - return ERR_CONN; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_connect_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = tcp_connect(msg->pcb, msg->connect.addr, msg->connect.port, msg->connect.cb); - return msg->err; -} - -static esp_err_t _tcp_connect(tcp_pcb* pcb, int8_t closed_slot, ip_addr_t* addr, uint16_t port, tcp_connected_fn cb) { - if (!pcb) { - return ESP_FAIL; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - msg.connect.addr = addr; - msg.connect.port = port; - msg.connect.cb = cb; - tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_bind_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = tcp_bind(msg->pcb, msg->bind.addr, msg->bind.port); - return msg->err; -} - -static esp_err_t _tcp_bind(tcp_pcb* pcb, ip_addr_t* addr, uint16_t port) { - if (!pcb) { - return ESP_FAIL; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = -1; - msg.bind.addr = addr; - msg.bind.port = port; - tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call_data*)&msg); - return msg.err; -} - -static err_t _tcp_listen_api(struct tcpip_api_call_data* api_call_msg) { - tcp_api_call_t* msg = (tcp_api_call_t*)api_call_msg; - msg->err = 0; - msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog); - return msg->err; -} - -static tcp_pcb* _tcp_listen_with_backlog(tcp_pcb* pcb, uint8_t backlog) { - if (!pcb) { - return NULL; - } - tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = -1; - msg.backlog = backlog ? backlog : 0xFF; - tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg); - return msg.pcb; -} - -/* - Async TCP Client - */ - -AsyncClient::AsyncClient(tcp_pcb* pcb) - : _connect_cb(0), _connect_cb_arg(0), _discard_cb(0), _discard_cb_arg(0), _sent_cb(0), _sent_cb_arg(0), _error_cb(0), _error_cb_arg(0), _recv_cb(0), _recv_cb_arg(0), _pb_cb(0), _pb_cb_arg(0), _timeout_cb(0), _timeout_cb_arg(0), _ack_pcb(true), _tx_last_packet(0), _rx_timeout(0), _rx_last_ack(0), _ack_timeout(CONFIG_ASYNC_TCP_MAX_ACK_TIME), _connect_port(0), prev(NULL), next(NULL) { - _pcb = pcb; - _closed_slot = INVALID_CLOSED_SLOT; - if (_pcb) { - _rx_last_packet = millis(); - tcp_arg(_pcb, this); - tcp_recv(_pcb, &_tcp_recv); - tcp_sent(_pcb, &_tcp_sent); - tcp_err(_pcb, &_tcp_error); - tcp_poll(_pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER); - if (!_allocate_closed_slot()) { - _close(); - } - } -} - -AsyncClient::~AsyncClient() { - if (_pcb) { - _close(); - } - _free_closed_slot(); -} - -/* - * Operators - * */ - -AsyncClient& AsyncClient::operator=(const AsyncClient& other) { - if (_pcb) { - _close(); - } - - _pcb = other._pcb; - _closed_slot = other._closed_slot; - if (_pcb) { - _rx_last_packet = millis(); - tcp_arg(_pcb, this); - tcp_recv(_pcb, &_tcp_recv); - tcp_sent(_pcb, &_tcp_sent); - tcp_err(_pcb, &_tcp_error); - tcp_poll(_pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER); - } - return *this; -} - -bool AsyncClient::operator==(const AsyncClient& other) { - return _pcb == other._pcb; -} - -AsyncClient& AsyncClient::operator+=(const AsyncClient& other) { - if (next == NULL) { - next = (AsyncClient*)(&other); - next->prev = this; - } else { - AsyncClient* c = next; - while (c->next != NULL) { - c = c->next; - } - c->next = (AsyncClient*)(&other); - c->next->prev = c; - } - return *this; -} - -/* - * Callback Setters - * */ - -void AsyncClient::onConnect(AcConnectHandler cb, void* arg) { - _connect_cb = cb; - _connect_cb_arg = arg; -} - -void AsyncClient::onDisconnect(AcConnectHandler cb, void* arg) { - _discard_cb = cb; - _discard_cb_arg = arg; -} - -void AsyncClient::onAck(AcAckHandler cb, void* arg) { - _sent_cb = cb; - _sent_cb_arg = arg; -} - -void AsyncClient::onError(AcErrorHandler cb, void* arg) { - _error_cb = cb; - _error_cb_arg = arg; -} - -void AsyncClient::onData(AcDataHandler cb, void* arg) { - _recv_cb = cb; - _recv_cb_arg = arg; -} - -void AsyncClient::onPacket(AcPacketHandler cb, void* arg) { - _pb_cb = cb; - _pb_cb_arg = arg; -} - -void AsyncClient::onTimeout(AcTimeoutHandler cb, void* arg) { - _timeout_cb = cb; - _timeout_cb_arg = arg; -} - -void AsyncClient::onPoll(AcConnectHandler cb, void* arg) { - _poll_cb = cb; - _poll_cb_arg = arg; -} - -/* - * Main Public Methods - * */ - -bool AsyncClient::_connect(ip_addr_t addr, uint16_t port) { - if (_pcb) { - log_d("already connected, state %d", _pcb->state); - return false; - } - if (!_start_async_task()) { - log_e("failed to start task"); - return false; - } - - if (!_allocate_closed_slot()) { - log_e("failed to allocate: closed slot full"); - return false; - } - - TCP_MUTEX_LOCK(); - tcp_pcb* pcb = tcp_new_ip_type(addr.type); - if (!pcb) { - TCP_MUTEX_UNLOCK(); - log_e("pcb == NULL"); - return false; - } - tcp_arg(pcb, this); - tcp_err(pcb, &_tcp_error); - tcp_recv(pcb, &_tcp_recv); - tcp_sent(pcb, &_tcp_sent); - tcp_poll(pcb, &_tcp_poll, CONFIG_ASYNC_TCP_POLL_TIMER); - TCP_MUTEX_UNLOCK(); - - esp_err_t err = _tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected); - return err == ESP_OK; -} - -bool AsyncClient::connect(const IPAddress& ip, uint16_t port) { - ip_addr_t addr; -#if ESP_IDF_VERSION_MAJOR < 5 - addr.u_addr.ip4.addr = ip; - addr.type = IPADDR_TYPE_V4; -#else - ip.to_ip_addr_t(&addr); -#endif - - return _connect(addr, port); -} - -#if LWIP_IPV6 && ESP_IDF_VERSION_MAJOR < 5 -bool AsyncClient::connect(const IPv6Address& ip, uint16_t port) { - auto ipaddr = static_cast(ip); - ip_addr_t addr = IPADDR6_INIT(ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); - - return _connect(addr, port); -} -#endif - -bool AsyncClient::connect(const char* host, uint16_t port) { - ip_addr_t addr; - - if (!_start_async_task()) { - log_e("failed to start task"); - return false; - } - - TCP_MUTEX_LOCK(); - err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this); - TCP_MUTEX_UNLOCK(); - if (err == ERR_OK) { -#if ESP_IDF_VERSION_MAJOR < 5 - #if LWIP_IPV6 - if (addr.type == IPADDR_TYPE_V6) { - return connect(IPv6Address(addr.u_addr.ip6.addr), port); - } - return connect(IPAddress(addr.u_addr.ip4.addr), port); - #else - return connect(IPAddress(addr.addr), port); - #endif -#else - return _connect(addr, port); -#endif - } else if (err == ERR_INPROGRESS) { - _connect_port = port; - return true; - } - log_d("error: %d", err); - return false; -} - -void AsyncClient::close(bool now) { - if (_pcb) { - _tcp_recved(_pcb, _closed_slot, _rx_ack_len); - } - _close(); -} - -int8_t AsyncClient::abort() { - if (_pcb) { - _tcp_abort(_pcb, _closed_slot); - _pcb = NULL; - } - return ERR_ABRT; -} - -size_t AsyncClient::space() { - if ((_pcb != NULL) && (_pcb->state == ESTABLISHED)) { - return tcp_sndbuf(_pcb); - } - return 0; -} - -size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) { - if (!_pcb || size == 0 || data == NULL) { - return 0; - } - size_t room = space(); - if (!room) { - return 0; - } - size_t will_send = (room < size) ? room : size; - int8_t err = ERR_OK; - err = _tcp_write(_pcb, _closed_slot, data, will_send, apiflags); - if (err != ERR_OK) { - return 0; - } - return will_send; -} - -bool AsyncClient::send() { - auto backup = _tx_last_packet; - _tx_last_packet = millis(); - if (_tcp_output(_pcb, _closed_slot) == ERR_OK) { - return true; - } - _tx_last_packet = backup; - return false; -} - -size_t AsyncClient::ack(size_t len) { - if (len > _rx_ack_len) - len = _rx_ack_len; - if (len) { - _tcp_recved(_pcb, _closed_slot, len); - } - _rx_ack_len -= len; - return len; -} - -void AsyncClient::ackPacket(struct pbuf* pb) { - if (!pb) { - return; - } - _tcp_recved(_pcb, _closed_slot, pb->len); - pbuf_free(pb); -} - -/* - * Main Private Methods - * */ - -int8_t AsyncClient::_close() { - // ets_printf("X: 0x%08x\n", (uint32_t)this); - int8_t err = ERR_OK; - if (_pcb) { - TCP_MUTEX_LOCK(); - tcp_arg(_pcb, NULL); - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - tcp_poll(_pcb, NULL, 0); - TCP_MUTEX_UNLOCK(); - _tcp_clear_events(this); - err = _tcp_close(_pcb, _closed_slot); - if (err != ERR_OK) { - err = abort(); - } - _free_closed_slot(); - _pcb = NULL; - if (_discard_cb) { - _discard_cb(_discard_cb_arg, this); - } - } - return err; -} - -bool AsyncClient::_allocate_closed_slot() { - if (_closed_slot != INVALID_CLOSED_SLOT) { - return true; - } - xSemaphoreTake(_slots_lock, portMAX_DELAY); - uint32_t closed_slot_min_index = 0; - for (int i = 0; i < _number_of_closed_slots; ++i) { - if ((_closed_slot == INVALID_CLOSED_SLOT || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) { - closed_slot_min_index = _closed_slots[i]; - _closed_slot = i; - } - } - if (_closed_slot != INVALID_CLOSED_SLOT) { - _closed_slots[_closed_slot] = 0; - } - xSemaphoreGive(_slots_lock); - return (_closed_slot != INVALID_CLOSED_SLOT); -} - -void AsyncClient::_free_closed_slot() { - xSemaphoreTake(_slots_lock, portMAX_DELAY); - if (_closed_slot != INVALID_CLOSED_SLOT) { - _closed_slots[_closed_slot] = _closed_index; - _closed_slot = INVALID_CLOSED_SLOT; - ++_closed_index; - } - xSemaphoreGive(_slots_lock); -} - -/* - * Private Callbacks - * */ - -int8_t AsyncClient::_connected(tcp_pcb* pcb, int8_t err) { - _pcb = reinterpret_cast(pcb); - if (_pcb) { - _rx_last_packet = millis(); - } - if (_connect_cb) { - _connect_cb(_connect_cb_arg, this); - } - return ERR_OK; -} - -void AsyncClient::_error(int8_t err) { - if (_pcb) { - TCP_MUTEX_LOCK(); - tcp_arg(_pcb, NULL); - if (_pcb->state == LISTEN) { - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - tcp_poll(_pcb, NULL, 0); - } - TCP_MUTEX_UNLOCK(); - _free_closed_slot(); - _pcb = NULL; - } - if (_error_cb) { - _error_cb(_error_cb_arg, this, err); - } - if (_discard_cb) { - _discard_cb(_discard_cb_arg, this); - } -} - -// In LwIP Thread -int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) { - if (!_pcb || pcb != _pcb) { - log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb); - return ERR_OK; - } - tcp_arg(_pcb, NULL); - if (_pcb->state == LISTEN) { - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - tcp_poll(_pcb, NULL, 0); - } - if (tcp_close(_pcb) != ERR_OK) { - tcp_abort(_pcb); - } - _free_closed_slot(); - _pcb = NULL; - return ERR_OK; -} - -// In Async Thread -int8_t AsyncClient::_fin(tcp_pcb* pcb, int8_t err) { - _tcp_clear_events(this); - if (_discard_cb) { - _discard_cb(_discard_cb_arg, this); - } - return ERR_OK; -} - -int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) { - _rx_last_ack = _rx_last_packet = millis(); - if (_sent_cb) { - _sent_cb(_sent_cb_arg, this, len, (_rx_last_packet - _tx_last_packet)); - } - return ERR_OK; -} - -int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) { - while (pb != NULL) { - _rx_last_packet = millis(); - // we should not ack before we assimilate the data - _ack_pcb = true; - pbuf* b = pb; - pb = b->next; - b->next = NULL; - if (_pb_cb) { - _pb_cb(_pb_cb_arg, this, b); - } else { - if (_recv_cb) { - _recv_cb(_recv_cb_arg, this, b->payload, b->len); - } - if (!_ack_pcb) { - _rx_ack_len += b->len; - } else if (_pcb) { - _tcp_recved(_pcb, _closed_slot, b->len); - } - } - pbuf_free(b); - } - return ERR_OK; -} - -int8_t AsyncClient::_poll(tcp_pcb* pcb) { - if (!_pcb) { - // log_d("pcb is NULL"); - return ERR_OK; - } - if (pcb != _pcb) { - log_d("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb); - return ERR_OK; - } - - uint32_t now = millis(); - - // ACK Timeout - if (_ack_timeout) { - const uint32_t one_day = 86400000; - bool last_tx_is_after_last_ack = (_rx_last_ack - _tx_last_packet + one_day) < one_day; - if (last_tx_is_after_last_ack && (now - _tx_last_packet) >= _ack_timeout) { - log_d("ack timeout %d", pcb->state); - if (_timeout_cb) - _timeout_cb(_timeout_cb_arg, this, (now - _tx_last_packet)); - return ERR_OK; - } - } - // RX Timeout - if (_rx_timeout && (now - _rx_last_packet) >= (_rx_timeout * 1000)) { - log_d("rx timeout %d", pcb->state); - _close(); - return ERR_OK; - } - // Everything is fine - if (_poll_cb) { - _poll_cb(_poll_cb_arg, this); - } - return ERR_OK; -} - -void AsyncClient::_dns_found(struct ip_addr* ipaddr) { -#if ESP_IDF_VERSION_MAJOR < 5 - if (ipaddr && IP_IS_V4(ipaddr)) { - connect(IPAddress(ip_addr_get_ip4_u32(ipaddr)), _connect_port); - #if LWIP_IPV6 - } else if (ipaddr && ipaddr->u_addr.ip6.addr) { - connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port); - #endif -#else - if (ipaddr) { - IPAddress ip; - ip.from_ip_addr_t(ipaddr); - connect(ip, _connect_port); -#endif - } else { - if (_error_cb) { - _error_cb(_error_cb_arg, this, -55); - } - if (_discard_cb) { - _discard_cb(_discard_cb_arg, this); - } - } -} - -/* - * Public Helper Methods - * */ - -bool AsyncClient::free() { - if (!_pcb) { - return true; - } - if (_pcb->state == CLOSED || _pcb->state > ESTABLISHED) { - return true; - } - return false; -} - -size_t AsyncClient::write(const char* data, size_t size, uint8_t apiflags) { - size_t will_send = add(data, size, apiflags); - if (!will_send || !send()) { - return 0; - } - return will_send; -} - -void AsyncClient::setRxTimeout(uint32_t timeout) { - _rx_timeout = timeout; -} - -uint32_t AsyncClient::getRxTimeout() { - return _rx_timeout; -} - -uint32_t AsyncClient::getAckTimeout() { - return _ack_timeout; -} - -void AsyncClient::setAckTimeout(uint32_t timeout) { - _ack_timeout = timeout; -} - -void AsyncClient::setNoDelay(bool nodelay) { - if (!_pcb) { - return; - } - if (nodelay) { - tcp_nagle_disable(_pcb); - } else { - tcp_nagle_enable(_pcb); - } -} - -bool AsyncClient::getNoDelay() { - if (!_pcb) { - return false; - } - return tcp_nagle_disabled(_pcb); -} - -void AsyncClient::setKeepAlive(uint32_t ms, uint8_t cnt) { - if (ms != 0) { - _pcb->so_options |= SOF_KEEPALIVE; // Turn on TCP Keepalive for the given pcb - // Set the time between keepalive messages in milli-seconds - _pcb->keep_idle = ms; - _pcb->keep_intvl = ms; - _pcb->keep_cnt = cnt; // The number of unanswered probes required to force closure of the socket - } else { - _pcb->so_options &= ~SOF_KEEPALIVE; // Turn off TCP Keepalive for the given pcb - } -} - -uint16_t AsyncClient::getMss() { - if (!_pcb) { - return 0; - } - return tcp_mss(_pcb); -} - -uint32_t AsyncClient::getRemoteAddress() { - if (!_pcb) { - return 0; - } -#if LWIP_IPV4 && LWIP_IPV6 - return _pcb->remote_ip.u_addr.ip4.addr; -#else - return _pcb->remote_ip.addr; -#endif -} - -#if LWIP_IPV6 -ip6_addr_t AsyncClient::getRemoteAddress6() { - if (!_pcb) { - ip6_addr_t nulladdr; - ip6_addr_set_zero(&nulladdr); - return nulladdr; - } - return _pcb->remote_ip.u_addr.ip6; -} - -ip6_addr_t AsyncClient::getLocalAddress6() { - if (!_pcb) { - ip6_addr_t nulladdr; - ip6_addr_set_zero(&nulladdr); - return nulladdr; - } - return _pcb->local_ip.u_addr.ip6; -} - #if ESP_IDF_VERSION_MAJOR < 5 -IPv6Address AsyncClient::remoteIP6() { - return IPv6Address(getRemoteAddress6().addr); -} - -IPv6Address AsyncClient::localIP6() { - return IPv6Address(getLocalAddress6().addr); -} - #else -IPAddress AsyncClient::remoteIP6() { - if (!_pcb) { - return IPAddress(IPType::IPv6); - } - IPAddress ip; - ip.from_ip_addr_t(&(_pcb->remote_ip)); - return ip; -} - -IPAddress AsyncClient::localIP6() { - if (!_pcb) { - return IPAddress(IPType::IPv6); - } - IPAddress ip; - ip.from_ip_addr_t(&(_pcb->local_ip)); - return ip; -} - #endif -#endif - -uint16_t AsyncClient::getRemotePort() { - if (!_pcb) { - return 0; - } - return _pcb->remote_port; -} - -uint32_t AsyncClient::getLocalAddress() { - if (!_pcb) { - return 0; - } -#if LWIP_IPV4 && LWIP_IPV6 - return _pcb->local_ip.u_addr.ip4.addr; -#else - return _pcb->local_ip.addr; -#endif -} - -uint16_t AsyncClient::getLocalPort() { - if (!_pcb) { - return 0; - } - return _pcb->local_port; -} - -IPAddress AsyncClient::remoteIP() { -#if ESP_IDF_VERSION_MAJOR < 5 - return IPAddress(getRemoteAddress()); -#else - if (!_pcb) { - return IPAddress(); - } - IPAddress ip; - ip.from_ip_addr_t(&(_pcb->remote_ip)); - return ip; -#endif -} - -uint16_t AsyncClient::remotePort() { - return getRemotePort(); -} - -IPAddress AsyncClient::localIP() { -#if ESP_IDF_VERSION_MAJOR < 5 - return IPAddress(getLocalAddress()); -#else - if (!_pcb) { - return IPAddress(); - } - IPAddress ip; - ip.from_ip_addr_t(&(_pcb->local_ip)); - return ip; -#endif -} - -uint16_t AsyncClient::localPort() { - return getLocalPort(); -} - -uint8_t AsyncClient::state() { - if (!_pcb) { - return 0; - } - return _pcb->state; -} - -bool AsyncClient::connected() { - if (!_pcb) { - return false; - } - return _pcb->state == ESTABLISHED; -} - -bool AsyncClient::connecting() { - if (!_pcb) { - return false; - } - return _pcb->state > CLOSED && _pcb->state < ESTABLISHED; -} - -bool AsyncClient::disconnecting() { - if (!_pcb) { - return false; - } - return _pcb->state > ESTABLISHED && _pcb->state < TIME_WAIT; -} - -bool AsyncClient::disconnected() { - if (!_pcb) { - return true; - } - return _pcb->state == CLOSED || _pcb->state == TIME_WAIT; -} - -bool AsyncClient::freeable() { - if (!_pcb) { - return true; - } - return _pcb->state == CLOSED || _pcb->state > ESTABLISHED; -} - -bool AsyncClient::canSend() { - return space() > 0; -} - -const char* AsyncClient::errorToString(int8_t error) { - switch (error) { - case ERR_OK: - return "OK"; - case ERR_MEM: - return "Out of memory error"; - case ERR_BUF: - return "Buffer error"; - case ERR_TIMEOUT: - return "Timeout"; - case ERR_RTE: - return "Routing problem"; - case ERR_INPROGRESS: - return "Operation in progress"; - case ERR_VAL: - return "Illegal value"; - case ERR_WOULDBLOCK: - return "Operation would block"; - case ERR_USE: - return "Address in use"; - case ERR_ALREADY: - return "Already connected"; - case ERR_CONN: - return "Not connected"; - case ERR_IF: - return "Low-level netif error"; - case ERR_ABRT: - return "Connection aborted"; - case ERR_RST: - return "Connection reset"; - case ERR_CLSD: - return "Connection closed"; - case ERR_ARG: - return "Illegal argument"; - case -55: - return "DNS failed"; - default: - return "UNKNOWN"; - } -} - -const char* AsyncClient::stateToString() { - switch (state()) { - case 0: - return "Closed"; - case 1: - return "Listen"; - case 2: - return "SYN Sent"; - case 3: - return "SYN Received"; - case 4: - return "Established"; - case 5: - return "FIN Wait 1"; - case 6: - return "FIN Wait 2"; - case 7: - return "Close Wait"; - case 8: - return "Closing"; - case 9: - return "Last ACK"; - case 10: - return "Time Wait"; - default: - return "UNKNOWN"; - } -} - -/* - * Static Callbacks (LwIP C2C++ interconnect) - * */ - -void AsyncClient::_s_dns_found(const char* name, struct ip_addr* ipaddr, void* arg) { - reinterpret_cast(arg)->_dns_found(ipaddr); -} - -int8_t AsyncClient::_s_poll(void* arg, struct tcp_pcb* pcb) { - return reinterpret_cast(arg)->_poll(pcb); -} - -int8_t AsyncClient::_s_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* pb, int8_t err) { - return reinterpret_cast(arg)->_recv(pcb, pb, err); -} - -int8_t AsyncClient::_s_fin(void* arg, struct tcp_pcb* pcb, int8_t err) { - return reinterpret_cast(arg)->_fin(pcb, err); -} - -int8_t AsyncClient::_s_lwip_fin(void* arg, struct tcp_pcb* pcb, int8_t err) { - return reinterpret_cast(arg)->_lwip_fin(pcb, err); -} - -int8_t AsyncClient::_s_sent(void* arg, struct tcp_pcb* pcb, uint16_t len) { - return reinterpret_cast(arg)->_sent(pcb, len); -} - -void AsyncClient::_s_error(void* arg, int8_t err) { - reinterpret_cast(arg)->_error(err); -} - -int8_t AsyncClient::_s_connected(void* arg, struct tcp_pcb* pcb, int8_t err) { - return reinterpret_cast(arg)->_connected(pcb, err); -} - -/* - Async TCP Server - */ - -AsyncServer::AsyncServer(IPAddress addr, uint16_t port) - : _port(port) -#if ESP_IDF_VERSION_MAJOR < 5 - , - _bind4(true), _bind6(false) -#else - , - _bind4(addr.type() != IPType::IPv6), _bind6(addr.type() == IPType::IPv6) -#endif - , - _addr(addr), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) { -} - -#if ESP_IDF_VERSION_MAJOR < 5 -AsyncServer::AsyncServer(IPv6Address addr, uint16_t port) - : _port(port), _bind4(false), _bind6(true), _addr6(addr), _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) {} -#endif - -AsyncServer::AsyncServer(uint16_t port) - : _port(port), _bind4(true), _bind6(false), _addr((uint32_t)IPADDR_ANY) -#if ESP_IDF_VERSION_MAJOR < 5 - , - _addr6() -#endif - , - _noDelay(false), _pcb(0), _connect_cb(0), _connect_cb_arg(0) { -} - -AsyncServer::~AsyncServer() { - end(); -} - -void AsyncServer::onClient(AcConnectHandler cb, void* arg) { - _connect_cb = cb; - _connect_cb_arg = arg; -} - -void AsyncServer::begin() { - if (_pcb) { - return; - } - - if (!_start_async_task()) { - log_e("failed to start task"); - return; - } - int8_t err; - TCP_MUTEX_LOCK(); - _pcb = tcp_new_ip_type(_bind4 && _bind6 ? IPADDR_TYPE_ANY : (_bind6 ? IPADDR_TYPE_V6 : IPADDR_TYPE_V4)); - TCP_MUTEX_UNLOCK(); - if (!_pcb) { - log_e("_pcb == NULL"); - return; - } - - ip_addr_t local_addr; -#if ESP_IDF_VERSION_MAJOR < 5 - if (_bind6) { // _bind6 && _bind4 both at the same time is not supported on Arduino 2 in this lib API - local_addr.type = IPADDR_TYPE_V6; - memcpy(local_addr.u_addr.ip6.addr, static_cast(_addr6), sizeof(uint32_t) * 4); - } else { - local_addr.type = IPADDR_TYPE_V4; - local_addr.u_addr.ip4.addr = _addr; - } -#else - _addr.to_ip_addr_t(&local_addr); -#endif - err = _tcp_bind(_pcb, &local_addr, _port); - - if (err != ERR_OK) { - _tcp_close(_pcb, -1); - log_e("bind error: %d", err); - return; - } - - static uint8_t backlog = 5; - _pcb = _tcp_listen_with_backlog(_pcb, backlog); - if (!_pcb) { - log_e("listen_pcb == NULL"); - return; - } - TCP_MUTEX_LOCK(); - tcp_arg(_pcb, (void*)this); - tcp_accept(_pcb, &_s_accept); - TCP_MUTEX_UNLOCK(); -} - -void AsyncServer::end() { - if (_pcb) { - TCP_MUTEX_LOCK(); - tcp_arg(_pcb, NULL); - tcp_accept(_pcb, NULL); - if (tcp_close(_pcb) != ERR_OK) { - TCP_MUTEX_UNLOCK(); - _tcp_abort(_pcb, -1); - } else { - TCP_MUTEX_UNLOCK(); - } - _pcb = NULL; - } -} - -// runs on LwIP thread -int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err) { - // ets_printf("+A: 0x%08x\n", pcb); - if (_connect_cb) { - AsyncClient* c = new AsyncClient(pcb); - if (c) { - c->setNoDelay(_noDelay); - return _tcp_accept(this, c); - } - } - if (tcp_close(pcb) != ERR_OK) { - tcp_abort(pcb); - } - log_d("FAIL"); - return ERR_OK; -} - -int8_t AsyncServer::_accepted(AsyncClient* client) { - if (_connect_cb) { - _connect_cb(_connect_cb_arg, client); - } - return ERR_OK; -} - -void AsyncServer::setNoDelay(bool nodelay) { - _noDelay = nodelay; -} - -bool AsyncServer::getNoDelay() { - return _noDelay; -} - -uint8_t AsyncServer::status() { - if (!_pcb) { - return 0; - } - return _pcb->state; -} - -int8_t AsyncServer::_s_accept(void* arg, tcp_pcb* pcb, int8_t err) { - return reinterpret_cast(arg)->_accept(pcb, err); -} - -int8_t AsyncServer::_s_accepted(void* arg, AsyncClient* client) { - return reinterpret_cast(arg)->_accepted(client); -} diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h b/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h deleted file mode 100644 index c909d051..00000000 --- a/Software/src/lib/mathieucarbou-AsyncTCP/src/AsyncTCP.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - Asynchronous TCP library for Espressif MCUs - - Copyright (c) 2016 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef ASYNCTCP_H_ -#define ASYNCTCP_H_ - -#define ASYNCTCP_VERSION "3.3.1" -#define ASYNCTCP_VERSION_MAJOR 3 -#define ASYNCTCP_VERSION_MINOR 3 -#define ASYNCTCP_VERSION_REVISION 1 -#define ASYNCTCP_FORK_mathieucarbou - -#include "../../../devboard/hal/hal.h" -#include "../../../system_settings.h" - -#include "IPAddress.h" -#if ESP_IDF_VERSION_MAJOR < 5 - #include "IPv6Address.h" -#endif -#include "lwip/ip6_addr.h" -#include "lwip/ip_addr.h" -#include - -#ifndef LIBRETINY - #include "sdkconfig.h" -extern "C" { - #include "freertos/semphr.h" - #include "lwip/pbuf.h" -} -#else -extern "C" { - #include - #include -} - #define CONFIG_ASYNC_TCP_RUNNING_CORE WIFI_CORE -#endif - -// If core is not defined, then we are running in Arduino or PIO -#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE - #define CONFIG_ASYNC_TCP_RUNNING_CORE WIFI_CORE -#endif - -// guard AsyncTCP task with watchdog -#ifndef CONFIG_ASYNC_TCP_USE_WDT - #define CONFIG_ASYNC_TCP_USE_WDT 0 -#endif - -#ifndef CONFIG_ASYNC_TCP_STACK_SIZE - #define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2 -#endif - -#ifndef CONFIG_ASYNC_TCP_PRIORITY - #define CONFIG_ASYNC_TCP_PRIORITY 10 -#endif - -#ifndef CONFIG_ASYNC_TCP_QUEUE_SIZE - #define CONFIG_ASYNC_TCP_QUEUE_SIZE 64 -#endif - -#ifndef CONFIG_ASYNC_TCP_MAX_ACK_TIME - #define CONFIG_ASYNC_TCP_MAX_ACK_TIME 5000 -#endif - -class AsyncClient; - -#define ASYNC_WRITE_FLAG_COPY 0x01 // will allocate new buffer to hold the data while sending (else will hold reference to the data given) -#define ASYNC_WRITE_FLAG_MORE 0x02 // will not send PSH flag, meaning that there should be more data to be sent before the application should react. - -typedef std::function AcConnectHandler; -typedef std::function AcAckHandler; -typedef std::function AcErrorHandler; -typedef std::function AcDataHandler; -typedef std::function AcPacketHandler; -typedef std::function AcTimeoutHandler; - -struct tcp_pcb; -struct ip_addr; - -class AsyncClient { - public: - AsyncClient(tcp_pcb* pcb = 0); - ~AsyncClient(); - - AsyncClient& operator=(const AsyncClient& other); - AsyncClient& operator+=(const AsyncClient& other); - - bool operator==(const AsyncClient& other); - - bool operator!=(const AsyncClient& other) { - return !(*this == other); - } - bool connect(const IPAddress& ip, uint16_t port); -#if ESP_IDF_VERSION_MAJOR < 5 - bool connect(const IPv6Address& ip, uint16_t port); -#endif - bool connect(const char* host, uint16_t port); - /** - * @brief close connection - * - * @param now - ignored - */ - void close(bool now = false); - // same as close() - void stop() { close(false); }; - int8_t abort(); - bool free(); - - // ack is not pending - bool canSend(); - // TCP buffer space available - size_t space(); - - /** - * @brief add data to be send (but do not send yet) - * @note add() would call lwip's tcp_write() - By default apiflags=ASYNC_WRITE_FLAG_COPY - You could try to use apiflags with this flag unset to pass data by reference and avoid copy to socket buffer, - but looks like it does not work for Arduino's lwip in ESP32/IDF at least - it is enforced in https://github.com/espressif/esp-lwip/blob/0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9/src/core/tcp_out.c#L422C5-L422C30 - if LWIP_NETIF_TX_SINGLE_PBUF is set, and it is set indeed in IDF - https://github.com/espressif/esp-idf/blob/a0f798cfc4bbd624aab52b2c194d219e242d80c1/components/lwip/port/include/lwipopts.h#L744 - * - * @param data - * @param size - * @param apiflags - * @return size_t amount of data that has been copied - */ - size_t add(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY); - - /** - * @brief send data previously add()'ed - * - * @return true on success - * @return false on error - */ - bool send(); - - /** - * @brief add and enqueue data for sending - * @note it is same as add() + send() - * @note only make sense when canSend() == true - * - * @param data - * @param size - * @param apiflags - * @return size_t - */ - size_t write(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY); - - /** - * @brief add and enque data for sending - * @note treats data as null-terminated string - * - * @param data - * @return size_t - */ - size_t write(const char* data) { return data == NULL ? 0 : write(data, strlen(data)); }; - - uint8_t state(); - bool connecting(); - bool connected(); - bool disconnecting(); - bool disconnected(); - - // disconnected or disconnecting - bool freeable(); - - uint16_t getMss(); - - uint32_t getRxTimeout(); - // no RX data timeout for the connection in seconds - void setRxTimeout(uint32_t timeout); - - uint32_t getAckTimeout(); - // no ACK timeout for the last sent packet in milliseconds - void setAckTimeout(uint32_t timeout); - - void setNoDelay(bool nodelay); - bool getNoDelay(); - - void setKeepAlive(uint32_t ms, uint8_t cnt); - - uint32_t getRemoteAddress(); - uint16_t getRemotePort(); - uint32_t getLocalAddress(); - uint16_t getLocalPort(); -#if LWIP_IPV6 - ip6_addr_t getRemoteAddress6(); - ip6_addr_t getLocalAddress6(); - #if ESP_IDF_VERSION_MAJOR < 5 - IPv6Address remoteIP6(); - IPv6Address localIP6(); - #else - IPAddress remoteIP6(); - IPAddress localIP6(); - #endif -#endif - - // compatibility - IPAddress remoteIP(); - uint16_t remotePort(); - IPAddress localIP(); - uint16_t localPort(); - - // set callback - on successful connect - void onConnect(AcConnectHandler cb, void* arg = 0); - // set callback - disconnected - void onDisconnect(AcConnectHandler cb, void* arg = 0); - // set callback - ack received - void onAck(AcAckHandler cb, void* arg = 0); - // set callback - unsuccessful connect or error - void onError(AcErrorHandler cb, void* arg = 0); - // set callback - data received (called if onPacket is not used) - void onData(AcDataHandler cb, void* arg = 0); - // set callback - data received - void onPacket(AcPacketHandler cb, void* arg = 0); - // set callback - ack timeout - void onTimeout(AcTimeoutHandler cb, void* arg = 0); - // set callback - every 125ms when connected - void onPoll(AcConnectHandler cb, void* arg = 0); - - // ack pbuf from onPacket - void ackPacket(struct pbuf* pb); - // ack data that you have not acked using the method below - size_t ack(size_t len); - // will not ack the current packet. Call from onData - void ackLater() { _ack_pcb = false; } - - static const char* errorToString(int8_t error); - const char* stateToString(); - - // internal callbacks - Do NOT call any of the functions below in user code! - static int8_t _s_poll(void* arg, struct tcp_pcb* tpcb); - static int8_t _s_recv(void* arg, struct tcp_pcb* tpcb, struct pbuf* pb, int8_t err); - static int8_t _s_fin(void* arg, struct tcp_pcb* tpcb, int8_t err); - static int8_t _s_lwip_fin(void* arg, struct tcp_pcb* tpcb, int8_t err); - static void _s_error(void* arg, int8_t err); - static int8_t _s_sent(void* arg, struct tcp_pcb* tpcb, uint16_t len); - static int8_t _s_connected(void* arg, struct tcp_pcb* tpcb, int8_t err); - static void _s_dns_found(const char* name, struct ip_addr* ipaddr, void* arg); - - int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err); - tcp_pcb* pcb() { return _pcb; } - - protected: - bool _connect(ip_addr_t addr, uint16_t port); - - tcp_pcb* _pcb; - int8_t _closed_slot; - - AcConnectHandler _connect_cb; - void* _connect_cb_arg; - AcConnectHandler _discard_cb; - void* _discard_cb_arg; - AcAckHandler _sent_cb; - void* _sent_cb_arg; - AcErrorHandler _error_cb; - void* _error_cb_arg; - AcDataHandler _recv_cb; - void* _recv_cb_arg; - AcPacketHandler _pb_cb; - void* _pb_cb_arg; - AcTimeoutHandler _timeout_cb; - void* _timeout_cb_arg; - AcConnectHandler _poll_cb; - void* _poll_cb_arg; - - bool _ack_pcb; - uint32_t _tx_last_packet; - uint32_t _rx_ack_len; - uint32_t _rx_last_packet; - uint32_t _rx_timeout; - uint32_t _rx_last_ack; - uint32_t _ack_timeout; - uint16_t _connect_port; - - int8_t _close(); - void _free_closed_slot(); - bool _allocate_closed_slot(); - int8_t _connected(tcp_pcb* pcb, int8_t err); - void _error(int8_t err); - int8_t _poll(tcp_pcb* pcb); - int8_t _sent(tcp_pcb* pcb, uint16_t len); - int8_t _fin(tcp_pcb* pcb, int8_t err); - int8_t _lwip_fin(tcp_pcb* pcb, int8_t err); - void _dns_found(struct ip_addr* ipaddr); - - public: - AsyncClient* prev; - AsyncClient* next; -}; - -class AsyncServer { - public: - AsyncServer(IPAddress addr, uint16_t port); -#if ESP_IDF_VERSION_MAJOR < 5 - AsyncServer(IPv6Address addr, uint16_t port); -#endif - AsyncServer(uint16_t port); - ~AsyncServer(); - void onClient(AcConnectHandler cb, void* arg); - void begin(); - void end(); - void setNoDelay(bool nodelay); - bool getNoDelay(); - uint8_t status(); - - // Do not use any of the functions below! - static int8_t _s_accept(void* arg, tcp_pcb* newpcb, int8_t err); - static int8_t _s_accepted(void* arg, AsyncClient* client); - - protected: - uint16_t _port; - bool _bind4 = false; - bool _bind6 = false; - IPAddress _addr; -#if ESP_IDF_VERSION_MAJOR < 5 - IPv6Address _addr6; -#endif - bool _noDelay; - tcp_pcb* _pcb; - AcConnectHandler _connect_cb; - void* _connect_cb_arg; - - int8_t _accept(tcp_pcb* newpcb, int8_t err); - int8_t _accepted(AsyncClient* client); -}; - -#endif /* ASYNCTCP_H_ */ diff --git a/Software/src/lib/me-no-dev-AsyncTCP/.gitignore b/Software/src/lib/me-no-dev-AsyncTCP/.gitignore new file mode 100644 index 00000000..9bea4330 --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/.gitignore @@ -0,0 +1,2 @@ + +.DS_Store diff --git a/Software/src/lib/me-no-dev-AsyncTCP/.travis.yml b/Software/src/lib/me-no-dev-AsyncTCP/.travis.yml new file mode 100644 index 00000000..dbfc064a --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/.travis.yml @@ -0,0 +1,34 @@ +sudo: false +language: python +os: + - linux + +git: + depth: false + +stages: + - build + +jobs: + include: + + - name: "Arduino Build" + if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) + stage: build + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh + + - name: "PlatformIO Build" + if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) + stage: build + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 1 + +notifications: + email: + on_success: change + on_failure: change + webhooks: + urls: + - https://webhooks.gitter.im/e/60e65d0c78ea0a920347 + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/CMakeLists.txt b/Software/src/lib/me-no-dev-AsyncTCP/CMakeLists.txt similarity index 100% rename from Software/src/lib/mathieucarbou-AsyncTCP/CMakeLists.txt rename to Software/src/lib/me-no-dev-AsyncTCP/CMakeLists.txt diff --git a/Software/src/lib/me-no-dev-AsyncTCP/Kconfig.projbuild b/Software/src/lib/me-no-dev-AsyncTCP/Kconfig.projbuild new file mode 100644 index 00000000..17749264 --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/Kconfig.projbuild @@ -0,0 +1,30 @@ +menu "AsyncTCP Configuration" + +choice ASYNC_TCP_RUNNING_CORE + bool "Core on which AsyncTCP's thread is running" + default ASYNC_TCP_RUN_CORE1 + help + Select on which core AsyncTCP is running + + config ASYNC_TCP_RUN_CORE0 + bool "CORE 0" + config ASYNC_TCP_RUN_CORE1 + bool "CORE 1" + config ASYNC_TCP_RUN_NO_AFFINITY + bool "BOTH" + +endchoice + +config ASYNC_TCP_RUNNING_CORE + int + default 0 if ASYNC_TCP_RUN_CORE0 + default 1 if ASYNC_TCP_RUN_CORE1 + default -1 if ASYNC_TCP_RUN_NO_AFFINITY + +config ASYNC_TCP_USE_WDT + bool "Enable WDT for the AsyncTCP task" + default "y" + help + Enable WDT for the AsyncTCP task, so it will trigger if a handler is locking the thread. + +endmenu diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/LICENSE b/Software/src/lib/me-no-dev-AsyncTCP/LICENSE similarity index 100% rename from Software/src/lib/mathieucarbou-AsyncTCP/LICENSE rename to Software/src/lib/me-no-dev-AsyncTCP/LICENSE diff --git a/Software/src/lib/me-no-dev-AsyncTCP/README.md b/Software/src/lib/me-no-dev-AsyncTCP/README.md new file mode 100644 index 00000000..79ffa9ef --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/README.md @@ -0,0 +1,15 @@ +This is commit ca8ac5f from https://github.com/me-no-dev/AsyncTCP + +# AsyncTCP +[![Build Status](https://travis-ci.org/me-no-dev/AsyncTCP.svg?branch=master)](https://travis-ci.org/me-no-dev/AsyncTCP) ![](https://github.com/me-no-dev/AsyncTCP/workflows/Async%20TCP%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2f7e4d1df8b446d192cbfec6dc174d2d)](https://www.codacy.com/manual/me-no-dev/AsyncTCP?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/AsyncTCP&utm_campaign=Badge_Grade) + +### Async TCP Library for ESP32 Arduino + +[![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs. + +This library is the base for [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) + +## AsyncClient and AsyncServer +The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use. diff --git a/Software/src/lib/mathieucarbou-AsyncTCP/component.mk b/Software/src/lib/me-no-dev-AsyncTCP/component.mk similarity index 100% rename from Software/src/lib/mathieucarbou-AsyncTCP/component.mk rename to Software/src/lib/me-no-dev-AsyncTCP/component.mk diff --git a/Software/src/lib/me-no-dev-AsyncTCP/library.json b/Software/src/lib/me-no-dev-AsyncTCP/library.json new file mode 100644 index 00000000..89f90e4e --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/library.json @@ -0,0 +1,22 @@ +{ + "name":"AsyncTCP", + "description":"Asynchronous TCP Library for ESP32", + "keywords":"async,tcp", + "authors": + { + "name": "Hristo Gochkov", + "maintainer": true + }, + "repository": + { + "type": "git", + "url": "https://github.com/me-no-dev/AsyncTCP.git" + }, + "version": "1.1.1", + "license": "LGPL-3.0", + "frameworks": "arduino", + "platforms": "espressif32", + "build": { + "libCompatMode": 2 + } +} diff --git a/Software/src/lib/me-no-dev-AsyncTCP/library.properties b/Software/src/lib/me-no-dev-AsyncTCP/library.properties new file mode 100644 index 00000000..eb4e26e9 --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/library.properties @@ -0,0 +1,9 @@ +name=AsyncTCP +version=1.1.1 +author=Me-No-Dev +maintainer=Me-No-Dev +sentence=Async TCP Library for ESP32 +paragraph=Async TCP Library for ESP32 +category=Other +url=https://github.com/me-no-dev/AsyncTCP +architectures=* diff --git a/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.cpp b/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.cpp new file mode 100644 index 00000000..acd89639 --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.cpp @@ -0,0 +1,1387 @@ +/* + Asynchronous TCP library for Espressif MCUs + + Copyright (c) 2016 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "Arduino.h" + +#include "AsyncTCP.h" +extern "C"{ +#include "lwip/opt.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "lwip/dns.h" +#include "lwip/err.h" +} +#include "esp_task_wdt.h" + +/* + * TCP/IP Event Task + * */ + +#define TAG "AsyncTCP" + +// https://github.com/espressif/arduino-esp32/issues/10526 +#ifdef CONFIG_LWIP_TCPIP_CORE_LOCKING +#define TCP_MUTEX_LOCK() \ + if (!sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \ + LOCK_TCPIP_CORE(); \ + } + +#define TCP_MUTEX_UNLOCK() \ + if (sys_thread_tcpip(LWIP_CORE_LOCK_QUERY_HOLDER)) { \ + UNLOCK_TCPIP_CORE(); \ + } +#else // CONFIG_LWIP_TCPIP_CORE_LOCKING +#define TCP_MUTEX_LOCK() +#define TCP_MUTEX_UNLOCK() +#endif // CONFIG_LWIP_TCPIP_CORE_LOCKING + +typedef enum { + LWIP_TCP_SENT, LWIP_TCP_RECV, LWIP_TCP_FIN, LWIP_TCP_ERROR, LWIP_TCP_POLL, LWIP_TCP_CLEAR, LWIP_TCP_ACCEPT, LWIP_TCP_CONNECTED, LWIP_TCP_DNS +} lwip_event_t; + +typedef struct { + lwip_event_t event; + void *arg; + union { + struct { + void * pcb; + int8_t err; + } connected; + struct { + int8_t err; + } error; + struct { + tcp_pcb * pcb; + uint16_t len; + } sent; + struct { + tcp_pcb * pcb; + pbuf * pb; + int8_t err; + } recv; + struct { + tcp_pcb * pcb; + int8_t err; + } fin; + struct { + tcp_pcb * pcb; + } poll; + struct { + AsyncClient * client; + } accept; + struct { + const char * name; + ip_addr_t addr; + } dns; + }; +} lwip_event_packet_t; + +static xQueueHandle _async_queue; +static TaskHandle_t _async_service_task_handle = NULL; + + +SemaphoreHandle_t _slots_lock; +const int _number_of_closed_slots = CONFIG_LWIP_MAX_ACTIVE_TCP; +static uint32_t _closed_slots[_number_of_closed_slots]; +static uint32_t _closed_index = []() { + _slots_lock = xSemaphoreCreateBinary(); + xSemaphoreGive(_slots_lock); + for (int i = 0; i < _number_of_closed_slots; ++ i) { + _closed_slots[i] = 1; + } + return 1; +}(); + + +static inline bool _init_async_event_queue(){ + if(!_async_queue){ + _async_queue = xQueueCreate(32, sizeof(lwip_event_packet_t *)); + if(!_async_queue){ + return false; + } + } + return true; +} + +static inline bool _send_async_event(lwip_event_packet_t ** e){ + return _async_queue && xQueueSend(_async_queue, e, portMAX_DELAY) == pdPASS; +} + +static inline bool _prepend_async_event(lwip_event_packet_t ** e){ + return _async_queue && xQueueSendToFront(_async_queue, e, portMAX_DELAY) == pdPASS; +} + +static inline bool _get_async_event(lwip_event_packet_t ** e){ + return _async_queue && xQueueReceive(_async_queue, e, portMAX_DELAY) == pdPASS; +} + +static bool _remove_events_with_arg(void * arg){ + lwip_event_packet_t * first_packet = NULL; + lwip_event_packet_t * packet = NULL; + + if(!_async_queue){ + return false; + } + //figure out which is the first packet so we can keep the order + while(!first_packet){ + if(xQueueReceive(_async_queue, &first_packet, 0) != pdPASS){ + return false; + } + //discard packet if matching + if((int)first_packet->arg == (int)arg){ + free(first_packet); + first_packet = NULL; + //return first packet to the back of the queue + } else if(xQueueSend(_async_queue, &first_packet, portMAX_DELAY) != pdPASS){ + return false; + } + } + + while(xQueuePeek(_async_queue, &packet, 0) == pdPASS && packet != first_packet){ + if(xQueueReceive(_async_queue, &packet, 0) != pdPASS){ + return false; + } + if((int)packet->arg == (int)arg){ + free(packet); + packet = NULL; + } else if(xQueueSend(_async_queue, &packet, portMAX_DELAY) != pdPASS){ + return false; + } + } + return true; +} + +static void _handle_async_event(lwip_event_packet_t * e){ + if(e->arg == NULL){ + // do nothing when arg is NULL + //ets_printf("event arg == NULL: 0x%08x\n", e->recv.pcb); + } else if(e->event == LWIP_TCP_CLEAR){ + _remove_events_with_arg(e->arg); + } else if(e->event == LWIP_TCP_RECV){ + //ets_printf("-R: 0x%08x\n", e->recv.pcb); + AsyncClient::_s_recv(e->arg, e->recv.pcb, e->recv.pb, e->recv.err); + } else if(e->event == LWIP_TCP_FIN){ + //ets_printf("-F: 0x%08x\n", e->fin.pcb); + AsyncClient::_s_fin(e->arg, e->fin.pcb, e->fin.err); + } else if(e->event == LWIP_TCP_SENT){ + //ets_printf("-S: 0x%08x\n", e->sent.pcb); + AsyncClient::_s_sent(e->arg, e->sent.pcb, e->sent.len); + } else if(e->event == LWIP_TCP_POLL){ + //ets_printf("-P: 0x%08x\n", e->poll.pcb); + AsyncClient::_s_poll(e->arg, e->poll.pcb); + } else if(e->event == LWIP_TCP_ERROR){ + //ets_printf("-E: 0x%08x %d\n", e->arg, e->error.err); + AsyncClient::_s_error(e->arg, e->error.err); + } else if(e->event == LWIP_TCP_CONNECTED){ + //ets_printf("C: 0x%08x 0x%08x %d\n", e->arg, e->connected.pcb, e->connected.err); + AsyncClient::_s_connected(e->arg, e->connected.pcb, e->connected.err); + } else if(e->event == LWIP_TCP_ACCEPT){ + //ets_printf("A: 0x%08x 0x%08x\n", e->arg, e->accept.client); + AsyncServer::_s_accepted(e->arg, e->accept.client); + } else if(e->event == LWIP_TCP_DNS){ + //ets_printf("D: 0x%08x %s = %s\n", e->arg, e->dns.name, ipaddr_ntoa(&e->dns.addr)); + AsyncClient::_s_dns_found(e->dns.name, &e->dns.addr, e->arg); + } + free((void*)(e)); +} + +static void _async_service_task(void *pvParameters){ + lwip_event_packet_t * packet = NULL; + for (;;) { + if(_get_async_event(&packet)){ +#if CONFIG_ASYNC_TCP_USE_WDT + if(esp_task_wdt_add(NULL) != ESP_OK){ + log_e("Failed to add async task to WDT"); + } +#endif + _handle_async_event(packet); +#if CONFIG_ASYNC_TCP_USE_WDT + if(esp_task_wdt_delete(NULL) != ESP_OK){ + log_e("Failed to remove loop task from WDT"); + } +#endif + } + } + vTaskDelete(NULL); + _async_service_task_handle = NULL; +} +/* +static void _stop_async_task(){ + if(_async_service_task_handle){ + vTaskDelete(_async_service_task_handle); + _async_service_task_handle = NULL; + } +} +*/ +static bool _start_async_task(){ + if(!_init_async_event_queue()){ + return false; + } + if(!_async_service_task_handle){ + xTaskCreateUniversal(_async_service_task, "async_tcp", 8192 * 2, NULL, TASK_CONNECTIVITY_PRIO, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE); + if(!_async_service_task_handle){ + return false; + } + } + return true; +} + +/* + * LwIP Callbacks + * */ + +static int8_t _tcp_clear_events(void * arg) { + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_CLEAR; + e->arg = arg; + if (!_prepend_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +static int8_t _tcp_connected(void * arg, tcp_pcb * pcb, int8_t err) { + //ets_printf("+C: 0x%08x\n", pcb); + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_CONNECTED; + e->arg = arg; + e->connected.pcb = pcb; + e->connected.err = err; + if (!_prepend_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +static int8_t _tcp_poll(void * arg, struct tcp_pcb * pcb) { + //ets_printf("+P: 0x%08x\n", pcb); + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_POLL; + e->arg = arg; + e->poll.pcb = pcb; + if (!_send_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +static int8_t _tcp_recv(void * arg, struct tcp_pcb * pcb, struct pbuf *pb, int8_t err) { + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->arg = arg; + if(pb){ + //ets_printf("+R: 0x%08x\n", pcb); + e->event = LWIP_TCP_RECV; + e->recv.pcb = pcb; + e->recv.pb = pb; + e->recv.err = err; + } else { + //ets_printf("+F: 0x%08x\n", pcb); + e->event = LWIP_TCP_FIN; + e->fin.pcb = pcb; + e->fin.err = err; + //close the PCB in LwIP thread + AsyncClient::_s_lwip_fin(e->arg, e->fin.pcb, e->fin.err); + } + if (!_send_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +static int8_t _tcp_sent(void * arg, struct tcp_pcb * pcb, uint16_t len) { + //ets_printf("+S: 0x%08x\n", pcb); + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_SENT; + e->arg = arg; + e->sent.pcb = pcb; + e->sent.len = len; + if (!_send_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +static void _tcp_error(void * arg, int8_t err) { + //ets_printf("+E: 0x%08x\n", arg); + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_ERROR; + e->arg = arg; + e->error.err = err; + if (!_send_async_event(&e)) { + free((void*)(e)); + } +} + +static void _tcp_dns_found(const char * name, struct ip_addr * ipaddr, void * arg) { + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + //ets_printf("+DNS: name=%s ipaddr=0x%08x arg=%x\n", name, ipaddr, arg); + e->event = LWIP_TCP_DNS; + e->arg = arg; + e->dns.name = name; + if (ipaddr) { + memcpy(&e->dns.addr, ipaddr, sizeof(struct ip_addr)); + } else { + memset(&e->dns.addr, 0, sizeof(e->dns.addr)); + } + if (!_send_async_event(&e)) { + free((void*)(e)); + } +} + +//Used to switch out from LwIP thread +static int8_t _tcp_accept(void * arg, AsyncClient * client) { + lwip_event_packet_t * e = (lwip_event_packet_t *)malloc(sizeof(lwip_event_packet_t)); + e->event = LWIP_TCP_ACCEPT; + e->arg = arg; + e->accept.client = client; + if (!_prepend_async_event(&e)) { + free((void*)(e)); + } + return ERR_OK; +} + +/* + * TCP/IP API Calls + * */ + +#include "lwip/priv/tcpip_priv.h" + +typedef struct { + struct tcpip_api_call_data call; + tcp_pcb * pcb; + int8_t closed_slot; + int8_t err; + union { + struct { + const char* data; + size_t size; + uint8_t apiflags; + } write; + size_t received; + struct { + ip_addr_t * addr; + uint16_t port; + tcp_connected_fn cb; + } connect; + struct { + ip_addr_t * addr; + uint16_t port; + } bind; + uint8_t backlog; + }; +} tcp_api_call_t; + +static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; + if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { + msg->err = tcp_output(msg->pcb); + } + return msg->err; +} + +static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) { + if(!pcb){ + return ERR_CONN; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; + if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { + msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags); + } + return msg->err; +} + +static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, size_t size, uint8_t apiflags) { + if(!pcb){ + return ERR_CONN; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + msg.write.data = data; + msg.write.size = size; + msg.write.apiflags = apiflags; + tcpip_api_call(_tcp_write_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; + if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { + msg->err = 0; + tcp_recved(msg->pcb, msg->received); + } + return msg->err; +} + +static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) { + if(!pcb){ + return ERR_CONN; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + msg.received = len; + tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; + if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { + msg->err = tcp_close(msg->pcb); + } + return msg->err; +} + +static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) { + if(!pcb){ + return ERR_CONN; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; + if(msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) { + tcp_abort(msg->pcb); + } + return msg->err; +} + +static esp_err_t _tcp_abort(tcp_pcb * pcb, int8_t closed_slot) { + if(!pcb){ + return ERR_CONN; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = tcp_connect(msg->pcb, msg->connect.addr, msg->connect.port, msg->connect.cb); + return msg->err; +} + +static esp_err_t _tcp_connect(tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * addr, uint16_t port, tcp_connected_fn cb) { + if(!pcb){ + return ESP_FAIL; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = closed_slot; + msg.connect.addr = addr; + msg.connect.port = port; + msg.connect.cb = cb; + tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_bind_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = tcp_bind(msg->pcb, msg->bind.addr, msg->bind.port); + return msg->err; +} + +static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) { + if(!pcb){ + return ESP_FAIL; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = -1; + msg.bind.addr = addr; + msg.bind.port = port; + tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call_data*)&msg); + return msg.err; +} + +static err_t _tcp_listen_api(struct tcpip_api_call_data *api_call_msg){ + tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = 0; + msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog); + return msg->err; +} + +static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) { + if(!pcb){ + return NULL; + } + tcp_api_call_t msg; + msg.pcb = pcb; + msg.closed_slot = -1; + msg.backlog = backlog?backlog:0xFF; + tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg); + return msg.pcb; +} + + + +/* + Async TCP Client + */ + +AsyncClient::AsyncClient(tcp_pcb* pcb) +: _connect_cb(0) +, _connect_cb_arg(0) +, _discard_cb(0) +, _discard_cb_arg(0) +, _sent_cb(0) +, _sent_cb_arg(0) +, _error_cb(0) +, _error_cb_arg(0) +, _recv_cb(0) +, _recv_cb_arg(0) +, _pb_cb(0) +, _pb_cb_arg(0) +, _timeout_cb(0) +, _timeout_cb_arg(0) +, _pcb_busy(false) +, _pcb_sent_at(0) +, _ack_pcb(true) +, _rx_last_packet(0) +, _rx_since_timeout(0) +, _ack_timeout(ASYNC_MAX_ACK_TIME) +, _connect_port(0) +, prev(NULL) +, next(NULL) +{ + _pcb = pcb; + _closed_slot = -1; + if(_pcb){ + _allocate_closed_slot(); + _rx_last_packet = millis(); + tcp_arg(_pcb, this); + tcp_recv(_pcb, &_tcp_recv); + tcp_sent(_pcb, &_tcp_sent); + tcp_err(_pcb, &_tcp_error); + tcp_poll(_pcb, &_tcp_poll, 1); + } +} + +AsyncClient::~AsyncClient(){ + if(_pcb) { + _close(); + } + _free_closed_slot(); +} + +/* + * Operators + * */ + +AsyncClient& AsyncClient::operator=(const AsyncClient& other){ + if (_pcb) { + _close(); + } + + _pcb = other._pcb; + _closed_slot = other._closed_slot; + if (_pcb) { + _rx_last_packet = millis(); + tcp_arg(_pcb, this); + tcp_recv(_pcb, &_tcp_recv); + tcp_sent(_pcb, &_tcp_sent); + tcp_err(_pcb, &_tcp_error); + tcp_poll(_pcb, &_tcp_poll, 1); + } + return *this; +} + +bool AsyncClient::operator==(const AsyncClient &other) { + return _pcb == other._pcb; +} + +AsyncClient & AsyncClient::operator+=(const AsyncClient &other) { + if(next == NULL){ + next = (AsyncClient*)(&other); + next->prev = this; + } else { + AsyncClient *c = next; + while(c->next != NULL) { + c = c->next; + } + c->next =(AsyncClient*)(&other); + c->next->prev = c; + } + return *this; +} + +/* + * Callback Setters + * */ + +void AsyncClient::onConnect(AcConnectHandler cb, void* arg){ + _connect_cb = cb; + _connect_cb_arg = arg; +} + +void AsyncClient::onDisconnect(AcConnectHandler cb, void* arg){ + _discard_cb = cb; + _discard_cb_arg = arg; +} + +void AsyncClient::onAck(AcAckHandler cb, void* arg){ + _sent_cb = cb; + _sent_cb_arg = arg; +} + +void AsyncClient::onError(AcErrorHandler cb, void* arg){ + _error_cb = cb; + _error_cb_arg = arg; +} + +void AsyncClient::onData(AcDataHandler cb, void* arg){ + _recv_cb = cb; + _recv_cb_arg = arg; +} + +void AsyncClient::onPacket(AcPacketHandler cb, void* arg){ + _pb_cb = cb; + _pb_cb_arg = arg; +} + +void AsyncClient::onTimeout(AcTimeoutHandler cb, void* arg){ + _timeout_cb = cb; + _timeout_cb_arg = arg; +} + +void AsyncClient::onPoll(AcConnectHandler cb, void* arg){ + _poll_cb = cb; + _poll_cb_arg = arg; +} + +/* + * Main Public Methods + * */ + +bool AsyncClient::connect(IPAddress ip, uint16_t port){ + if (_pcb){ + log_w("already connected, state %d", _pcb->state); + return false; + } + if(!_start_async_task()){ + log_e("failed to start task"); + return false; + } + + ip_addr_t addr; + addr.type = IPADDR_TYPE_V4; + addr.u_addr.ip4.addr = ip; + + TCP_MUTEX_LOCK(); + tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4); + if (!pcb){ + TCP_MUTEX_UNLOCK(); + log_e("pcb == NULL"); + return false; + } + + tcp_arg(pcb, this); + tcp_err(pcb, &_tcp_error); + tcp_recv(pcb, &_tcp_recv); + tcp_sent(pcb, &_tcp_sent); + tcp_poll(pcb, &_tcp_poll, 1); + TCP_MUTEX_UNLOCK(); + //_tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); + _tcp_connect(pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected); + return true; +} + +bool AsyncClient::connect(const char* host, uint16_t port){ + ip_addr_t addr; + + if(!_start_async_task()){ + log_e("failed to start task"); + return false; + } + TCP_MUTEX_LOCK(); + err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this); + TCP_MUTEX_UNLOCK(); + if(err == ERR_OK) { + return connect(IPAddress(addr.u_addr.ip4.addr), port); + } else if(err == ERR_INPROGRESS) { + _connect_port = port; + return true; + } + log_e("error: %d", err); + return false; +} + +void AsyncClient::close(bool now){ + if(_pcb){ + _tcp_recved(_pcb, _closed_slot, _rx_ack_len); + } + _close(); +} + +int8_t AsyncClient::abort(){ + if(_pcb) { + _tcp_abort(_pcb, _closed_slot ); + _pcb = NULL; + } + return ERR_ABRT; +} + +size_t AsyncClient::space(){ + if((_pcb != NULL) && (_pcb->state == 4)){ + return tcp_sndbuf(_pcb); + } + return 0; +} + +size_t AsyncClient::add(const char* data, size_t size, uint8_t apiflags) { + if(!_pcb || size == 0 || data == NULL) { + return 0; + } + size_t room = space(); + if(!room) { + return 0; + } + size_t will_send = (room < size) ? room : size; + int8_t err = ERR_OK; + err = _tcp_write(_pcb, _closed_slot, data, will_send, apiflags); + if(err != ERR_OK) { + return 0; + } + return will_send; +} + +bool AsyncClient::send(){ + int8_t err = ERR_OK; + err = _tcp_output(_pcb, _closed_slot); + if(err == ERR_OK){ + _pcb_busy = true; + _pcb_sent_at = millis(); + return true; + } + return false; +} + +size_t AsyncClient::ack(size_t len){ + if(len > _rx_ack_len) + len = _rx_ack_len; + if(len){ + _tcp_recved(_pcb, _closed_slot, len); + } + _rx_ack_len -= len; + return len; +} + +void AsyncClient::ackPacket(struct pbuf * pb){ + if(!pb){ + return; + } + _tcp_recved(_pcb, _closed_slot, pb->len); + pbuf_free(pb); +} + +/* + * Main Private Methods + * */ + +int8_t AsyncClient::_close(){ + //ets_printf("X: 0x%08x\n", (uint32_t)this); + int8_t err = ERR_OK; + if(_pcb) { + //log_i(""); + TCP_MUTEX_LOCK(); + tcp_arg(_pcb, NULL); + tcp_sent(_pcb, NULL); + tcp_recv(_pcb, NULL); + tcp_err(_pcb, NULL); + tcp_poll(_pcb, NULL, 0); + TCP_MUTEX_UNLOCK(); + _tcp_clear_events(this); + err = _tcp_close(_pcb, _closed_slot); + if(err != ERR_OK) { + err = abort(); + } + _pcb = NULL; + if(_discard_cb) { + _discard_cb(_discard_cb_arg, this); + } + } + return err; +} + +void AsyncClient::_allocate_closed_slot(){ + xSemaphoreTake(_slots_lock, portMAX_DELAY); + uint32_t closed_slot_min_index = 0; + for (int i = 0; i < _number_of_closed_slots; ++ i) { + if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) { + closed_slot_min_index = _closed_slots[i]; + _closed_slot = i; + } + } + if (_closed_slot != -1) { + _closed_slots[_closed_slot] = 0; + } + xSemaphoreGive(_slots_lock); +} + +void AsyncClient::_free_closed_slot(){ + if (_closed_slot != -1) { + _closed_slots[_closed_slot] = _closed_index; + _closed_slot = -1; + ++ _closed_index; + } +} + +/* + * Private Callbacks + * */ + +int8_t AsyncClient::_connected(void* pcb, int8_t err){ + _pcb = reinterpret_cast(pcb); + if(_pcb){ + _rx_last_packet = millis(); + _pcb_busy = false; +// tcp_recv(_pcb, &_tcp_recv); +// tcp_sent(_pcb, &_tcp_sent); +// tcp_poll(_pcb, &_tcp_poll, 1); + } + if(_connect_cb) { + _connect_cb(_connect_cb_arg, this); + } + return ERR_OK; +} + +void AsyncClient::_error(int8_t err) { + if(_pcb){ + tcp_arg(_pcb, NULL); + if(_pcb->state == LISTEN) { + tcp_sent(_pcb, NULL); + tcp_recv(_pcb, NULL); + tcp_err(_pcb, NULL); + tcp_poll(_pcb, NULL, 0); + } + _pcb = NULL; + } + if(_error_cb) { + _error_cb(_error_cb_arg, this, err); + } + if(_discard_cb) { + _discard_cb(_discard_cb_arg, this); + } +} + +//In LwIP Thread +int8_t AsyncClient::_lwip_fin(tcp_pcb* pcb, int8_t err) { + if(!_pcb || pcb != _pcb){ + log_e("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb); + return ERR_OK; + } + tcp_arg(_pcb, NULL); + if(_pcb->state == LISTEN) { + tcp_sent(_pcb, NULL); + tcp_recv(_pcb, NULL); + tcp_err(_pcb, NULL); + tcp_poll(_pcb, NULL, 0); + } + if(tcp_close(_pcb) != ERR_OK) { + tcp_abort(_pcb); + } + _free_closed_slot(); + _pcb = NULL; + return ERR_OK; +} + +//In Async Thread +int8_t AsyncClient::_fin(tcp_pcb* pcb, int8_t err) { + _tcp_clear_events(this); + if(_discard_cb) { + _discard_cb(_discard_cb_arg, this); + } + return ERR_OK; +} + +int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) { + _rx_last_packet = millis(); + //log_i("%u", len); + _pcb_busy = false; + if(_sent_cb) { + _sent_cb(_sent_cb_arg, this, len, (millis() - _pcb_sent_at)); + } + return ERR_OK; +} + +int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) { + while(pb != NULL) { + _rx_last_packet = millis(); + //we should not ack before we assimilate the data + _ack_pcb = true; + pbuf *b = pb; + pb = b->next; + b->next = NULL; + if(_pb_cb){ + _pb_cb(_pb_cb_arg, this, b); + } else { + if(_recv_cb) { + _recv_cb(_recv_cb_arg, this, b->payload, b->len); + } + if(!_ack_pcb) { + _rx_ack_len += b->len; + } else if(_pcb) { + _tcp_recved(_pcb, _closed_slot, b->len); + } + pbuf_free(b); + } + } + return ERR_OK; +} + +int8_t AsyncClient::_poll(tcp_pcb* pcb){ + if(!_pcb){ + log_w("pcb is NULL"); + return ERR_OK; + } + if(pcb != _pcb){ + log_e("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb); + return ERR_OK; + } + + uint32_t now = millis(); + + // ACK Timeout + if(_pcb_busy && _ack_timeout && (now - _pcb_sent_at) >= _ack_timeout){ + _pcb_busy = false; + log_w("ack timeout %d", pcb->state); + if(_timeout_cb) + _timeout_cb(_timeout_cb_arg, this, (now - _pcb_sent_at)); + return ERR_OK; + } + // RX Timeout + if(_rx_since_timeout && (now - _rx_last_packet) >= (_rx_since_timeout * 1000)){ + log_w("rx timeout %d", pcb->state); + _close(); + return ERR_OK; + } + // Everything is fine + if(_poll_cb) { + _poll_cb(_poll_cb_arg, this); + } + return ERR_OK; +} + +void AsyncClient::_dns_found(struct ip_addr *ipaddr){ + if(ipaddr && ipaddr->u_addr.ip4.addr){ + connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port); + } else { + if(_error_cb) { + _error_cb(_error_cb_arg, this, -55); + } + if(_discard_cb) { + _discard_cb(_discard_cb_arg, this); + } + } +} + +/* + * Public Helper Methods + * */ + +void AsyncClient::stop() { + close(false); +} + +bool AsyncClient::free(){ + if(!_pcb) { + return true; + } + if(_pcb->state == 0 || _pcb->state > 4) { + return true; + } + return false; +} + +size_t AsyncClient::write(const char* data) { + if(data == NULL) { + return 0; + } + return write(data, strlen(data)); +} + +size_t AsyncClient::write(const char* data, size_t size, uint8_t apiflags) { + size_t will_send = add(data, size, apiflags); + if(!will_send || !send()) { + return 0; + } + return will_send; +} + +void AsyncClient::setRxTimeout(uint32_t timeout){ + _rx_since_timeout = timeout; +} + +uint32_t AsyncClient::getRxTimeout(){ + return _rx_since_timeout; +} + +uint32_t AsyncClient::getAckTimeout(){ + return _ack_timeout; +} + +void AsyncClient::setAckTimeout(uint32_t timeout){ + _ack_timeout = timeout; +} + +void AsyncClient::setNoDelay(bool nodelay){ + if(!_pcb) { + return; + } + if(nodelay) { + tcp_nagle_disable(_pcb); + } else { + tcp_nagle_enable(_pcb); + } +} + +bool AsyncClient::getNoDelay(){ + if(!_pcb) { + return false; + } + return tcp_nagle_disabled(_pcb); +} + +uint16_t AsyncClient::getMss(){ + if(!_pcb) { + return 0; + } + return tcp_mss(_pcb); +} + +uint32_t AsyncClient::getRemoteAddress() { + if(!_pcb) { + return 0; + } + return _pcb->remote_ip.u_addr.ip4.addr; +} + +uint16_t AsyncClient::getRemotePort() { + if(!_pcb) { + return 0; + } + return _pcb->remote_port; +} + +uint32_t AsyncClient::getLocalAddress() { + if(!_pcb) { + return 0; + } + return _pcb->local_ip.u_addr.ip4.addr; +} + +uint16_t AsyncClient::getLocalPort() { + if(!_pcb) { + return 0; + } + return _pcb->local_port; +} + +IPAddress AsyncClient::remoteIP() { + return IPAddress(getRemoteAddress()); +} + +uint16_t AsyncClient::remotePort() { + return getRemotePort(); +} + +IPAddress AsyncClient::localIP() { + return IPAddress(getLocalAddress()); +} + +uint16_t AsyncClient::localPort() { + return getLocalPort(); +} + +uint8_t AsyncClient::state() { + if(!_pcb) { + return 0; + } + return _pcb->state; +} + +bool AsyncClient::connected(){ + if (!_pcb) { + return false; + } + return _pcb->state == 4; +} + +bool AsyncClient::connecting(){ + if (!_pcb) { + return false; + } + return _pcb->state > 0 && _pcb->state < 4; +} + +bool AsyncClient::disconnecting(){ + if (!_pcb) { + return false; + } + return _pcb->state > 4 && _pcb->state < 10; +} + +bool AsyncClient::disconnected(){ + if (!_pcb) { + return true; + } + return _pcb->state == 0 || _pcb->state == 10; +} + +bool AsyncClient::freeable(){ + if (!_pcb) { + return true; + } + return _pcb->state == 0 || _pcb->state > 4; +} + +bool AsyncClient::canSend(){ + return space() > 0; +} + +const char * AsyncClient::errorToString(int8_t error){ + switch(error){ + case ERR_OK: return "OK"; + case ERR_MEM: return "Out of memory error"; + case ERR_BUF: return "Buffer error"; + case ERR_TIMEOUT: return "Timeout"; + case ERR_RTE: return "Routing problem"; + case ERR_INPROGRESS: return "Operation in progress"; + case ERR_VAL: return "Illegal value"; + case ERR_WOULDBLOCK: return "Operation would block"; + case ERR_USE: return "Address in use"; + case ERR_ALREADY: return "Already connected"; + case ERR_CONN: return "Not connected"; + case ERR_IF: return "Low-level netif error"; + case ERR_ABRT: return "Connection aborted"; + case ERR_RST: return "Connection reset"; + case ERR_CLSD: return "Connection closed"; + case ERR_ARG: return "Illegal argument"; + case -55: return "DNS failed"; + default: return "UNKNOWN"; + } +} + +const char * AsyncClient::stateToString(){ + switch(state()){ + case 0: return "Closed"; + case 1: return "Listen"; + case 2: return "SYN Sent"; + case 3: return "SYN Received"; + case 4: return "Established"; + case 5: return "FIN Wait 1"; + case 6: return "FIN Wait 2"; + case 7: return "Close Wait"; + case 8: return "Closing"; + case 9: return "Last ACK"; + case 10: return "Time Wait"; + default: return "UNKNOWN"; + } +} + +/* + * Static Callbacks (LwIP C2C++ interconnect) + * */ + +void AsyncClient::_s_dns_found(const char * name, struct ip_addr * ipaddr, void * arg){ + reinterpret_cast(arg)->_dns_found(ipaddr); +} + +int8_t AsyncClient::_s_poll(void * arg, struct tcp_pcb * pcb) { + return reinterpret_cast(arg)->_poll(pcb); +} + +int8_t AsyncClient::_s_recv(void * arg, struct tcp_pcb * pcb, struct pbuf *pb, int8_t err) { + return reinterpret_cast(arg)->_recv(pcb, pb, err); +} + +int8_t AsyncClient::_s_fin(void * arg, struct tcp_pcb * pcb, int8_t err) { + return reinterpret_cast(arg)->_fin(pcb, err); +} + +int8_t AsyncClient::_s_lwip_fin(void * arg, struct tcp_pcb * pcb, int8_t err) { + return reinterpret_cast(arg)->_lwip_fin(pcb, err); +} + +int8_t AsyncClient::_s_sent(void * arg, struct tcp_pcb * pcb, uint16_t len) { + return reinterpret_cast(arg)->_sent(pcb, len); +} + +void AsyncClient::_s_error(void * arg, int8_t err) { + reinterpret_cast(arg)->_error(err); +} + +int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){ + return reinterpret_cast(arg)->_connected(pcb, err); +} + +/* + Async TCP Server + */ + +AsyncServer::AsyncServer(IPAddress addr, uint16_t port) +: _port(port) +, _addr(addr) +, _noDelay(false) +, _pcb(0) +, _connect_cb(0) +, _connect_cb_arg(0) +{} + +AsyncServer::AsyncServer(uint16_t port) +: _port(port) +, _addr((uint32_t) IPADDR_ANY) +, _noDelay(false) +, _pcb(0) +, _connect_cb(0) +, _connect_cb_arg(0) +{} + +AsyncServer::~AsyncServer(){ + end(); +} + +void AsyncServer::onClient(AcConnectHandler cb, void* arg){ + _connect_cb = cb; + _connect_cb_arg = arg; +} + +void AsyncServer::begin(){ + if(_pcb) { + return; + } + + if(!_start_async_task()){ + log_e("failed to start task"); + return; + } + int8_t err; + TCP_MUTEX_LOCK(); + _pcb = tcp_new_ip_type(IPADDR_TYPE_V4); + TCP_MUTEX_UNLOCK(); + if (!_pcb){ + log_e("_pcb == NULL"); + return; + } + + ip_addr_t local_addr; + local_addr.type = IPADDR_TYPE_V4; + local_addr.u_addr.ip4.addr = (uint32_t) _addr; + err = _tcp_bind(_pcb, &local_addr, _port); + + if (err != ERR_OK) { + _tcp_close(_pcb, -1); + log_e("bind error: %d", err); + return; + } + + static uint8_t backlog = 5; + _pcb = _tcp_listen_with_backlog(_pcb, backlog); + if (!_pcb) { + log_e("listen_pcb == NULL"); + return; + } + TCP_MUTEX_LOCK(); + tcp_arg(_pcb, (void*) this); + tcp_accept(_pcb, &_s_accept); + TCP_MUTEX_UNLOCK(); +} + +void AsyncServer::end(){ + if(_pcb){ + TCP_MUTEX_LOCK(); + tcp_arg(_pcb, NULL); + tcp_accept(_pcb, NULL); + TCP_MUTEX_UNLOCK(); + if(tcp_close(_pcb) != ERR_OK){ + _tcp_abort(_pcb, -1); + } + _pcb = NULL; + } +} + +//runs on LwIP thread +int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err){ + //ets_printf("+A: 0x%08x\n", pcb); + if(_connect_cb){ + AsyncClient *c = new AsyncClient(pcb); + if(c){ + c->setNoDelay(_noDelay); + return _tcp_accept(this, c); + } + } + if(tcp_close(pcb) != ERR_OK){ + tcp_abort(pcb); + } + log_e("FAIL"); + return ERR_OK; +} + +int8_t AsyncServer::_accepted(AsyncClient* client){ + if(_connect_cb){ + _connect_cb(_connect_cb_arg, client); + } + return ERR_OK; +} + +void AsyncServer::setNoDelay(bool nodelay){ + _noDelay = nodelay; +} + +bool AsyncServer::getNoDelay(){ + return _noDelay; +} + +uint8_t AsyncServer::status(){ + if (!_pcb) { + return 0; + } + return _pcb->state; +} + +int8_t AsyncServer::_s_accept(void * arg, tcp_pcb * pcb, int8_t err){ + return reinterpret_cast(arg)->_accept(pcb, err); +} + +int8_t AsyncServer::_s_accepted(void *arg, AsyncClient* client){ + return reinterpret_cast(arg)->_accepted(client); +} diff --git a/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.h b/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.h new file mode 100644 index 00000000..b89fb122 --- /dev/null +++ b/Software/src/lib/me-no-dev-AsyncTCP/src/AsyncTCP.h @@ -0,0 +1,220 @@ +/* + Asynchronous TCP library for Espressif MCUs + + Copyright (c) 2016 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ASYNCTCP_H_ +#define ASYNCTCP_H_ + +#include "IPAddress.h" +#include "sdkconfig.h" +#include +extern "C" { + #include "freertos/semphr.h" + #include "lwip/pbuf.h" +} + +#include "../../../system_settings.h" +#include "../../../devboard/hal/hal.h" + +//If core is not defined, then we are running in Arduino or PIO +#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE +#define CONFIG_ASYNC_TCP_RUNNING_CORE WIFI_CORE //any available core +#define CONFIG_ASYNC_TCP_USE_WDT 0 //if enabled, adds between 33us and 200us per event +#endif + +class AsyncClient; + +#define ASYNC_MAX_ACK_TIME 5000 +#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given) +#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react. + +typedef std::function AcConnectHandler; +typedef std::function AcAckHandler; +typedef std::function AcErrorHandler; +typedef std::function AcDataHandler; +typedef std::function AcPacketHandler; +typedef std::function AcTimeoutHandler; + +struct tcp_pcb; +struct ip_addr; + +class AsyncClient { + public: + AsyncClient(tcp_pcb* pcb = 0); + ~AsyncClient(); + + AsyncClient & operator=(const AsyncClient &other); + AsyncClient & operator+=(const AsyncClient &other); + + bool operator==(const AsyncClient &other); + + bool operator!=(const AsyncClient &other) { + return !(*this == other); + } + bool connect(IPAddress ip, uint16_t port); + bool connect(const char* host, uint16_t port); + void close(bool now = false); + void stop(); + int8_t abort(); + bool free(); + + bool canSend();//ack is not pending + size_t space();//space available in the TCP window + size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending + bool send();//send all data added with the method above + + //write equals add()+send() + size_t write(const char* data); + size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true + + uint8_t state(); + bool connecting(); + bool connected(); + bool disconnecting(); + bool disconnected(); + bool freeable();//disconnected or disconnecting + + uint16_t getMss(); + + uint32_t getRxTimeout(); + void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds + + uint32_t getAckTimeout(); + void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds + + void setNoDelay(bool nodelay); + bool getNoDelay(); + + uint32_t getRemoteAddress(); + uint16_t getRemotePort(); + uint32_t getLocalAddress(); + uint16_t getLocalPort(); + + //compatibility + IPAddress remoteIP(); + uint16_t remotePort(); + IPAddress localIP(); + uint16_t localPort(); + + void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect + void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected + void onAck(AcAckHandler cb, void* arg = 0); //ack received + void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error + void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used) + void onPacket(AcPacketHandler cb, void* arg = 0); //data received + void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout + void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected + + void ackPacket(struct pbuf * pb);//ack pbuf from onPacket + size_t ack(size_t len); //ack data that you have not acked using the method below + void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData + + const char * errorToString(int8_t error); + const char * stateToString(); + + //Do not use any of the functions below! + static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb); + static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err); + static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err); + static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err); + static void _s_error(void *arg, int8_t err); + static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len); + static int8_t _s_connected(void* arg, void* tpcb, int8_t err); + static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg); + + int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err); + tcp_pcb * pcb(){ return _pcb; } + + protected: + tcp_pcb* _pcb; + int8_t _closed_slot; + + AcConnectHandler _connect_cb; + void* _connect_cb_arg; + AcConnectHandler _discard_cb; + void* _discard_cb_arg; + AcAckHandler _sent_cb; + void* _sent_cb_arg; + AcErrorHandler _error_cb; + void* _error_cb_arg; + AcDataHandler _recv_cb; + void* _recv_cb_arg; + AcPacketHandler _pb_cb; + void* _pb_cb_arg; + AcTimeoutHandler _timeout_cb; + void* _timeout_cb_arg; + AcConnectHandler _poll_cb; + void* _poll_cb_arg; + + bool _pcb_busy; + uint32_t _pcb_sent_at; + bool _ack_pcb; + uint32_t _rx_ack_len; + uint32_t _rx_last_packet; + uint32_t _rx_since_timeout; + uint32_t _ack_timeout; + uint16_t _connect_port; + + int8_t _close(); + void _free_closed_slot(); + void _allocate_closed_slot(); + int8_t _connected(void* pcb, int8_t err); + void _error(int8_t err); + int8_t _poll(tcp_pcb* pcb); + int8_t _sent(tcp_pcb* pcb, uint16_t len); + int8_t _fin(tcp_pcb* pcb, int8_t err); + int8_t _lwip_fin(tcp_pcb* pcb, int8_t err); + void _dns_found(struct ip_addr *ipaddr); + + public: + AsyncClient* prev; + AsyncClient* next; +}; + +class AsyncServer { + public: + AsyncServer(IPAddress addr, uint16_t port); + AsyncServer(uint16_t port); + ~AsyncServer(); + void onClient(AcConnectHandler cb, void* arg); + void begin(); + void end(); + void setNoDelay(bool nodelay); + bool getNoDelay(); + uint8_t status(); + + //Do not use any of the functions below! + static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err); + static int8_t _s_accepted(void *arg, AsyncClient* client); + + protected: + uint16_t _port; + IPAddress _addr; + bool _noDelay; + tcp_pcb* _pcb; + AcConnectHandler _connect_cb; + void* _connect_cb_arg; + + int8_t _accept(tcp_pcb* newpcb, int8_t err); + int8_t _accepted(AsyncClient* client); +}; + + +#endif /* ASYNCTCP_H_ */ diff --git a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncEventSource.h b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncEventSource.h index 94a0c51e..d3d1b1d4 100644 --- a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncEventSource.h +++ b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncEventSource.h @@ -22,7 +22,7 @@ #include #ifdef ESP32 -#include "../../mathieucarbou-AsyncTCP/src/AsyncTCP.h" +#include "../../me-no-dev-AsyncTCP/src/AsyncTCP.h" #define SSE_MAX_QUEUED_MESSAGES 32 #else #include diff --git a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncWebSocket.h b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncWebSocket.h index 2ef8f9ec..747399b8 100644 --- a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncWebSocket.h +++ b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/AsyncWebSocket.h @@ -23,7 +23,7 @@ #include #ifdef ESP32 -#include "../../mathieucarbou-AsyncTCP/src/AsyncTCP.h" +#include "../../me-no-dev-AsyncTCP/src/AsyncTCP.h" #define WS_MAX_QUEUED_MESSAGES 32 #else #include diff --git a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h index 7731a14c..664c0a5c 100644 --- a/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h +++ b/Software/src/lib/me-no-dev-ESPAsyncWebServer/src/ESPAsyncWebServer.h @@ -30,10 +30,10 @@ #ifdef ESP32 #include -#include "../../mathieucarbou-AsyncTCP/src/AsyncTCP.h" +#include "../../me-no-dev-AsyncTCP/src/AsyncTCP.h" #elif defined(ESP8266) #include -#include "../../mathieucarbou-AsyncTCP/src/AsyncTCP.h" +#include "../../me-no-dev-AsyncTCP/src/AsyncTCP.h" #else #error Platform not supported #endif From bd5984de29bf7907189acafafe6b7020a0d98fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Dec 2024 15:39:54 +0200 Subject: [PATCH 37/93] Restore USER_SETTINGS file --- Software/USER_SETTINGS.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 90cb37f7..2cefdb7a 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -33,7 +33,7 @@ //#define TESLA_MODEL_3Y_BATTERY //#define TESLA_MODEL_SX_BATTERY //#define VOLVO_SPA_BATTERY -#define TEST_FAKE_BATTERY +//#define TEST_FAKE_BATTERY //#define DOUBLE_BATTERY //Enable this line if you use two identical batteries at the same time (requires CAN_ADDON setup) /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ @@ -53,8 +53,8 @@ //#define SOLAX_CAN //Enable this line to emulate a "SolaX Triple Power LFP" over CAN bus /* Select hardware used for Battery-Emulator */ -//#define HW_LILYGO -#define HW_STARK +#define HW_LILYGO +//#define HW_STARK //#define HW_3LB /* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */ 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 38/93] 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 023fbc6e72313136eb1cfcb71bdf38928b372dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 23 Dec 2024 16:09:42 +0200 Subject: [PATCH 39/93] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d3acd4be..2e897f0e 100644 --- a/README.md +++ b/README.md @@ -44,17 +44,18 @@ For more examples showing wiring, see each battery types own Wiki page. For inst 3. Click `File` menu -> `Preferences` -> `Additional Development` -> `Additional Board Manager URLs` -> Enter the URL in the input box: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json` and click OK. 4. Click `Tools` menu -> `Board: "...."` -> `Boards Manager...`, install the `esp32` package by `Espressif Systems` (not `Arduino ESP32 Boards`), then press `Close`. -**NOTE: The version depends on which release of Battery-Emulator you are running!** +**NOTE: The ESP32 version depends on which release of Battery-Emulator you are running!** - ⚠️ Make sure to use a 2.x.x version if you are on a release **older** than 6.0.0 (For instance ESP32 v2.0.11 when using Battery-Emulator v5.4.0) -- ⚠️ Make sure to use a 3.x.x version if you are on a release **newer** than 6.0.0 (For instance ESP32 v3.0.0 when using Battery-Emulator v6.0.0) - +- ⚠️ Make sure to use a 3.0.x version if you are on a release **newer** than 6.0.0 (For instance ESP32 v3.0.0 when using Battery-Emulator v6.0.0) +- ⚠️ Make sure to use a 3.1.x version if you are on a release **newer** than 8.0.0 (For instance ESP32 v3.1.0 when using Battery-Emulator v8.0.0) + ![bild](https://github.com/dalathegreat/Battery-Emulator/assets/26695010/6a2414b1-f2ca-4746-8e8d-9afd78bd9252) 5. The Arduino board should be set to `ESP32 Dev Module` (under `Tools` -> `Board` -> `ESP32 Arduino`) with the following settings: ![alt text](https://github.com/Xinyuan-LilyGO/T-CAN485/blob/main/img/arduino_setting.png) 6. Select which battery type you will use, along with other optional settings. This is done in the `USER_SETTINGS.h` file. -7. Copy the `USER_SECRETS.TEMPLATE.h` file to `USER_SECRETS.h` and update relevant secrets. +7. Copy the `USER_SECRETS.TEMPLATE.h` file to `USER_SECRETS.h` and update connectivity settings inside this file. 8. Press `Verify` and `Upload` to send the sketch to the board. NOTE: In some cases, the LilyGo must be powered through the main power connector instead of USB-C when performing the initial firmware upload. 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 40/93] 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 From ad84b7e0f8230573dc92539c11f4a51456094078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 24 Dec 2024 00:22:33 +0200 Subject: [PATCH 41/93] Make USER_SETTINGS more simplified --- Software/Software.ino | 14 ++++++-------- Software/USER_SECRETS.TEMPLATE.h | 27 +++++++++++++++++---------- Software/USER_SETTINGS.cpp | 28 ++++++++++------------------ Software/USER_SETTINGS.h | 22 +++++++--------------- Software/src/devboard/wifi/wifi.cpp | 8 ++------ 5 files changed, 42 insertions(+), 57 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 60cc30d2..ce84181b 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -1,16 +1,13 @@ /* Do not change any code below this line unless you are sure what you are doing */ /* Only change battery specific settings in "USER_SETTINGS.h" */ - -#include "src/include.h" - #include "HardwareSerial.h" +#include "USER_SECRETS.h" #include "USER_SETTINGS.h" #include "esp_system.h" #include "esp_task_wdt.h" #include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "src/charger/CHARGERS.h" #include "src/communication/can/comm_can.h" #include "src/communication/contactorcontrol/comm_contactorcontrol.h" #include "src/communication/equipmentstopbutton/comm_equipmentstopbutton.h" @@ -22,6 +19,7 @@ #include "src/devboard/utils/led_handler.h" #include "src/devboard/utils/logging.h" #include "src/devboard/utils/value_mapping.h" +#include "src/include.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h" #include "src/lib/bblanchon-ArduinoJson/ArduinoJson.h" @@ -30,7 +28,10 @@ #include "src/lib/eModbus-eModbus/scripts/mbServerFCs.h" #include "src/lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" #include "src/lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" - +#ifndef AP_PASSWORD +#error \ + "Initial setup not completed, USER_SECRETS.h is missing. Please rename the file USER_SECRETS.TEMPLATE.h to USER_SECRETS.h and fill in the required credentials. This file is ignored by version control to keep sensitive information private." +#endif #ifdef WIFI #include "src/devboard/wifi/wifi.h" #ifdef WEBSERVER @@ -233,9 +234,6 @@ void core_loop(void* task_time_us) { update_machineryprotection(); // Check safeties (Not on serial link reciever board) #endif // SERIAL_LINK_RECEIVER update_values_inverter(); // Update values heading towards inverter - if (DUMMY_EVENT_ENABLED) { - set_event(EVENT_DUMMY_ERROR, (uint8_t)millis()); - } } END_TIME_MEASUREMENT_MAX(time_values, datalayer.system.status.time_values_us); diff --git a/Software/USER_SECRETS.TEMPLATE.h b/Software/USER_SECRETS.TEMPLATE.h index 1d1b0569..1cd013b9 100644 --- a/Software/USER_SECRETS.TEMPLATE.h +++ b/Software/USER_SECRETS.TEMPLATE.h @@ -1,13 +1,20 @@ -#define WIFI_SSID "REPLACE_WITH_YOUR_SSID" // Maximum of 63 characters -#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" // Minimum of 8 characters +/* This file should be renamed to USER_SECRETS.h to be able to use the software! +It contains all the credentials that should never be made public */ + +//Password to the access point generated by the Battery-Emulator #define AP_PASSWORD "123456789" // Minimum of 8 characters; set to blank if you want the access point to be open -#define WEBSERVER_AUTH_REQUIRED \ - false //Set this line to true to activate webserver authentication (this line must not be commented). -#define HTTP_USERNAME "admin" // username to webserver authentication; -#define HTTP_PASSWORD "admin" // password to webserver authentication; +//Name and password of Wifi network you want the emulator to connect to +#define WIFI_SSID "REPLACE_WITH_YOUR_SSID" // Maximum of 63 characters +#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" // Minimum of 8 characters -#define MQTT_SERVER "192.168.xxx.yyy" // mqtt server address -#define MQTT_PORT 1883 // mqtt server port -#define MQTT_USER NULL // mqtt username, leave blank for no authentication -#define MQTT_PASSWORD NULL // mqtt password, leave blank for no authentication +//Set WEBSERVER_AUTH_REQUIRED to true to require a password when accessing the webserver homepage. Improves cybersecurity. +#define WEBSERVER_AUTH_REQUIRED false +#define HTTP_USERNAME "admin" // Username for webserver authentication +#define HTTP_PASSWORD "admin" // Password for webserver authentication + +//MQTT credentials +#define MQTT_SERVER "192.168.xxx.yyy" // MQTT server address +#define MQTT_PORT 1883 // MQTT server port +#define MQTT_USER NULL // MQTT username, leave blank for no authentication +#define MQTT_PASSWORD NULL // MQTT password, leave blank for no authentication diff --git a/Software/USER_SETTINGS.cpp b/Software/USER_SETTINGS.cpp index 7c406893..0ed5c847 100644 --- a/Software/USER_SETTINGS.cpp +++ b/Software/USER_SETTINGS.cpp @@ -20,28 +20,21 @@ volatile CAN_Configuration can_config = { .charger = CAN_NATIVE // (OPTIONAL) Which CAN is your charger connected to? }; -#ifdef WIFI +std::string ssid = WIFI_SSID; // Set in USER_SECRETS.h +std::string password = WIFI_PASSWORD; // Set in USER_SECRETS.h +const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface +const char* passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h +const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection -volatile uint8_t AccessPointEnabled = true; //Set to either true/false to enable direct wifi access point -std::string ssid = WIFI_SSID; // Set in USER_SECRETS.h -std::string password = WIFI_PASSWORD; // Set in USER_SECRETS.h -const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface -const char* passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h -const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection - -#ifdef WIFICONFIG -// Set your Static IP address -IPAddress local_IP(192, 168, 10, 150); -// Set your Gateway IP address -IPAddress gateway(192, 168, 10, 1); -// Set your Subnet IP address -IPAddress subnet(255, 255, 255, 0); -#endif #ifdef WEBSERVER const char* http_username = HTTP_USERNAME; // Set in USER_SECRETS.h const char* http_password = HTTP_PASSWORD; // Set in USER_SECRETS.h - +// Set your Static IP address. Only used incase WIFICONFIG is set in USER_SETTINGS.h +IPAddress local_IP(192, 168, 10, 150); +IPAddress gateway(192, 168, 10, 1); +IPAddress subnet(255, 255, 255, 0); #endif // WEBSERVER + // MQTT #ifdef MQTT const char* mqtt_user = MQTT_USER; // Set in USER_SECRETS.h @@ -55,7 +48,6 @@ const char* mqtt_device_name = "Battery Emulator"; // Custom device name in Home Assistant. Previously, the name was automatically set to "BatteryEmulator_esp32-XXXXXX" #endif // MQTT_MANUAL_TOPIC_OBJECT_NAME #endif // USE_MQTT -#endif // WIFI #ifdef EQUIPMENT_STOP_BUTTON // Equipment stop button behavior. Use NC button for safety reasons. diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index a73799c5..a541950b 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -3,7 +3,7 @@ #include #include -/* This file contains all the battery/inverter protocol settings Battery-Emulator software */ +/* This file contains all sthe battery/inverter protocol settings Battery-Emulator software */ /* To switch between batteries/inverters, uncomment a line to enable, comment out to disable. */ /* There are also some options for battery limits and extra functionality */ /* To edit battery specific limits, see also the USER_SETTINGS.cpp file*/ @@ -77,20 +77,17 @@ //#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery) #define CRYSTAL_FREQUENCY_MHZ 8 //CAN_ADDON option, what is your MCP2515 add-on boards crystal frequency? //#define CANFD_ADDON //Enable this line to activate an isolated secondary CAN-FD bus using add-on MCP2518FD chip / Native CANFD on Stark board -#ifdef CANFD_ADDON // CANFD_ADDON additional options if enabled #define CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ \ - ACAN2517FDSettings:: \ - OSC_40MHz //CANFD_ADDON option, what is your MCP2518 add-on boards crystal frequency? (Default OSC_40MHz) -#endif // CANFD_ADDON + ACAN2517FDSettings::OSC_40MHz //CANFD_ADDON option, what is your MCP2518 add-on boards crystal frequency? //#define USE_CANFD_INTERFACE_AS_CLASSIC_CAN // Enable this line if you intend to use the CANFD as normal CAN //#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter) //#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery) #define WIFI //#define WIFICONFIG //Enable this line to set a static IP address / gateway /subnet mask for the device. see USER_SETTINGS.cpp for the settings #define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings. -#define WIFIAP //Disable this line to permanently disable WIFI AP mode (make sure to hardcode ssid and password of you home wifi network). When enabled WIFI AP can still be disabled by a setting in the future. +#define WIFIAP //When enabled, the emulator will broadcast its own access point Wifi. Can be used at the same time as a normal Wifi connection to a router. #define MDNSRESPONDER //Enable this line to enable MDNS, allows battery monitor te be found by .local address. Requires WEBSERVER to be enabled. -#define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot (overrides Wifi/battery settings set below) +#define LOAD_SAVED_SETTINGS_ON_BOOT // Enable this line to read settings stored via the webserver on boot (overrides Wifi credentials set here) //#define FUNCTION_TIME_MEASUREMENT // Enable this to record execution times and present them in the web UI (WARNING, raises CPU load, do not use for production) //#define EQUIPMENT_STOP_BUTTON // Enable this to allow an equipment stop button connected to the Battery-Emulator to disengage the battery @@ -107,12 +104,9 @@ /* Home Assistant options */ #define HA_AUTODISCOVERY // Enable this line to send Home Assistant autodiscovery messages. If not enabled manual configuration of Home Assitant is required -/* Event options*/ -#define DUMMY_EVENT_ENABLED false //Enable this line to have a dummy event that gets logged to test the interface - /* Select charger used (Optional) */ //#define CHEVYVOLT_CHARGER //Enable this line to control a Chevrolet Volt charger connected to battery - for example, when generator charging or using an inverter without a charging function. -//#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging +#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging /* Battery settings */ // Predefined total energy capacity of the battery in Watt-hours @@ -138,8 +132,8 @@ // 3000 = 300.0V, Target discharge voltage (Value can be tuned on the fly via webserver). Not used unless BATTERY_USE_VOLTAGE_LIMITS = true #define BATTERY_MAX_DISCHARGE_VOLTAGE 3000 -/* Do not change any code below this line unless you are sure what you are doing */ -/* Only change battery specific settings in "USER_SETTINGS.h" */ +/* Do not change any code below this line */ +/* Only change battery specific settings above and in "USER_SETTINGS.cpp" */ typedef enum { CAN_NATIVE = 0, CANFD_NATIVE = 1, CAN_ADDON_MCP2515 = 2, CANFD_ADDON_MCP2518 = 3 } CAN_Interface; typedef struct { CAN_Interface battery; @@ -169,9 +163,7 @@ extern volatile STOP_BUTTON_BEHAVIOR equipment_stop_behavior; #ifdef WIFICONFIG extern IPAddress local_IP; -// Set your Gateway IP address extern IPAddress gateway; -// Set your Subnet IP address extern IPAddress subnet; #endif diff --git a/Software/src/devboard/wifi/wifi.cpp b/Software/src/devboard/wifi/wifi.cpp index 3dba4b72..7ebcc9c3 100644 --- a/Software/src/devboard/wifi/wifi.cpp +++ b/Software/src/devboard/wifi/wifi.cpp @@ -29,12 +29,8 @@ static bool connected_once = false; void init_WiFi() { #ifdef WIFIAP - if (AccessPointEnabled) { - WiFi.mode(WIFI_AP_STA); // Simultaneous WiFi AP and Router connection - init_WiFi_AP(); - } else { - WiFi.mode(WIFI_STA); // Only Router connection - } + WiFi.mode(WIFI_AP_STA); // Simultaneous WiFi AP and Router connection + init_WiFi_AP(); #else WiFi.mode(WIFI_STA); // Only Router connection #endif // WIFIAP From 24baf4199449e533e62da334756bea20eafe9a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 24 Dec 2024 00:31:13 +0200 Subject: [PATCH 42/93] fix order of includes --- Software/Software.ino | 2 +- Software/USER_SETTINGS.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index ce84181b..2cbecee8 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -1,5 +1,6 @@ /* Do not change any code below this line unless you are sure what you are doing */ /* Only change battery specific settings in "USER_SETTINGS.h" */ +#include "src/include.h" #include "HardwareSerial.h" #include "USER_SECRETS.h" #include "USER_SETTINGS.h" @@ -19,7 +20,6 @@ #include "src/devboard/utils/led_handler.h" #include "src/devboard/utils/logging.h" #include "src/devboard/utils/value_mapping.h" -#include "src/include.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h" #include "src/lib/bblanchon-ArduinoJson/ArduinoJson.h" diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index a541950b..248332fa 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -3,7 +3,7 @@ #include #include -/* This file contains all sthe battery/inverter protocol settings Battery-Emulator software */ +/* This file contains all the battery/inverter protocol settings Battery-Emulator software */ /* To switch between batteries/inverters, uncomment a line to enable, comment out to disable. */ /* There are also some options for battery limits and extra functionality */ /* To edit battery specific limits, see also the USER_SETTINGS.cpp file*/ @@ -106,7 +106,7 @@ /* Select charger used (Optional) */ //#define CHEVYVOLT_CHARGER //Enable this line to control a Chevrolet Volt charger connected to battery - for example, when generator charging or using an inverter without a charging function. -#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging +//#define NISSANLEAF_CHARGER //Enable this line to control a Nissan LEAF PDM connected to battery - for example, when generator charging /* Battery settings */ // Predefined total energy capacity of the battery in Watt-hours From 0199d01287e44d6aa2ba9c42f684cf4cdc8f3ae0 Mon Sep 17 00:00:00 2001 From: lenvm Date: Tue, 24 Dec 2024 22:07:10 +0100 Subject: [PATCH 43/93] make MCP2515 and MCP2518FD unique, such that they can be used simultaneously --- Software/src/communication/can/comm_can.cpp | 56 +++++++++++---------- Software/src/devboard/utils/events.cpp | 8 +-- Software/src/devboard/utils/events.h | 4 +- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index 8fa2ab3d..b9aa2259 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -9,11 +9,13 @@ volatile bool send_ok = 0; #ifdef CAN_ADDON static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h -ACAN2515 can(MCP2515_CS, SPI, MCP2515_INT); +SPIClass SPI2515; +ACAN2515 can(MCP2515_CS, SPI2515, MCP2515_INT); static ACAN2515_Buffer16 gBuffer; #endif //CAN_ADDON #ifdef CANFD_ADDON -ACAN2517FD canfd(MCP2517_CS, SPI, MCP2517_INT); +SPIClass SPI2517; +ACAN2517FD canfd(MCP2517_CS, SPI2517, MCP2517_INT); #endif //CANFD_ADDON // Initialization functions @@ -39,20 +41,20 @@ void init_CAN() { logging.println("Dual CAN Bus (ESP32+MCP2515) selected"); #endif // DEBUG_LOG gBuffer.initWithSize(25); - SPI.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI); - ACAN2515Settings settings(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s - settings.mRequestedMode = ACAN2515Settings::NormalMode; - const uint16_t errorCodeMCP = can.begin(settings, [] { can.isr(); }); - if (errorCodeMCP == 0) { + SPI2515.begin(MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI); + ACAN2515Settings settings2515(QUARTZ_FREQUENCY, 500UL * 1000UL); // CAN bit rate 500 kb/s + settings2515.mRequestedMode = ACAN2515Settings::NormalMode; + const uint16_t errorCode2515 = can.begin(settings2515, [] { can.isr(); }); + if (errorCode2515 == 0) { #ifdef DEBUG_LOG logging.println("Can ok"); #endif // DEBUG_LOG } else { #ifdef DEBUG_LOG logging.print("Error Can: 0x"); - logging.println(errorCodeMCP, HEX); + logging.println(errorCode2515, HEX); #endif // DEBUG_LOG - set_event(EVENT_CANMCP_INIT_FAILURE, (uint8_t)errorCodeMCP); + set_event(EVENT_CANMCP2515_INIT_FAILURE, (uint8_t)errorCode2515); } #endif // CAN_ADDON @@ -60,41 +62,41 @@ void init_CAN() { #ifdef DEBUG_LOG logging.println("CAN FD add-on (ESP32+MCP2517) selected"); #endif // DEBUG_LOG - SPI.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI); - ACAN2517FDSettings settings(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000, - DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s + SPI2517.begin(MCP2517_SCK, MCP2517_SDO, MCP2517_SDI); + ACAN2517FDSettings settings2517(CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, 500 * 1000, + DataBitRateFactor::x4); // Arbitration bit rate: 500 kbit/s, data bit rate: 2 Mbit/s #ifdef USE_CANFD_INTERFACE_AS_CLASSIC_CAN - settings.mRequestedMode = ACAN2517FDSettings::Normal20B; // ListenOnly / Normal20B / NormalFD -#else // not USE_CANFD_INTERFACE_AS_CLASSIC_CAN - settings.mRequestedMode = ACAN2517FDSettings::NormalFD; // ListenOnly / Normal20B / NormalFD -#endif // USE_CANFD_INTERFACE_AS_CLASSIC_CAN - const uint32_t errorCode = canfd.begin(settings, [] { canfd.isr(); }); + settings2517.mRequestedMode = ACAN2517FDSettings::Normal20B; // ListenOnly / Normal20B / NormalFD +#else // not USE_CANFD_INTERFACE_AS_CLASSIC_CAN + settings2517.mRequestedMode = ACAN2517FDSettings::NormalFD; // ListenOnly / Normal20B / NormalFD +#endif // USE_CANFD_INTERFACE_AS_CLASSIC_CAN + const uint32_t errorCode2517 = canfd.begin(settings2517, [] { canfd.isr(); }); canfd.poll(); - if (errorCode == 0) { + if (errorCode2517 == 0) { #ifdef DEBUG_LOG logging.print("Bit Rate prescaler: "); - logging.println(settings.mBitRatePrescaler); + logging.println(settings2517.mBitRatePrescaler); logging.print("Arbitration Phase segment 1: "); - logging.print(settings.mArbitrationPhaseSegment1); + logging.print(settings2517.mArbitrationPhaseSegment1); logging.print(" segment 2: "); - logging.print(settings.mArbitrationPhaseSegment2); + logging.print(settings2517.mArbitrationPhaseSegment2); logging.print(" SJW: "); - logging.println(settings.mArbitrationSJW); + logging.println(settings2517.mArbitrationSJW); logging.print("Actual Arbitration Bit Rate: "); - logging.print(settings.actualArbitrationBitRate()); + logging.print(settings2517.actualArbitrationBitRate()); logging.print(" bit/s"); logging.print(" (Exact:"); - logging.println(settings.exactArbitrationBitRate() ? "yes)" : "no)"); + logging.println(settings2517.exactArbitrationBitRate() ? "yes)" : "no)"); logging.print("Arbitration Sample point: "); - logging.print(settings.arbitrationSamplePointFromBitStart()); + logging.print(settings2517.arbitrationSamplePointFromBitStart()); logging.println("%"); #endif // DEBUG_LOG } else { #ifdef DEBUG_LOG logging.print("CAN-FD Configuration error 0x"); - logging.println(errorCode, HEX); + logging.println(errorCode2517, HEX); #endif // DEBUG_LOG - set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode); + set_event(EVENT_CANMCP2517FD_INIT_FAILURE, (uint8_t)errorCode2517); } #endif // CANFD_ADDON } diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 021b1660..88546af3 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -140,8 +140,8 @@ void init_events(void) { events.entries[i].MQTTpublished = false; // Not published by default } - events.entries[EVENT_CANFD_INIT_FAILURE].level = EVENT_LEVEL_WARNING; - events.entries[EVENT_CANMCP_INIT_FAILURE].level = EVENT_LEVEL_WARNING; + events.entries[EVENT_CANMCP2517FD_INIT_FAILURE].level = EVENT_LEVEL_WARNING; + events.entries[EVENT_CANMCP2515_INIT_FAILURE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CANFD_BUFFER_FULL].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO; events.entries[EVENT_CANFD_RX_OVERRUN].level = EVENT_LEVEL_WARNING; @@ -264,9 +264,9 @@ void set_event_MQTTpublished(EVENTS_ENUM_TYPE event) { const char* get_event_message_string(EVENTS_ENUM_TYPE event) { switch (event) { - case EVENT_CANFD_INIT_FAILURE: + case EVENT_CANMCP2517FD_INIT_FAILURE: return "CAN-FD initialization failed. Check hardware or bitrate settings"; - case EVENT_CANMCP_INIT_FAILURE: + case EVENT_CANMCP2515_INIT_FAILURE: return "CAN-MCP addon initialization failed. Check hardware"; case EVENT_CANFD_BUFFER_FULL: return "CAN-FD buffer overflowed. Some CAN messages were not sent. Contact developers."; diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index d410d66f..972842fd 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -26,8 +26,8 @@ */ #define EVENTS_ENUM_TYPE(XX) \ - XX(EVENT_CANFD_INIT_FAILURE) \ - XX(EVENT_CANMCP_INIT_FAILURE) \ + XX(EVENT_CANMCP2517FD_INIT_FAILURE) \ + XX(EVENT_CANMCP2515_INIT_FAILURE) \ XX(EVENT_CANFD_BUFFER_FULL) \ XX(EVENT_CAN_OVERRUN) \ XX(EVENT_CANFD_RX_OVERRUN) \ From 126ab438a7e1fcdd9835a26b0b1eb1d6423c30a9 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 25 Dec 2024 20:14:05 +1300 Subject: [PATCH 44/93] Update TESLA-BATTERY.cpp Change values that hold either a true/false could instead of being defined as: static uint8_t battery_packCtrsOpenNowRequested = 0; Instead be defined as: static bool battery_packCtrsOpenNowRequested = false; --- Software/src/battery/TESLA-BATTERY.cpp | 419 ++++++++++++------------- 1 file changed, 206 insertions(+), 213 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 5ecd958e..7d372393 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -37,8 +37,8 @@ static uint16_t battery_energy_to_charge_complete = 0; // kWh static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh static uint16_t battery_expected_energy_remaining = 0; // kWh static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh -static uint8_t battery_full_charge_complete = 0; // kWh -static uint8_t battery_fully_charged = 0; // kWh +static bool battery_full_charge_complete = false; // Changed to bool +static bool battery_fully_charged = false; // Changed to bool static uint16_t battery_ideal_energy_remaining = 0; // kWh static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_energy_remaining = 0; // kWh @@ -98,46 +98,46 @@ static uint8_t battery_hvil_status = 0; static uint8_t battery_packContNegativeState = 0; static uint8_t battery_packContPositiveState = 0; static uint8_t battery_packContactorSetState = 0; -static uint8_t battery_packCtrsClosingAllowed = 0; -static uint8_t battery_pyroTestInProgress = 0; -static uint8_t battery_packCtrsOpenNowRequested = 0; -static uint8_t battery_packCtrsOpenRequested = 0; +static bool battery_packCtrsClosingAllowed = false; // Change to bool +static bool battery_pyroTestInProgress = false; // Change to bool +static bool battery_packCtrsOpenNowRequested = false; // Change to bool +static bool battery_packCtrsOpenRequested = false; // Change to bool static uint8_t battery_packCtrsRequestStatus = 0; -static uint8_t battery_packCtrsResetRequestRequired = 0; -static uint8_t battery_dcLinkAllowedToEnergize = 0; -static uint8_t battery_fcContNegativeAuxOpen = 0; +static bool battery_packCtrsResetRequestRequired = false; // Change to bool +static bool battery_dcLinkAllowedToEnergize = false; // Change to bool +static bool battery_fcContNegativeAuxOpen = false; // Change to bool static uint8_t battery_fcContNegativeState = 0; -static uint8_t battery_fcContPositiveAuxOpen = 0; +static bool battery_fcContPositiveAuxOpen = false; // Change to bool static uint8_t battery_fcContPositiveState = 0; static uint8_t battery_fcContactorSetState = 0; -static uint8_t battery_fcCtrsClosingAllowed = 0; -static uint8_t battery_fcCtrsOpenNowRequested = 0; -static uint8_t battery_fcCtrsOpenRequested = 0; +static bool battery_fcCtrsClosingAllowed = false; // Change to bool +static bool battery_fcCtrsOpenNowRequested = false; // Change to bool +static bool battery_fcCtrsOpenRequested = false; // Change to bool static uint8_t battery_fcCtrsRequestStatus = 0; -static uint8_t battery_fcCtrsResetRequestRequired = 0; -static uint8_t battery_fcLinkAllowedToEnergize = 0; +static bool battery_fcCtrsResetRequestRequired = false; // Change to bool +static bool battery_fcLinkAllowedToEnergize = false; // Change to bool //0x212: 530 BMS_status -static uint8_t battery_BMS_hvacPowerRequest = 0; -static uint8_t battery_BMS_notEnoughPowerForDrive = 0; -static uint8_t battery_BMS_notEnoughPowerForSupport = 0; -static uint8_t battery_BMS_preconditionAllowed = 0; -static uint8_t battery_BMS_updateAllowed = 0; -static uint8_t battery_BMS_activeHeatingWorthwhile = 0; -static uint8_t battery_BMS_cpMiaOnHvs = 0; +static bool battery_BMS_hvacPowerRequest = false; //Change to bool +static bool battery_BMS_notEnoughPowerForDrive = false; //Change to bool +static bool battery_BMS_notEnoughPowerForSupport = false; //Change to bool +static bool battery_BMS_preconditionAllowed = false; //Change to bool +static bool battery_BMS_updateAllowed = false; //Change to bool +static bool battery_BMS_activeHeatingWorthwhile = false; //Change to bool +static bool battery_BMS_cpMiaOnHvs = false; //Change to bool static uint8_t battery_BMS_contactorState = 0; static uint8_t battery_BMS_state = 0; static uint8_t battery_BMS_hvState = 0; static uint16_t battery_BMS_isolationResistance = 0; -static uint8_t battery_BMS_chargeRequest = 0; -static uint8_t battery_BMS_keepWarmRequest = 0; +static bool battery_BMS_chargeRequest = false; //Change to bool +static bool battery_BMS_keepWarmRequest = false; //Change to bool static uint8_t battery_BMS_uiChargeStatus = 0; -static uint8_t battery_BMS_diLimpRequest = 0; -static uint8_t battery_BMS_okToShipByAir = 0; -static uint8_t battery_BMS_okToShipByLand = 0; +static bool battery_BMS_diLimpRequest = false; //Change to bool +static bool battery_BMS_okToShipByAir = false; //Change to bool +static bool battery_BMS_okToShipByLand = false; //Change to bool static uint32_t battery_BMS_chgPowerAvailable = 0; static uint8_t battery_BMS_chargeRetryCount = 0; -static uint8_t battery_BMS_pcsPwmEnabled = 0; -static uint8_t battery_BMS_ecuLogUploadRequest = 0; +static bool battery_BMS_pcsPwmEnabled = false; //Change to bool +static bool battery_BMS_ecuLogUploadRequest = false; //Change to bool static uint8_t battery_BMS_minPackTemperature = 0; // 0x224:548 PCS_dcdcStatus static uint8_t battery_PCS_dcdcPrechargeStatus = 0; @@ -145,8 +145,8 @@ static uint8_t battery_PCS_dcdc12VSupportStatus = 0; static uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; static uint16_t battery_PCS_dcdcMainState = 0; static uint8_t battery_PCS_dcdcSubState = 0; -static uint8_t battery_PCS_dcdcFaulted = 0; -static uint8_t battery_PCS_dcdcOutputIsLimited = 0; +static bool battery_PCS_dcdcFaulted = false; //Change to bool +static bool battery_PCS_dcdcOutputIsLimited = false; //Change to bool static uint32_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; static uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; static uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0; @@ -196,38 +196,38 @@ static uint16_t PCS_dcdcIntervalMinLvOutputCurr = 0; static uint32_t PCS_dcdc12vSupportLifetimekWh = 0; //0x7AA: //1962 HVP_debugMessage: static uint8_t HVP_debugMessageMultiplexer = 0; -static uint8_t HVP_gpioPassivePyroDepl = 0; -static uint8_t HVP_gpioPyroIsoEn = 0; -static uint8_t HVP_gpioCpFaultIn = 0; -static uint8_t HVP_gpioPackContPowerEn = 0; -static uint8_t HVP_gpioHvCablesOk = 0; -static uint8_t HVP_gpioHvpSelfEnable = 0; -static uint8_t HVP_gpioLed = 0; -static uint8_t HVP_gpioCrashSignal = 0; -static uint8_t HVP_gpioShuntDataReady = 0; -static uint8_t HVP_gpioFcContPosAux = 0; -static uint8_t HVP_gpioFcContNegAux = 0; -static uint8_t HVP_gpioBmsEout = 0; -static uint8_t HVP_gpioCpFaultOut = 0; -static uint8_t HVP_gpioPyroPor = 0; -static uint8_t HVP_gpioShuntEn = 0; -static uint8_t HVP_gpioHvpVerEn = 0; -static uint8_t HVP_gpioPackCoontPosFlywheel = 0; -static uint8_t HVP_gpioCpLatchEnable = 0; -static uint8_t HVP_gpioPcsEnable = 0; -static uint8_t HVP_gpioPcsDcdcPwmEnable = 0; -static uint8_t HVP_gpioPcsChargePwmEnable = 0; -static uint8_t HVP_gpioFcContPowerEnable = 0; -static uint8_t HVP_gpioHvilEnable = 0; -static uint8_t HVP_gpioSecDrdy = 0; +static bool HVP_gpioPassivePyroDepl = false; //Change to bool +static bool HVP_gpioPyroIsoEn = false; //Change to bool +static bool HVP_gpioCpFaultIn = false; //Change to bool +static bool HVP_gpioPackContPowerEn = false; //Change to bool +static bool HVP_gpioHvCablesOk = false; //Change to bool +static bool HVP_gpioHvpSelfEnable = false; //Change to bool +static bool HVP_gpioLed = false; //Change to bool +static bool HVP_gpioCrashSignal = false; //Change to bool +static bool HVP_gpioShuntDataReady = false; //Change to bool +static bool HVP_gpioFcContPosAux = false; //Change to bool +static bool HVP_gpioFcContNegAux = false; //Change to bool +static bool HVP_gpioBmsEout = false; //Change to bool +static bool HVP_gpioCpFaultOut = false; //Change to bool +static bool HVP_gpioPyroPor = false; //Change to bool +static bool HVP_gpioShuntEn = false; //Change to bool +static bool HVP_gpioHvpVerEn = false; //Change to bool +static bool HVP_gpioPackCoontPosFlywheel = false; //Change to bool +static bool HVP_gpioCpLatchEnable = false; //Change to bool +static bool HVP_gpioPcsEnable = false; //Change to bool +static bool HVP_gpioPcsDcdcPwmEnable = false; //Change to bool +static bool HVP_gpioPcsChargePwmEnable = false; //Change to bool +static bool HVP_gpioFcContPowerEnable = false; //Change to bool +static bool HVP_gpioHvilEnable = false; //Change to bool +static bool HVP_gpioSecDrdy = false; //Change to bool static uint16_t HVP_hvp1v5Ref = 0; static int16_t HVP_shuntCurrentDebug = 0; -static uint8_t HVP_packCurrentMia = 0; -static uint8_t HVP_auxCurrentMia = 0; -static uint8_t HVP_currentSenseMia = 0; -static uint8_t HVP_shuntRefVoltageMismatch = 0; -static uint8_t HVP_shuntThermistorMia = 0; -static uint8_t HVP_shuntHwMia = 0; +static bool HVP_packCurrentMia = false; //Change to bool +static bool HVP_auxCurrentMia = false; //Change to bool +static bool HVP_currentSenseMia =false; //Change to bool +static bool HVP_shuntRefVoltageMismatch = false; //Change to bool +static bool HVP_shuntThermistorMia = false; //Change to bool +static bool HVP_shuntHwMia = false; //Change to bool static int16_t HVP_dcLinkVoltage = 0; static int16_t HVP_packVoltage = 0; static int16_t HVP_fcLinkVoltage = 0; @@ -252,159 +252,152 @@ static int16_t HVP_shuntAsicTempDbg = 0; static uint8_t HVP_shuntAuxCurrentStatus = 0; static uint8_t HVP_shuntBarTempStatus = 0; static uint8_t HVP_shuntAsicTempStatus = 0; -//0x3aa: HVP_alertMatrix1 Fault codes -static uint8_t battery_WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset. -static uint8_t battery_PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss. -static uint8_t battery_SwAssertion = 0; //An internal software assertion has failed. -static uint8_t battery_CrashEvent = 0; //Warns if the crash signal is detected by HVP -static uint8_t battery_OverDchgCurrentFault = 0; //Warns if the pack discharge is above max discharge current limit -static uint8_t battery_OverChargeCurrentFault = - 0; //Warns if the pack discharge current is above max charge current limit -static uint8_t battery_OverCurrentFault = - 0; //Warns if the pack current (discharge or charge) is above max current limit. -static uint8_t battery_OverTemperatureFault = 0; //A pack module temperature is above maximum temperature limit -static uint8_t battery_OverVoltageFault = 0; //A brick voltage is above maximum voltage limit -static uint8_t battery_UnderVoltageFault = 0; //A brick voltage is below minimum voltage limit -static uint8_t battery_PrimaryBmbMiaFault = - 0; //Warns if the voltage and temperature readings from primary BMB chain are mia -static uint8_t battery_SecondaryBmbMiaFault = - 0; //Warns if the voltage and temperature readings from secondary BMB chain are mia -static uint8_t battery_BmbMismatchFault = - 0; //Warns if the primary and secondary BMB chain readings don't match with each other -static uint8_t battery_BmsHviMiaFault = 0; //Warns if the BMS node is mia on HVS or HVI CAN -static uint8_t battery_CpMiaFault = 0; //Warns if the CP node is mia on HVS CAN -static uint8_t battery_PcsMiaFault = 0; //The PCS node is mia on HVS CAN -static uint8_t battery_BmsFault = 0; //Warns if the BMS ECU has faulted -static uint8_t battery_PcsFault = 0; //Warns if the PCS ECU has faulted -static uint8_t battery_CpFault = 0; //Warns if the CP ECU has faulted -static uint8_t battery_ShuntHwMiaFault = 0; //Warns if the shunt current reading is not available -static uint8_t battery_PyroMiaFault = 0; //Warns if the pyro squib is not connected -static uint8_t battery_hvsMiaFault = 0; //Warns if the pack contactor hw fault -static uint8_t battery_hviMiaFault = 0; //Warns if the FC contactor hw fault -static uint8_t battery_Supply12vFault = 0; //Warns if the low voltage (12V) battery is below minimum voltage threshold -static uint8_t battery_VerSupplyFault = - 0; //Warns if the Energy reserve voltage supply is below minimum voltage threshold -static uint8_t battery_HvilFault = 0; //Warn if a High Voltage Inter Lock fault is detected -static uint8_t battery_BmsHvsMiaFault = 0; //Warns if the BMS node is mia on HVS or HVI CAN -static uint8_t battery_PackVoltMismatchFault = - 0; //Warns if the pack voltage doesn't match approximately with sum of brick voltages -static uint8_t battery_EnsMiaFault = 0; //Warns if the ENS line is not connected to HVC -static uint8_t battery_PackPosCtrArcFault = 0; //Warns if the HVP detectes series arc at pack contactor -static uint8_t battery_packNegCtrArcFault = 0; //Warns if the HVP detectes series arc at FC contactor -static uint8_t battery_ShuntHwAndBmsMiaFault = 0; -static uint8_t battery_fcContHwFault = 0; -static uint8_t battery_robinOverVoltageFault = 0; -static uint8_t battery_packContHwFault = 0; -static uint8_t battery_pyroFuseBlown = 0; -static uint8_t battery_pyroFuseFailedToBlow = 0; -static uint8_t battery_CpilFault = 0; -static uint8_t battery_PackContactorFellOpen = 0; -static uint8_t battery_FcContactorFellOpen = 0; -static uint8_t battery_packCtrCloseBlocked = 0; -static uint8_t battery_fcCtrCloseBlocked = 0; -static uint8_t battery_packContactorForceOpen = 0; -static uint8_t battery_fcContactorForceOpen = 0; -static uint8_t battery_dcLinkOverVoltage = 0; -static uint8_t battery_shuntOverTemperature = 0; -static uint8_t battery_passivePyroDeploy = 0; -static uint8_t battery_logUploadRequest = 0; -static uint8_t battery_packCtrCloseFailed = 0; -static uint8_t battery_fcCtrCloseFailed = 0; -static uint8_t battery_shuntThermistorMia = 0; +//0x3aa: HVP_alertMatrix1 Fault codes // Change to bool +static bool battery_WatchdogReset = false; //Warns if the processor has experienced a reset due to watchdog reset. +static bool battery_PowerLossReset = false; //Warns if the processor has experienced a reset due to power loss. +static bool battery_SwAssertion = false; //An internal software assertion has failed. +static bool battery_CrashEvent = false; //Warns if the crash signal is detected by HVP +static bool battery_OverDchgCurrentFault = false; //Warns if the pack discharge is above max discharge current limit +static bool battery_OverChargeCurrentFault = false; //Warns if the pack discharge current is above max charge current limit +static bool battery_OverCurrentFault = false; //Warns if the pack current (discharge or charge) is above max current limit. +static bool battery_OverTemperatureFault = false; //A pack module temperature is above maximum temperature limit +static bool battery_OverVoltageFault = false; //A brick voltage is above maximum voltage limit +static bool battery_UnderVoltageFault = false; //A brick voltage is below minimum voltage limit +static bool battery_PrimaryBmbMiaFault = false; //Warns if the voltage and temperature readings from primary BMB chain are mia +static bool battery_SecondaryBmbMiaFault = false; //Warns if the voltage and temperature readings from secondary BMB chain are mia +static bool battery_BmbMismatchFault = false; //Warns if the primary and secondary BMB chain readings don't match with each other +static bool battery_BmsHviMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN +static bool battery_CpMiaFault = false; //Warns if the CP node is mia on HVS CAN +static bool battery_PcsMiaFault = false; //The PCS node is mia on HVS CAN +static bool battery_BmsFault = false; //Warns if the BMS ECU has faulted +static bool battery_PcsFault = false; //Warns if the PCS ECU has faulted +static bool battery_CpFault = false; //Warns if the CP ECU has faulted +static bool battery_ShuntHwMiaFault = false; //Warns if the shunt current reading is not available +static bool battery_PyroMiaFault = false; //Warns if the pyro squib is not connected +static bool battery_hvsMiaFault = false; //Warns if the pack contactor hw fault +static bool battery_hviMiaFault = false; //Warns if the FC contactor hw fault +static bool battery_Supply12vFault = false; //Warns if the low voltage (12V) battery is below minimum voltage threshold +static bool battery_VerSupplyFault = false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold +static bool battery_HvilFault = false; //Warn if a High Voltage Inter Lock fault is detected +static bool battery_BmsHvsMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN +static bool battery_PackVoltMismatchFault = false; //Warns if the pack voltage doesn't match approximately with sum of brick voltages +static bool battery_EnsMiaFault = false; //Warns if the ENS line is not connected to HVC +static bool battery_PackPosCtrArcFault = false; //Warns if the HVP detectes series arc at pack contactor +static bool battery_packNegCtrArcFault = false; //Warns if the HVP detectes series arc at FC contactor +static bool battery_ShuntHwAndBmsMiaFault = false; +static bool battery_fcContHwFault = false; +static bool battery_robinOverVoltageFault = false; +static bool battery_packContHwFault = false; +static bool battery_pyroFuseBlown = false; +static bool battery_pyroFuseFailedToBlow = false; +static bool battery_CpilFault = false; +static bool battery_PackContactorFellOpen = false; +static bool battery_FcContactorFellOpen = false; +static bool battery_packCtrCloseBlocked = false; +static bool battery_fcCtrCloseBlocked = false; +static bool battery_packContactorForceOpen = false; +static bool battery_fcContactorForceOpen = false; +static bool battery_dcLinkOverVoltage = false; +static bool battery_shuntOverTemperature = false; +static bool battery_passivePyroDeploy = false; +static bool battery_logUploadRequest = false; +static bool battery_packCtrCloseFailed = false; +static bool battery_fcCtrCloseFailed = false; +static bool battery_shuntThermistorMia = false; //0x320: 800 BMS_alertMatrix -static uint8_t battery_BMS_matrixIndex = 4; -static uint8_t battery_BMS_a061_robinBrickOverVoltage = 1; -static uint8_t battery_BMS_a062_SW_BrickV_Imbalance = 1; -static uint8_t battery_BMS_a063_SW_ChargePort_Fault = 1; -static uint8_t battery_BMS_a064_SW_SOC_Imbalance = 1; -static uint8_t battery_BMS_a127_SW_shunt_SNA = 1; -static uint8_t battery_BMS_a128_SW_shunt_MIA = 1; -static uint8_t battery_BMS_a069_SW_Low_Power = 1; -static uint8_t battery_BMS_a130_IO_CAN_Error = 1; -static uint8_t battery_BMS_a071_SW_SM_TransCon_Not_Met = 1; -static uint8_t battery_BMS_a132_HW_BMB_OTP_Uncorrctbl = 1; -static uint8_t battery_BMS_a134_SW_Delayed_Ctr_Off = 1; -static uint8_t battery_BMS_a075_SW_Chg_Disable_Failure = 1; -static uint8_t battery_BMS_a076_SW_Dch_While_Charging = 1; -static uint8_t battery_BMS_a017_SW_Brick_OV = 1; -static uint8_t battery_BMS_a018_SW_Brick_UV = 1; -static uint8_t battery_BMS_a019_SW_Module_OT = 1; -static uint8_t battery_BMS_a021_SW_Dr_Limits_Regulation = 1; -static uint8_t battery_BMS_a022_SW_Over_Current = 1; -static uint8_t battery_BMS_a023_SW_Stack_OV = 1; -static uint8_t battery_BMS_a024_SW_Islanded_Brick = 1; -static uint8_t battery_BMS_a025_SW_PwrBalance_Anomaly = 1; -static uint8_t battery_BMS_a026_SW_HFCurrent_Anomaly = 1; -static uint8_t battery_BMS_a087_SW_Feim_Test_Blocked = 1; -static uint8_t battery_BMS_a088_SW_VcFront_MIA_InDrive = 1; -static uint8_t battery_BMS_a089_SW_VcFront_MIA = 1; -static uint8_t battery_BMS_a090_SW_Gateway_MIA = 1; -static uint8_t battery_BMS_a091_SW_ChargePort_MIA = 1; -static uint8_t battery_BMS_a092_SW_ChargePort_Mia_On_Hv = 1; -static uint8_t battery_BMS_a034_SW_Passive_Isolation = 1; -static uint8_t battery_BMS_a035_SW_Isolation = 1; -static uint8_t battery_BMS_a036_SW_HvpHvilFault = 1; -static uint8_t battery_BMS_a037_SW_Flood_Port_Open = 1; -static uint8_t battery_BMS_a158_SW_HVP_HVI_Comms = 1; -static uint8_t battery_BMS_a039_SW_DC_Link_Over_Voltage = 1; -static uint8_t battery_BMS_a041_SW_Power_On_Reset = 1; -static uint8_t battery_BMS_a042_SW_MPU_Error = 1; -static uint8_t battery_BMS_a043_SW_Watch_Dog_Reset = 1; -static uint8_t battery_BMS_a044_SW_Assertion = 1; -static uint8_t battery_BMS_a045_SW_Exception = 1; -static uint8_t battery_BMS_a046_SW_Task_Stack_Usage = 1; -static uint8_t battery_BMS_a047_SW_Task_Stack_Overflow = 1; -static uint8_t battery_BMS_a048_SW_Log_Upload_Request = 1; -static uint8_t battery_BMS_a169_SW_FC_Pack_Weld = 1; -static uint8_t battery_BMS_a050_SW_Brick_Voltage_MIA = 1; -static uint8_t battery_BMS_a051_SW_HVC_Vref_Bad = 1; -static uint8_t battery_BMS_a052_SW_PCS_MIA = 1; -static uint8_t battery_BMS_a053_SW_ThermalModel_Sanity = 1; -static uint8_t battery_BMS_a054_SW_Ver_Supply_Fault = 1; -static uint8_t battery_BMS_a176_SW_GracefulPowerOff = 1; -static uint8_t battery_BMS_a059_SW_Pack_Voltage_Sensing = 1; -static uint8_t battery_BMS_a060_SW_Leakage_Test_Failure = 1; -static uint8_t battery_BMS_a077_SW_Charger_Regulation = 1; -static uint8_t battery_BMS_a081_SW_Ctr_Close_Blocked = 1; -static uint8_t battery_BMS_a082_SW_Ctr_Force_Open = 1; -static uint8_t battery_BMS_a083_SW_Ctr_Close_Failure = 1; -static uint8_t battery_BMS_a084_SW_Sleep_Wake_Aborted = 1; -static uint8_t battery_BMS_a094_SW_Drive_Inverter_MIA = 1; -static uint8_t battery_BMS_a099_SW_BMB_Communication = 1; -static uint8_t battery_BMS_a105_SW_One_Module_Tsense = 1; -static uint8_t battery_BMS_a106_SW_All_Module_Tsense = 1; -static uint8_t battery_BMS_a107_SW_Stack_Voltage_MIA = 1; -static uint8_t battery_BMS_a121_SW_NVRAM_Config_Error = 1; -static uint8_t battery_BMS_a122_SW_BMS_Therm_Irrational = 1; -static uint8_t battery_BMS_a123_SW_Internal_Isolation = 1; -static uint8_t battery_BMS_a129_SW_VSH_Failure = 1; -static uint8_t battery_BMS_a131_Bleed_FET_Failure = 1; -static uint8_t battery_BMS_a136_SW_Module_OT_Warning = 1; -static uint8_t battery_BMS_a137_SW_Brick_UV_Warning = 1; -static uint8_t battery_BMS_a138_SW_Brick_OV_Warning = 1; -static uint8_t battery_BMS_a139_SW_DC_Link_V_Irrational = 1; -static uint8_t battery_BMS_a141_SW_BMB_Status_Warning = 1; -static uint8_t battery_BMS_a144_Hvp_Config_Mismatch = 1; -static uint8_t battery_BMS_a145_SW_SOC_Change = 1; -static uint8_t battery_BMS_a146_SW_Brick_Overdischarged = 1; -static uint8_t battery_BMS_a149_SW_Missing_Config_Block = 1; -static uint8_t battery_BMS_a151_SW_external_isolation = 1; -static uint8_t battery_BMS_a156_SW_BMB_Vref_bad = 1; -static uint8_t battery_BMS_a157_SW_HVP_HVS_Comms = 1; -static uint8_t battery_BMS_a159_SW_HVP_ECU_Error = 1; -static uint8_t battery_BMS_a161_SW_DI_Open_Request = 1; -static uint8_t battery_BMS_a162_SW_No_Power_For_Support = 1; -static uint8_t battery_BMS_a163_SW_Contactor_Mismatch = 1; -static uint8_t battery_BMS_a164_SW_Uncontrolled_Regen = 1; -static uint8_t battery_BMS_a165_SW_Pack_Partial_Weld = 1; -static uint8_t battery_BMS_a166_SW_Pack_Full_Weld = 1; -static uint8_t battery_BMS_a167_SW_FC_Partial_Weld = 1; -static uint8_t battery_BMS_a168_SW_FC_Full_Weld = 1; -static uint8_t battery_BMS_a170_SW_Limp_Mode = 1; -static uint8_t battery_BMS_a171_SW_Stack_Voltage_Sense = 1; -static uint8_t battery_BMS_a174_SW_Charge_Failure = 1; -static uint8_t battery_BMS_a179_SW_Hvp_12V_Fault = 1; -static uint8_t battery_BMS_a180_SW_ECU_reset_blocked = 1; +static uint8_t battery_BMS_matrixIndex = 0; // Changed to bool +static bool battery_BMS_a061_robinBrickOverVoltage = false; +static bool battery_BMS_a062_SW_BrickV_Imbalance = false; +static bool battery_BMS_a063_SW_ChargePort_Fault = false; +static bool battery_BMS_a064_SW_SOC_Imbalance = false; +static bool battery_BMS_a027_SW_shunt_SNA = false; +static bool battery_BMS_a128_SW_shunt_MIA = false; +static bool battery_BMS_a069_SW_Low_Power = false; +static bool battery_BMS_a130_IO_CAN_Error = false; +static bool battery_BMS_a071_SW_SM_TransCon_Not_Met = false; +static bool battery_BMS_a132_HW_BMB_OTP_Uncorrctbl = false; +static bool battery_BMS_a134_SW_Delayed_Ctr_Off = false; +static bool battery_BMS_a075_SW_Chg_Disable_Failure = false; +static bool battery_BMS_a076_SW_Dch_While_Charging = false; +static bool battery_BMS_a017_SW_Brick_OV = false; +static bool battery_BMS_a018_SW_Brick_UV = false; +static bool battery_BMS_a019_SW_Module_OT = false; +static bool battery_BMS_a021_SW_Dr_Limits_Regulation = false; +static bool battery_BMS_a022_SW_Over_Current = false; +static bool battery_BMS_a023_SW_Stack_OV = false; +static bool battery_BMS_a024_SW_Islanded_Brick = false; +static bool battery_BMS_a025_SW_PwrBalance_Anomaly = false; +static bool battery_BMS_a026_SW_HFCurrent_Anomaly = false; +static bool battery_BMS_a087_SW_Feim_Test_Blocked = false; +static bool battery_BMS_a088_SW_VcFront_MIA_InDrive = false; +static bool battery_BMS_a089_SW_VcFront_MIA = false; +static bool battery_BMS_a090_SW_Gateway_MIA = false; +static bool battery_BMS_a091_SW_ChargePort_MIA = false; +static bool battery_BMS_a092_SW_ChargePort_Mia_On_Hv = false; +static bool battery_BMS_a034_SW_Passive_Isolation = false; +static bool battery_BMS_a035_SW_Isolation = false; +static bool battery_BMS_a036_SW_HvpHvilFault = false; +static bool battery_BMS_a037_SW_Flood_Port_Open = false; +static bool battery_BMS_a158_SW_HVP_HVI_Comms = false; +static bool battery_BMS_a039_SW_DC_Link_Over_Voltage = false; +static bool battery_BMS_a041_SW_Power_On_Reset = false; +static bool battery_BMS_a042_SW_MPU_Error = false; +static bool battery_BMS_a043_SW_Watch_Dog_Reset = false; +static bool battery_BMS_a044_SW_Assertion = false; +static bool battery_BMS_a045_SW_Exception = false; +static bool battery_BMS_a046_SW_Task_Stack_Usage = false; +static bool battery_BMS_a047_SW_Task_Stack_Overflow = false; +static bool battery_BMS_a048_SW_Log_Upload_Request = false; +static bool battery_BMS_a169_SW_FC_Pack_Weld = false; +static bool battery_BMS_a050_SW_Brick_Voltage_MIA = false; +static bool battery_BMS_a051_SW_HVC_Vref_Bad = false; +static bool battery_BMS_a052_SW_PCS_MIA = false; +static bool battery_BMS_a053_SW_ThermalModel_Sanity = false; +static bool battery_BMS_a054_SW_Ver_Supply_Fault = false; +static bool battery_BMS_a176_SW_GracefulPowerOff = false; +static bool battery_BMS_a059_SW_Pack_Voltage_Sensing = false; +static bool battery_BMS_a060_SW_Leakage_Test_Failure = false; +static bool battery_BMS_a077_SW_Charger_Regulation = false; +static bool battery_BMS_a081_SW_Ctr_Close_Blocked = false; +static bool battery_BMS_a082_SW_Ctr_Force_Open = false; +static bool battery_BMS_a083_SW_Ctr_Close_Failure = false; +static bool battery_BMS_a084_SW_Sleep_Wake_Aborted = false; +static bool battery_BMS_a094_SW_Drive_Inverter_MIA = false; +static bool battery_BMS_a099_SW_BMB_Communication = false; +static bool battery_BMS_a105_SW_One_Module_Tsense = false; +static bool battery_BMS_a106_SW_All_Module_Tsense = false; +static bool battery_BMS_a107_SW_Stack_Voltage_MIA = false; +static bool battery_BMS_a121_SW_NVRAM_Config_Error = false; +static bool battery_BMS_a122_SW_BMS_Therm_Irrational = false; +static bool battery_BMS_a123_SW_Internal_Isolation = false; +static bool battery_BMS_a129_SW_VSH_Failure = false; +static bool battery_BMS_a131_Bleed_FET_Failure = false; +static bool battery_BMS_a136_SW_Module_OT_Warning = false; +static bool battery_BMS_a137_SW_Brick_UV_Warning = false; +static bool battery_BMS_a138_SW_Brick_OV_Warning = false; +static bool battery_BMS_a139_SW_DC_Link_V_Irrational = false; +static bool battery_BMS_a141_SW_BMB_Status_Warning = false; +static bool battery_BMS_a144_Hvp_Config_Mismatch = false; +static bool battery_BMS_a145_SW_SOC_Change = false; +static bool battery_BMS_a146_SW_Brick_Overdischarged = false; +static bool battery_BMS_a149_SW_Missing_Config_Block = false; +static bool battery_BMS_a151_SW_external_isolation = false; +static bool battery_BMS_a156_SW_BMB_Vref_bad = false; +static bool battery_BMS_a157_SW_HVP_HVS_Comms = false; +static bool battery_BMS_a159_SW_HVP_ECU_Error = false; +static bool battery_BMS_a161_SW_DI_Open_Request = false; +static bool battery_BMS_a162_SW_No_Power_For_Support = false; +static bool battery_BMS_a163_SW_Contactor_Mismatch = false; +static bool battery_BMS_a164_SW_Uncontrolled_Regen = false; +static bool battery_BMS_a165_SW_Pack_Partial_Weld = false; +static bool battery_BMS_a166_SW_Pack_Full_Weld = false; +static bool battery_BMS_a167_SW_FC_Partial_Weld = false; +static bool battery_BMS_a168_SW_FC_Full_Weld = false; +static bool battery_BMS_a170_SW_Limp_Mode = false; +static bool battery_BMS_a171_SW_Stack_Voltage_Sense = false; +static bool battery_BMS_a174_SW_Charge_Failure = false; +static bool battery_BMS_a179_SW_Hvp_12V_Fault = false; +static bool battery_BMS_a180_SW_ECU_reset_blocked = false; #ifdef DOUBLE_BATTERY //need to update for battery2 From 931f99fb3564805e7093f205e300a4f6be5a99b8 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 25 Dec 2024 20:54:16 +1300 Subject: [PATCH 45/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 145 +++++++++++++------------ 1 file changed, 76 insertions(+), 69 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 8c1fe984..b15b2639 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -37,8 +37,8 @@ static uint16_t battery_energy_to_charge_complete = 0; // kWh static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh static uint16_t battery_expected_energy_remaining = 0; // kWh static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh -static bool battery_full_charge_complete = false; // Changed to bool -static bool battery_fully_charged = false; // Changed to bool +static bool battery_full_charge_complete = false; // Changed to bool +static bool battery_fully_charged = false; // Changed to bool static uint16_t battery_ideal_energy_remaining = 0; // kWh static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_energy_remaining = 0; // kWh @@ -98,46 +98,46 @@ static uint8_t battery_hvil_status = 0; static uint8_t battery_packContNegativeState = 0; static uint8_t battery_packContPositiveState = 0; static uint8_t battery_packContactorSetState = 0; -static bool battery_packCtrsClosingAllowed = false; // Change to bool -static bool battery_pyroTestInProgress = false; // Change to bool -static bool battery_packCtrsOpenNowRequested = false; // Change to bool -static bool battery_packCtrsOpenRequested = false; // Change to bool +static bool battery_packCtrsClosingAllowed = false; // Change to bool +static bool battery_pyroTestInProgress = false; // Change to bool +static bool battery_packCtrsOpenNowRequested = false; // Change to bool +static bool battery_packCtrsOpenRequested = false; // Change to bool static uint8_t battery_packCtrsRequestStatus = 0; -static bool battery_packCtrsResetRequestRequired = false; // Change to bool -static bool battery_dcLinkAllowedToEnergize = false; // Change to bool -static bool battery_fcContNegativeAuxOpen = false; // Change to bool +static bool battery_packCtrsResetRequestRequired = false; // Change to bool +static bool battery_dcLinkAllowedToEnergize = false; // Change to bool +static bool battery_fcContNegativeAuxOpen = false; // Change to bool static uint8_t battery_fcContNegativeState = 0; -static bool battery_fcContPositiveAuxOpen = false; // Change to bool +static bool battery_fcContPositiveAuxOpen = false; // Change to bool static uint8_t battery_fcContPositiveState = 0; static uint8_t battery_fcContactorSetState = 0; -static bool battery_fcCtrsClosingAllowed = false; // Change to bool -static bool battery_fcCtrsOpenNowRequested = false; // Change to bool -static bool battery_fcCtrsOpenRequested = false; // Change to bool +static bool battery_fcCtrsClosingAllowed = false; // Change to bool +static bool battery_fcCtrsOpenNowRequested = false; // Change to bool +static bool battery_fcCtrsOpenRequested = false; // Change to bool static uint8_t battery_fcCtrsRequestStatus = 0; -static bool battery_fcCtrsResetRequestRequired = false; // Change to bool -static bool battery_fcLinkAllowedToEnergize = false; // Change to bool +static bool battery_fcCtrsResetRequestRequired = false; // Change to bool +static bool battery_fcLinkAllowedToEnergize = false; // Change to bool //0x212: 530 BMS_status -static bool battery_BMS_hvacPowerRequest = false; //Change to bool -static bool battery_BMS_notEnoughPowerForDrive = false; //Change to bool -static bool battery_BMS_notEnoughPowerForSupport = false; //Change to bool -static bool battery_BMS_preconditionAllowed = false; //Change to bool -static bool battery_BMS_updateAllowed = false; //Change to bool -static bool battery_BMS_activeHeatingWorthwhile = false; //Change to bool -static bool battery_BMS_cpMiaOnHvs = false; //Change to bool +static bool battery_BMS_hvacPowerRequest = false; //Change to bool +static bool battery_BMS_notEnoughPowerForDrive = false; //Change to bool +static bool battery_BMS_notEnoughPowerForSupport = false; //Change to bool +static bool battery_BMS_preconditionAllowed = false; //Change to bool +static bool battery_BMS_updateAllowed = false; //Change to bool +static bool battery_BMS_activeHeatingWorthwhile = false; //Change to bool +static bool battery_BMS_cpMiaOnHvs = false; //Change to bool static uint8_t battery_BMS_contactorState = 0; static uint8_t battery_BMS_state = 0; static uint8_t battery_BMS_hvState = 0; static uint16_t battery_BMS_isolationResistance = 0; -static bool battery_BMS_chargeRequest = false; //Change to bool -static bool battery_BMS_keepWarmRequest = false; //Change to bool +static bool battery_BMS_chargeRequest = false; //Change to bool +static bool battery_BMS_keepWarmRequest = false; //Change to bool static uint8_t battery_BMS_uiChargeStatus = 0; -static bool battery_BMS_diLimpRequest = false; //Change to bool -static bool battery_BMS_okToShipByAir = false; //Change to bool -static bool battery_BMS_okToShipByLand = false; //Change to bool +static bool battery_BMS_diLimpRequest = false; //Change to bool +static bool battery_BMS_okToShipByAir = false; //Change to bool +static bool battery_BMS_okToShipByLand = false; //Change to bool static uint32_t battery_BMS_chgPowerAvailable = 0; static uint8_t battery_BMS_chargeRetryCount = 0; -static bool battery_BMS_pcsPwmEnabled = false; //Change to bool -static bool battery_BMS_ecuLogUploadRequest = false; //Change to bool +static bool battery_BMS_pcsPwmEnabled = false; //Change to bool +static bool battery_BMS_ecuLogUploadRequest = false; //Change to bool static uint8_t battery_BMS_minPackTemperature = 0; // 0x224:548 PCS_dcdcStatus static uint8_t battery_PCS_dcdcPrechargeStatus = 0; @@ -145,7 +145,7 @@ static uint8_t battery_PCS_dcdc12VSupportStatus = 0; static uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; static uint16_t battery_PCS_dcdcMainState = 0; static uint8_t battery_PCS_dcdcSubState = 0; -static bool battery_PCS_dcdcFaulted = false; //Change to bool +static bool battery_PCS_dcdcFaulted = false; //Change to bool static bool battery_PCS_dcdcOutputIsLimited = false; //Change to bool static uint32_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; static uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; @@ -196,38 +196,38 @@ static uint16_t PCS_dcdcIntervalMinLvOutputCurr = 0; static uint32_t PCS_dcdc12vSupportLifetimekWh = 0; //0x7AA: //1962 HVP_debugMessage: static uint8_t HVP_debugMessageMultiplexer = 0; -static bool HVP_gpioPassivePyroDepl = false; //Change to bool -static bool HVP_gpioPyroIsoEn = false; //Change to bool -static bool HVP_gpioCpFaultIn = false; //Change to bool -static bool HVP_gpioPackContPowerEn = false; //Change to bool -static bool HVP_gpioHvCablesOk = false; //Change to bool -static bool HVP_gpioHvpSelfEnable = false; //Change to bool -static bool HVP_gpioLed = false; //Change to bool -static bool HVP_gpioCrashSignal = false; //Change to bool -static bool HVP_gpioShuntDataReady = false; //Change to bool -static bool HVP_gpioFcContPosAux = false; //Change to bool -static bool HVP_gpioFcContNegAux = false; //Change to bool -static bool HVP_gpioBmsEout = false; //Change to bool -static bool HVP_gpioCpFaultOut = false; //Change to bool -static bool HVP_gpioPyroPor = false; //Change to bool -static bool HVP_gpioShuntEn = false; //Change to bool -static bool HVP_gpioHvpVerEn = false; //Change to bool -static bool HVP_gpioPackCoontPosFlywheel = false; //Change to bool -static bool HVP_gpioCpLatchEnable = false; //Change to bool -static bool HVP_gpioPcsEnable = false; //Change to bool -static bool HVP_gpioPcsDcdcPwmEnable = false; //Change to bool -static bool HVP_gpioPcsChargePwmEnable = false; //Change to bool -static bool HVP_gpioFcContPowerEnable = false; //Change to bool -static bool HVP_gpioHvilEnable = false; //Change to bool -static bool HVP_gpioSecDrdy = false; //Change to bool +static bool HVP_gpioPassivePyroDepl = false; //Change to bool +static bool HVP_gpioPyroIsoEn = false; //Change to bool +static bool HVP_gpioCpFaultIn = false; //Change to bool +static bool HVP_gpioPackContPowerEn = false; //Change to bool +static bool HVP_gpioHvCablesOk = false; //Change to bool +static bool HVP_gpioHvpSelfEnable = false; //Change to bool +static bool HVP_gpioLed = false; //Change to bool +static bool HVP_gpioCrashSignal = false; //Change to bool +static bool HVP_gpioShuntDataReady = false; //Change to bool +static bool HVP_gpioFcContPosAux = false; //Change to bool +static bool HVP_gpioFcContNegAux = false; //Change to bool +static bool HVP_gpioBmsEout = false; //Change to bool +static bool HVP_gpioCpFaultOut = false; //Change to bool +static bool HVP_gpioPyroPor = false; //Change to bool +static bool HVP_gpioShuntEn = false; //Change to bool +static bool HVP_gpioHvpVerEn = false; //Change to bool +static bool HVP_gpioPackCoontPosFlywheel = false; //Change to bool +static bool HVP_gpioCpLatchEnable = false; //Change to bool +static bool HVP_gpioPcsEnable = false; //Change to bool +static bool HVP_gpioPcsDcdcPwmEnable = false; //Change to bool +static bool HVP_gpioPcsChargePwmEnable = false; //Change to bool +static bool HVP_gpioFcContPowerEnable = false; //Change to bool +static bool HVP_gpioHvilEnable = false; //Change to bool +static bool HVP_gpioSecDrdy = false; //Change to bool static uint16_t HVP_hvp1v5Ref = 0; static int16_t HVP_shuntCurrentDebug = 0; -static bool HVP_packCurrentMia = false; //Change to bool -static bool HVP_auxCurrentMia = false; //Change to bool -static bool HVP_currentSenseMia =false; //Change to bool -static bool HVP_shuntRefVoltageMismatch = false; //Change to bool -static bool HVP_shuntThermistorMia = false; //Change to bool -static bool HVP_shuntHwMia = false; //Change to bool +static bool HVP_packCurrentMia = false; //Change to bool +static bool HVP_auxCurrentMia = false; //Change to bool +static bool HVP_currentSenseMia = false; //Change to bool +static bool HVP_shuntRefVoltageMismatch = false; //Change to bool +static bool HVP_shuntThermistorMia = false; //Change to bool +static bool HVP_shuntHwMia = false; //Change to bool static int16_t HVP_dcLinkVoltage = 0; static int16_t HVP_packVoltage = 0; static int16_t HVP_fcLinkVoltage = 0; @@ -258,14 +258,19 @@ static bool battery_PowerLossReset = false; //Warns if the processor has experi static bool battery_SwAssertion = false; //An internal software assertion has failed. static bool battery_CrashEvent = false; //Warns if the crash signal is detected by HVP static bool battery_OverDchgCurrentFault = false; //Warns if the pack discharge is above max discharge current limit -static bool battery_OverChargeCurrentFault = false; //Warns if the pack discharge current is above max charge current limit -static bool battery_OverCurrentFault = false; //Warns if the pack current (discharge or charge) is above max current limit. +static bool battery_OverChargeCurrentFault = + false; //Warns if the pack discharge current is above max charge current limit +static bool battery_OverCurrentFault = + false; //Warns if the pack current (discharge or charge) is above max current limit. static bool battery_OverTemperatureFault = false; //A pack module temperature is above maximum temperature limit static bool battery_OverVoltageFault = false; //A brick voltage is above maximum voltage limit static bool battery_UnderVoltageFault = false; //A brick voltage is below minimum voltage limit -static bool battery_PrimaryBmbMiaFault = false; //Warns if the voltage and temperature readings from primary BMB chain are mia -static bool battery_SecondaryBmbMiaFault = false; //Warns if the voltage and temperature readings from secondary BMB chain are mia -static bool battery_BmbMismatchFault = false; //Warns if the primary and secondary BMB chain readings don't match with each other +static bool battery_PrimaryBmbMiaFault = + false; //Warns if the voltage and temperature readings from primary BMB chain are mia +static bool battery_SecondaryBmbMiaFault = + false; //Warns if the voltage and temperature readings from secondary BMB chain are mia +static bool battery_BmbMismatchFault = + false; //Warns if the primary and secondary BMB chain readings don't match with each other static bool battery_BmsHviMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN static bool battery_CpMiaFault = false; //Warns if the CP node is mia on HVS CAN static bool battery_PcsMiaFault = false; //The PCS node is mia on HVS CAN @@ -276,11 +281,13 @@ static bool battery_ShuntHwMiaFault = false; //Warns if the shunt current readi static bool battery_PyroMiaFault = false; //Warns if the pyro squib is not connected static bool battery_hvsMiaFault = false; //Warns if the pack contactor hw fault static bool battery_hviMiaFault = false; //Warns if the FC contactor hw fault -static bool battery_Supply12vFault = false; //Warns if the low voltage (12V) battery is below minimum voltage threshold -static bool battery_VerSupplyFault = false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold +static bool battery_Supply12vFault = false; //Warns if the low voltage (12V) battery is below minimum voltage threshold +static bool battery_VerSupplyFault = + false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold static bool battery_HvilFault = false; //Warn if a High Voltage Inter Lock fault is detected static bool battery_BmsHvsMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN -static bool battery_PackVoltMismatchFault = false; //Warns if the pack voltage doesn't match approximately with sum of brick voltages +static bool battery_PackVoltMismatchFault = + false; //Warns if the pack voltage doesn't match approximately with sum of brick voltages static bool battery_EnsMiaFault = false; //Warns if the ENS line is not connected to HVC static bool battery_PackPosCtrArcFault = false; //Warns if the HVP detectes series arc at pack contactor static bool battery_packNegCtrArcFault = false; //Warns if the HVP detectes series arc at FC contactor @@ -305,7 +312,7 @@ static bool battery_packCtrCloseFailed = false; static bool battery_fcCtrCloseFailed = false; static bool battery_shuntThermistorMia = false; //0x320: 800 BMS_alertMatrix -static uint8_t battery_BMS_matrixIndex = 0; // Changed to bool +static uint8_t battery_BMS_matrixIndex = 0; // Changed to bool static bool battery_BMS_a061_robinBrickOverVoltage = false; static bool battery_BMS_a062_SW_BrickV_Imbalance = false; static bool battery_BMS_a063_SW_ChargePort_Fault = false; From 76efc1528f88330cd3465c2b4cbfd9c50625be0c Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:36:45 +1300 Subject: [PATCH 46/93] Update bool and battery2 --- Software/src/battery/TESLA-BATTERY.cpp | 446 +++++++++++++------------ 1 file changed, 224 insertions(+), 222 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index b15b2639..0fbe0b6d 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -66,8 +66,7 @@ static uint16_t battery_bms_min_voltage = 0; //0x2b4: 692 PCS_dcdcRailStatus static uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt static uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt -static uint16_t battery_dcdcLvOutputCurrent = - 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent +static uint16_t battery_dcdcLvOutputCurrent = 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent //0x292: 658 BMS_socStatus static uint16_t battery_beginning_of_life = 600; // kWh static uint16_t battery_soc_min = 0; @@ -164,8 +163,8 @@ static uint16_t BMS_inletPassiveTargetT = 0; static uint16_t BMS_inletActiveHeatTargetT = 0; static uint16_t BMS_packTMin = 0; static uint16_t BMS_packTMax = 0; -static uint16_t BMS_pcsNoFlowRequest = 0; -static uint16_t BMS_noFlowRequest = 0; +static bool BMS_pcsNoFlowRequest = false; +static bool BMS_noFlowRequest = false; //0x2A4; 676 PCS_thermalStatus static int16_t PCS_chgPhATemp = 0; static int16_t PCS_chgPhBTemp = 0; @@ -317,7 +316,7 @@ static bool battery_BMS_a061_robinBrickOverVoltage = false; static bool battery_BMS_a062_SW_BrickV_Imbalance = false; static bool battery_BMS_a063_SW_ChargePort_Fault = false; static bool battery_BMS_a064_SW_SOC_Imbalance = false; -static bool battery_BMS_a027_SW_shunt_SNA = false; +static bool battery_BMS_a127_SW_shunt_SNA = false; static bool battery_BMS_a128_SW_shunt_MIA = false; static bool battery_BMS_a069_SW_Low_Power = false; static bool battery_BMS_a130_IO_CAN_Error = false; @@ -421,8 +420,8 @@ static uint16_t battery2_energy_to_charge_complete = 0; static uint16_t battery2_energy_to_charge_complete_m1 = 0; // kWh static uint16_t battery2_expected_energy_remaining = 0; static uint16_t battery2_expected_energy_remaining_m1 = 0; // kWh -static uint8_t battery2_full_charge_complete = 0; -static uint8_t battery2_fully_charged = 0; +static bool battery2_full_charge_complete = false; +static bool battery2_fully_charged = false; static uint16_t battery2_ideal_energy_remaining = 0; static uint16_t battery2_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery2_nominal_energy_remaining = 0; @@ -435,10 +434,13 @@ static int16_t battery2_amps = 0; // A static int16_t battery2_raw_amps = 0; // A static uint16_t battery2_charge_time_remaining = 0; // Minutes //0x252 594 BMS_powerAvailable -static uint16_t BMS2_regenerative_limit = 0; -static uint16_t BMS2_discharge_limit = 0; -static uint16_t BMS2_max_heat_park = 0; -static uint16_t BMS2_hvac_max_power = 0; +static uint16_t BMS2_maxRegenPower = 0; //rename from battery_regenerative_limit +static uint16_t BMS2_maxDischargePower = 0; // rename from battery_discharge_limit +static uint16_t BMS2_maxStationaryHeatPower = 0; //rename from battery_max_heat_park +static uint16_t BMS2_hvacPowerBudget = 0; //rename from battery_hvac_max_power +static uint8_t BMS2_notEnoughPowerForHeatPump = 0; +static uint8_t BMS2_powerLimitState = 0; +static uint8_t BMS2_inverterTQF = 0; //0x2d2: 722 BMSVAlimits static uint16_t battery2_max_discharge_current = 0; static uint16_t battery2_max_charge_current = 0; @@ -478,46 +480,46 @@ static uint8_t battery2_hvil_status = 0; static uint8_t battery2_packContNegativeState = 0; static uint8_t battery2_packContPositiveState = 0; static uint8_t battery2_packContactorSetState = 0; -static uint8_t battery2_packCtrsClosingAllowed = 0; -static uint8_t battery2_pyroTestInProgress = 0; -static uint8_t battery2_packCtrsOpenNowRequested = 0; -static uint8_t battery2_packCtrsOpenRequested = 0; +static bool battery2_packCtrsClosingAllowed = false; +static bool battery2_pyroTestInProgress = false; +static bool battery2_packCtrsOpenNowRequested = false; +static bool battery2_packCtrsOpenRequested = false; static uint8_t battery2_packCtrsRequestStatus = 0; -static uint8_t battery2_packCtrsResetRequestRequired = 0; -static uint8_t battery2_dcLinkAllowedToEnergize = 0; -static uint8_t battery2_fcContNegativeAuxOpen = 0; +static bool battery2_packCtrsResetRequestRequired = false; +static bool battery2_dcLinkAllowedToEnergize = false; +static bool battery2_fcContNegativeAuxOpen = false; static uint8_t battery2_fcContNegativeState = 0; -static uint8_t battery2_fcContPositiveAuxOpen = 0; +static bool battery2_fcContPositiveAuxOpen = false; static uint8_t battery2_fcContPositiveState = 0; static uint8_t battery2_fcContactorSetState = 0; -static uint8_t battery2_fcCtrsClosingAllowed = 0; -static uint8_t battery2_fcCtrsOpenNowRequested = 0; -static uint8_t battery2_fcCtrsOpenRequested = 0; +static bool battery2_fcCtrsClosingAllowed = false; +static bool battery2_fcCtrsOpenNowRequested = false; +static bool battery2_fcCtrsOpenRequested = false; static uint8_t battery2_fcCtrsRequestStatus = 0; -static uint8_t battery2_fcCtrsResetRequestRequired = 0; -static uint8_t battery2_fcLinkAllowedToEnergize = 0; +static bool battery2_fcCtrsResetRequestRequired = false; +static bool battery2_fcLinkAllowedToEnergize = false; //0x212: 530 BMS_status -static uint8_t battery2_BMS_hvacPowerRequest = 0; -static uint8_t battery2_BMS_notEnoughPowerForDrive = 0; -static uint8_t battery2_BMS_notEnoughPowerForSupport = 0; -static uint8_t battery2_BMS_preconditionAllowed = 0; -static uint8_t battery2_BMS_updateAllowed = 0; -static uint8_t battery2_BMS_activeHeatingWorthwhile = 0; -static uint8_t battery2_BMS_cpMiaOnHvs = 0; +static bool battery2_BMS_hvacPowerRequest = false; +static bool battery2_BMS_notEnoughPowerForDrive = false; +static bool battery2_BMS_notEnoughPowerForSupport = false; +static bool battery2_BMS_preconditionAllowed = false; +static bool battery2_BMS_updateAllowed = false; +static bool battery2_BMS_activeHeatingWorthwhile = false; +static bool battery2_BMS_cpMiaOnHvs = false; static uint8_t battery2_BMS_contactorState = 0; static uint8_t battery2_BMS_state = 0; static uint8_t battery2_BMS_hvState = 0; static uint16_t battery2_BMS_isolationResistance = 0; -static uint8_t battery2_BMS_chargeRequest = 0; -static uint8_t battery2_BMS_keepWarmRequest = 0; +static bool battery2_BMS_chargeRequest = false; +static bool battery2_BMS_keepWarmRequest = false; static uint8_t battery2_BMS_uiChargeStatus = 0; -static uint8_t battery2_BMS_diLimpRequest = 0; -static uint8_t battery2_BMS_okToShipByAir = 0; -static uint8_t battery2_BMS_okToShipByLand = 0; +static bool battery2_BMS_diLimpRequest = false; +static bool battery2_BMS_okToShipByAir = false; +static bool battery2_BMS_okToShipByLand = false; static uint32_t battery2_BMS_chgPowerAvailable = 0; static uint8_t battery2_BMS_chargeRetryCount = 0; -static uint8_t battery2_BMS_pcsPwmEnabled = 0; -static uint8_t battery2_BMS_ecuLogUploadRequest = 0; +static bool battery2_BMS_pcsPwmEnabled = false; +static bool battery2_BMS_ecuLogUploadRequest = false; static uint8_t battery2_BMS_minPackTemperature = 0; // 0x224:548 PCS_dcdcStatus static uint8_t battery2_PCS_dcdcPrechargeStatus = 0; @@ -525,8 +527,8 @@ static uint8_t battery2_PCS_dcdc12VSupportStatus = 0; static uint8_t battery2_PCS_dcdcHvBusDischargeStatus = 0; static uint16_t battery2_PCS_dcdcMainState = 0; static uint8_t battery2_PCS_dcdcSubState = 0; -static uint8_t battery2_PCS_dcdcFaulted = 0; -static uint8_t battery2_PCS_dcdcOutputIsLimited = 0; +static bool battery2_PCS_dcdcFaulted = false; +static bool battery2_PCS_dcdcOutputIsLimited = false; static uint32_t battery2_PCS_dcdcMaxOutputCurrentAllowed = 0; static uint8_t battery2_PCS_dcdcPrechargeRtyCnt = 0; static uint8_t battery2_PCS_dcdc12VSupportRtyCnt = 0; @@ -544,8 +546,8 @@ static uint16_t BMS2_inletPassiveTargetT = 0; static uint16_t BMS2_inletActiveHeatTargetT = 0; static uint16_t BMS2_packTMin = 0; static uint16_t BMS2_packTMax = 0; -static uint16_t BMS2_pcsNoFlowRequest = 0; -static uint16_t BMS2_noFlowRequest = 0; +static bool BMS2_pcsNoFlowRequest = false; +static bool BMS2_noFlowRequest = false; //0x2A4; 676 PCS_thermalStatus static int16_t PCS2_chgPhATemp = 0; static int16_t PCS2_chgPhBTemp = 0; @@ -576,38 +578,38 @@ static uint16_t PCS2_dcdcIntervalMinLvOutputCurr = 0; static uint32_t PCS2_dcdc12vSupportLifetimekWh = 0; //0x7AA: //1962 HVP_debugMessage: static uint8_t HVP2_debugMessageMultiplexer = 0; -static uint8_t HVP2_gpioPassivePyroDepl = 0; -static uint8_t HVP2_gpioPyroIsoEn = 0; -static uint8_t HVP2_gpioCpFaultIn = 0; -static uint8_t HVP2_gpioPackContPowerEn = 0; -static uint8_t HVP2_gpioHvCablesOk = 0; -static uint8_t HVP2_gpioHVPSelfEnable = 0; -static uint8_t HVP2_gpioLed = 0; -static uint8_t HVP2_gpioCrashSignal = 0; -static uint8_t HVP2_gpioShuntDataReady = 0; -static uint8_t HVP2_gpioFcContPosAux = 0; -static uint8_t HVP2_gpioFcContNegAux = 0; -static uint8_t HVP2_gpioBmsEout = 0; -static uint8_t HVP2_gpioCpFaultOut = 0; -static uint8_t HVP2_gpioPyroPor = 0; -static uint8_t HVP2_gpioShuntEn = 0; -static uint8_t HVP2_gpioHVPVerEn = 0; -static uint8_t HVP2_gpioPackCoontPosFlywheel = 0; -static uint8_t HVP2_gpioCpLatchEnable = 0; -static uint8_t HVP2_gpioPcsEnable = 0; -static uint8_t HVP2_gpioPcsDcdcPwmEnable = 0; -static uint8_t HVP2_gpioPcsChargePwmEnable = 0; -static uint8_t HVP2_gpioFcContPowerEnable = 0; -static uint8_t HVP2_gpioHvilEnable = 0; -static uint8_t HVP2_gpioSecDrdy = 0; +static bool HVP2_gpioPassivePyroDepl = false; +static bool HVP2_gpioPyroIsoEn = false; +static bool HVP2_gpioCpFaultIn = false; +static bool HVP2_gpioPackContPowerEn = false; +static bool HVP2_gpioHvCablesOk = false; +static bool HVP2_gpioHVPSelfEnable = false; +static bool HVP2_gpioLed = false; +static bool HVP2_gpioCrashSignal = false; +static bool HVP2_gpioShuntDataReady = false; +static bool HVP2_gpioFcContPosAux = false; +static bool HVP2_gpioFcContNegAux = false; +static bool HVP2_gpioBmsEout = false; +static bool HVP2_gpioCpFaultOut = false; +static bool HVP2_gpioPyroPor = false; +static bool HVP2_gpioShuntEn = false; +static bool HVP2_gpioHVPVerEn = false; +static bool HVP2_gpioPackCoontPosFlywheel = false; +static bool HVP2_gpioCpLatchEnable = false; +static bool HVP2_gpioPcsEnable = false; +static bool HVP2_gpioPcsDcdcPwmEnable = false; +static bool HVP2_gpioPcsChargePwmEnable = false; +static bool HVP2_gpioFcContPowerEnable = false; +static bool HVP2_gpioHvilEnable = false; +static bool HVP2_gpioSecDrdy = false; static uint16_t HVP2_hvp1v5Ref = 0; static int16_t HVP2_shuntCurrentDebug = 0; -static uint8_t HVP2_packCurrentMia = 0; -static uint8_t HVP2_auxCurrentMia = 0; -static uint8_t HVP2_currentSenseMia = 0; -static uint8_t HVP2_shuntRefVoltageMismatch = 0; -static uint8_t HVP2_shuntThermistorMia = 0; -static uint8_t HVP2_shuntHwMia = 0; +static bool HVP2_packCurrentMia = false; +static bool HVP2_auxCurrentMia = false; +static bool HVP2_currentSenseMia = false; +static bool HVP2_shuntRefVoltageMismatch = false; +static bool HVP2_shuntThermistorMia = false; +static bool HVP2_shuntHwMia = false; static int16_t HVP2_dcLinkVoltage = 0; static int16_t HVP2_packVoltage = 0; static int16_t HVP2_fcLinkVoltage = 0; @@ -633,158 +635,158 @@ static uint8_t HVP2_shuntAuxCurrentStatus = 0; static uint8_t HVP2_shuntBarTempStatus = 0; static uint8_t HVP2_shuntAsicTempStatus = 0; //0x3aa: HVP_alertMatrix1 Fault codes -static uint8_t battery2_WatchdogReset = 0; //Warns if the processor has experienced a reset due to watchdog reset. -static uint8_t battery2_PowerLossReset = 0; //Warns if the processor has experienced a reset due to power loss. -static uint8_t battery2_SwAssertion = 0; //An internal software assertion has failed. -static uint8_t battery2_CrashEvent = 0; //Warns if the crash signal is detected by HVP -static uint8_t battery2_OverDchgCurrentFault = 0; //Warns if the pack discharge is above max discharge current limit -static uint8_t battery2_OverChargeCurrentFault = - 0; //Warns if the pack discharge current is above max charge current limit -static uint8_t battery2_OverCurrentFault = - 0; //Warns if the pack current (discharge or charge) is above max current limit. -static uint8_t battery2_OverTemperatureFault = 0; //A pack module temperature is above maximum temperature limit -static uint8_t battery2_OverVoltageFault = 0; //A brick voltage is above maximum voltage limit -static uint8_t battery2_UnderVoltageFault = 0; //A brick voltage is below minimum voltage limit -static uint8_t battery2_PrimaryBmbMiaFault = - 0; //Warns if the voltage and temperature readings from primary BMB chain are mia -static uint8_t battery2_SecondaryBmbMiaFault = - 0; //Warns if the voltage and temperature readings from secondary BMB chain are mia -static uint8_t battery2_BmbMismatchFault = - 0; //Warns if the primary and secondary BMB chain readings don't match with each other -static uint8_t battery2_BmsHviMiaFault = 0; //Warns if the BMS node is mia on HVS or HVI CAN -static uint8_t battery2_CpMiaFault = 0; //Warns if the CP node is mia on HVS CAN -static uint8_t battery2_PcsMiaFault = 0; //The PCS node is mia on HVS CAN -static uint8_t battery2_BmsFault = 0; //Warns if the BMS ECU has faulted -static uint8_t battery2_PcsFault = 0; //Warns if the PCS ECU has faulted -static uint8_t battery2_CpFault = 0; //Warns if the CP ECU has faulted -static uint8_t battery2_ShuntHwMiaFault = 0; //Warns if the shunt current reading is not available -static uint8_t battery2_PyroMiaFault = 0; //Warns if the pyro squib is not connected -static uint8_t battery2_hvsMiaFault = 0; //Warns if the pack contactor hw fault -static uint8_t battery2_hviMiaFault = 0; //Warns if the FC contactor hw fault -static uint8_t battery2_Supply12vFault = 0; //Warns if the low voltage (12V) battery is below minimum voltage threshold -static uint8_t battery2_VerSupplyFault = - 0; //Warns if the Energy reserve voltage supply is below minimum voltage threshold -static uint8_t battery2_HvilFault = 0; //Warn if a High Voltage Inter Lock fault is detected -static uint8_t battery2_BmsHvsMiaFault = 0; //Warns if the BMS node is mia on HVS or HVI CAN -static uint8_t battery2_PackVoltMismatchFault = - 0; //Warns if the pack voltage doesn't match approximately with sum of brick voltages -static uint8_t battery2_EnsMiaFault = 0; //Warns if the ENS line is not connected to HVC -static uint8_t battery2_PackPosCtrArcFault = 0; //Warns if the HVP detectes series arc at pack contactor -static uint8_t battery2_packNegCtrArcFault = 0; //Warns if the HVP detectes series arc at FC contactor -static uint8_t battery2_ShuntHwAndBmsMiaFault = 0; -static uint8_t battery2_fcContHwFault = 0; -static uint8_t battery2_robinOverVoltageFault = 0; -static uint8_t battery2_packContHwFault = 0; -static uint8_t battery2_pyroFuseBlown = 0; -static uint8_t battery2_pyroFuseFailedToBlow = 0; -static uint8_t battery2_CpilFault = 0; -static uint8_t battery2_PackContactorFellOpen = 0; -static uint8_t battery2_FcContactorFellOpen = 0; -static uint8_t battery2_packCtrCloseBlocked = 0; -static uint8_t battery2_fcCtrCloseBlocked = 0; -static uint8_t battery2_packContactorForceOpen = 0; -static uint8_t battery2_fcContactorForceOpen = 0; -static uint8_t battery2_dcLinkOverVoltage = 0; -static uint8_t battery2_shuntOverTemperature = 0; -static uint8_t battery2_passivePyroDeploy = 0; -static uint8_t battery2_logUploadRequest = 0; -static uint8_t battery2_packCtrCloseFailed = 0; -static uint8_t battery2_fcCtrCloseFailed = 0; -static uint8_t battery2_shuntThermistorMia = 0; +static bool battery2_WatchdogReset = false; //Warns if the processor has experienced a reset due to watchdog reset. +static bool battery2_PowerLossReset = false; //Warns if the processor has experienced a reset due to power loss. +static bool battery2_SwAssertion = false; //An internal software assertion has failed. +static bool battery2_CrashEvent = false; //Warns if the crash signal is detected by HVP +static bool battery2_OverDchgCurrentFault = false; //Warns if the pack discharge is above max discharge current limit +static bool battery2_OverChargeCurrentFault = + false; //Warns if the pack discharge current is above max charge current limit +static bool battery2_OverCurrentFault = + false; //Warns if the pack current (discharge or charge) is above max current limit. +static bool battery2_OverTemperatureFault = false; //A pack module temperature is above maximum temperature limit +static bool battery2_OverVoltageFault = false; //A brick voltage is above maximum voltage limit +static bool battery2_UnderVoltageFault = false; //A brick voltage is below minimum voltage limit +static bool battery2_PrimaryBmbMiaFault = + false; //Warns if the voltage and temperature readings from primary BMB chain are mia +static bool battery2_SecondaryBmbMiaFault = + false; //Warns if the voltage and temperature readings from secondary BMB chain are mia +static bool battery2_BmbMismatchFault = + false; //Warns if the primary and secondary BMB chain readings don't match with each other +static bool battery2_BmsHviMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN +static bool battery2_CpMiaFault = false; //Warns if the CP node is mia on HVS CAN +static bool battery2_PcsMiaFault = false; //The PCS node is mia on HVS CAN +static bool battery2_BmsFault = false; //Warns if the BMS ECU has faulted +static bool battery2_PcsFault = false; //Warns if the PCS ECU has faulted +static bool battery2_CpFault = false; //Warns if the CP ECU has faulted +static bool battery2_ShuntHwMiaFault = false; //Warns if the shunt current reading is not available +static bool battery2_PyroMiaFault = false; //Warns if the pyro squib is not connected +static bool battery2_hvsMiaFault = false; //Warns if the pack contactor hw fault +static bool battery2_hviMiaFault = false; //Warns if the FC contactor hw fault +static bool battery2_Supply12vFault = false; //Warns if the low voltage (12V) battery is below minimum voltage threshold +static bool battery2_VerSupplyFault = + false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold +static bool battery2_HvilFault = false; //Warn if a High Voltage Inter Lock fault is detected +static bool battery2_BmsHvsMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN +static bool battery2_PackVoltMismatchFault = + false; //Warns if the pack voltage doesn't match approximately with sum of brick voltages +static bool battery2_EnsMiaFault = false; //Warns if the ENS line is not connected to HVC +static bool battery2_PackPosCtrArcFault = false; //Warns if the HVP detectes series arc at pack contactor +static bool battery2_packNegCtrArcFault = false; //Warns if the HVP detectes series arc at FC contactor +static bool battery2_ShuntHwAndBmsMiaFault = false; +static bool battery2_fcContHwFault = false; +static bool battery2_robinOverVoltageFault = false; +static bool battery2_packContHwFault = false; +static bool battery2_pyroFuseBlown = false; +static bool battery2_pyroFuseFailedToBlow = false; +static bool battery2_CpilFault = false; +static bool battery2_PackContactorFellOpen = false; +static bool battery2_FcContactorFellOpen = false; +static bool battery2_packCtrCloseBlocked = false; +static bool battery2_fcCtrCloseBlocked = false; +static bool battery2_packContactorForceOpen = false; +static bool battery2_fcContactorForceOpen = false; +static bool battery2_dcLinkOverVoltage = false; +static bool battery2_shuntOverTemperature = false; +static bool battery2_passivePyroDeploy = false; +static bool battery2_logUploadRequest = false; +static bool battery2_packCtrCloseFailed = false; +static bool battery2_fcCtrCloseFailed = false; +static bool battery2_shuntThermistorMia = false; //0x320: 800 BMS_alertMatrix static uint8_t battery2_BMS_matrixIndex = 4; -static uint8_t battery2_BMS_a061_robinBrickOverVoltage = 1; -static uint8_t battery2_BMS_a062_SW_BrickV_Imbalance = 1; -static uint8_t battery2_BMS_a063_SW_ChargePort_Fault = 1; -static uint8_t battery2_BMS_a064_SW_SOC_Imbalance = 1; -static uint8_t battery2_BMS_a127_SW_shunt_SNA = 1; -static uint8_t battery2_BMS_a128_SW_shunt_MIA = 1; -static uint8_t battery2_BMS_a069_SW_Low_Power = 1; -static uint8_t battery2_BMS_a130_IO_CAN_Error = 1; -static uint8_t battery2_BMS_a071_SW_SM_TransCon_Not_Met = 1; -static uint8_t battery2_BMS_a132_HW_BMB_OTP_Uncorrctbl = 1; -static uint8_t battery2_BMS_a134_SW_Delayed_Ctr_Off = 1; -static uint8_t battery2_BMS_a075_SW_Chg_Disable_Failure = 1; -static uint8_t battery2_BMS_a076_SW_Dch_While_Charging = 1; -static uint8_t battery2_BMS_a017_SW_Brick_OV = 1; -static uint8_t battery2_BMS_a018_SW_Brick_UV = 1; -static uint8_t battery2_BMS_a019_SW_Module_OT = 1; -static uint8_t battery2_BMS_a021_SW_Dr_Limits_Regulation = 1; -static uint8_t battery2_BMS_a022_SW_Over_Current = 1; -static uint8_t battery2_BMS_a023_SW_Stack_OV = 1; -static uint8_t battery2_BMS_a024_SW_Islanded_Brick = 1; -static uint8_t battery2_BMS_a025_SW_PwrBalance_Anomaly = 1; -static uint8_t battery2_BMS_a026_SW_HFCurrent_Anomaly = 1; -static uint8_t battery2_BMS_a087_SW_Feim_Test_Blocked = 1; -static uint8_t battery2_BMS_a088_SW_VcFront_MIA_InDrive = 1; -static uint8_t battery2_BMS_a089_SW_VcFront_MIA = 1; -static uint8_t battery2_BMS_a090_SW_Gateway_MIA = 1; -static uint8_t battery2_BMS_a091_SW_ChargePort_MIA = 1; -static uint8_t battery2_BMS_a092_SW_ChargePort_Mia_On_Hv = 1; -static uint8_t battery2_BMS_a034_SW_Passive_Isolation = 1; -static uint8_t battery2_BMS_a035_SW_Isolation = 1; -static uint8_t battery2_BMS_a036_SW_HvpHvilFault = 1; -static uint8_t battery2_BMS_a037_SW_Flood_Port_Open = 1; -static uint8_t battery2_BMS_a158_SW_HVP_HVI_Comms = 1; -static uint8_t battery2_BMS_a039_SW_DC_Link_Over_Voltage = 1; -static uint8_t battery2_BMS_a041_SW_Power_On_Reset = 1; -static uint8_t battery2_BMS_a042_SW_MPU_Error = 1; -static uint8_t battery2_BMS_a043_SW_Watch_Dog_Reset = 1; -static uint8_t battery2_BMS_a044_SW_Assertion = 1; -static uint8_t battery2_BMS_a045_SW_Exception = 1; -static uint8_t battery2_BMS_a046_SW_Task_Stack_Usage = 1; -static uint8_t battery2_BMS_a047_SW_Task_Stack_Overflow = 1; -static uint8_t battery2_BMS_a048_SW_Log_Upload_Request = 1; -static uint8_t battery2_BMS_a169_SW_FC_Pack_Weld = 1; -static uint8_t battery2_BMS_a050_SW_Brick_Voltage_MIA = 1; -static uint8_t battery2_BMS_a051_SW_HVC_Vref_Bad = 1; -static uint8_t battery2_BMS_a052_SW_PCS_MIA = 1; -static uint8_t battery2_BMS_a053_SW_ThermalModel_Sanity = 1; -static uint8_t battery2_BMS_a054_SW_Ver_Supply_Fault = 1; -static uint8_t battery2_BMS_a176_SW_GracefulPowerOff = 1; -static uint8_t battery2_BMS_a059_SW_Pack_Voltage_Sensing = 1; -static uint8_t battery2_BMS_a060_SW_Leakage_Test_Failure = 1; -static uint8_t battery2_BMS_a077_SW_Charger_Regulation = 1; -static uint8_t battery2_BMS_a081_SW_Ctr_Close_Blocked = 1; -static uint8_t battery2_BMS_a082_SW_Ctr_Force_Open = 1; -static uint8_t battery2_BMS_a083_SW_Ctr_Close_Failure = 1; -static uint8_t battery2_BMS_a084_SW_Sleep_Wake_Aborted = 1; -static uint8_t battery2_BMS_a094_SW_Drive_Inverter_MIA = 1; -static uint8_t battery2_BMS_a099_SW_BMB_Communication = 1; -static uint8_t battery2_BMS_a105_SW_One_Module_Tsense = 1; -static uint8_t battery2_BMS_a106_SW_All_Module_Tsense = 1; -static uint8_t battery2_BMS_a107_SW_Stack_Voltage_MIA = 1; -static uint8_t battery2_BMS_a121_SW_NVRAM_Config_Error = 1; -static uint8_t battery2_BMS_a122_SW_BMS_Therm_Irrational = 1; -static uint8_t battery2_BMS_a123_SW_Internal_Isolation = 1; -static uint8_t battery2_BMS_a129_SW_VSH_Failure = 1; -static uint8_t battery2_BMS_a131_Bleed_FET_Failure = 1; -static uint8_t battery2_BMS_a136_SW_Module_OT_Warning = 1; -static uint8_t battery2_BMS_a137_SW_Brick_UV_Warning = 1; -static uint8_t battery2_BMS_a138_SW_Brick_OV_Warning = 1; -static uint8_t battery2_BMS_a139_SW_DC_Link_V_Irrational = 1; -static uint8_t battery2_BMS_a141_SW_BMB_Status_Warning = 1; -static uint8_t battery2_BMS_a144_Hvp_Config_Mismatch = 1; -static uint8_t battery2_BMS_a145_SW_SOC_Change = 1; -static uint8_t battery2_BMS_a146_SW_Brick_Overdischarged = 1; -static uint8_t battery2_BMS_a149_SW_Missing_Config_Block = 1; -static uint8_t battery2_BMS_a151_SW_external_isolation = 1; -static uint8_t battery2_BMS_a156_SW_BMB_Vref_bad = 1; -static uint8_t battery2_BMS_a157_SW_HVP_HVS_Comms = 1; -static uint8_t battery2_BMS_a159_SW_HVP_ECU_Error = 1; -static uint8_t battery2_BMS_a161_SW_DI_Open_Request = 1; -static uint8_t battery2_BMS_a162_SW_No_Power_For_Support = 1; -static uint8_t battery2_BMS_a163_SW_Contactor_Mismatch = 1; -static uint8_t battery2_BMS_a164_SW_Uncontrolled_Regen = 1; -static uint8_t battery2_BMS_a165_SW_Pack_Partial_Weld = 1; -static uint8_t battery2_BMS_a166_SW_Pack_Full_Weld = 1; -static uint8_t battery2_BMS_a167_SW_FC_Partial_Weld = 1; -static uint8_t battery2_BMS_a168_SW_FC_Full_Weld = 1; -static uint8_t battery2_BMS_a170_SW_Limp_Mode = 1; -static uint8_t battery2_BMS_a171_SW_Stack_Voltage_Sense = 1; -static uint8_t battery2_BMS_a174_SW_Charge_Failure = 1; -static uint8_t battery2_BMS_a179_SW_Hvp_12V_Fault = 1; -static uint8_t battery2_BMS_a180_SW_ECU_reset_blocked = 1; +static bool battery2_BMS_a061_robinBrickOverVoltage = false; +static bool battery2_BMS_a062_SW_BrickV_Imbalance = false; +static bool battery2_BMS_a063_SW_ChargePort_Fault = false; +static bool battery2_BMS_a064_SW_SOC_Imbalance = false; +static bool battery2_BMS_a127_SW_shunt_SNA = false; +static bool battery2_BMS_a128_SW_shunt_MIA = false; +static bool battery2_BMS_a069_SW_Low_Power = false; +static bool battery2_BMS_a130_IO_CAN_Error = false; +static bool battery2_BMS_a071_SW_SM_TransCon_Not_Met = false; +static bool battery2_BMS_a132_HW_BMB_OTP_Uncorrctbl = false; +static bool battery2_BMS_a134_SW_Delayed_Ctr_Off = false; +static bool battery2_BMS_a075_SW_Chg_Disable_Failure = false; +static bool battery2_BMS_a076_SW_Dch_While_Charging = false; +static bool battery2_BMS_a017_SW_Brick_OV = false; +static bool battery2_BMS_a018_SW_Brick_UV = false; +static bool battery2_BMS_a019_SW_Module_OT = false; +static bool battery2_BMS_a021_SW_Dr_Limits_Regulation = false; +static bool battery2_BMS_a022_SW_Over_Current = false; +static bool battery2_BMS_a023_SW_Stack_OV = false; +static bool battery2_BMS_a024_SW_Islanded_Brick = false; +static bool battery2_BMS_a025_SW_PwrBalance_Anomaly = false; +static bool battery2_BMS_a026_SW_HFCurrent_Anomaly = false; +static bool battery2_BMS_a087_SW_Feim_Test_Blocked = false; +static bool battery2_BMS_a088_SW_VcFront_MIA_InDrive = false; +static bool battery2_BMS_a089_SW_VcFront_MIA = false; +static bool battery2_BMS_a090_SW_Gateway_MIA = false; +static bool battery2_BMS_a091_SW_ChargePort_MIA = false; +static bool battery2_BMS_a092_SW_ChargePort_Mia_On_Hv = false; +static bool battery2_BMS_a034_SW_Passive_Isolation = false; +static bool battery2_BMS_a035_SW_Isolation = false; +static bool battery2_BMS_a036_SW_HvpHvilFault = false; +static bool battery2_BMS_a037_SW_Flood_Port_Open = false; +static bool battery2_BMS_a158_SW_HVP_HVI_Comms = false; +static bool battery2_BMS_a039_SW_DC_Link_Over_Voltage = 1; +static bool battery2_BMS_a041_SW_Power_On_Reset = false; +static bool battery2_BMS_a042_SW_MPU_Error = false; +static bool battery2_BMS_a043_SW_Watch_Dog_Reset = false; +static bool battery2_BMS_a044_SW_Assertion = false; +static bool battery2_BMS_a045_SW_Exception = false; +static bool battery2_BMS_a046_SW_Task_Stack_Usage = false; +static bool battery2_BMS_a047_SW_Task_Stack_Overflow = false; +static bool battery2_BMS_a048_SW_Log_Upload_Request = false; +static bool battery2_BMS_a169_SW_FC_Pack_Weld = false; +static bool battery2_BMS_a050_SW_Brick_Voltage_MIA = false; +static bool battery2_BMS_a051_SW_HVC_Vref_Bad = false; +static bool battery2_BMS_a052_SW_PCS_MIA = false; +static bool battery2_BMS_a053_SW_ThermalModel_Sanity = false; +static bool battery2_BMS_a054_SW_Ver_Supply_Fault = false; +static bool battery2_BMS_a176_SW_GracefulPowerOff = false; +static bool battery2_BMS_a059_SW_Pack_Voltage_Sensing = false; +static bool battery2_BMS_a060_SW_Leakage_Test_Failure = false; +static bool battery2_BMS_a077_SW_Charger_Regulation = false; +static bool battery2_BMS_a081_SW_Ctr_Close_Blocked = false; +static bool battery2_BMS_a082_SW_Ctr_Force_Open = false; +static bool battery2_BMS_a083_SW_Ctr_Close_Failure = false; +static bool battery2_BMS_a084_SW_Sleep_Wake_Aborted = false; +static bool battery2_BMS_a094_SW_Drive_Inverter_MIA = false; +static bool battery2_BMS_a099_SW_BMB_Communication = false; +static bool battery2_BMS_a105_SW_One_Module_Tsense = false; +static bool battery2_BMS_a106_SW_All_Module_Tsense = false; +static bool battery2_BMS_a107_SW_Stack_Voltage_MIA = false; +static bool battery2_BMS_a121_SW_NVRAM_Config_Error = false; +static bool battery2_BMS_a122_SW_BMS_Therm_Irrational = false; +static bool battery2_BMS_a123_SW_Internal_Isolation = false; +static bool battery2_BMS_a129_SW_VSH_Failure = false; +static bool battery2_BMS_a131_Bleed_FET_Failure = false; +static bool battery2_BMS_a136_SW_Module_OT_Warning = false; +static bool battery2_BMS_a137_SW_Brick_UV_Warning = false; +static bool battery2_BMS_a138_SW_Brick_OV_Warning = false; +static bool battery2_BMS_a139_SW_DC_Link_V_Irrational = false; +static bool battery2_BMS_a141_SW_BMB_Status_Warning = false; +static bool battery2_BMS_a144_Hvp_Config_Mismatch = false; +static bool battery2_BMS_a145_SW_SOC_Change = false; +static bool battery2_BMS_a146_SW_Brick_Overdischarged = false; +static bool battery2_BMS_a149_SW_Missing_Config_Block = false; +static bool battery2_BMS_a151_SW_external_isolation = false; +static bool battery2_BMS_a156_SW_BMB_Vref_bad = false; +static bool battery2_BMS_a157_SW_HVP_HVS_Comms = false; +static bool battery2_BMS_a159_SW_HVP_ECU_Error = false; +static bool battery2_BMS_a16false_SW_DI_Open_Request = false; +static bool battery2_BMS_a162_SW_No_Power_For_Support = false; +static bool battery2_BMS_a163_SW_Contactor_Mismatch = false; +static bool battery2_BMS_a164_SW_Uncontrolled_Regen = false; +static bool battery2_BMS_a165_SW_Pack_Partial_Weld = false; +static bool battery2_BMS_a166_SW_Pack_Full_Weld = false; +static bool battery2_BMS_a167_SW_FC_Partial_Weld = false; +static bool battery2_BMS_a168_SW_FC_Full_Weld = false; +static bool battery2_BMS_a170_SW_Limp_Mode = false; +static bool battery2_BMS_a171_SW_Stack_Voltage_Sense = false; +static bool battery2_BMS_a174_SW_Charge_Failure = false; +static bool battery2_BMS_a179_SW_Hvp_12V_Fault = false; +static bool battery2_BMS_a180_SW_ECU_reset_blocked = false; #endif //DOUBLE_BATTERY From 7edba4efc62f5d7f8c43286b0ffe2cf9f7a3aa0b Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 25 Dec 2024 21:38:58 +1300 Subject: [PATCH 47/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 0fbe0b6d..c4de734e 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -66,7 +66,8 @@ static uint16_t battery_bms_min_voltage = 0; //0x2b4: 692 PCS_dcdcRailStatus static uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt static uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt -static uint16_t battery_dcdcLvOutputCurrent = 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent +static uint16_t battery_dcdcLvOutputCurrent = + 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent //0x292: 658 BMS_socStatus static uint16_t battery_beginning_of_life = 600; // kWh static uint16_t battery_soc_min = 0; @@ -663,9 +664,10 @@ static bool battery2_ShuntHwMiaFault = false; //Warns if the shunt current read static bool battery2_PyroMiaFault = false; //Warns if the pyro squib is not connected static bool battery2_hvsMiaFault = false; //Warns if the pack contactor hw fault static bool battery2_hviMiaFault = false; //Warns if the FC contactor hw fault -static bool battery2_Supply12vFault = false; //Warns if the low voltage (12V) battery is below minimum voltage threshold +static bool battery2_Supply12vFault = + false; //Warns if the low voltage (12V) battery is below minimum voltage threshold static bool battery2_VerSupplyFault = - false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold + false; //Warns if the Energy reserve voltage supply is below minimum voltage threshold static bool battery2_HvilFault = false; //Warn if a High Voltage Inter Lock fault is detected static bool battery2_BmsHvsMiaFault = false; //Warns if the BMS node is mia on HVS or HVI CAN static bool battery2_PackVoltMismatchFault = From a113cd309324832181d1cf80b4385fc1c3e80697 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Wed, 25 Dec 2024 22:06:17 +1300 Subject: [PATCH 48/93] Return to send 30ms message --- Software/src/battery/TESLA-BATTERY.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index c4de734e..3630f8dd 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -8,7 +8,7 @@ /* Do not change code below unless you are sure what you are doing */ /* Credits: Most of the code comes from Per Carlen's bms_comms_tesla_model3.py (https://gitlab.com/pelle8/batt2gen24/) */ -static unsigned long previousMillis50 = 0; // will store last time a 30ms CAN Message was send +static unsigned long previousMillis30 = 0; // will store last time a 30ms CAN Message was send CAN_frame TESLA_221_1 = { .FD = false, @@ -2658,14 +2658,14 @@ the first, for a few cycles, then stop all messages which causes the contactor #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) //Send 30ms message - if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { + if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis50 >= INTERVAL_50_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis50)); + if ((currentMillis - previousMillis30 >= INTERVAL_30_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis30)); } else { clear_event(EVENT_CAN_OVERRUN); } - previousMillis50 = currentMillis; + previousMillis30 = currentMillis; if ((datalayer.system.status.inverter_allows_contactor_closing == true) && (datalayer.battery.status.bms_status != FAULT)) { From 4f07290d172a1bfa7641edb4a1341f82851f2b80 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:35:48 +1300 Subject: [PATCH 49/93] Update bool values in datalayer and advanced battery --- Software/src/datalayer/datalayer_extended.h | 84 ++++++------ .../webserver/advanced_battery_html.cpp | 122 +++++++++--------- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/Software/src/datalayer/datalayer_extended.h b/Software/src/datalayer/datalayer_extended.h index d5a4ece6..19064035 100644 --- a/Software/src/datalayer/datalayer_extended.h +++ b/Software/src/datalayer/datalayer_extended.h @@ -215,12 +215,12 @@ typedef struct { uint8_t packCtrsClosingAllowed = 0; /** uint8_t */ /** Pyro test in progress */ - uint8_t pyroTestInProgress = 0; - uint8_t battery_packCtrsOpenNowRequested = 0; - uint8_t battery_packCtrsOpenRequested = 0; + bool pyroTestInProgress = false; + bool battery_packCtrsOpenNowRequested = false; + bool battery_packCtrsOpenRequested = false; uint8_t battery_packCtrsRequestStatus = 0; - uint8_t battery_packCtrsResetRequestRequired = 0; - uint8_t battery_dcLinkAllowedToEnergize = 0; + bool battery_packCtrsResetRequestRequired = false; + bool battery_dcLinkAllowedToEnergize = false; uint8_t battery_beginning_of_life = 0; uint8_t battery_battTempPct = 0; uint16_t battery_dcdcLvBusVolt = 0; @@ -238,8 +238,8 @@ typedef struct { uint16_t battery_energy_buffer_m1 = 0; uint16_t battery_expected_energy_remaining = 0; uint16_t battery_expected_energy_remaining_m1 = 0; - uint16_t battery_full_charge_complete = 0; - uint8_t battery_fully_charged = 0; + bool battery_full_charge_complete = false; + bool battery_fully_charged = false; uint16_t battery_total_discharge = 0; uint16_t battery_total_charge = 0; uint16_t battery_BrickVoltageMax = 0; @@ -268,16 +268,16 @@ typedef struct { uint8_t battery_BMS_hvState = 0; uint16_t battery_BMS_isolationResistance = 0; uint8_t battery_BMS_uiChargeStatus = 0; - uint8_t battery_BMS_diLimpRequest = 0; + bool battery_BMS_diLimpRequest = false; uint16_t battery_BMS_chgPowerAvailable = 0; - uint8_t battery_BMS_pcsPwmEnabled = 0; + bool battery_BMS_pcsPwmEnabled = false; uint8_t battery_PCS_dcdcPrechargeStatus = 0; uint8_t battery_PCS_dcdc12VSupportStatus = 0; uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; uint8_t battery_PCS_dcdcMainState = 0; uint8_t battery_PCS_dcdcSubState = 0; - uint8_t battery_PCS_dcdcFaulted = 0; - uint8_t battery_PCS_dcdcOutputIsLimited = 0; + bool battery_PCS_dcdcFaulted = false; + bool battery_PCS_dcdcOutputIsLimited = false; uint16_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0; @@ -300,8 +300,8 @@ typedef struct { uint16_t BMS_inletActiveHeatTargetT = 0; uint16_t BMS_packTMin = 0; uint16_t BMS_packTMax = 0; - uint8_t BMS_pcsNoFlowRequest = 0; - uint8_t BMS_noFlowRequest = 0; + bool BMS_pcsNoFlowRequest = false; + bool BMS_noFlowRequest = false; uint16_t PCS_dcdcTemp = 0; uint16_t PCS_ambientTemp = 0; uint16_t PCS_dcdcMaxLvOutputCurrent = 0; @@ -324,37 +324,37 @@ typedef struct { uint16_t PCS_dcdcIntervalMinLvBusVolt = 0; uint16_t PCS_dcdcIntervalMinLvOutputCurr = 0; uint32_t PCS_dcdc12vSupportLifetimekWh = 0; - uint8_t HVP_gpioPassivePyroDepl = 0; - uint8_t HVP_gpioPyroIsoEn = 0; - uint8_t HVP_gpioCpFaultIn = 0; - uint8_t HVP_gpioPackContPowerEn = 0; - uint8_t HVP_gpioHvCablesOk = 0; - uint8_t HVP_gpioHvpSelfEnable = 0; - uint8_t HVP_gpioLed = 0; - uint8_t HVP_gpioCrashSignal = 0; - uint8_t HVP_gpioShuntDataReady = 0; - uint8_t HVP_gpioFcContPosAux = 0; - uint8_t HVP_gpioFcContNegAux = 0; - uint8_t HVP_gpioBmsEout = 0; - uint8_t HVP_gpioCpFaultOut = 0; - uint8_t HVP_gpioPyroPor = 0; - uint8_t HVP_gpioShuntEn = 0; - uint8_t HVP_gpioHvpVerEn = 0; - uint8_t HVP_gpioPackCoontPosFlywheel = 0; - uint8_t HVP_gpioCpLatchEnable = 0; - uint8_t HVP_gpioPcsEnable = 0; - uint8_t HVP_gpioPcsDcdcPwmEnable = 0; - uint8_t HVP_gpioPcsChargePwmEnable = 0; - uint8_t HVP_gpioFcContPowerEnable = 0; - uint8_t HVP_gpioHvilEnable = 0; - uint8_t HVP_gpioSecDrdy = 0; + bool HVP_gpioPassivePyroDepl = false; + bool HVP_gpioPyroIsoEn = false; + bool HVP_gpioCpFaultIn = false; + bool HVP_gpioPackContPowerEn = false; + bool HVP_gpioHvCablesOk = false; + bool HVP_gpioHvpSelfEnable = false; + bool HVP_gpioLed = false; + bool HVP_gpioCrashSignal = false; + bool HVP_gpioShuntDataReady = false; + bool HVP_gpioFcContPosAux = false; + bool HVP_gpioFcContNegAux = false; + bool HVP_gpioBmsEout = false; + bool HVP_gpioCpFaultOut = false; + bool HVP_gpioPyroPor = false; + bool HVP_gpioShuntEn = false; + bool HVP_gpioHvpVerEn = false; + bool HVP_gpioPackCoontPosFlywheel = false; + bool HVP_gpioCpLatchEnable = false; + bool HVP_gpioPcsEnable = false; + bool HVP_gpioPcsDcdcPwmEnable = false; + bool HVP_gpioPcsChargePwmEnable = false; + bool HVP_gpioFcContPowerEnable = false; + bool HVP_gpioHvilEnable = false; + bool HVP_gpioSecDrdy = false; uint16_t HVP_hvp1v5Ref = 0; uint16_t HVP_shuntCurrentDebug = 0; - uint8_t HVP_packCurrentMia = 0; - uint8_t HVP_auxCurrentMia = 0; - uint8_t HVP_currentSenseMia = 0; - uint8_t HVP_shuntRefVoltageMismatch = 0; - uint8_t HVP_shuntThermistorMia = 0; + bool HVP_packCurrentMia = false; + bool HVP_auxCurrentMia = false; + bool HVP_currentSenseMia = false; + bool HVP_shuntRefVoltageMismatch = false; + bool HVP_shuntThermistorMia = false; uint8_t HVP_shuntHwMia = 0; uint16_t HVP_dcLinkVoltage = 0; uint16_t HVP_packVoltage = 0; diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index f2e055bb..5f1016e1 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -502,20 +502,20 @@ String advanced_battery_processor(const String& var) { "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; - content += "

Closing allowed?: " + String(falseTrue[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; - content += "

Pyrotest in Progress: " + String(falseTrue[datalayer_extended.tesla.pyroTestInProgress]) + "

"; + content += "

Closing allowed?: " + String(datalayer_extended.tesla.packCtrsClosingAllowed) + "

"; //bool + content += "

Pyrotest in Progress: " + String(datalayer_extended.tesla.pyroTestInProgress) + "

"; //bool content += "

Contactors Open Now Requested: " + - String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; + String(datalayer_extended.tesla.battery_packCtrsOpenNowRequested) + ""; //bool content += - "

Contactors Open Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + - "

"; + "

Contactors Open Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenRequested) + + "

"; //bool content += "

Contactors Request Status: " + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; content += "

Contactors Reset Request Required: " + - String(noYes[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; + String(datalayer_extended.tesla.battery_packCtrsResetRequestRequired) + ""; //bool content += - "

DC Link Allowed to Energize:" + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + - "

"; + "

DC Link Allowed to Energize:" + String(datalayer_extended.tesla.battery_dcLinkAllowedToEnergize) + + "

"; //bool // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -544,25 +544,25 @@ String advanced_battery_processor(const String& var) { "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; - content += "

PCS Faulted: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "

"; + content += "

PCS Faulted: " + String(datalayer_extended.tesla.battery_PCS_dcdcFaulted) + "

"; //bool content += - "

Output Is Limited: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; + "

Output Is Limited: " + String(datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited) + "

"; //bool content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; - content += "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + - "

"; + content += "

Precharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt) + + "

"; //bool content += - "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + - "

"; - content += "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + - "

"; + "

12V Support Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt) + + "

"; // bool + content += "

Discharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt) + + "

"; //bool content += - "

PWM Enable Line: " + String(noYes[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; + "

PWM Enable Line: " + String(datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine) + "

"; //bool content += "

Supporting Fixed LV Target: " + - String(noYes[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; + String(datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget) + ""; //bool content += "

Precharge Restart Cnt: " + - String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt) + ""; //bool content += "

Initial Precharge Substate: " + - String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + ""; //0x2C4 708 PCS_logging content += "

PCS_dcdcMaxLvOutputCurrent: " + String(PCS_dcdcMaxLvOutputCurrent) + " A

"; content += "

PCS_dcdcCurrentLimit: " + String(PCS_dcdcCurrentLimit) + " A

"; @@ -597,7 +597,7 @@ String advanced_battery_processor(const String& var) { content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; content += - "

BMS PCS PWM Enabled: " + String(noYes[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; + "

BMS PCS PWM Enabled: " + String(datalayer_extended.tesla.battery_BMS_pcsPwmEnabled) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Early BMS 0x352:

"; //if using older BMS <2021 and comment 0x352 without MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "

"; @@ -607,7 +607,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; content += - "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; + "

Full Charge Complete: " + String(datalayer_extended.tesla.battery_full_charge_complete) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; @@ -617,7 +617,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer_m1) + " KWh

"; content += "

Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh

"; - content += "

Fully Charged: " + String(noYes[datalayer_extended.tesla.battery_fully_charged]) + "

"; + content += "

Fully Charged: " + String(datalayer_extended.tesla.battery_fully_charged) + "

"; //bool //0x392 BMS_packConfig content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; @@ -642,8 +642,8 @@ String advanced_battery_processor(const String& var) { content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; content += - "

Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + - "

"; + "

Not Enough Power For Heat Pump: " + String(datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump) + + "

"; //bool content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; @@ -655,57 +655,57 @@ String advanced_battery_processor(const String& var) { content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; - content += "

PCS No Flow Request: " + String(falseTrue[datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; - content += "

BMS No Flow Request: " + String(falseTrue[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; + content += "

PCS No Flow Request: " + String(datalayer_extended.tesla.BMS_pcsNoFlowRequest) + "

"; //bool + content += "

BMS No Flow Request: " + String(datalayer_extended.tesla.BMS_noFlowRequest) + "

"; //bool //0x7AA 1962 HVP_debugMessage content += - "

HVP_gpioPassivePyroDepl: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; - content += "

HVP_gpioPyroIsoEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; - content += "

HVP_gpioCpFaultIn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; + "

HVP_gpioPassivePyroDepl: " + String(datalayer_extended.tesla.HVP_gpioPassivePyroDepl) + "

"; //bool + content += "

HVP_gpioPyroIsoEn: " + String(datalayer_extended.tesla.HVP_gpioPyroIsoEn) + "

"; //bool + content += "

HVP_gpioCpFaultIn: " + String(datalayer_extended.tesla.HVP_gpioCpFaultIn) + "

"; //bool content += - "

HVP_gpioPackContPowerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; - content += "

HVP_gpioHvCablesOk: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; + "

HVP_gpioPackContPowerEn: " + String(datalayer_extended.tesla.HVP_gpioPackContPowerEn) + "

"; //bool + content += "

HVP_gpioHvCablesOk: " + String(datalayer_extended.tesla.HVP_gpioHvCablesOk) + "

"; //bool content += - "

HVP_gpioHvpSelfEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; - content += "

HVP_gpioLed: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioLed]) + "

"; - content += "

HVP_gpioCrashSignal: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; + "

HVP_gpioHvpSelfEnable: " + String(datalayer_extended.tesla.HVP_gpioHvpSelfEnable) + "

"; //bool + content += "

HVP_gpioLed: " + String(datalayer_extended.tesla.HVP_gpioLed) + "

"; //bool + content += "

HVP_gpioCrashSignal: " + String(datalayer_extended.tesla.HVP_gpioCrashSignal) + "

"; //bool content += - "

HVP_gpioShuntDataReady: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; + "

HVP_gpioShuntDataReady: " + String(datalayer_extended.tesla.HVP_gpioShuntDataReady) + "

"; //bool content += - "

HVP_gpioFcContPosAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; + "

HVP_gpioFcContPosAux: " + String(datalayer_extended.tesla.HVP_gpioFcContPosAux) + "

"; //bool content += - "

HVP_gpioFcContNegAux: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; - content += "

HVP_gpioBmsEout: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; - content += "

HVP_gpioCpFaultOut: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; - content += "

HVP_gpioPyroPor: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; - content += "

HVP_gpioShuntEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; - content += "

HVP_gpioHvpVerEn: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; + "

HVP_gpioFcContNegAux: " + String(datalayer_extended.tesla.HVP_gpioFcContNegAux) + "

"; //bool + content += "

HVP_gpioBmsEout: " + String(datalayer_extended.tesla.HVP_gpioBmsEout) + "

"; //bool + content += "

HVP_gpioCpFaultOut: " + String(datalayer_extended.tesla.HVP_gpioCpFaultOut) + "

"; //bool + content += "

HVP_gpioPyroPor: " + String(datalayer_extended.tesla.HVP_gpioPyroPor) + "

"; //bool + content += "

HVP_gpioShuntEn: " + String(datalayer_extended.tesla.HVP_gpioShuntEn) + "

"; //bool + content += "

HVP_gpioHvpVerEn: " + String(datalayer_extended.tesla.HVP_gpioHvpVerEn) + "

"; //bool content += "

HVP_gpioPackCoontPosFlywheel: " + - String(falseTrue[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + "

"; + String(datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel) + ""; //bool content += - "

HVP_gpioCpLatchEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; - content += "

HVP_gpioPcsEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; - content += "

HVP_gpioPcsDcdcPwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + - "

"; + "

HVP_gpioCpLatchEnable: " + String(datalayer_extended.tesla.HVP_gpioCpLatchEnable) + "

"; //bool + content += "

HVP_gpioPcsEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsEnable) + "

"; //bool + content += "

HVP_gpioPcsDcdcPwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable) + + "

"; //bool content += - "

HVP_gpioPcsChargePwmEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + - "

"; + "

HVP_gpioPcsChargePwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable) + + "

"; //bool content += - "

HVP_gpioFcContPowerEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + - "

"; - content += "

HVP_gpioHvilEnable: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; - content += "

HVP_gpioSecDrdy: " + String(falseTrue[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; + "

HVP_gpioFcContPowerEnable: " + String(datalayer_extended.tesla.HVP_gpioFcContPowerEnable) + + "

"; //bool + content += "

HVP_gpioHvilEnable: " + String(datalayer_extended.tesla.HVP_gpioHvilEnable) + "

"; //bool + content += "

HVP_gpioSecDrdy: " + String(datalayer_extended.tesla.HVP_gpioSecDrdy) + "

"; //bool content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; - content += "

HVP_packCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; - content += "

HVP_auxCurrentMia: " + String(falseTrue[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; - content += "

HVP_currentSenseMia: " + String(falseTrue[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; + content += "

HVP_packCurrentMia: " + String(datalayer_extended.tesla.HVP_packCurrentMia) + "

"; //bool + content += "

HVP_auxCurrentMia: " + String(datalayer_extended.tesla.HVP_auxCurrentMia) + "

"; //bool + content += "

HVP_currentSenseMia: " + String(datalayer_extended.tesla.HVP_currentSenseMia) + "

"; //bool content += - "

HVP_shuntRefVoltageMismatch: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + - "

"; + "

HVP_shuntRefVoltageMismatch: " + String(datalayer_extended.tesla.HVP_shuntRefVoltageMismatch) + + "

"; //bool content += - "

HVP_shuntThermistorMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; - content += "

HVP_shuntHwMia: " + String(falseTrue[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; + "

HVP_shuntThermistorMia: " + String(datalayer_extended.tesla.HVP_shuntThermistorMia) + "

"; //bool + content += "

HVP_shuntHwMia: " + String(datalayer_extended.tesla.HVP_shuntHwMia) + "

"; //bool content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; content += "

HVP_fcLinkVoltage: " + String(HVP_fcLinkVoltage) + " V

"; From b8e10c3b289dd37e9e9448428d6fb7243673ebb1 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:36:33 +1300 Subject: [PATCH 50/93] Update bool values --- .../webserver/advanced_battery_html.cpp | 133 ++++++++---------- 1 file changed, 62 insertions(+), 71 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 5f1016e1..3e68190e 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -502,20 +502,19 @@ String advanced_battery_processor(const String& var) { "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; - content += "

Closing allowed?: " + String(datalayer_extended.tesla.packCtrsClosingAllowed) + "

"; //bool - content += "

Pyrotest in Progress: " + String(datalayer_extended.tesla.pyroTestInProgress) + "

"; //bool - content += "

Contactors Open Now Requested: " + - String(datalayer_extended.tesla.battery_packCtrsOpenNowRequested) + "

"; //bool + content += "

Closing allowed?: " + String(datalayer_extended.tesla.packCtrsClosingAllowed) + "

"; //bool + content += "

Pyrotest in Progress: " + String(datalayer_extended.tesla.pyroTestInProgress) + "

"; //bool content += - "

Contactors Open Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenRequested) + - "

"; //bool + "

Contactors Open Now Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenNowRequested) + + "

"; //bool + content += "

Contactors Open Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenRequested) + + "

"; //bool content += "

Contactors Request Status: " + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; content += "

Contactors Reset Request Required: " + - String(datalayer_extended.tesla.battery_packCtrsResetRequestRequired) + "

"; //bool - content += - "

DC Link Allowed to Energize:" + String(datalayer_extended.tesla.battery_dcLinkAllowedToEnergize) + - "

"; //bool + String(datalayer_extended.tesla.battery_packCtrsResetRequestRequired) + ""; //bool + content += "

DC Link Allowed to Energize:" + String(datalayer_extended.tesla.battery_dcLinkAllowedToEnergize) + + "

"; //bool // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -544,23 +543,23 @@ String advanced_battery_processor(const String& var) { "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; - content += "

PCS Faulted: " + String(datalayer_extended.tesla.battery_PCS_dcdcFaulted) + "

"; //bool + content += "

PCS Faulted: " + String(datalayer_extended.tesla.battery_PCS_dcdcFaulted) + "

"; //bool content += "

Output Is Limited: " + String(datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited) + "

"; //bool content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; - content += "

Precharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt) + - "

"; //bool content += - "

12V Support Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt) + - "

"; // bool - content += "

Discharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt) + - "

"; //bool + "

Precharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt) + "

"; //bool + content += "

12V Support Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt) + + "

"; // bool content += - "

PWM Enable Line: " + String(datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine) + "

"; //bool - content += "

Supporting Fixed LV Target: " + - String(datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget) + "

"; //bool - content += "

Precharge Restart Cnt: " + - String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt) + "

"; //bool + "

Discharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt) + "

"; //bool + content += + "

PWM Enable Line: " + String(datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine) + "

"; //bool + content += + "

Supporting Fixed LV Target: " + String(datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget) + + "

"; //bool + content += "

Precharge Restart Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt) + + "

"; //bool content += "

Initial Precharge Substate: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; //0x2C4 708 PCS_logging @@ -597,7 +596,7 @@ String advanced_battery_processor(const String& var) { content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; content += - "

BMS PCS PWM Enabled: " + String(datalayer_extended.tesla.battery_BMS_pcsPwmEnabled) + "

"; //bool + "

BMS PCS PWM Enabled: " + String(datalayer_extended.tesla.battery_BMS_pcsPwmEnabled) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Early BMS 0x352:

"; //if using older BMS <2021 and comment 0x352 without MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "

"; @@ -607,7 +606,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; content += - "

Full Charge Complete: " + String(datalayer_extended.tesla.battery_full_charge_complete) + "

"; //bool + "

Full Charge Complete: " + String(datalayer_extended.tesla.battery_full_charge_complete) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; @@ -617,7 +616,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer_m1) + " KWh

"; content += "

Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh

"; - content += "

Fully Charged: " + String(datalayer_extended.tesla.battery_fully_charged) + "

"; //bool + content += "

Fully Charged: " + String(datalayer_extended.tesla.battery_fully_charged) + "

"; //bool //0x392 BMS_packConfig content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; @@ -641,9 +640,8 @@ String advanced_battery_processor(const String& var) { content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; - content += - "

Not Enough Power For Heat Pump: " + String(datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump) + - "

"; //bool + content += "

Not Enough Power For Heat Pump: " + String(datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump) + + "

"; //bool content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; @@ -655,57 +653,50 @@ String advanced_battery_processor(const String& var) { content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; - content += "

PCS No Flow Request: " + String(datalayer_extended.tesla.BMS_pcsNoFlowRequest) + "

"; //bool - content += "

BMS No Flow Request: " + String(datalayer_extended.tesla.BMS_noFlowRequest) + "

"; //bool + content += "

PCS No Flow Request: " + String(datalayer_extended.tesla.BMS_pcsNoFlowRequest) + "

"; //bool + content += "

BMS No Flow Request: " + String(datalayer_extended.tesla.BMS_noFlowRequest) + "

"; //bool //0x7AA 1962 HVP_debugMessage content += - "

HVP_gpioPassivePyroDepl: " + String(datalayer_extended.tesla.HVP_gpioPassivePyroDepl) + "

"; //bool - content += "

HVP_gpioPyroIsoEn: " + String(datalayer_extended.tesla.HVP_gpioPyroIsoEn) + "

"; //bool - content += "

HVP_gpioCpFaultIn: " + String(datalayer_extended.tesla.HVP_gpioCpFaultIn) + "

"; //bool + "

HVP_gpioPassivePyroDepl: " + String(datalayer_extended.tesla.HVP_gpioPassivePyroDepl) + "

"; //bool + content += "

HVP_gpioPyroIsoEn: " + String(datalayer_extended.tesla.HVP_gpioPyroIsoEn) + "

"; //bool + content += "

HVP_gpioCpFaultIn: " + String(datalayer_extended.tesla.HVP_gpioCpFaultIn) + "

"; //bool content += - "

HVP_gpioPackContPowerEn: " + String(datalayer_extended.tesla.HVP_gpioPackContPowerEn) + "

"; //bool - content += "

HVP_gpioHvCablesOk: " + String(datalayer_extended.tesla.HVP_gpioHvCablesOk) + "

"; //bool + "

HVP_gpioPackContPowerEn: " + String(datalayer_extended.tesla.HVP_gpioPackContPowerEn) + "

"; //bool + content += "

HVP_gpioHvCablesOk: " + String(datalayer_extended.tesla.HVP_gpioHvCablesOk) + "

"; //bool + content += "

HVP_gpioHvpSelfEnable: " + String(datalayer_extended.tesla.HVP_gpioHvpSelfEnable) + "

"; //bool + content += "

HVP_gpioLed: " + String(datalayer_extended.tesla.HVP_gpioLed) + "

"; //bool + content += "

HVP_gpioCrashSignal: " + String(datalayer_extended.tesla.HVP_gpioCrashSignal) + "

"; //bool content += - "

HVP_gpioHvpSelfEnable: " + String(datalayer_extended.tesla.HVP_gpioHvpSelfEnable) + "

"; //bool - content += "

HVP_gpioLed: " + String(datalayer_extended.tesla.HVP_gpioLed) + "

"; //bool - content += "

HVP_gpioCrashSignal: " + String(datalayer_extended.tesla.HVP_gpioCrashSignal) + "

"; //bool + "

HVP_gpioShuntDataReady: " + String(datalayer_extended.tesla.HVP_gpioShuntDataReady) + "

"; //bool + content += "

HVP_gpioFcContPosAux: " + String(datalayer_extended.tesla.HVP_gpioFcContPosAux) + "

"; //bool + content += "

HVP_gpioFcContNegAux: " + String(datalayer_extended.tesla.HVP_gpioFcContNegAux) + "

"; //bool + content += "

HVP_gpioBmsEout: " + String(datalayer_extended.tesla.HVP_gpioBmsEout) + "

"; //bool + content += "

HVP_gpioCpFaultOut: " + String(datalayer_extended.tesla.HVP_gpioCpFaultOut) + "

"; //bool + content += "

HVP_gpioPyroPor: " + String(datalayer_extended.tesla.HVP_gpioPyroPor) + "

"; //bool + content += "

HVP_gpioShuntEn: " + String(datalayer_extended.tesla.HVP_gpioShuntEn) + "

"; //bool + content += "

HVP_gpioHvpVerEn: " + String(datalayer_extended.tesla.HVP_gpioHvpVerEn) + "

"; //bool + content += "

HVP_gpioPackCoontPosFlywheel: " + String(datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel) + + "

"; //bool + content += "

HVP_gpioCpLatchEnable: " + String(datalayer_extended.tesla.HVP_gpioCpLatchEnable) + "

"; //bool + content += "

HVP_gpioPcsEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsEnable) + "

"; //bool content += - "

HVP_gpioShuntDataReady: " + String(datalayer_extended.tesla.HVP_gpioShuntDataReady) + "

"; //bool - content += - "

HVP_gpioFcContPosAux: " + String(datalayer_extended.tesla.HVP_gpioFcContPosAux) + "

"; //bool - content += - "

HVP_gpioFcContNegAux: " + String(datalayer_extended.tesla.HVP_gpioFcContNegAux) + "

"; //bool - content += "

HVP_gpioBmsEout: " + String(datalayer_extended.tesla.HVP_gpioBmsEout) + "

"; //bool - content += "

HVP_gpioCpFaultOut: " + String(datalayer_extended.tesla.HVP_gpioCpFaultOut) + "

"; //bool - content += "

HVP_gpioPyroPor: " + String(datalayer_extended.tesla.HVP_gpioPyroPor) + "

"; //bool - content += "

HVP_gpioShuntEn: " + String(datalayer_extended.tesla.HVP_gpioShuntEn) + "

"; //bool - content += "

HVP_gpioHvpVerEn: " + String(datalayer_extended.tesla.HVP_gpioHvpVerEn) + "

"; //bool - content += "

HVP_gpioPackCoontPosFlywheel: " + - String(datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel) + "

"; //bool - content += - "

HVP_gpioCpLatchEnable: " + String(datalayer_extended.tesla.HVP_gpioCpLatchEnable) + "

"; //bool - content += "

HVP_gpioPcsEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsEnable) + "

"; //bool - content += "

HVP_gpioPcsDcdcPwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable) + - "

"; //bool - content += - "

HVP_gpioPcsChargePwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable) + - "

"; //bool - content += - "

HVP_gpioFcContPowerEnable: " + String(datalayer_extended.tesla.HVP_gpioFcContPowerEnable) + - "

"; //bool - content += "

HVP_gpioHvilEnable: " + String(datalayer_extended.tesla.HVP_gpioHvilEnable) + "

"; //bool - content += "

HVP_gpioSecDrdy: " + String(datalayer_extended.tesla.HVP_gpioSecDrdy) + "

"; //bool + "

HVP_gpioPcsDcdcPwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable) + "

"; //bool + content += "

HVP_gpioPcsChargePwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable) + + "

"; //bool + content += "

HVP_gpioFcContPowerEnable: " + String(datalayer_extended.tesla.HVP_gpioFcContPowerEnable) + + "

"; //bool + content += "

HVP_gpioHvilEnable: " + String(datalayer_extended.tesla.HVP_gpioHvilEnable) + "

"; //bool + content += "

HVP_gpioSecDrdy: " + String(datalayer_extended.tesla.HVP_gpioSecDrdy) + "

"; //bool content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; - content += "

HVP_packCurrentMia: " + String(datalayer_extended.tesla.HVP_packCurrentMia) + "

"; //bool - content += "

HVP_auxCurrentMia: " + String(datalayer_extended.tesla.HVP_auxCurrentMia) + "

"; //bool - content += "

HVP_currentSenseMia: " + String(datalayer_extended.tesla.HVP_currentSenseMia) + "

"; //bool + content += "

HVP_packCurrentMia: " + String(datalayer_extended.tesla.HVP_packCurrentMia) + "

"; //bool + content += "

HVP_auxCurrentMia: " + String(datalayer_extended.tesla.HVP_auxCurrentMia) + "

"; //bool + content += "

HVP_currentSenseMia: " + String(datalayer_extended.tesla.HVP_currentSenseMia) + "

"; //bool + content += "

HVP_shuntRefVoltageMismatch: " + String(datalayer_extended.tesla.HVP_shuntRefVoltageMismatch) + + "

"; //bool content += - "

HVP_shuntRefVoltageMismatch: " + String(datalayer_extended.tesla.HVP_shuntRefVoltageMismatch) + - "

"; //bool - content += - "

HVP_shuntThermistorMia: " + String(datalayer_extended.tesla.HVP_shuntThermistorMia) + "

"; //bool - content += "

HVP_shuntHwMia: " + String(datalayer_extended.tesla.HVP_shuntHwMia) + "

"; //bool + "

HVP_shuntThermistorMia: " + String(datalayer_extended.tesla.HVP_shuntThermistorMia) + "

"; //bool + content += "

HVP_shuntHwMia: " + String(datalayer_extended.tesla.HVP_shuntHwMia) + "

"; //bool content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; content += "

HVP_fcLinkVoltage: " + String(HVP_fcLinkVoltage) + " V

"; From aadd9df47083f93d017d67b971ac26865c888080 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:33:41 +1300 Subject: [PATCH 51/93] Add delay adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. --- Software/src/battery/TESLA-BATTERY.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index cd6afd08..0c83fab6 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -1226,6 +1226,8 @@ the first, for a few cycles, then stop all messages which causes the contactor } #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) + delay(3000) // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. + //Send 30ms message if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { // Check if sending of CAN messages has been delayed too much. From 3ef5bec6e2530a7ee11e202ff03c7bf4d9bb18d8 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:35:28 +1300 Subject: [PATCH 52/93] Add delay adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. --- Software/src/battery/TESLA-BATTERY.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 0c83fab6..8decbee2 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -1226,10 +1226,11 @@ the first, for a few cycles, then stop all messages which causes the contactor } #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) - delay(3000) // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. + delay( + 3000) // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. - //Send 30ms message - if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { + //Send 30ms message + if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { // Check if sending of CAN messages has been delayed too much. if ((currentMillis - previousMillis30 >= INTERVAL_30_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis30)); From fc90d3eca92857b19be0e84e61bf5bde628ae368 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 13:02:35 +1300 Subject: [PATCH 53/93] Update TESLA-BATTERY.cpp Change location of delay --- Software/src/battery/TESLA-BATTERY.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 8decbee2..65257afe 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -1198,6 +1198,9 @@ the first, for a few cycles, then stop all messages which causes the contactor unsigned long currentMillis = millis(); + delay( + 3000); // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. + #if defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) if ((datalayer.system.status.inverter_allows_contactor_closing) && (datalayer.battery.status.bms_status != FAULT)) { if (currentMillis - lastSend1CF >= 10) { @@ -1226,9 +1229,6 @@ the first, for a few cycles, then stop all messages which causes the contactor } #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) - delay( - 3000) // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. - //Send 30ms message if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { // Check if sending of CAN messages has been delayed too much. From 22c8d7dbe3b3a014594942560ec9dadf9a43d1c6 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Thu, 26 Dec 2024 13:03:03 +1300 Subject: [PATCH 54/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 65257afe..e41f581c 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -1229,8 +1229,8 @@ the first, for a few cycles, then stop all messages which causes the contactor } #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) - //Send 30ms message - if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { + //Send 30ms message + if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { // Check if sending of CAN messages has been delayed too much. if ((currentMillis - previousMillis30 >= INTERVAL_30_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis30)); From 7d9f8cf72d7f27ca7f1601b78f4dcff6fcc31320 Mon Sep 17 00:00:00 2001 From: lenvm Date: Thu, 26 Dec 2024 16:15:50 +0100 Subject: [PATCH 55/93] add LED pin, that turns on when SMA allows contactor closing --- Software/src/inverter/BYD-SMA.cpp | 19 ++++++++++++++++--- Software/src/inverter/SMA-CAN.cpp | 18 +++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Software/src/inverter/BYD-SMA.cpp b/Software/src/inverter/BYD-SMA.cpp index 34e33063..4892eacf 100644 --- a/Software/src/inverter/BYD-SMA.cpp +++ b/Software/src/inverter/BYD-SMA.cpp @@ -130,10 +130,18 @@ void update_values_can_inverter() { //This function maps all the values fetched } //Error bits - if (!datalayer.system.status.inverter_allows_contactor_closing) { - SMA_158.data.u8[2] = 0x6A; - } else { + if (datalayer.system.status.inverter_allows_contactor_closing) { SMA_158.data.u8[2] = 0xAA; +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, + HIGH); // Turn on LED to indicate that SMA inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN + } else { + SMA_158.data.u8[2] = 0x6A; +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, + LOW); // Turn off LED to indicate that SMA inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN } /* @@ -251,10 +259,15 @@ void send_can_inverter() { } } } + void setup_inverter(void) { // Performs one time setup at startup over CAN bus strncpy(datalayer.system.info.inverter_protocol, "BYD Battery-Box HVS over SMA CAN", 63); datalayer.system.info.inverter_protocol[63] = '\0'; datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first pinMode(INVERTER_CONTACTOR_ENABLE_PIN, INPUT); +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + pinMode(INVERTER_CONTACTOR_ENABLE_LED_PIN, OUTPUT); + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, LOW); // Turn LED off, until inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN } #endif diff --git a/Software/src/inverter/SMA-CAN.cpp b/Software/src/inverter/SMA-CAN.cpp index 5831406d..43ccad0d 100644 --- a/Software/src/inverter/SMA-CAN.cpp +++ b/Software/src/inverter/SMA-CAN.cpp @@ -127,10 +127,18 @@ void update_values_can_inverter() { //This function maps all the values fetched } //Error bits - if (!datalayer.system.status.inverter_allows_contactor_closing) { - SMA_158.data.u8[2] = 0x6A; - } else { + if (datalayer.system.status.inverter_allows_contactor_closing) { SMA_158.data.u8[2] = 0xAA; +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, + HIGH); // Turn on LED to indicate that SMA inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN + } else { + SMA_158.data.u8[2] = 0x6A; +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, + LOW); // Turn off LED to indicate that SMA inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN } /* @@ -253,5 +261,9 @@ void send_can_inverter() { void setup_inverter(void) { // Performs one time setup at startup over CAN bus strncpy(datalayer.system.info.inverter_protocol, "SMA CAN", 63); datalayer.system.info.inverter_protocol[63] = '\0'; +#ifdef INVERTER_CONTACTOR_ENABLE_LED_PIN + pinMode(INVERTER_CONTACTOR_ENABLE_LED_PIN, OUTPUT); + digitalWrite(INVERTER_CONTACTOR_ENABLE_LED_PIN, LOW); // Turn LED off, until inverter allows contactor closing +#endif // INVERTER_CONTACTOR_ENABLE_LED_PIN } #endif From b9a067800782c6dd54acf8b745c330a6a2a4995b Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:21:16 +1300 Subject: [PATCH 56/93] Update advanced_battery_html.cpp Changed the displayed data format. --- .../webserver/advanced_battery_html.cpp | 107 +++++++++--------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 3e68190e..12d5f803 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -495,6 +495,7 @@ String advanced_battery_processor(const String& var) { static const char* HVP_contactor[] = {"NOT_ACTIVE", "ACTIVE", "COMPLETED"}; static const char* falseTrue[] = {"False", "True"}; static const char* noYes[] = {"No", "Yes"}; + static const char* Fault[] = {"NOT_ACTIVE", "ACTIVE"}; //0x20A 522 HVP_contatorState content += "

Contactor Status: " + String(contactorText[datalayer_extended.tesla.status_contactor]) + "

"; content += "

HVIL: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "

"; @@ -502,18 +503,18 @@ String advanced_battery_processor(const String& var) { "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; - content += "

Closing allowed?: " + String(datalayer_extended.tesla.packCtrsClosingAllowed) + "

"; //bool - content += "

Pyrotest in Progress: " + String(datalayer_extended.tesla.pyroTestInProgress) + "

"; //bool + content += "

Closing allowed?: " + String(noYes[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; //bool + content += "

Pyrotest in Progress: " + String(noYes[datalayer_extended.tesla.pyroTestInProgress]) + "

"; //bool content += - "

Contactors Open Now Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenNowRequested) + + "

Contactors Open Now Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; //bool - content += "

Contactors Open Requested: " + String(datalayer_extended.tesla.battery_packCtrsOpenRequested) + + content += "

Contactors Open Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; //bool content += "

Contactors Request Status: " + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; content += "

Contactors Reset Request Required: " + - String(datalayer_extended.tesla.battery_packCtrsResetRequestRequired) + "

"; //bool - content += "

DC Link Allowed to Energize:" + String(datalayer_extended.tesla.battery_dcLinkAllowedToEnergize) + + String(noYes[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; //bool + content += "

DC Link Allowed to Energize: " + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "

"; //bool // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates @@ -543,22 +544,22 @@ String advanced_battery_processor(const String& var) { "

Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "

"; content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; - content += "

PCS Faulted: " + String(datalayer_extended.tesla.battery_PCS_dcdcFaulted) + "

"; //bool + content += "

PCS Faulted: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "

"; //bool content += - "

Output Is Limited: " + String(datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited) + "

"; //bool + "

Output Is Limited: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; //bool content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; content += - "

Precharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt) + "

"; //bool - content += "

12V Support Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt) + + "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + "

"; //bool + content += "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + "

"; // bool content += - "

Discharge Rty Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt) + "

"; //bool + "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + "

"; //bool content += - "

PWM Enable Line: " + String(datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine) + "

"; //bool + "

PWM Enable Line: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; //bool content += - "

Supporting Fixed LV Target: " + String(datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget) + + "

Supporting Fixed LV Target: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; //bool - content += "

Precharge Restart Cnt: " + String(datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt) + + content += "

Precharge Restart Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; //bool content += "

Initial Precharge Substate: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; @@ -596,7 +597,7 @@ String advanced_battery_processor(const String& var) { content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; content += - "

BMS PCS PWM Enabled: " + String(datalayer_extended.tesla.battery_BMS_pcsPwmEnabled) + "

"; //bool + "

BMS PCS PWM Enabled: " + String(Fault[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Early BMS 0x352:

"; //if using older BMS <2021 and comment 0x352 without MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "

"; @@ -606,7 +607,7 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; content += - "

Full Charge Complete: " + String(datalayer_extended.tesla.battery_full_charge_complete) + "

"; //bool + "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //bool //0x352 850 BMS_energyStatus content += "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; @@ -616,11 +617,11 @@ String advanced_battery_processor(const String& var) { content += "

Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer_m1) + " KWh

"; content += "

Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh

"; - content += "

Fully Charged: " + String(datalayer_extended.tesla.battery_fully_charged) + "

"; //bool + content += "

Fully Charged: " + String(noYes[datalayer_extended.tesla.battery_fully_charged]) + "

"; //bool //0x392 BMS_packConfig - content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; - content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; - content += "

reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "

"; + //content += "

packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "

"; + //content += "

moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "

"; + //content += "

reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "

"; content += "

Battery Pack Mass: " + String(packMass) + " KG

"; content += "

Platform Max Bus Voltage: " + String(platformMaxBusVoltage) + " V

"; //0x2D2 722 BMSVAlimits @@ -640,7 +641,7 @@ String advanced_battery_processor(const String& var) { content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; - content += "

Not Enough Power For Heat Pump: " + String(datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump) + + content += "

Not Enough Power For Heat Pump: " + String(falseTrue[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + "

"; //bool content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; @@ -653,50 +654,50 @@ String advanced_battery_processor(const String& var) { content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; - content += "

PCS No Flow Request: " + String(datalayer_extended.tesla.BMS_pcsNoFlowRequest) + "

"; //bool - content += "

BMS No Flow Request: " + String(datalayer_extended.tesla.BMS_noFlowRequest) + "

"; //bool + content += "

PCS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; //bool + content += "

BMS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; //bool //0x7AA 1962 HVP_debugMessage content += - "

HVP_gpioPassivePyroDepl: " + String(datalayer_extended.tesla.HVP_gpioPassivePyroDepl) + "

"; //bool - content += "

HVP_gpioPyroIsoEn: " + String(datalayer_extended.tesla.HVP_gpioPyroIsoEn) + "

"; //bool - content += "

HVP_gpioCpFaultIn: " + String(datalayer_extended.tesla.HVP_gpioCpFaultIn) + "

"; //bool + "

HVP_gpioPassivePyroDepl: " + String(Fault[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; //bool + content += "

HVP_gpioPyroIsoEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; //bool + content += "

HVP_gpioCpFaultIn: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; //bool content += - "

HVP_gpioPackContPowerEn: " + String(datalayer_extended.tesla.HVP_gpioPackContPowerEn) + "

"; //bool - content += "

HVP_gpioHvCablesOk: " + String(datalayer_extended.tesla.HVP_gpioHvCablesOk) + "

"; //bool - content += "

HVP_gpioHvpSelfEnable: " + String(datalayer_extended.tesla.HVP_gpioHvpSelfEnable) + "

"; //bool - content += "

HVP_gpioLed: " + String(datalayer_extended.tesla.HVP_gpioLed) + "

"; //bool - content += "

HVP_gpioCrashSignal: " + String(datalayer_extended.tesla.HVP_gpioCrashSignal) + "

"; //bool + "

HVP_gpioPackContPowerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; //bool + content += "

HVP_gpioHvCablesOk: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; //bool + content += "

HVP_gpioHvpSelfEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; //bool + content += "

HVP_gpioLed: " + String(Fault[datalayer_extended.tesla.HVP_gpioLed]) + "

"; //bool + content += "

HVP_gpioCrashSignal: " + String(Fault[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; //bool content += - "

HVP_gpioShuntDataReady: " + String(datalayer_extended.tesla.HVP_gpioShuntDataReady) + "

"; //bool - content += "

HVP_gpioFcContPosAux: " + String(datalayer_extended.tesla.HVP_gpioFcContPosAux) + "

"; //bool - content += "

HVP_gpioFcContNegAux: " + String(datalayer_extended.tesla.HVP_gpioFcContNegAux) + "

"; //bool - content += "

HVP_gpioBmsEout: " + String(datalayer_extended.tesla.HVP_gpioBmsEout) + "

"; //bool - content += "

HVP_gpioCpFaultOut: " + String(datalayer_extended.tesla.HVP_gpioCpFaultOut) + "

"; //bool - content += "

HVP_gpioPyroPor: " + String(datalayer_extended.tesla.HVP_gpioPyroPor) + "

"; //bool - content += "

HVP_gpioShuntEn: " + String(datalayer_extended.tesla.HVP_gpioShuntEn) + "

"; //bool - content += "

HVP_gpioHvpVerEn: " + String(datalayer_extended.tesla.HVP_gpioHvpVerEn) + "

"; //bool - content += "

HVP_gpioPackCoontPosFlywheel: " + String(datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel) + + "

HVP_gpioShuntDataReady: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; //bool + content += "

HVP_gpioFcContPosAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; //bool + content += "

HVP_gpioFcContNegAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; //bool + content += "

HVP_gpioBmsEout: " + String(Fault[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; //bool + content += "

HVP_gpioCpFaultOut: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; //bool + content += "

HVP_gpioPyroPor: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; //bool + content += "

HVP_gpioShuntEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; //bool + content += "

HVP_gpioHvpVerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; //bool + content += "

HVP_gpioPackCoontPosFlywheel: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + "

"; //bool - content += "

HVP_gpioCpLatchEnable: " + String(datalayer_extended.tesla.HVP_gpioCpLatchEnable) + "

"; //bool - content += "

HVP_gpioPcsEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsEnable) + "

"; //bool + content += "

HVP_gpioCpLatchEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; //bool + content += "

HVP_gpioPcsEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; //bool content += - "

HVP_gpioPcsDcdcPwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable) + "

"; //bool - content += "

HVP_gpioPcsChargePwmEnable: " + String(datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable) + + "

HVP_gpioPcsDcdcPwmEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + "

"; //bool + content += "

HVP_gpioPcsChargePwmEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + "

"; //bool - content += "

HVP_gpioFcContPowerEnable: " + String(datalayer_extended.tesla.HVP_gpioFcContPowerEnable) + + content += "

HVP_gpioFcContPowerEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + "

"; //bool - content += "

HVP_gpioHvilEnable: " + String(datalayer_extended.tesla.HVP_gpioHvilEnable) + "

"; //bool - content += "

HVP_gpioSecDrdy: " + String(datalayer_extended.tesla.HVP_gpioSecDrdy) + "

"; //bool + content += "

HVP_gpioHvilEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; //bool + content += "

HVP_gpioSecDrdy: " + String(Fault[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; //bool content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; - content += "

HVP_packCurrentMia: " + String(datalayer_extended.tesla.HVP_packCurrentMia) + "

"; //bool - content += "

HVP_auxCurrentMia: " + String(datalayer_extended.tesla.HVP_auxCurrentMia) + "

"; //bool - content += "

HVP_currentSenseMia: " + String(datalayer_extended.tesla.HVP_currentSenseMia) + "

"; //bool - content += "

HVP_shuntRefVoltageMismatch: " + String(datalayer_extended.tesla.HVP_shuntRefVoltageMismatch) + + content += "

HVP_packCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; //bool + content += "

HVP_auxCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; //bool + content += "

HVP_currentSenseMia: " + String(noYes[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; //bool + content += "

HVP_shuntRefVoltageMismatch: " + String(noYes[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + "

"; //bool content += - "

HVP_shuntThermistorMia: " + String(datalayer_extended.tesla.HVP_shuntThermistorMia) + "

"; //bool - content += "

HVP_shuntHwMia: " + String(datalayer_extended.tesla.HVP_shuntHwMia) + "

"; //bool + "

HVP_shuntThermistorMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; //bool + content += "

HVP_shuntHwMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; //bool content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; content += "

HVP_fcLinkVoltage: " + String(HVP_fcLinkVoltage) + " V

"; From 256bf19201427b2fc6c207472ea8029be6f5d356 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Fri, 27 Dec 2024 19:21:25 +1300 Subject: [PATCH 57/93] Update advanced_battery_html.cpp --- .../webserver/advanced_battery_html.cpp | 141 ++++++++++-------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/Software/src/devboard/webserver/advanced_battery_html.cpp b/Software/src/devboard/webserver/advanced_battery_html.cpp index 12d5f803..c1569714 100644 --- a/Software/src/devboard/webserver/advanced_battery_html.cpp +++ b/Software/src/devboard/webserver/advanced_battery_html.cpp @@ -503,19 +503,22 @@ String advanced_battery_processor(const String& var) { "

Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "

"; content += "

Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "

"; - content += "

Closing allowed?: " + String(noYes[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; //bool - content += "

Pyrotest in Progress: " + String(noYes[datalayer_extended.tesla.pyroTestInProgress]) + "

"; //bool content += - "

Contactors Open Now Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + + "

Closing allowed?: " + String(noYes[datalayer_extended.tesla.packCtrsClosingAllowed]) + "

"; //bool + content += + "

Pyrotest in Progress: " + String(noYes[datalayer_extended.tesla.pyroTestInProgress]) + "

"; //bool + content += "

Contactors Open Now Requested: " + + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "

"; //bool + content += + "

Contactors Open Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + "

"; //bool - content += "

Contactors Open Requested: " + String(noYes[datalayer_extended.tesla.battery_packCtrsOpenRequested]) + - "

"; //bool content += "

Contactors Request Status: " + String(HVP_contactor[datalayer_extended.tesla.battery_packCtrsRequestStatus]) + "

"; content += "

Contactors Reset Request Required: " + String(noYes[datalayer_extended.tesla.battery_packCtrsResetRequestRequired]) + "

"; //bool - content += "

DC Link Allowed to Energize: " + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + - "

"; //bool + content += + "

DC Link Allowed to Energize: " + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + + "

"; //bool // Comment what data you would like to dislay, order can be changed. //0x292 658 BMS_socStates content += "

Battery Beginning of Life: " + String(beginning_of_life) + " KWh

"; @@ -545,22 +548,22 @@ String advanced_battery_processor(const String& var) { content += "

Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "

"; content += "

PCS Faulted: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "

"; //bool - content += - "

Output Is Limited: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; //bool - content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; - content += - "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + "

"; //bool - content += "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + - "

"; // bool - content += - "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + "

"; //bool - content += - "

PWM Enable Line: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "

"; //bool - content += - "

Supporting Fixed LV Target: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + - "

"; //bool - content += "

Precharge Restart Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + + content += "

Output Is Limited: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "

"; //bool + content += "

Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A

"; + content += "

Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) + + "

"; //bool + content += + "

12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + + "

"; // bool + content += "

Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) + + "

"; //bool + content += "

PWM Enable Line: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + + "

"; //bool + content += "

Supporting Fixed LV Target: " + + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "

"; //bool + content += "

Precharge Restart Cnt: " + + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "

"; //bool content += "

Initial Precharge Substate: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "

"; //0x2C4 708 PCS_logging @@ -596,8 +599,8 @@ String advanced_battery_processor(const String& var) { content += "

BMS HV State: " + String(BMS_hvState[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; content += "

BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) + "

"; - content += - "

BMS PCS PWM Enabled: " + String(Fault[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "

"; //bool + content += "

BMS PCS PWM Enabled: " + String(Fault[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + + "

"; //bool //0x352 850 BMS_energyStatus content += "

Early BMS 0x352:

"; //if using older BMS <2021 and comment 0x352 without MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "

"; @@ -606,8 +609,8 @@ String advanced_battery_processor(const String& var) { content += "

Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh

"; content += "

Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh

"; content += "

Energy Buffer: " + String(energy_buffer) + " KWh

"; - content += - "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + "

"; //bool + content += "

Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + + "

"; //bool //0x352 850 BMS_energyStatus content += "

Late BMS 0x352 with Mux:

"; //if using newer BMS >2021 and comment 0x352 with MUX content += "

Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "

"; @@ -641,8 +644,8 @@ String advanced_battery_processor(const String& var) { content += "

Max Discharge Power: " + String(BMS_maxDischargePower) + " KW

"; content += "

Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh

"; content += "

HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW

"; - content += "

Not Enough Power For Heat Pump: " + String(falseTrue[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + - "

"; //bool + content += "

Not Enough Power For Heat Pump: " + + String(falseTrue[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + "

"; //bool content += "

Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "

"; content += "

Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "

"; @@ -654,50 +657,64 @@ String advanced_battery_processor(const String& var) { content += "

Inlet Active Heat Target Temp: " + String(BMS_inletActiveHeatTargetT) + " DegC

"; content += "

Pack Temp Min: " + String(BMS_packTMin) + " DegC

"; content += "

Pack Temp Max: " + String(BMS_packTMax) + " DegC

"; - content += "

PCS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; //bool - content += "

BMS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; //bool + content += + "

PCS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_pcsNoFlowRequest]) + "

"; //bool + content += + "

BMS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_noFlowRequest]) + "

"; //bool //0x7AA 1962 HVP_debugMessage + content += "

HVP_gpioPassivePyroDepl: " + String(Fault[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + + "

"; //bool + content += "

HVP_gpioPyroIsoEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; //bool + content += "

HVP_gpioCpFaultIn: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; //bool + content += "

HVP_gpioPackContPowerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + + "

"; //bool content += - "

HVP_gpioPassivePyroDepl: " + String(Fault[datalayer_extended.tesla.HVP_gpioPassivePyroDepl]) + "

"; //bool - content += "

HVP_gpioPyroIsoEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroIsoEn]) + "

"; //bool - content += "

HVP_gpioCpFaultIn: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultIn]) + "

"; //bool + "

HVP_gpioHvCablesOk: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; //bool content += - "

HVP_gpioPackContPowerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackContPowerEn]) + "

"; //bool - content += "

HVP_gpioHvCablesOk: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvCablesOk]) + "

"; //bool - content += "

HVP_gpioHvpSelfEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; //bool - content += "

HVP_gpioLed: " + String(Fault[datalayer_extended.tesla.HVP_gpioLed]) + "

"; //bool - content += "

HVP_gpioCrashSignal: " + String(Fault[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; //bool + "

HVP_gpioHvpSelfEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpSelfEnable]) + "

"; //bool + content += "

HVP_gpioLed: " + String(Fault[datalayer_extended.tesla.HVP_gpioLed]) + "

"; //bool content += - "

HVP_gpioShuntDataReady: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntDataReady]) + "

"; //bool - content += "

HVP_gpioFcContPosAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; //bool - content += "

HVP_gpioFcContNegAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; //bool - content += "

HVP_gpioBmsEout: " + String(Fault[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; //bool - content += "

HVP_gpioCpFaultOut: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; //bool - content += "

HVP_gpioPyroPor: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; //bool - content += "

HVP_gpioShuntEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; //bool - content += "

HVP_gpioHvpVerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; //bool - content += "

HVP_gpioPackCoontPosFlywheel: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + - "

"; //bool - content += "

HVP_gpioCpLatchEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; //bool - content += "

HVP_gpioPcsEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; //bool + "

HVP_gpioCrashSignal: " + String(Fault[datalayer_extended.tesla.HVP_gpioCrashSignal]) + "

"; //bool + content += "

HVP_gpioShuntDataReady: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntDataReady]) + + "

"; //bool content += - "

HVP_gpioPcsDcdcPwmEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + "

"; //bool + "

HVP_gpioFcContPosAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContPosAux]) + "

"; //bool + content += + "

HVP_gpioFcContNegAux: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContNegAux]) + "

"; //bool + content += "

HVP_gpioBmsEout: " + String(Fault[datalayer_extended.tesla.HVP_gpioBmsEout]) + "

"; //bool + content += + "

HVP_gpioCpFaultOut: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpFaultOut]) + "

"; //bool + content += "

HVP_gpioPyroPor: " + String(Fault[datalayer_extended.tesla.HVP_gpioPyroPor]) + "

"; //bool + content += "

HVP_gpioShuntEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioShuntEn]) + "

"; //bool + content += "

HVP_gpioHvpVerEn: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvpVerEn]) + "

"; //bool + content += + "

HVP_gpioPackCoontPosFlywheel: " + String(Fault[datalayer_extended.tesla.HVP_gpioPackCoontPosFlywheel]) + + "

"; //bool + content += + "

HVP_gpioCpLatchEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioCpLatchEnable]) + "

"; //bool + content += "

HVP_gpioPcsEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsEnable]) + "

"; //bool + content += "

HVP_gpioPcsDcdcPwmEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsDcdcPwmEnable]) + + "

"; //bool content += "

HVP_gpioPcsChargePwmEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioPcsChargePwmEnable]) + "

"; //bool content += "

HVP_gpioFcContPowerEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioFcContPowerEnable]) + - "

"; //bool - content += "

HVP_gpioHvilEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; //bool - content += "

HVP_gpioSecDrdy: " + String(Fault[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; //bool - content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; - content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; - content += "

HVP_packCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; //bool - content += "

HVP_auxCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; //bool - content += "

HVP_currentSenseMia: " + String(noYes[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; //bool - content += "

HVP_shuntRefVoltageMismatch: " + String(noYes[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + "

"; //bool content += - "

HVP_shuntThermistorMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntThermistorMia]) + "

"; //bool - content += "

HVP_shuntHwMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; //bool + "

HVP_gpioHvilEnable: " + String(Fault[datalayer_extended.tesla.HVP_gpioHvilEnable]) + "

"; //bool + content += "

HVP_gpioSecDrdy: " + String(Fault[datalayer_extended.tesla.HVP_gpioSecDrdy]) + "

"; //bool + content += "

HVP_hvp1v5Ref: " + String(HVP_hvp1v5Ref) + " V

"; + content += "

HVP_shuntCurrentDebug: " + String(HVP_shuntCurrentDebug) + " A

"; + content += + "

HVP_packCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_packCurrentMia]) + "

"; //bool + content += "

HVP_auxCurrentMia: " + String(noYes[datalayer_extended.tesla.HVP_auxCurrentMia]) + "

"; //bool + content += + "

HVP_currentSenseMia: " + String(noYes[datalayer_extended.tesla.HVP_currentSenseMia]) + "

"; //bool + content += + "

HVP_shuntRefVoltageMismatch: " + String(noYes[datalayer_extended.tesla.HVP_shuntRefVoltageMismatch]) + + "

"; //bool + content += "

HVP_shuntThermistorMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntThermistorMia]) + + "

"; //bool + content += "

HVP_shuntHwMia: " + String(noYes[datalayer_extended.tesla.HVP_shuntHwMia]) + "

"; //bool content += "

HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V

"; content += "

HVP_packVoltage: " + String(HVP_packVoltage) + " V

"; content += "

HVP_fcLinkVoltage: " + String(HVP_fcLinkVoltage) + " V

"; From f27408b2f3a52e684949e69bb364f21992cb78b7 Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sat, 28 Dec 2024 09:11:04 +1300 Subject: [PATCH 58/93] Update TESLA-BATTERY.cpp Update 0x221 send time to 50ms. Adjust default values before CAN mapping cell voltage, remove delay that was not working. --- Software/src/battery/TESLA-BATTERY.cpp | 35 ++++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index e41f581c..2467e072 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -8,8 +8,8 @@ /* Do not change code below unless you are sure what you are doing */ /* Credits: Most of the code comes from Per Carlen's bms_comms_tesla_model3.py (https://gitlab.com/pelle8/batt2gen24/) */ -static unsigned long previousMillis30 = 0; // will store last time a 30ms CAN Message was send - +static unsigned long previousMillis50 = 0; // will store last time a 50ms CAN Message was send +//0x221 545 VCFRONT_LVPowerState: "GenMsgCycleTime" 50ms CAN_frame TESLA_221_1 = { .FD = false, .ext_ID = false, @@ -42,9 +42,9 @@ static uint16_t battery_ideal_energy_remaining = 0; // kWh static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_energy_remaining = 0; // kWh static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_full_pack_energy = 600; // Kwh -static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh -static uint16_t battery_beginning_of_life = 600; // kWh +static uint16_t battery_nominal_full_pack_energy = 0; // Kwh +static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh +static uint16_t battery_beginning_of_life = 0; // kWh static uint16_t battery_charge_time_remaining = 0; // Minutes static uint16_t battery_regenerative_limit = 0; static uint16_t battery_discharge_limit = 0; @@ -62,8 +62,8 @@ static uint16_t battery_soc_min = 0; static uint16_t battery_soc_max = 0; static uint16_t battery_soc_ui = 0; //Change name from battery_soc_vi to reflect DBC battery_soc_ui static uint16_t battery_soc_ave = 0; -static uint16_t battery_cell_max_v = 3700; -static uint16_t battery_cell_min_v = 3700; +static uint16_t battery_cell_max_v = 3300; //Voltage value used on boot before CAN values have been mapped +static uint16_t battery_cell_min_v = 3300; //Changed from 3700 static uint16_t battery_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV static uint8_t battery_max_vno = 0; static uint8_t battery_min_vno = 0; @@ -160,9 +160,9 @@ static uint16_t battery2_ideal_energy_remaining = 0; static uint16_t battery2_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery2_nominal_energy_remaining = 0; static uint16_t battery2_nominal_energy_remaining_m0 = 0; // kWh -static uint16_t battery2_nominal_full_pack_energy = 600; -static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh -static uint16_t battery2_beginning_of_life = 600; +static uint16_t battery2_nominal_full_pack_energy = 0; +static uint16_t battery2_nominal_full_pack_energy_m0 = 0; // Kwh +static uint16_t battery2_beginning_of_life = 0; static uint16_t battery2_charge_time_remaining = 0; // Minutes static uint16_t battery2_regenerative_limit = 0; static uint16_t battery2_discharge_limit = 0; @@ -179,8 +179,8 @@ static uint16_t battery2_soc_min = 0; static uint16_t battery2_soc_max = 0; static uint16_t battery2_soc_ui = 0; static uint16_t battery2_soc_ave = 0; -static uint16_t battery2_cell_max_v = 3700; -static uint16_t battery2_cell_min_v = 3700; +static uint16_t battery2_cell_max_v = 3300; +static uint16_t battery2_cell_min_v = 3300; static uint16_t battery2_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV static uint8_t battery2_max_vno = 0; static uint8_t battery2_min_vno = 0; @@ -1198,9 +1198,6 @@ the first, for a few cycles, then stop all messages which causes the contactor unsigned long currentMillis = millis(); - delay( - 3000); // adding 3s delay to allow cell voltage min/max to be read before transmit_can to stop false under/over cell voltage events. - #if defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) if ((datalayer.system.status.inverter_allows_contactor_closing) && (datalayer.battery.status.bms_status != FAULT)) { if (currentMillis - lastSend1CF >= 10) { @@ -1230,14 +1227,14 @@ the first, for a few cycles, then stop all messages which causes the contactor #endif //defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) //Send 30ms message - if (currentMillis - previousMillis30 >= INTERVAL_30_MS) { + if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis30 >= INTERVAL_30_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis30)); + if ((currentMillis - previousMillis50 >= INTERVAL_50_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis50)); } else { clear_event(EVENT_CAN_OVERRUN); } - previousMillis30 = currentMillis; + previousMillis50 = currentMillis; if ((datalayer.system.status.inverter_allows_contactor_closing == true) && (datalayer.battery.status.bms_status != FAULT)) { From 7b67eab81de6b4f7a0e0ca0f1a6194ef80b6a03d Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sat, 28 Dec 2024 09:11:54 +1300 Subject: [PATCH 59/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 2467e072..cc2cd2ee 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -25,27 +25,27 @@ CAN_frame TESLA_221_2 = { static uint16_t sendContactorClosingMessagesStill = 300; static uint32_t battery_total_discharge = 0; static uint32_t battery_total_charge = 0; -static uint16_t battery_volts = 0; // V -static int16_t battery_amps = 0; // A -static uint16_t battery_raw_amps = 0; // A -static int16_t battery_max_temp = 0; // C* -static int16_t battery_min_temp = 0; // C* -static uint16_t battery_energy_buffer = 0; // kWh -static uint16_t battery_energy_buffer_m1 = 0; // kWh -static uint16_t battery_energy_to_charge_complete = 0; // kWh -static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh -static uint16_t battery_expected_energy_remaining = 0; // kWh -static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh -static uint8_t battery_full_charge_complete = 0; // kWh -static uint8_t battery_fully_charged = 0; // kWh -static uint16_t battery_ideal_energy_remaining = 0; // kWh -static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_energy_remaining = 0; // kWh -static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_full_pack_energy = 0; // Kwh -static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh -static uint16_t battery_beginning_of_life = 0; // kWh -static uint16_t battery_charge_time_remaining = 0; // Minutes +static uint16_t battery_volts = 0; // V +static int16_t battery_amps = 0; // A +static uint16_t battery_raw_amps = 0; // A +static int16_t battery_max_temp = 0; // C* +static int16_t battery_min_temp = 0; // C* +static uint16_t battery_energy_buffer = 0; // kWh +static uint16_t battery_energy_buffer_m1 = 0; // kWh +static uint16_t battery_energy_to_charge_complete = 0; // kWh +static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh +static uint16_t battery_expected_energy_remaining = 0; // kWh +static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh +static uint8_t battery_full_charge_complete = 0; // kWh +static uint8_t battery_fully_charged = 0; // kWh +static uint16_t battery_ideal_energy_remaining = 0; // kWh +static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh +static uint16_t battery_nominal_energy_remaining = 0; // kWh +static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh +static uint16_t battery_nominal_full_pack_energy = 0; // Kwh +static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh +static uint16_t battery_beginning_of_life = 0; // kWh +static uint16_t battery_charge_time_remaining = 0; // Minutes static uint16_t battery_regenerative_limit = 0; static uint16_t battery_discharge_limit = 0; static uint16_t battery_max_heat_park = 0; @@ -62,8 +62,8 @@ static uint16_t battery_soc_min = 0; static uint16_t battery_soc_max = 0; static uint16_t battery_soc_ui = 0; //Change name from battery_soc_vi to reflect DBC battery_soc_ui static uint16_t battery_soc_ave = 0; -static uint16_t battery_cell_max_v = 3300; //Voltage value used on boot before CAN values have been mapped -static uint16_t battery_cell_min_v = 3300; //Changed from 3700 +static uint16_t battery_cell_max_v = 3300; //Voltage value used on boot before CAN values have been mapped +static uint16_t battery_cell_min_v = 3300; //Changed from 3700 static uint16_t battery_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV static uint8_t battery_max_vno = 0; static uint8_t battery_min_vno = 0; From 30a07aba771e9df2aac572ce54bc6eed9669c7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 12:45:17 +0300 Subject: [PATCH 60/93] Pre-commit fix --- Software/Software.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/Software.ino b/Software/Software.ino index 2cbecee8..ce84181b 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -1,6 +1,5 @@ /* Do not change any code below this line unless you are sure what you are doing */ /* Only change battery specific settings in "USER_SETTINGS.h" */ -#include "src/include.h" #include "HardwareSerial.h" #include "USER_SECRETS.h" #include "USER_SETTINGS.h" @@ -20,6 +19,7 @@ #include "src/devboard/utils/led_handler.h" #include "src/devboard/utils/logging.h" #include "src/devboard/utils/value_mapping.h" +#include "src/include.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime.h" #include "src/lib/YiannisBourkelis-Uptime-Library/src/uptime_formatter.h" #include "src/lib/bblanchon-ArduinoJson/ArduinoJson.h" From c9c5e696cbf82f89c86cf8f60ea1a5c5180a7520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 14:42:44 +0300 Subject: [PATCH 61/93] Apply diff from successful testing --- Software/src/inverter/SMA-TRIPOWER-CAN.cpp | 91 ++++++++++++++++------ 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp index 1296cbe7..dac1af9c 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp @@ -12,9 +12,19 @@ */ /* Do not change code below unless you are sure what you are doing */ -static unsigned long previousMillis500ms = 0; // will store last time a 100ms CAN Message was send +static unsigned long previousMillis250ms = 0; // will store last time a 250ms CAN Message was send +static unsigned long previousMillis500ms = 0; // will store last time a 500ms CAN Message was send static unsigned long previousMillis2s = 0; // will store last time a 2s CAN Message was send static unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send +static unsigned long previousMillis60s = 0; // will store last time a 60s CAN Message was send + +typedef struct { + CAN_frame* frame; + void (*callback)(); +} Frame; + +static unsigned short listLength = 0; +static Frame framesToSend[20]; static uint32_t inverter_time = 0; static uint16_t inverter_voltage = 0; @@ -33,7 +43,7 @@ CAN_frame SMA_598 = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x598, - .data = {0x12, 0x30, 0x8A, 0x5B, 0x00, 0x00, 0x00, 0x00}}; //B0-4 Serial? + .data = {0x12, 0xD6, 0x43, 0xA4, 0x00, 0x00, 0x00, 0x00}}; //B0-4 Serial 301100932 CAN_frame SMA_5D8 = {.FD = false, .ext_ID = false, .DLC = 8, @@ -168,6 +178,17 @@ void receive_can_inverter(CAN_frame rx_frame) { } } +void pushFrame(CAN_frame* frame, void (*callback)() = NULL) { + if (listLength >= 20) { + return; //TODO: scream. + } + framesToSend[listLength] = { + .frame = frame, + .callback = callback, + }; + listLength++; +} + void send_can_inverter() { unsigned long currentMillis = millis(); @@ -176,43 +197,63 @@ void send_can_inverter() { return; } + if (listLength > 0 && currentMillis - previousMillis250ms >= INTERVAL_250_MS) { + previousMillis250ms = currentMillis; + // Send next frame. + Frame frame = framesToSend[0]; + transmit_can(frame.frame, can_config.inverter); + if (frame.callback != NULL) { + frame.callback(); + } + for (int i = 0; i < listLength - 1; i++) { + framesToSend[i] = framesToSend[i + 1]; + } + listLength--; + } + + if (!pairing_completed) { + return; + } + // Send CAN Message every 2s if (currentMillis - previousMillis2s >= INTERVAL_2_S) { previousMillis2s = currentMillis; - transmit_can(&SMA_358, can_config.inverter); + pushFrame(&SMA_358); } // Send CAN Message every 10s if (currentMillis - previousMillis10s >= INTERVAL_10_S) { previousMillis10s = currentMillis; - transmit_can(&SMA_518, can_config.inverter); - transmit_can(&SMA_4D8, can_config.inverter); - transmit_can(&SMA_3D8, can_config.inverter); - if (pairing_completed) { - transmit_can( - &SMA_458, - can_config - .inverter); //TODO; not confirmed if battery sends. Transmission starts only after battery is paired - } + pushFrame(&SMA_518); + pushFrame(&SMA_4D8); + pushFrame(&SMA_3D8); } } -void send_tripower_init() { - transmit_can(&SMA_558, can_config.inverter); //Pairing start - Vendor - transmit_can(&SMA_598, can_config.inverter); //Serial - transmit_can(&SMA_5D8, can_config.inverter); //BYD - transmit_can(&SMA_618_0, can_config.inverter); //BATTERY - transmit_can(&SMA_618_1, can_config.inverter); //-Box Pr - transmit_can(&SMA_618_2, can_config.inverter); //emium H - transmit_can(&SMA_618_3, can_config.inverter); //VS - transmit_can(&SMA_358, can_config.inverter); - transmit_can(&SMA_3D8, can_config.inverter); - transmit_can(&SMA_458, can_config.inverter); - transmit_can(&SMA_4D8, can_config.inverter); - transmit_can(&SMA_518, can_config.inverter); + +void completePairing() { pairing_completed = true; } +void send_tripower_init() { + listLength = 0; // clear all frames + + pushFrame(&SMA_558); //Pairing start - Vendor + pushFrame(&SMA_598); //Serial + pushFrame(&SMA_5D8); //BYD + pushFrame(&SMA_618_0); //BATTERY + pushFrame(&SMA_618_1); //-Box Pr + pushFrame(&SMA_618_2); //emium H + pushFrame(&SMA_618_3); //VS + pushFrame(&SMA_358); + pushFrame(&SMA_3D8); + pushFrame(&SMA_458); + pushFrame(&SMA_4D8); + pushFrame(&SMA_518, completePairing); +} + void setup_inverter(void) { // Performs one time setup at startup over CAN bus strncpy(datalayer.system.info.inverter_protocol, "SMA Tripower CAN", 63); datalayer.system.info.inverter_protocol[63] = '\0'; + datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first + pinMode(INVERTER_CONTACTOR_ENABLE_PIN, INPUT); } #endif From 866357157994fa850b92d91e4c02e104df60837e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 14:58:47 +0300 Subject: [PATCH 62/93] Add SMA Tripower to contactor allow writing --- .../communication/contactorcontrol/comm_contactorcontrol.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp index c09e6c17..9a93936a 100644 --- a/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp +++ b/Software/src/communication/contactorcontrol/comm_contactorcontrol.cpp @@ -90,9 +90,9 @@ void init_contactors() { // Main functions void handle_contactors() { -#ifdef BYD_SMA +#if defined(BYD_SMA) || defined(SMA_TRIPOWER_CAN) datalayer.system.status.inverter_allows_contactor_closing = digitalRead(INVERTER_CONTACTOR_ENABLE_PIN); -#endif // BYD_SMA +#endif #ifdef CONTACTOR_CONTROL_DOUBLE_BATTERY handle_contactors_battery2(); From d0ffb97816d251719e2f3c3f216fc2bf7fea02e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 16:19:41 +0300 Subject: [PATCH 63/93] Rename to stellantis, add TODO --- .github/workflows/compile-all-batteries.yml | 1 + ...pile-all-combinations-part2-batteries-N-to-Z.yml | 1 + Software/USER_SETTINGS.h | 2 +- Software/src/battery/BATTERIES.h | 2 +- Software/src/battery/ECMP-BATTERY.cpp | 13 ++++++++++++- Software/src/battery/ECMP-BATTERY.h | 4 ++-- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/compile-all-batteries.yml b/.github/workflows/compile-all-batteries.yml index 80466e52..09e852ca 100644 --- a/.github/workflows/compile-all-batteries.yml +++ b/.github/workflows/compile-all-batteries.yml @@ -70,6 +70,7 @@ jobs: - RENAULT_ZOE_GEN1_BATTERY - RENAULT_ZOE_GEN2_BATTERY - SANTA_FE_PHEV_BATTERY + - STELLANTIS_ECMP_BATTERY - TESLA_MODEL_3Y_BATTERY - TESLA_MODEL_SX_BATTERY - VOLVO_SPA_BATTERY diff --git a/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml b/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml index 8c77e237..abec324e 100644 --- a/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml +++ b/.github/workflows/compile-all-combinations-part2-batteries-N-to-Z.yml @@ -63,6 +63,7 @@ jobs: - RENAULT_ZOE_GEN1_BATTERY - RENAULT_ZOE_GEN2_BATTERY - SANTA_FE_PHEV_BATTERY + - STELLANTIS_ECMP_BATTERY - TESLA_MODEL_3Y_BATTERY - TESLA_MODEL_SX_BATTERY - VOLVO_SPA_BATTERY diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 9f8d970e..2496c2ce 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -23,7 +23,6 @@ //#define MEB_BATTERY //#define MG_5_BATTERY //#define NISSAN_LEAF_BATTERY -//#define ECMP_BATTERY //#define PYLON_BATTERY //#define RJXZS_BMS //#define RANGE_ROVER_PHEV_BATTERY @@ -32,6 +31,7 @@ //#define RENAULT_ZOE_GEN1_BATTERY //#define RENAULT_ZOE_GEN2_BATTERY //#define SANTA_FE_PHEV_BATTERY +//#define STELLANTIS_ECMP_BATTERY //#define TESLA_MODEL_3Y_BATTERY //#define TESLA_MODEL_SX_BATTERY //#define VOLVO_SPA_BATTERY diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index aec7d71f..7be73f22 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -27,7 +27,7 @@ #include "CHADEMO-SHUNTS.h" #endif -#ifdef ECMP_BATTERY +#ifdef STELLANTIS_ECMP_BATTERY #include "ECMP-BATTERY.h" #endif diff --git a/Software/src/battery/ECMP-BATTERY.cpp b/Software/src/battery/ECMP-BATTERY.cpp index f1ef2ea5..afcfd98b 100644 --- a/Software/src/battery/ECMP-BATTERY.cpp +++ b/Software/src/battery/ECMP-BATTERY.cpp @@ -1,10 +1,21 @@ #include "../include.h" -#ifdef ECMP_BATTERY +#ifdef STELLANTIS_ECMP_BATTERY #include // For std::min and std::max #include "../datalayer/datalayer.h" #include "../devboard/utils/events.h" #include "ECMP-BATTERY.h" +/* TODO: +This integration is still ongoing. Here is what still needs to be done in order to use this battery type +- Find SOC% +- Find battery voltage +- Find current value +- Find/estimate charge/discharge limits +- Find temperature +- Figure out contactor closing + - Which CAN messages need to be sent towards the battery? +*/ + /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was sent diff --git a/Software/src/battery/ECMP-BATTERY.h b/Software/src/battery/ECMP-BATTERY.h index ef4232f9..14955bd6 100644 --- a/Software/src/battery/ECMP-BATTERY.h +++ b/Software/src/battery/ECMP-BATTERY.h @@ -1,5 +1,5 @@ -#ifndef ECMP_BATTERY_H -#define ECMP_BATTERY_H +#ifndef STELLANTIS_ECMP_BATTERY_H +#define STELLANTIS_ECMP_BATTERY_H #include #include "../include.h" From 7cc63902b048a4405e4b38721e402f52f774a8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 19:43:48 +0300 Subject: [PATCH 64/93] Make Ultra messages part of normal sending --- Software/src/inverter/SOLAX-CAN.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Software/src/inverter/SOLAX-CAN.cpp b/Software/src/inverter/SOLAX-CAN.cpp index 60f684b9..31adfe16 100644 --- a/Software/src/inverter/SOLAX-CAN.cpp +++ b/Software/src/inverter/SOLAX-CAN.cpp @@ -68,7 +68,7 @@ CAN_frame SOLAX_187E = {.FD = false, //Needed for Ultra .ext_ID = true, .DLC = 8, .ID = 0x187E, - .data = {0x0, 0x2D, 0x0, 0x0, 0x0, 0x5F, 0x0, 0x0}}; + .data = {0x60, 0xEA, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0}}; CAN_frame SOLAX_187D = {.FD = false, //Needed for Ultra .ext_ID = true, .DLC = 8, @@ -88,7 +88,7 @@ CAN_frame SOLAX_187A = {.FD = false, //Needed for Ultra .ext_ID = true, .DLC = 8, .ID = 0x187A, - .data = {0x01, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; + .data = {0x01, (uint8_t)BATTERY_TYPE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; CAN_frame SOLAX_1881 = {.FD = false, .ext_ID = true, .DLC = 8, @@ -190,6 +190,13 @@ void update_values_can_inverter() { //This function maps all the values fetched SOLAX_1801.data.u8[0] = 2; SOLAX_1801.data.u8[2] = 1; SOLAX_1801.data.u8[4] = 1; + + //Ultra messages + SOLAX_187E.data.u8[0] = (uint8_t)capped_remaining_capacity_Wh; + SOLAX_187E.data.u8[1] = (capped_remaining_capacity_Wh >> 8); + SOLAX_187E.data.u8[2] = 0; + SOLAX_187E.data.u8[3] = 0; + SOLAX_187E.data.u8[5] = (uint8_t)(datalayer.battery.status.reported_soc / 100); } void send_can_inverter() { @@ -212,7 +219,9 @@ void receive_can_inverter(CAN_frame rx_frame) { #endif datalayer.system.status.inverter_allows_contactor_closing = false; SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on. - for (int i = 0; i <= number_of_batteries; i++) { + for (uint8_t i = 0; i <= number_of_batteries; i++) { + transmit_can(&SOLAX_187E, can_config.inverter); + transmit_can(&SOLAX_187A, can_config.inverter); transmit_can(&SOLAX_1872, can_config.inverter); transmit_can(&SOLAX_1873, can_config.inverter); transmit_can(&SOLAX_1874, can_config.inverter); @@ -230,6 +239,8 @@ void receive_can_inverter(CAN_frame rx_frame) { case (WAITING_FOR_CONTACTOR): SOLAX_1875.data.u8[4] = (0x00); // Inform Inverter: Contactor 0=off, 1=on. + transmit_can(&SOLAX_187E, can_config.inverter); + transmit_can(&SOLAX_187A, can_config.inverter); transmit_can(&SOLAX_1872, can_config.inverter); transmit_can(&SOLAX_1873, can_config.inverter); transmit_can(&SOLAX_1874, can_config.inverter); @@ -247,6 +258,8 @@ void receive_can_inverter(CAN_frame rx_frame) { case (CONTACTOR_CLOSED): datalayer.system.status.inverter_allows_contactor_closing = true; SOLAX_1875.data.u8[4] = (0x01); // Inform Inverter: Contactor 0=off, 1=on. + transmit_can(&SOLAX_187E, can_config.inverter); + transmit_can(&SOLAX_187A, can_config.inverter); transmit_can(&SOLAX_1872, can_config.inverter); transmit_can(&SOLAX_1873, can_config.inverter); transmit_can(&SOLAX_1874, can_config.inverter); @@ -281,12 +294,5 @@ void setup_inverter(void) { // Performs one time setup at startup strncpy(datalayer.system.info.inverter_protocol, "SolaX Triple Power LFP over CAN bus", 63); datalayer.system.info.inverter_protocol[63] = '\0'; datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first - - // Sending these messages once towards the inverter makes SOC% work on the Ultra variant - transmit_can(&SOLAX_187E, can_config.inverter); - transmit_can(&SOLAX_187D, can_config.inverter); - transmit_can(&SOLAX_187C, can_config.inverter); - transmit_can(&SOLAX_187B, can_config.inverter); - transmit_can(&SOLAX_187A, can_config.inverter); } #endif From fe451cc18a767508b96423d2688fa0ca4eed5612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sat, 28 Dec 2024 19:52:41 +0300 Subject: [PATCH 65/93] Revert to hardcoded ID --- Software/src/inverter/SOLAX-CAN.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/inverter/SOLAX-CAN.cpp b/Software/src/inverter/SOLAX-CAN.cpp index 31adfe16..e3c5dad2 100644 --- a/Software/src/inverter/SOLAX-CAN.cpp +++ b/Software/src/inverter/SOLAX-CAN.cpp @@ -88,7 +88,7 @@ CAN_frame SOLAX_187A = {.FD = false, //Needed for Ultra .ext_ID = true, .DLC = 8, .ID = 0x187A, - .data = {0x01, (uint8_t)BATTERY_TYPE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; + .data = {0x01, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; CAN_frame SOLAX_1881 = {.FD = false, .ext_ID = true, .DLC = 8, From a0907b7ef66e73642d814b880e706a46212b1cdb Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:02:17 +1300 Subject: [PATCH 66/93] Update TESLA-BATTERY.cpp Update starting cell voltage to 3300mV, update starting pack energy to 0kWh, add cellvoltageRead to 0x332, add check of cellvoltageRead in send_can. --- Software/src/battery/TESLA-BATTERY.cpp | 29 ++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 5bcff8af..80aae62d 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -24,9 +24,10 @@ CAN_frame TESLA_221_2 = { .data = {0x61, 0x15, 0x01, 0x00, 0x00, 0x00, 0x20, 0xBA}}; //Contactor Frame 221 - hv_up_for_drive static uint16_t sendContactorClosingMessagesStill = 300; -static uint16_t battery_cell_max_v = 3700; -static uint16_t battery_cell_min_v = 3700; +static uint16_t battery_cell_max_v = 3300; +static uint16_t battery_cell_min_v = 3300; static uint16_t battery_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV +static bool cellvoltagesRead = false; //0x3d2: 978 BMS_kwhCounter static uint32_t battery_total_discharge = 0; static uint32_t battery_total_charge = 0; @@ -68,8 +69,8 @@ static uint16_t battery_ideal_energy_remaining = 0; // kWh static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh static uint16_t battery_nominal_energy_remaining = 0; // kWh static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_full_pack_energy = 600; // Kwh -static uint16_t battery_nominal_full_pack_energy_m0 = 600; // Kwh +static uint16_t battery_nominal_full_pack_energy = 0; // Kwh +static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery_volts = 0; // V static int16_t battery_amps = 0; // A @@ -94,7 +95,7 @@ static uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_volt static uint16_t battery_dcdcLvOutputCurrent = 0; // Change name from battery_output_current to battery_dcdcLvOutputCurrent //0x292: 658 BMS_socStatus -static uint16_t battery_beginning_of_life = 600; // kWh +static uint16_t battery_beginning_of_life = 0; // kWh static uint16_t battery_soc_min = 0; static uint16_t battery_soc_max = 0; static uint16_t battery_soc_ui = 0; //Change name from battery_soc_vi to reflect DBC battery_soc_ui @@ -445,9 +446,10 @@ static bool battery_BMS_a180_SW_ECU_reset_blocked = false; #ifdef DOUBLE_BATTERY //need to update for battery2 -static uint16_t battery2_cell_max_v = 3700; -static uint16_t battery2_cell_min_v = 3700; +static uint16_t battery2_cell_max_v = 3300; +static uint16_t battery2_cell_min_v = 3300; static uint16_t battery2_cell_deviation_mV = 0; //contains the deviation between highest and lowest cell in mV +static bool battery2_cellvoltagesRead = false; //0x3d2: 978 BMS_kwhCounter static uint32_t battery2_total_discharge = 0; static uint32_t battery2_total_charge = 0; @@ -466,9 +468,8 @@ static uint16_t battery2_nominal_energy_remaining = 0; static uint16_t battery2_nominal_energy_remaining_m0 = 0; // kWh static uint16_t battery2_nominal_full_pack_energy = 0; static uint16_t battery2_nominal_full_pack_energy_m0 = 0; // Kwh -static uint16_t battery2_beginning_of_life = 0; -static uint16_t battery2_nominal_full_pack_energy = 600; -static uint16_t battery2_nominal_full_pack_energy_m0 = 600; // Kwh +static uint16_t battery2_nominal_full_pack_energy = 0; +static uint16_t battery2_nominal_full_pack_energy_m0 = 0; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery2_volts = 0; // V static int16_t battery2_amps = 0; // A @@ -492,7 +493,7 @@ static uint16_t battery2_dcdcHvBusVolt = 0; //update name static uint16_t battery2_dcdcLvBusVolt = 0; //update name static uint16_t battery2_dcdcLvOutputCurrent = 0; //update name //0x292: 658 BMS_socStatus -static uint16_t battery2_beginning_of_life = 600; +static uint16_t battery2_beginning_of_life = 0; static uint16_t battery2_soc_min = 0; static uint16_t battery2_soc_max = 0; static uint16_t battery2_soc_ui = 0; @@ -1398,6 +1399,7 @@ void receive_can_battery(CAN_frame rx_frame) { temp = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); temp = (temp & 0xFFF); battery_cell_min_v = temp * 2; + cellvoltagesRead = true; //BattBrickVoltageMax m1 : 2|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[1] & (0x3FU)) << 6) | ((_d[0] >> 2) & (0x3FU)); battery_BrickVoltageMax = ((rx_frame.data.u8[1] & (0x3F)) << 6) | ((rx_frame.data.u8[0] >> 2) & (0x3F)); //to datalayer_extended @@ -2043,6 +2045,7 @@ void receive_can_battery2(CAN_frame rx_frame) { temp = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); temp = (temp & 0xFFF); battery2_cell_min_v = temp * 2; + battery2_cellvoltagesRead = true; //BattBrickVoltageMax m1 : 2|12@1+ (0.002,0) [0|0] "V" Receiver ((_d[1] & (0x3FU)) << 6) | ((_d[0] >> 2) & (0x3FU)); battery2_BrickVoltageMax = ((rx_frame.data.u8[1] & (0x3F)) << 6) | ((rx_frame.data.u8[0] >> 2) & (0x3F)); //to datalayer_extended @@ -2681,6 +2684,10 @@ the first, for a few cycles, then stop all messages which causes the contactor unsigned long currentMillis = millis(); +if (!cellvoltagesRead ) { + return; //All cellvoltages not read yet, do not proceed with contactor closing +} + #if defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) if ((datalayer.system.status.inverter_allows_contactor_closing) && (datalayer.battery.status.bms_status != FAULT)) { if (currentMillis - lastSend1CF >= 10) { From 1bbbaacb7011b5c69631e094ac04289822b6a7eb Mon Sep 17 00:00:00 2001 From: josiahhiggs <79869367+josiahhiggs@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:02:32 +1300 Subject: [PATCH 67/93] Update TESLA-BATTERY.cpp --- Software/src/battery/TESLA-BATTERY.cpp | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Software/src/battery/TESLA-BATTERY.cpp b/Software/src/battery/TESLA-BATTERY.cpp index 80aae62d..4e17068e 100644 --- a/Software/src/battery/TESLA-BATTERY.cpp +++ b/Software/src/battery/TESLA-BATTERY.cpp @@ -57,20 +57,20 @@ static uint16_t battery_discharge_limit = 0; static uint16_t battery_max_heat_park = 0; static uint16_t battery_hvac_max_power = 0; //0x352: 850 BMS_energyStatus -static uint16_t battery_energy_buffer = 0; // kWh -static uint16_t battery_energy_buffer_m1 = 0; // kWh -static uint16_t battery_energy_to_charge_complete = 0; // kWh -static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh -static uint16_t battery_expected_energy_remaining = 0; // kWh -static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh -static bool battery_full_charge_complete = false; // Changed to bool -static bool battery_fully_charged = false; // Changed to bool -static uint16_t battery_ideal_energy_remaining = 0; // kWh -static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_energy_remaining = 0; // kWh -static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh -static uint16_t battery_nominal_full_pack_energy = 0; // Kwh -static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh +static uint16_t battery_energy_buffer = 0; // kWh +static uint16_t battery_energy_buffer_m1 = 0; // kWh +static uint16_t battery_energy_to_charge_complete = 0; // kWh +static uint16_t battery_energy_to_charge_complete_m1 = 0; // kWh +static uint16_t battery_expected_energy_remaining = 0; // kWh +static uint16_t battery_expected_energy_remaining_m1 = 0; // kWh +static bool battery_full_charge_complete = false; // Changed to bool +static bool battery_fully_charged = false; // Changed to bool +static uint16_t battery_ideal_energy_remaining = 0; // kWh +static uint16_t battery_ideal_energy_remaining_m0 = 0; // kWh +static uint16_t battery_nominal_energy_remaining = 0; // kWh +static uint16_t battery_nominal_energy_remaining_m0 = 0; // kWh +static uint16_t battery_nominal_full_pack_energy = 0; // Kwh +static uint16_t battery_nominal_full_pack_energy_m0 = 0; // Kwh //0x132 306 HVBattAmpVolt static uint16_t battery_volts = 0; // V static int16_t battery_amps = 0; // A @@ -2684,9 +2684,9 @@ the first, for a few cycles, then stop all messages which causes the contactor unsigned long currentMillis = millis(); -if (!cellvoltagesRead ) { - return; //All cellvoltages not read yet, do not proceed with contactor closing -} + if (!cellvoltagesRead) { + return; //All cellvoltages not read yet, do not proceed with contactor closing + } #if defined(TESLA_MODEL_SX_BATTERY) || defined(EXP_TESLA_BMS_DIGITAL_HVIL) if ((datalayer.system.status.inverter_allows_contactor_closing) && (datalayer.battery.status.bms_status != FAULT)) { From 40399b446e162cce7f448d9413ba31822db9d3d6 Mon Sep 17 00:00:00 2001 From: No-Signal Date: Sun, 29 Dec 2024 13:42:14 +0000 Subject: [PATCH 68/93] Adding ability to log CAN frames to SD card --- Software/Software.ino | 22 +++ Software/USER_SETTINGS.h | 1 + Software/src/communication/can/comm_can.cpp | 9 ++ Software/src/communication/can/comm_can.h | 2 - Software/src/devboard/sdcard/sdcard.cpp | 151 ++++++++++++++++++ Software/src/devboard/sdcard/sdcard.h | 23 +++ Software/src/devboard/utils/types.h | 7 + .../devboard/webserver/can_logging_html.cpp | 6 + Software/src/devboard/webserver/webserver.cpp | 18 +++ 9 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 Software/src/devboard/sdcard/sdcard.cpp create mode 100644 Software/src/devboard/sdcard/sdcard.h diff --git a/Software/Software.ino b/Software/Software.ino index 60cc30d2..306bd994 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -18,6 +18,7 @@ #include "src/communication/rs485/comm_rs485.h" #include "src/communication/seriallink/comm_seriallink.h" #include "src/datalayer/datalayer.h" +#include "src/devboard/sdcard/sdcard.h" #include "src/devboard/utils/events.h" #include "src/devboard/utils/led_handler.h" #include "src/devboard/utils/logging.h" @@ -78,12 +79,16 @@ MyTimer core_task_timer_10s(INTERVAL_10_S); int64_t connectivity_task_time_us; MyTimer connectivity_task_timer_10s(INTERVAL_10_S); +int64_t logging_task_time_us; +MyTimer logging_task_timer_10s(INTERVAL_10_S); + MyTimer loop_task_timer_10s(INTERVAL_10_S); MyTimer check_pause_2s(INTERVAL_2_S); TaskHandle_t main_loop_task; TaskHandle_t connectivity_loop_task; +TaskHandle_t logging_loop_task; Logging logging; @@ -98,6 +103,11 @@ void setup() { TASK_CONNECTIVITY_PRIO, &connectivity_loop_task, WIFI_CORE); #endif +#ifdef LOG_CAN_TO_SD + xTaskCreatePinnedToCore((TaskFunction_t)&logging_loop, "logging_loop", 4096, &logging_task_time_us, + TASK_CONNECTIVITY_PRIO, &logging_loop_task, WIFI_CORE); +#endif + init_events(); init_CAN(); @@ -137,6 +147,18 @@ void loop() { #endif } +#ifdef LOG_CAN_TO_SD +void logging_loop(void* task_time_us) { + + init_logging_buffer(); + init_sdcard(); + + while (true) { + write_can_frame_to_sdcard(); + } +} +#endif + #ifdef WIFI void connectivity_loop(void* task_time_us) { diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index a73799c5..bacd3d9a 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -73,6 +73,7 @@ #endif //#define DEBUG_CAN_DATA //Enable this line to print incoming/outgoing CAN & CAN-FD messages to USB serial (WARNING, raises CPU load, do not use for production) +//#define LOG_CAN_TO_SD //Enable this line to log incoming/outgoing CAN & CAN-FD messages to SD card //#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting //#define CAN_ADDON //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery) #define CRYSTAL_FREQUENCY_MHZ 8 //CAN_ADDON option, what is your MCP2515 add-on boards crystal frequency? diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index 8fa2ab3d..4a04959d 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -1,5 +1,6 @@ #include "comm_can.h" #include "../../include.h" +#include "src/devboard/sdcard/sdcard.h" // Parameters @@ -107,6 +108,10 @@ void transmit_can(CAN_frame* tx_frame, int interface) { } print_can_frame(*tx_frame, frameDirection(MSG_TX)); +#ifdef LOG_CAN_TO_SD + add_can_frame_to_buffer(*tx_frame, frameDirection(MSG_TX)); +#endif + switch (interface) { case CAN_NATIVE: CAN_frame_t frame; @@ -186,6 +191,10 @@ void send_can() { void receive_can(CAN_frame* rx_frame, int interface) { print_can_frame(*rx_frame, frameDirection(MSG_RX)); +#ifdef LOG_CAN_TO_SD + add_can_frame_to_buffer(*rx_frame, frameDirection(MSG_RX)); +#endif + if (interface == can_config.battery) { receive_can_battery(*rx_frame); #ifdef CHADEMO_BATTERY diff --git a/Software/src/communication/can/comm_can.h b/Software/src/communication/can/comm_can.h index 48e3c9c3..38ca2da8 100644 --- a/Software/src/communication/can/comm_can.h +++ b/Software/src/communication/can/comm_can.h @@ -15,8 +15,6 @@ #include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h" #endif //CANFD_ADDON -enum frameDirection { MSG_RX, MSG_TX }; //RX = 0, TX = 1 - /** * @brief Initialization function for CAN. * diff --git a/Software/src/devboard/sdcard/sdcard.cpp b/Software/src/devboard/sdcard/sdcard.cpp new file mode 100644 index 00000000..9cb2ff61 --- /dev/null +++ b/Software/src/devboard/sdcard/sdcard.cpp @@ -0,0 +1,151 @@ +#include "sdcard.h" +#include "freertos/ringbuf.h" + +File can_log_file; +RingbufHandle_t can_bufferHandle; + +bool can_logging_paused = false; +bool can_file_open = false; +bool delete_can_file = false; +bool sd_card_active = false; + +void delete_can_log() { + can_logging_paused = true; + delete_can_file = true; +} + +void resume_can_writing() { + can_logging_paused = false; + can_log_file = SD.open(CAN_LOG_FILE, FILE_APPEND); + can_file_open = true; +} + +void pause_can_writing() { + can_logging_paused = true; +} + +void add_can_frame_to_buffer(CAN_frame frame, frameDirection msgDir) { + + if (!sd_card_active) + return; + + CAN_log_frame log_frame = {frame, msgDir}; + if (xRingbufferSend(can_bufferHandle, &log_frame, sizeof(log_frame), 0) != pdTRUE) { + Serial.println("Failed to send CAN frame to ring buffer!"); + return; + } +} + +void write_can_frame_to_sdcard() { + + if (!sd_card_active) + return; + + size_t receivedMessageSize; + CAN_log_frame* log_frame = + (CAN_log_frame*)xRingbufferReceive(can_bufferHandle, &receivedMessageSize, pdMS_TO_TICKS(10)); + + if (log_frame != NULL) { + + if (can_logging_paused) { + if (can_file_open) { + can_log_file.close(); + can_file_open = false; + } + if (delete_can_file) { + SD.remove(CAN_LOG_FILE); + delete_can_file = false; + can_logging_paused = false; + } + vRingbufferReturnItem(can_bufferHandle, (void*)log_frame); + return; + } + + if (can_file_open == false) { + can_log_file = SD.open(CAN_LOG_FILE, FILE_APPEND); + can_file_open = true; + } + + uint8_t i = 0; + can_log_file.print("("); + can_log_file.print(millis() / 1000.0); + (log_frame->direction == MSG_RX) ? can_log_file.print(") RX0 ") : can_log_file.print(") TX1 "); + can_log_file.print(log_frame->frame.ID, HEX); + can_log_file.print(" ["); + can_log_file.print(log_frame->frame.DLC); + can_log_file.print("] "); + for (i = 0; i < log_frame->frame.DLC; i++) { + can_log_file.print(log_frame->frame.data.u8[i] < 16 ? "0" : ""); + can_log_file.print(log_frame->frame.data.u8[i], HEX); + if (i < log_frame->frame.DLC - 1) + can_log_file.print(" "); + } + can_log_file.println(""); + + vRingbufferReturnItem(can_bufferHandle, (void*)log_frame); + } +} + +void init_logging_buffer() { + can_bufferHandle = xRingbufferCreate(64 * 1024, RINGBUF_TYPE_BYTEBUF); + if (can_bufferHandle == NULL) { + Serial.println("Failed to create CAN ring buffer!"); + return; + } +} + +void init_sdcard() { + + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + pinMode(SD_SCLK_PIN, OUTPUT); + pinMode(SD_MOSI_PIN, OUTPUT); + pinMode(SD_MISO_PIN, INPUT); + + SPI.begin(SD_SCLK_PIN, SD_MISO_PIN, SD_MOSI_PIN, SD_CS_PIN); + if (!SD.begin(SD_CS_PIN)) { + Serial.println("SD Card initialization failed!"); + return; + } + + Serial.println("SD Card initialization successful."); + sd_card_active = true; + + print_sdcard_details(); +} + +void print_sdcard_details() { + + Serial.print("SD Card Type: "); + switch (SD.cardType()) { + case CARD_MMC: + Serial.println("MMC"); + break; + case CARD_SD: + Serial.println("SD"); + break; + case CARD_SDHC: + Serial.println("SDHC"); + break; + case CARD_UNKNOWN: + Serial.println("UNKNOWN"); + break; + case CARD_NONE: + Serial.println("No SD Card found"); + break; + } + + if (SD.cardType() != CARD_NONE) { + Serial.print("SD Card Size: "); + Serial.print(SD.cardSize() / 1024 / 1024); + Serial.println(" MB"); + + Serial.print("Total space: "); + Serial.print(SD.totalBytes() / 1024 / 1024); + Serial.println(" MB"); + + Serial.print("Used space: "); + Serial.print(SD.usedBytes() / 1024 / 1024); + Serial.println(" MB"); + } +} diff --git a/Software/src/devboard/sdcard/sdcard.h b/Software/src/devboard/sdcard/sdcard.h new file mode 100644 index 00000000..0f792358 --- /dev/null +++ b/Software/src/devboard/sdcard/sdcard.h @@ -0,0 +1,23 @@ +#ifndef SDCARD_H +#define SDCARD_H + +#include +#include +#include "../../communication/can/comm_can.h" +#include "../hal/hal.h" + +#define CAN_LOG_FILE "/canlog.txt" + +void init_logging_buffer(); + +void init_sdcard(); +void print_sdcard_details(); + +void add_can_frame_to_buffer(CAN_frame frame, frameDirection msgDir); +void write_can_frame_to_sdcard(); + +void pause_can_writing(); +void resume_can_writing(); +void delete_can_log(); + +#endif diff --git a/Software/src/devboard/utils/types.h b/Software/src/devboard/utils/types.h index 126aff26..d5cbf2c7 100644 --- a/Software/src/devboard/utils/types.h +++ b/Software/src/devboard/utils/types.h @@ -51,6 +51,13 @@ typedef struct { } data; } CAN_frame; +enum frameDirection { MSG_RX, MSG_TX }; //RX = 0, TX = 1 + +typedef struct { + CAN_frame frame; + frameDirection direction; +} CAN_log_frame; + std::string getBMSStatus(bms_status_enum status); #endif diff --git a/Software/src/devboard/webserver/can_logging_html.cpp b/Software/src/devboard/webserver/can_logging_html.cpp index 77f1975e..e64de232 100644 --- a/Software/src/devboard/webserver/can_logging_html.cpp +++ b/Software/src/devboard/webserver/can_logging_html.cpp @@ -24,6 +24,9 @@ String can_logger_processor(const String& var) { content += ""; content += " "; content += " "; +#ifdef LOG_CAN_TO_SD + content += " "; +#endif content += ""; // Start a new block for the CAN messages @@ -52,6 +55,9 @@ String can_logger_processor(const String& var) { content += "