From 9b818bb41e637e0e0546942140dbc82f2f7441b2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Jun 2024 21:15:19 +0300 Subject: [PATCH 01/15] Add skeleton for Kia-Hybrid --- Software/USER_SETTINGS.h | 1 + Software/src/battery/BATTERIES.h | 4 + .../battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 100 ++++++++++++++++++ .../src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h | 12 +++ 4 files changed, 117 insertions(+) create mode 100644 Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp create mode 100644 Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index c2f64fd8..0e5b6e67 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -14,6 +14,7 @@ //#define IMIEV_CZERO_ION_BATTERY //#define KIA_HYUNDAI_64_BATTERY //#define KIA_E_GMP_BATTERY +//#define KIA_HYUNDAI_HYBRID_BATTERY //#define MG_5_BATTERY //#define NISSAN_LEAF_BATTERY //#define PYLON_BATTERY diff --git a/Software/src/battery/BATTERIES.h b/Software/src/battery/BATTERIES.h index 80c7b82c..bc7be021 100644 --- a/Software/src/battery/BATTERIES.h +++ b/Software/src/battery/BATTERIES.h @@ -27,6 +27,10 @@ #include "KIA-HYUNDAI-64-BATTERY.h" #endif +#ifdef KIA_HYUNDAI_HYBRID_BATTERY +#include "KIA-HYUNDAI-HYBRID-BATTERY.h" +#endif + #ifdef MG_5_BATTERY #include "MG-5-BATTERY.h" #endif diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp new file mode 100644 index 00000000..85d91401 --- /dev/null +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -0,0 +1,100 @@ +#include "../include.h" +#ifdef KIA_HYUNDAI_HYBRID_BATTERY +#include "../datalayer/datalayer.h" +#include "../devboard/utils/events.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/CAN_config.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" +#include "KIA-HYUNDAI-HYBRID-BATTERY.h" + +/* Do not change code below unless you are sure what you are doing */ +static unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send +static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send + +static int SOC_1 = 0; +static int SOC_2 = 0; +static int SOC_3 = 0; + +CAN_frame_t HYBRID_200 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x200, + .data = {0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00}}; + +void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus + + 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.max_discharge_power_W; + + datalayer.battery.status.max_charge_power_W; + + datalayer.battery.status.active_power_W; + + datalayer.battery.status.temperature_min_dC; + + datalayer.battery.status.temperature_max_dC; + +#ifdef DEBUG_VIA_USB + +#endif +} + +void receive_can_battery(CAN_frame_t rx_frame) { + datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; + switch (rx_frame.MsgID) { + case 0x5F1: + break; + case 0x51E: + break; + case 0x588: + break; + case 0x5AE: + break; + case 0x5AD: + break; + case 0x670: + break; + default: + break; + } +} +void send_can_battery() { + unsigned long currentMillis = millis(); + //Send 10ms message + if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { + // Check if sending of CAN messages has been delayed too much. + if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { + set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); + } + previousMillis10 = currentMillis; + + //ESP32Can.CANWriteFrame(&HYBRID_200); + } + // Send 100ms CAN Message + if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { + previousMillis100 = currentMillis; + + //ESP32Can.CANWriteFrame(&HYBRID_200); + } +} + +void setup_battery(void) { // Performs one time setup at startup +#ifdef DEBUG_VIA_USB + Serial.println("Kia/Hyundai Hybrid battery selected"); +#endif + + datalayer.battery.info.max_design_voltage_dV = 4040; //TODO: Values? + datalayer.battery.info.min_design_voltage_dV = 1000; +} + +#endif diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h new file mode 100644 index 00000000..bc23d89a --- /dev/null +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.h @@ -0,0 +1,12 @@ +#ifndef KIA_HYUNDAI_HYBRID_BATTERY_H +#define KIA_HYUNDAI_HYBRID_BATTERY_H +#include +#include "../include.h" +#include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" + +#define BATTERY_SELECTED +#define MAX_CELL_DEVIATION_MV 100 + +void setup_battery(void); + +#endif From 06f3d123b2d6429d7cb7157f7fea99346af9ae9f Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Jun 2024 21:39:29 +0300 Subject: [PATCH 02/15] Add CAN findings --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 12 +++++++++++- Software/src/devboard/webserver/webserver.cpp | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 85d91401..9fae374d 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -13,6 +13,8 @@ static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN static int SOC_1 = 0; static int SOC_2 = 0; static int SOC_3 = 0; +static bool interlock_seated = true; +static uint16_t battery_current = 0; CAN_frame_t HYBRID_200 = {.FIR = {.B = { @@ -28,7 +30,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.voltage_dV; - datalayer.battery.status.current_dA; + datalayer.battery.status.current_dA = battery_current; datalayer.battery.info.total_capacity_Wh; @@ -44,6 +46,12 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_max_dC; + if (!interlock_seated) { + set_event(EVENT_HVIL_FAILURE, 0); + } else { + clear_event(EVENT_HVIL_FAILURE); + } + #ifdef DEBUG_VIA_USB #endif @@ -59,8 +67,10 @@ void receive_can_battery(CAN_frame_t rx_frame) { case 0x588: break; case 0x5AE: + interlock_seated = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; break; case 0x5AD: + battery_current = (rx_frame.data.u8[3] << 8) + rx_frame.data.u8[2]; break; case 0x670: break; diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index dcebd583..c6d1154e 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -460,6 +460,9 @@ String processor(const String& var) { #ifdef KIA_E_GMP_BATTERY content += "Kia/Hyundai EGMP platform"; #endif +#ifdef KIA_HYUNDAI_HYBRID_BATTERY + content += "Kia/Hyundai Hybrid"; +#endif #ifdef MG_5_BATTERY content += "MG 5"; #endif From 2a52871251b77d37ea680d9a1f2b1513b4c616c9 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Jun 2024 22:31:59 +0300 Subject: [PATCH 03/15] Fix interlock logic --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 9fae374d..afab4b18 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -13,7 +13,7 @@ static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN static int SOC_1 = 0; static int SOC_2 = 0; static int SOC_3 = 0; -static bool interlock_seated = true; +static bool interlock_missing = false; static uint16_t battery_current = 0; CAN_frame_t HYBRID_200 = {.FIR = {.B = @@ -46,7 +46,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_max_dC; - if (!interlock_seated) { + if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); } else { clear_event(EVENT_HVIL_FAILURE); @@ -67,7 +67,9 @@ void receive_can_battery(CAN_frame_t rx_frame) { case 0x588: break; case 0x5AE: - interlock_seated = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; + interlock_missing = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; + break; + case 0x5AF: break; case 0x5AD: battery_current = (rx_frame.data.u8[3] << 8) + rx_frame.data.u8[2]; From 5a35403b92c64aa669e36d6a78214c8765449f35 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Jun 2024 22:57:25 +0300 Subject: [PATCH 04/15] Add temperature mapping --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index afab4b18..de2ba51c 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -15,7 +15,8 @@ static int SOC_2 = 0; static int SOC_3 = 0; static bool interlock_missing = false; static uint16_t battery_current = 0; - +static uint16_t voltage = 0; +static int8_t temperature = 0; CAN_frame_t HYBRID_200 = {.FIR = {.B = { .DLC = 8, @@ -42,9 +43,9 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.active_power_W; - datalayer.battery.status.temperature_min_dC; + datalayer.battery.status.temperature_min_dC = temperature * 10; - datalayer.battery.status.temperature_max_dC; + datalayer.battery.status.temperature_max_dC = temperature * 10; if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); @@ -68,6 +69,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { break; case 0x5AE: interlock_missing = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; + temperature = rx_frame.data.u8[3]; // Is this correct byte? Or is it 5AD 4/5? The one there is 1deg higher break; case 0x5AF: break; From 9667c263dfa3d19bbebec281ad118a417be09be1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Jun 2024 23:04:41 +0300 Subject: [PATCH 05/15] Add best guesses --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index de2ba51c..78bda303 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -10,9 +10,7 @@ static unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send -static int SOC_1 = 0; -static int SOC_2 = 0; -static int SOC_3 = 0; +static uint16_t SOC = 0; static bool interlock_missing = false; static uint16_t battery_current = 0; static uint16_t voltage = 0; @@ -27,9 +25,9 @@ CAN_frame_t HYBRID_200 = {.FIR = {.B = void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus - datalayer.battery.status.real_soc; + datalayer.battery.status.real_soc = SOC * 100; - datalayer.battery.status.voltage_dV; + datalayer.battery.status.voltage_dV = voltage * 10; datalayer.battery.status.current_dA = battery_current; @@ -62,12 +60,16 @@ void receive_can_battery(CAN_frame_t rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; switch (rx_frame.MsgID) { case 0x5F1: + SOC = rx_frame.data.u8[2]; //Best guess so far, could be very wrong break; case 0x51E: break; case 0x588: break; case 0x5AE: + if (rx_frame.data.u8[0] > 100) { + voltage = rx_frame.data.u8[0]; + } interlock_missing = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; temperature = rx_frame.data.u8[3]; // Is this correct byte? Or is it 5AD 4/5? The one there is 1deg higher break; From 2ee5673312527b23b6e5b18c03f2796c1ba4e133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Thu, 20 Jun 2024 00:17:20 +0300 Subject: [PATCH 06/15] Add PID polling --- .../battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 131 ++++++++++++++++-- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 78bda303..5b1ccff1 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -15,13 +15,43 @@ static bool interlock_missing = false; static uint16_t battery_current = 0; static uint16_t voltage = 0; static int8_t temperature = 0; -CAN_frame_t HYBRID_200 = {.FIR = {.B = - { - .DLC = 8, - .FF = CAN_frame_std, - }}, - .MsgID = 0x200, - .data = {0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00}}; +static int16_t poll_data_pid = 0; + +CAN_frame_t KIA_7E4_id1 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x7E4, + .data = {0x03, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 01 +CAN_frame_t KIA_7E4_id2 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x7E4, + .data = {0x03, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 02 +CAN_frame_t KIA_7E4_id3 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x7E4, + .data = {0x03, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 03 +CAN_frame_t KIA_7E4_id4 = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x7E4, + .data = {0x03, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 05 +CAN_frame_t KIA_7E4_ack = {.FIR = {.B = + { + .DLC = 8, + .FF = CAN_frame_std, + }}, + .MsgID = 0x7E4, //Ack frame, correct PID is returned. Flow control message + .data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus @@ -80,6 +110,75 @@ void receive_can_battery(CAN_frame_t rx_frame) { break; case 0x670: break; + case 0x7EC: //Data From polled PID group, BigEndian + switch (rx_frame.data.u8[0]) { + case 0x10: //"PID Header" + if (rx_frame.data.u8[4] == poll_data_pid) { + ESP32Can.CANWriteFrame(&KIA_7E4_ack); //Send ack to BMS if the same frame is sent as polled + } + break; + case 0x21: //First frame in PID group + if (poll_data_pid == 1) { + + } else if (poll_data_pid == 2) { + + } else if (poll_data_pid == 3) { + + } else if (poll_data_pid == 4) { + } + break; + case 0x22: //Second datarow in PID group + if (poll_data_pid == 2) { + + } else if (poll_data_pid == 3) { + + } else if (poll_data_pid == 4) { + + } else if (poll_data_pid == 6) { + } + break; + case 0x23: //Third datarow in PID group + if (poll_data_pid == 1) { + + } else if (poll_data_pid == 2) { + + } else if (poll_data_pid == 3) { + + } else if (poll_data_pid == 4) { + + } else if (poll_data_pid == 5) { + } + break; + case 0x24: //Fourth datarow in PID group + if (poll_data_pid == 1) { + + } else if (poll_data_pid == 2) { + + } else if (poll_data_pid == 3) { + + } else if (poll_data_pid == 4) { + + } else if (poll_data_pid == 5) { + } + break; + case 0x25: //Fifth datarow in PID group + if (poll_data_pid == 2) { + + } else if (poll_data_pid == 3) { + + } else if (poll_data_pid == 4) { + + } else if (poll_data_pid == 5) { + } + break; + case 0x26: //Sixth datarow in PID group + break; + case 0x27: //Seventh datarow in PID group + break; + case 0x28: //Eighth datarow in PID group + break; + } + break; default: break; } @@ -93,14 +192,26 @@ void send_can_battery() { set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); } previousMillis10 = currentMillis; - - //ESP32Can.CANWriteFrame(&HYBRID_200); } // Send 100ms CAN Message if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { previousMillis100 = currentMillis; - //ESP32Can.CANWriteFrame(&HYBRID_200); + //PID data is polled after last message sent from battery: + if (poll_data_pid >= 5) { //polling one of 5 PIDs at 100ms, resolution = 500ms + poll_data_pid = 0; + } + poll_data_pid++; + if (poll_data_pid == 1) { + ESP32Can.CANWriteFrame(&KIA_7E4_id1); + } else if (poll_data_pid == 2) { + ESP32Can.CANWriteFrame(&KIA_7E4_id2); + } else if (poll_data_pid == 3) { + ESP32Can.CANWriteFrame(&KIA_7E4_id3); + } else if (poll_data_pid == 4) { + ESP32Can.CANWriteFrame(&KIA_7E4_id4); + } else if (poll_data_pid == 5) { + } } } From 61cfdb15871d3ef79ffcf11ae5ced69cef81333e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 23 Jun 2024 21:51:56 +0300 Subject: [PATCH 07/15] Tweak OBD2 PID poll --- .../battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 5b1ccff1..7b9ce07b 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -7,15 +7,15 @@ #include "KIA-HYUNDAI-HYBRID-BATTERY.h" /* Do not change code below unless you are sure what you are doing */ -static unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send -static unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send +static unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send +static unsigned long previousMillis1000 = 0; // will store last time a 100ms CAN Message was send static uint16_t SOC = 0; static bool interlock_missing = false; static uint16_t battery_current = 0; static uint16_t voltage = 0; static int8_t temperature = 0; -static int16_t poll_data_pid = 0; +static uint8_t poll_data_pid = 0; CAN_frame_t KIA_7E4_id1 = {.FIR = {.B = { @@ -23,28 +23,28 @@ CAN_frame_t KIA_7E4_id1 = {.FIR = {.B = .FF = CAN_frame_std, }}, .MsgID = 0x7E4, - .data = {0x03, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 01 + .data = {0x02, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}}; CAN_frame_t KIA_7E4_id2 = {.FIR = {.B = { .DLC = 8, .FF = CAN_frame_std, }}, .MsgID = 0x7E4, - .data = {0x03, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 02 + .data = {0x02, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}}; CAN_frame_t KIA_7E4_id3 = {.FIR = {.B = { .DLC = 8, .FF = CAN_frame_std, }}, .MsgID = 0x7E4, - .data = {0x03, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 03 -CAN_frame_t KIA_7E4_id4 = {.FIR = {.B = + .data = {0x02, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}; +CAN_frame_t KIA_7E4_id5 = {.FIR = {.B = { .DLC = 8, .FF = CAN_frame_std, }}, .MsgID = 0x7E4, - .data = {0x03, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 21 05 + .data = {0x02, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00}}; CAN_frame_t KIA_7E4_ack = {.FIR = {.B = { .DLC = 8, @@ -113,7 +113,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { case 0x7EC: //Data From polled PID group, BigEndian switch (rx_frame.data.u8[0]) { case 0x10: //"PID Header" - if (rx_frame.data.u8[4] == poll_data_pid) { + if (rx_frame.data.u8[3] == poll_data_pid) { ESP32Can.CANWriteFrame(&KIA_7E4_ack); //Send ack to BMS if the same frame is sent as polled } break; @@ -124,17 +124,17 @@ void receive_can_battery(CAN_frame_t rx_frame) { } else if (poll_data_pid == 3) { - } else if (poll_data_pid == 4) { + } else if (poll_data_pid == 5) { } break; case 0x22: //Second datarow in PID group - if (poll_data_pid == 2) { + if (poll_data_pid == 1) { + + } else if (poll_data_pid == 2) { } else if (poll_data_pid == 3) { - } else if (poll_data_pid == 4) { - - } else if (poll_data_pid == 6) { + } else if (poll_data_pid == 5) { } break; case 0x23: //Third datarow in PID group @@ -144,8 +144,6 @@ void receive_can_battery(CAN_frame_t rx_frame) { } else if (poll_data_pid == 3) { - } else if (poll_data_pid == 4) { - } else if (poll_data_pid == 5) { } break; @@ -156,18 +154,16 @@ void receive_can_battery(CAN_frame_t rx_frame) { } else if (poll_data_pid == 3) { - } else if (poll_data_pid == 4) { - } else if (poll_data_pid == 5) { } break; case 0x25: //Fifth datarow in PID group - if (poll_data_pid == 2) { + if (poll_data_pid == 1) { + + } else if (poll_data_pid == 2) { } else if (poll_data_pid == 3) { - } else if (poll_data_pid == 4) { - } else if (poll_data_pid == 5) { } break; @@ -193,9 +189,9 @@ void send_can_battery() { } previousMillis10 = currentMillis; } - // Send 100ms CAN Message - if (currentMillis - previousMillis100 >= INTERVAL_100_MS) { - previousMillis100 = currentMillis; + // Send 1000ms CAN Message + if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { + previousMillis1000 = currentMillis; //PID data is polled after last message sent from battery: if (poll_data_pid >= 5) { //polling one of 5 PIDs at 100ms, resolution = 500ms @@ -209,8 +205,9 @@ void send_can_battery() { } else if (poll_data_pid == 3) { ESP32Can.CANWriteFrame(&KIA_7E4_id3); } else if (poll_data_pid == 4) { - ESP32Can.CANWriteFrame(&KIA_7E4_id4); + } else if (poll_data_pid == 5) { + ESP32Can.CANWriteFrame(&KIA_7E4_id5); } } } From 3c54261a163ae3dd77550bd0845134ab826ad89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 30 Jun 2024 23:39:59 +0300 Subject: [PATCH 08/15] Update CAN mappings from OBD2 poll --- .../battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 152 ++++++++++++------ 1 file changed, 99 insertions(+), 53 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 7b9ce07b..f628a961 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -7,15 +7,18 @@ #include "KIA-HYUNDAI-HYBRID-BATTERY.h" /* Do not change code below unless you are sure what you are doing */ -static unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send static unsigned long previousMillis1000 = 0; // will store last time a 100ms CAN Message was send static uint16_t SOC = 0; +static uint16_t SOC_display = 0; static bool interlock_missing = false; -static uint16_t battery_current = 0; -static uint16_t voltage = 0; -static int8_t temperature = 0; +static int16_t battery_current = 0; +static uint8_t battery_current_high_byte = 0; +static uint16_t battery_voltage = 0; +static int8_t battery_module_max_temperature = 0; +static int8_t battery_module_min_temperature = 0; static uint8_t poll_data_pid = 0; +static uint16_t cellvoltages_mv[59]; CAN_frame_t KIA_7E4_id1 = {.FIR = {.B = { @@ -55,58 +58,49 @@ CAN_frame_t KIA_7E4_ack = {.FIR = {.B = void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus - datalayer.battery.status.real_soc = SOC * 100; + datalayer.battery.status.real_soc = SOC * 50; - datalayer.battery.status.voltage_dV = voltage * 10; + datalayer.battery.status.voltage_dV = battery_voltage; datalayer.battery.status.current_dA = battery_current; - datalayer.battery.info.total_capacity_Wh; + datalayer.battery.status.remaining_capacity_Wh = static_cast( + (static_cast(datalayer.battery.status.real_soc) / 10000) * datalayer.battery.info.total_capacity_Wh); - datalayer.battery.status.remaining_capacity_Wh; + datalayer.battery.status.max_discharge_power_W = available_discharge_power * 10; - datalayer.battery.status.max_discharge_power_W; + datalayer.battery.status.max_charge_power_W = available_charge_power * 10; - datalayer.battery.status.max_charge_power_W; + //Power in watts, Negative = charging batt + datalayer.battery.status.active_power_W = + ((datalayer.battery.status.voltage_dV * datalayer.battery.status.current_dA) / 100); - datalayer.battery.status.active_power_W; + datalayer.battery.status.temperature_min_dC = (int16_t)(battery_module_min_temperature * 10); - datalayer.battery.status.temperature_min_dC = temperature * 10; - - datalayer.battery.status.temperature_max_dC = temperature * 10; + datalayer.battery.status.temperature_max_dC = (int16_t)(battery_module_max_temperature * 10); if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); } else { clear_event(EVENT_HVIL_FAILURE); } - -#ifdef DEBUG_VIA_USB - -#endif } void receive_can_battery(CAN_frame_t rx_frame) { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; switch (rx_frame.MsgID) { case 0x5F1: - SOC = rx_frame.data.u8[2]; //Best guess so far, could be very wrong break; case 0x51E: break; case 0x588: break; case 0x5AE: - if (rx_frame.data.u8[0] > 100) { - voltage = rx_frame.data.u8[0]; - } interlock_missing = (bool)(rx_frame.data.u8[1] & 0x02) >> 1; - temperature = rx_frame.data.u8[3]; // Is this correct byte? Or is it 5AD 4/5? The one there is 1deg higher break; case 0x5AF: break; case 0x5AD: - battery_current = (rx_frame.data.u8[3] << 8) + rx_frame.data.u8[2]; break; case 0x670: break; @@ -117,53 +111,112 @@ void receive_can_battery(CAN_frame_t rx_frame) { ESP32Can.CANWriteFrame(&KIA_7E4_ack); //Send ack to BMS if the same frame is sent as polled } break; - case 0x21: //First frame in PID group - if (poll_data_pid == 1) { - - } else if (poll_data_pid == 2) { - - } else if (poll_data_pid == 3) { - - } else if (poll_data_pid == 5) { + case 0x21: //First frame in PID group + if (poll_data_pid == 1) { // 21 01 + SOC = rx_frame.data.u8[1]; // 0xBC = 188 /2 = 94% + available_charge_power = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); + available_discharge_power = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); + battery_current_high_byte = rx_frame.data.u8[7]; + } else if (poll_data_pid == 2) { //21 02 + cellvoltages_mv[0] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[1] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[2] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[3] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[4] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[5] = (rx_frame.data.u8[7] * 20); + } else if (poll_data_pid == 3) { //21 03 + cellvoltages_mv[31] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[32] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[33] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[34] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[35] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[36] = (rx_frame.data.u8[7] * 20); + } else if (poll_data_pid == 5) { //21 05 } break; case 0x22: //Second datarow in PID group if (poll_data_pid == 1) { - + battery_current = ((battery_current_high_byte << 8) | rx_frame.data.u8[1]); + battery_voltage = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); + battery_module_max_temperature = rx_frame.data.u8[4]; + battery_module_min_temperature = rx_frame.data.u8[5]; } else if (poll_data_pid == 2) { + cellvoltages_mv[6] = (rx_frame.data.u8[1] * 20); + cellvoltages_mv[7] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[8] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[9] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[10] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[11] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[12] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 3) { - + cellvoltages_mv[37] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[38] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[39] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[40] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[41] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[42] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 5) { } break; case 0x23: //Third datarow in PID group if (poll_data_pid == 1) { - + max_cell_voltage = rx_frame.data.u8[6] * 20; } else if (poll_data_pid == 2) { - + cellvoltages_mv[13] = (rx_frame.data.u8[1] * 20); + cellvoltages_mv[14] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[15] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[16] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[17] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[18] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[19] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 3) { - + cellvoltages_mv[43] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[44] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[45] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[46] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[47] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[48] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 5) { } break; case 0x24: //Fourth datarow in PID group if (poll_data_pid == 1) { - + min_cell_voltage = rx_frame.data.u8[1] * 20; } else if (poll_data_pid == 2) { - + cellvoltages_mv[20] = (rx_frame.data.u8[1] * 20); + cellvoltages_mv[21] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[22] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[23] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[24] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[25] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[26] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 3) { - + cellvoltages_mv[49] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[50] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[51] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[52] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[53] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[54] = (rx_frame.data.u8[7] * 20); } else if (poll_data_pid == 5) { + SOC_display = rx_frame.data.u8[7]; //0x26 = 38% } break; case 0x25: //Fifth datarow in PID group if (poll_data_pid == 1) { } else if (poll_data_pid == 2) { - + cellvoltages_mv[27] = (rx_frame.data.u8[1] * 20); + cellvoltages_mv[28] = (rx_frame.data.u8[2] * 20); + cellvoltages_mv[29] = (rx_frame.data.u8[3] * 20); + cellvoltages_mv[30] = (rx_frame.data.u8[4] * 20); } else if (poll_data_pid == 3) { - + cellvoltages_mv[55] = (rx_frame.data.u8[4] * 20); + cellvoltages_mv[56] = (rx_frame.data.u8[5] * 20); + cellvoltages_mv[57] = (rx_frame.data.u8[6] * 20); + cellvoltages_mv[58] = (rx_frame.data.u8[7] * 20); + //Map all cell voltages to the global array + memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages_mv, 59 * sizeof(uint16_t)); } else if (poll_data_pid == 5) { } break; @@ -181,14 +234,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { } void send_can_battery() { unsigned long currentMillis = millis(); - //Send 10ms message - if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { - // Check if sending of CAN messages has been delayed too much. - if ((currentMillis - previousMillis10 >= INTERVAL_10_MS_DELAYED) && (currentMillis > BOOTUP_TIME)) { - set_event(EVENT_CAN_OVERRUN, (currentMillis - previousMillis10)); - } - previousMillis10 = currentMillis; - } + // Send 1000ms CAN Message if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { previousMillis1000 = currentMillis; @@ -216,9 +262,9 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Kia/Hyundai Hybrid battery selected"); #endif - - datalayer.battery.info.max_design_voltage_dV = 4040; //TODO: Values? - datalayer.battery.info.min_design_voltage_dV = 1000; + datalayer.battery.info.number_of_cells = 59; + datalayer.battery.info.max_design_voltage_dV = 2550; //TODO: Values OK? + datalayer.battery.info.min_design_voltage_dV = 1700; } #endif From 92d327f0392156f5a1e24e35287826bddcba90b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 30 Jun 2024 23:48:30 +0300 Subject: [PATCH 09/15] Add Kia hybrid pack to workflow --- .github/workflows/compile-all-batteries.yml | 1 + .github/workflows/compile-all-combinations.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/compile-all-batteries.yml b/.github/workflows/compile-all-batteries.yml index 653de40f..ea586d19 100644 --- a/.github/workflows/compile-all-batteries.yml +++ b/.github/workflows/compile-all-batteries.yml @@ -38,6 +38,7 @@ jobs: - CHADEMO_BATTERY - IMIEV_CZERO_ION_BATTERY - KIA_HYUNDAI_64_BATTERY + - KIA_HYUNDAI_HYBRID_BATTERY - NISSAN_LEAF_BATTERY - PYLON_BATTERY - RENAULT_KANGOO_BATTERY diff --git a/.github/workflows/compile-all-combinations.yml b/.github/workflows/compile-all-combinations.yml index 3a930fd1..157dda52 100644 --- a/.github/workflows/compile-all-combinations.yml +++ b/.github/workflows/compile-all-combinations.yml @@ -41,6 +41,7 @@ jobs: - CHADEMO_BATTERY - IMIEV_CZERO_ION_BATTERY - KIA_HYUNDAI_64_BATTERY + - KIA_HYUNDAI_HYBRID_BATTERY - NISSAN_LEAF_BATTERY - PYLON_BATTERY - RENAULT_KANGOO_BATTERY From eac1f3e2cbf33e1476e53823a88aba28785d443a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Sun, 30 Jun 2024 23:55:09 +0300 Subject: [PATCH 10/15] Add min/max cellvoltage mapping --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index f628a961..1a810e00 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -19,6 +19,8 @@ static int8_t battery_module_max_temperature = 0; static int8_t battery_module_min_temperature = 0; static uint8_t poll_data_pid = 0; static uint16_t cellvoltages_mv[59]; +static uint16_t min_cell_voltage_mv = 3700; +static uint16_t max_cell_voltage_mv = 3700; CAN_frame_t KIA_7E4_id1 = {.FIR = {.B = { @@ -79,6 +81,10 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.temperature_max_dC = (int16_t)(battery_module_max_temperature * 10); + datalayer.battery.status.cell_max_voltage_mV = max_cell_voltage_mv; + + datalayer.battery.status.cell_min_voltage_mV = min_cell_voltage_mv; + if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); } else { @@ -161,7 +167,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { break; case 0x23: //Third datarow in PID group if (poll_data_pid == 1) { - max_cell_voltage = rx_frame.data.u8[6] * 20; + max_cell_voltage_mv = rx_frame.data.u8[6] * 20; } else if (poll_data_pid == 2) { cellvoltages_mv[13] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[14] = (rx_frame.data.u8[2] * 20); @@ -182,7 +188,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { break; case 0x24: //Fourth datarow in PID group if (poll_data_pid == 1) { - min_cell_voltage = rx_frame.data.u8[1] * 20; + min_cell_voltage_mv = rx_frame.data.u8[1] * 20; } else if (poll_data_pid == 2) { cellvoltages_mv[20] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[21] = (rx_frame.data.u8[2] * 20); From b200710d2d67f0958e52e474e3a2868c9350e1e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 1 Jul 2024 00:01:44 +0300 Subject: [PATCH 11/15] Fix compilation error --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 1a810e00..04432312 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -15,6 +15,8 @@ static bool interlock_missing = false; static int16_t battery_current = 0; static uint8_t battery_current_high_byte = 0; static uint16_t battery_voltage = 0; +static uint32_t available_charge_power = 0; +static uint32_t available_discharge_power = 0; static int8_t battery_module_max_temperature = 0; static int8_t battery_module_min_temperature = 0; static uint8_t poll_data_pid = 0; From aac1632c61143eb42e94c0a7485223cf12f4b56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 1 Jul 2024 10:07:22 +0300 Subject: [PATCH 12/15] Fix byteswap on voltage value --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 04432312..2c42c3fe 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -145,7 +145,7 @@ void receive_can_battery(CAN_frame_t rx_frame) { case 0x22: //Second datarow in PID group if (poll_data_pid == 1) { battery_current = ((battery_current_high_byte << 8) | rx_frame.data.u8[1]); - battery_voltage = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); + battery_voltage = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]); battery_module_max_temperature = rx_frame.data.u8[4]; battery_module_min_temperature = rx_frame.data.u8[5]; } else if (poll_data_pid == 2) { From fe046246c5496a19dfbd3158a92ac6e8b1849728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 1 Jul 2024 20:49:48 +0300 Subject: [PATCH 13/15] Move cellvoltage arraycopy location --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 2c42c3fe..cafd09f3 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -87,6 +87,9 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_min_voltage_mV = min_cell_voltage_mv; + //Map all cell voltages to the global array + memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages_mv, 59 * sizeof(uint16_t)); + if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); } else { @@ -223,8 +226,6 @@ void receive_can_battery(CAN_frame_t rx_frame) { cellvoltages_mv[56] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[57] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[58] = (rx_frame.data.u8[7] * 20); - //Map all cell voltages to the global array - memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages_mv, 59 * sizeof(uint16_t)); } else if (poll_data_pid == 5) { } break; From bc959a9b84668f50e8b9f49fe1af15ada1ab07ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 2 Jul 2024 21:10:50 +0300 Subject: [PATCH 14/15] Fix scaling of charge/discharge allowed --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index cafd09f3..136cfa6b 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -125,8 +125,8 @@ void receive_can_battery(CAN_frame_t rx_frame) { case 0x21: //First frame in PID group if (poll_data_pid == 1) { // 21 01 SOC = rx_frame.data.u8[1]; // 0xBC = 188 /2 = 94% - available_charge_power = ((rx_frame.data.u8[3] << 8) | rx_frame.data.u8[2]); - available_discharge_power = ((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); + available_charge_power = ((rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3]); + available_discharge_power = ((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]); battery_current_high_byte = rx_frame.data.u8[7]; } else if (poll_data_pid == 2) { //21 02 cellvoltages_mv[0] = (rx_frame.data.u8[2] * 20); From e03df3836998ef65e272f68e92395d17a617e048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Tue, 2 Jul 2024 22:58:03 +0300 Subject: [PATCH 15/15] Final tweaks, add TODO at top --- Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp index 136cfa6b..ec3cfe27 100644 --- a/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-HYBRID-BATTERY.cpp @@ -6,6 +6,11 @@ #include "../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "KIA-HYUNDAI-HYBRID-BATTERY.h" +/* TODO: +- The HEV battery seems to turn off after 1 minute of use. When this happens SOC% stops updating. +- We need to figure out how to keep the BMS alive. Most likely we need to send a specific CAN message +*/ + /* Do not change code below unless you are sure what you are doing */ static unsigned long previousMillis1000 = 0; // will store last time a 100ms CAN Message was send @@ -20,7 +25,7 @@ static uint32_t available_discharge_power = 0; static int8_t battery_module_max_temperature = 0; static int8_t battery_module_min_temperature = 0; static uint8_t poll_data_pid = 0; -static uint16_t cellvoltages_mv[59]; +static uint16_t cellvoltages_mv[98]; static uint16_t min_cell_voltage_mv = 3700; static uint16_t max_cell_voltage_mv = 3700; @@ -88,7 +93,7 @@ void update_values_battery() { //This function maps all the values fetched via datalayer.battery.status.cell_min_voltage_mV = min_cell_voltage_mv; //Map all cell voltages to the global array - memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages_mv, 59 * sizeof(uint16_t)); + memcpy(datalayer.battery.status.cell_voltages_mV, cellvoltages_mv, 98 * sizeof(uint16_t)); if (interlock_missing) { set_event(EVENT_HVIL_FAILURE, 0); @@ -271,7 +276,7 @@ void setup_battery(void) { // Performs one time setup at startup #ifdef DEBUG_VIA_USB Serial.println("Kia/Hyundai Hybrid battery selected"); #endif - datalayer.battery.info.number_of_cells = 59; + datalayer.battery.info.number_of_cells = 56; // HEV , TODO: Make dynamic according to HEV/PHEV datalayer.battery.info.max_design_voltage_dV = 2550; //TODO: Values OK? datalayer.battery.info.min_design_voltage_dV = 1700; }