From ce2f17aa6909de7ddd0fd8705e6f624af5eca510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 26 Feb 2025 19:08:05 +0200 Subject: [PATCH 1/5] Add SOC estimation from cellvoltage min-max --- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 42 ++++++++++++++++++++++ Software/src/battery/KIA-E-GMP-BATTERY.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index fcda66f4..89ca129f 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -32,6 +32,8 @@ static uint16_t inverterVoltage = 0; static uint16_t soc_calculated = 0; static uint16_t SOC_BMS = 0; static uint16_t SOC_Display = 0; +static uint16_t SOC_estimated_lowest = 0; +static uint16_t SOC_estimated_highest = 0; static uint16_t batterySOH = 1000; static uint16_t CellVoltMax_mV = 3700; static uint16_t CellVoltMin_mV = 3700; @@ -61,6 +63,40 @@ static uint8_t ticks_200ms_counter = 0; static uint8_t EGMP_1CF_counter = 0; static uint8_t EGMP_3XF_counter = 0; +// Define the data points for %SOC depending on cell voltage +const uint8_t numPoints = 14; +const uint16_t SOC[] = {10000, 9626, 9259, 8899, 8546, 8200, 7859, 7524, 7193, 6867, 6544, 6224, 5907, 5590, 5275, + 4959, 4643, 4325, 4004, 3680, 3350, 3016, 2674, 2325, 1967, 1599, 1220, 827, 421, 0}; +const uint16_t voltage[] = {4250, 4200, 4150, 4100, 4050, 4000, 3950, 3900, 3850, 3800, 3750, 3700, 3650, 3600, 3550, + 3500, 3450, 3400, 3350, 3300, 3250, 3200, 3150, 3100, 3050, 3000, 2950, 2900, 2850, 2800}; + +uint16_t estimateSOC(uint16_t cellVoltage) { // Linear interpolation function + if (cellVoltage >= voltage[0]) { + return SOC[0]; + } + if (cellVoltage <= voltage[numPoints - 1]) { + return SOC[numPoints - 1]; + } + + for (int i = 1; i < numPoints; ++i) { + if (cellVoltage >= voltage[i]) { + double t = (cellVoltage - voltage[i]) / (voltage[i - 1] - voltage[i]); + return SOC[i] + t * (SOC[i - 1] - SOC[i]); + } + } + return 0; // Default return for safety, should never reach here +} + +uint8_t selectSOC(uint8_t SOC_low, uint8_t SOC_high) { + if (SOC_low == 0 || SOC_high == 0) { + return 0; // If either value is 0, return 0 + } + if (SOC_low == 10000 || SOC_high == 10000) { + return 10000; // If either value is 100, return 100 + } + return (SOC_low < SOC_high) ? SOC_low : SOC_high; // Otherwise, return the lowest value +} + /* These messages are needed for contactor closing */ unsigned long startMillis; uint8_t messageIndex = 0; @@ -632,7 +668,13 @@ static uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_ void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus +#ifdef ESTIMATE_SOC_FROM_CELLVOLTAGE + SOC_estimated_lowest = estimateSOC(CellVoltMin_mV); + SOC_estimated_highest = estimateSOC(CellVoltMax_mV); + datalayer.battery.status.real_soc = selectSOC(SOC_estimated_lowest, SOC_estimated_highest); +#else datalayer.battery.status.real_soc = (SOC_Display * 10); //increase SOC range from 0-100.0 -> 100.00 +#endif datalayer.battery.status.soh_pptt = (batterySOH * 10); //Increase decimals from 100.0% -> 100.00% diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.h b/Software/src/battery/KIA-E-GMP-BATTERY.h index b0f3dccc..11ca62a0 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.h +++ b/Software/src/battery/KIA-E-GMP-BATTERY.h @@ -6,6 +6,8 @@ extern ACAN2517FD canfd; +#define ESTIMATE_SOC_FROM_CELLVOLTAGE + #define BATTERY_SELECTED #define MAX_PACK_VOLTAGE_DV 8064 //5000 = 500.0V #define MIN_PACK_VOLTAGE_DV 4320 From 3463cf861d50edb3cd19085e0a2181003db0fb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 26 Feb 2025 19:11:12 +0200 Subject: [PATCH 2/5] Increase number of points --- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index 89ca129f..5add5881 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -64,7 +64,7 @@ static uint8_t EGMP_1CF_counter = 0; static uint8_t EGMP_3XF_counter = 0; // Define the data points for %SOC depending on cell voltage -const uint8_t numPoints = 14; +const uint8_t numPoints = 30; const uint16_t SOC[] = {10000, 9626, 9259, 8899, 8546, 8200, 7859, 7524, 7193, 6867, 6544, 6224, 5907, 5590, 5275, 4959, 4643, 4325, 4004, 3680, 3350, 3016, 2674, 2325, 1967, 1599, 1220, 827, 421, 0}; const uint16_t voltage[] = {4250, 4200, 4150, 4100, 4050, 4000, 3950, 3900, 3850, 3800, 3750, 3700, 3650, 3600, 3550, From 86950908d51e8d5d8f3279dd03b1ad93e2b920e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 5 Mar 2025 22:26:10 +0200 Subject: [PATCH 3/5] Tweak lookup table --- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index 5add5881..ae6db136 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -67,8 +67,8 @@ static uint8_t EGMP_3XF_counter = 0; const uint8_t numPoints = 30; const uint16_t SOC[] = {10000, 9626, 9259, 8899, 8546, 8200, 7859, 7524, 7193, 6867, 6544, 6224, 5907, 5590, 5275, 4959, 4643, 4325, 4004, 3680, 3350, 3016, 2674, 2325, 1967, 1599, 1220, 827, 421, 0}; -const uint16_t voltage[] = {4250, 4200, 4150, 4100, 4050, 4000, 3950, 3900, 3850, 3800, 3750, 3700, 3650, 3600, 3550, - 3500, 3450, 3400, 3350, 3300, 3250, 3200, 3150, 3100, 3050, 3000, 2950, 2900, 2850, 2800}; +const uint16_t voltage[] = {4200, 4170, 4140, 4110, 4080, 4050, 4020, 3990, 3960, 3930, 3900, 3870, 3840, 3810, 3780, + 3750, 3720, 3690, 3660, 3630, 3600, 3570, 3540, 3510, 3480, 3450, 3420, 3390, 3360, 3330}; uint16_t estimateSOC(uint16_t cellVoltage) { // Linear interpolation function if (cellVoltage >= voltage[0]) { From 44f4d6538e7cef9fc9a5a76d7ce5a14e45d0311e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Wed, 12 Mar 2025 22:32:08 +0200 Subject: [PATCH 4/5] Fix truncation of values --- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index ae6db136..19875a72 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -87,7 +87,7 @@ uint16_t estimateSOC(uint16_t cellVoltage) { // Linear interpolation function return 0; // Default return for safety, should never reach here } -uint8_t selectSOC(uint8_t SOC_low, uint8_t SOC_high) { +uint16_t selectSOC(uint16_t SOC_low, uint16_t SOC_high) { if (SOC_low == 0 || SOC_high == 0) { return 0; // If either value is 0, return 0 } From 12323154b1be6f0438ed19258ce8d487f78d3f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96ster?= Date: Mon, 17 Mar 2025 18:08:51 +0200 Subject: [PATCH 5/5] Update voltage estimation map with more points --- Software/src/battery/KIA-E-GMP-BATTERY.cpp | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/Software/src/battery/KIA-E-GMP-BATTERY.cpp b/Software/src/battery/KIA-E-GMP-BATTERY.cpp index 19875a72..1a578ca9 100644 --- a/Software/src/battery/KIA-E-GMP-BATTERY.cpp +++ b/Software/src/battery/KIA-E-GMP-BATTERY.cpp @@ -64,11 +64,23 @@ static uint8_t EGMP_1CF_counter = 0; static uint8_t EGMP_3XF_counter = 0; // Define the data points for %SOC depending on cell voltage -const uint8_t numPoints = 30; -const uint16_t SOC[] = {10000, 9626, 9259, 8899, 8546, 8200, 7859, 7524, 7193, 6867, 6544, 6224, 5907, 5590, 5275, - 4959, 4643, 4325, 4004, 3680, 3350, 3016, 2674, 2325, 1967, 1599, 1220, 827, 421, 0}; -const uint16_t voltage[] = {4200, 4170, 4140, 4110, 4080, 4050, 4020, 3990, 3960, 3930, 3900, 3870, 3840, 3810, 3780, - 3750, 3720, 3690, 3660, 3630, 3600, 3570, 3540, 3510, 3480, 3450, 3420, 3390, 3360, 3330}; +const uint8_t numPoints = 100; + +const uint16_t SOC[] = {10000, 9900, 9800, 9700, 9600, 9500, 9400, 9300, 9200, 9100, 9000, 8900, 8800, 8700, 8600, + 8500, 8400, 8300, 8200, 8100, 8000, 7900, 7800, 7700, 7600, 7500, 7400, 7300, 7200, 7100, + 7000, 6900, 6800, 6700, 6600, 6500, 6400, 6300, 6200, 6100, 6000, 5900, 5800, 5700, 5600, + 5500, 5400, 5300, 5200, 5100, 5000, 4900, 4800, 4700, 4600, 4500, 4400, 4300, 4200, 4100, + 4000, 3900, 3800, 3700, 3600, 3500, 3400, 3300, 3200, 3100, 3000, 2900, 2800, 2700, 2600, + 2500, 2400, 2300, 2200, 2100, 2000, 1900, 1800, 1700, 1600, 1500, 1400, 1300, 1200, 1100, + 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 0}; + +const uint16_t voltage[] = {4200, 4171, 4143, 4117, 4093, 4070, 4050, 4031, 4013, 3998, 3985, 3973, 3964, 3957, 3952, + 3950, 3941, 3933, 3924, 3916, 3907, 3899, 3890, 3881, 3873, 3864, 3856, 3847, 3839, 3830, + 3821, 3813, 3804, 3796, 3787, 3779, 3770, 3761, 3753, 3744, 3736, 3727, 3719, 3710, 3701, + 3693, 3684, 3676, 3667, 3659, 3650, 3641, 3633, 3624, 3616, 3607, 3599, 3590, 3581, 3573, + 3564, 3556, 3547, 3539, 3530, 3521, 3513, 3504, 3496, 3487, 3479, 3470, 3461, 3453, 3444, + 3436, 3427, 3419, 3410, 3401, 3393, 3384, 3376, 3367, 3359, 3350, 3333, 3315, 3297, 3278, + 3258, 3237, 3215, 3192, 3166, 3139, 3108, 3074, 3033, 2979, 2850}; uint16_t estimateSOC(uint16_t cellVoltage) { // Linear interpolation function if (cellVoltage >= voltage[0]) { @@ -80,8 +92,14 @@ uint16_t estimateSOC(uint16_t cellVoltage) { // Linear interpolation function for (int i = 1; i < numPoints; ++i) { if (cellVoltage >= voltage[i]) { - double t = (cellVoltage - voltage[i]) / (voltage[i - 1] - voltage[i]); - return SOC[i] + t * (SOC[i - 1] - SOC[i]); + // Fix: Cast to float or double to ensure proper floating-point division + float t = (float)(cellVoltage - voltage[i]) / (float)(voltage[i - 1] - voltage[i]); + + // Calculate interpolated SOC value + uint16_t socDiff = SOC[i - 1] - SOC[i]; + uint16_t interpolatedValue = SOC[i] + (uint16_t)(t * socDiff); + + return interpolatedValue; } } return 0; // Default return for safety, should never reach here