Use base class for KIA EGMP battery

This commit is contained in:
Jaakko Haakana 2025-05-19 21:10:32 +03:00
parent 764fc8cca9
commit abf7fe3c26
2 changed files with 73 additions and 60 deletions

View file

@ -1,14 +1,11 @@
#include "../include.h" #include "../include.h"
#ifdef KIA_E_GMP_BATTERY #ifdef KIA_E_GMP_BATTERY
#include "../communication/can/comm_can.h"
#include "../datalayer/datalayer.h" #include "../datalayer/datalayer.h"
#include "../devboard/utils/events.h" #include "../devboard/utils/events.h"
#include "../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h" #include "../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
#include "KIA-E-GMP-BATTERY.h" #include "KIA-E-GMP-BATTERY.h"
/* Do not change code below unless you are sure what you are doing */
static unsigned long previousMillis200ms = 0; // will store last time a 200ms CAN Message was send
static unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send
const unsigned char crc8_table[256] = const unsigned char crc8_table[256] =
{ // CRC8_SAE_J1850_ZER0 formula,0x1D Poly,initial value 0x3F,Final XOR value varies { // CRC8_SAE_J1850_ZER0 formula,0x1D Poly,initial value 0x3F,Final XOR value varies
0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0, 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, 0xCD, 0xD0,
@ -27,42 +24,6 @@ const unsigned char crc8_table[256] =
0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0,
0xE3, 0xFE, 0xD9, 0xC4}; 0xE3, 0xFE, 0xD9, 0xC4};
static uint16_t inverterVoltageFrameHigh = 0;
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;
static uint16_t batteryVoltage = 6700;
static int16_t leadAcidBatteryVoltage = 120;
static int16_t batteryAmps = 0;
static int16_t temperatureMax = 0;
static int16_t temperatureMin = 0;
static int16_t allowedDischargePower = 0;
static int16_t allowedChargePower = 0;
static int16_t poll_data_pid = 0;
static uint8_t CellVmaxNo = 0;
static uint8_t CellVminNo = 0;
static uint8_t batteryManagementMode = 0;
static uint8_t BMS_ign = 0;
static uint8_t batteryRelay = 0;
static uint8_t waterleakageSensor = 164;
static bool startedUp = false;
static bool ok_start_polling_battery = false;
static uint8_t counter_200 = 0;
static uint8_t KIA_7E4_COUNTER = 0x01;
static int8_t temperature_water_inlet = 0;
static int8_t powerRelayTemperature = 0;
static int8_t heatertemp = 0;
static bool set_voltage_limits = false;
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 // Define the data points for %SOC depending on cell voltage
const uint8_t numPoints = 100; const uint8_t numPoints = 100;
@ -107,7 +68,7 @@ uint16_t estimateSOCFromCell(uint16_t cellVoltage) {
} }
// Simplified version of the pack-based SOC estimation with compensation // Simplified version of the pack-based SOC estimation with compensation
uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps) { uint16_t KiaEGmpBattery::estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps) {
// If cell count is still the default 192 but we haven't confirmed it yet // If cell count is still the default 192 but we haven't confirmed it yet
if (!set_voltage_limits && cellCount == 192) { if (!set_voltage_limits && cellCount == 192) {
// Fall back to BMS-reported SOC while cell count is uncertain // Fall back to BMS-reported SOC while cell count is uncertain
@ -695,7 +656,7 @@ void set_cell_voltages(CAN_frame rx_frame, int start, int length, int startCell)
} }
} }
void set_voltage_minmax_limits() { void KiaEGmpBattery::set_voltage_minmax_limits() {
uint8_t valid_cell_count = 0; uint8_t valid_cell_count = 0;
for (int i = 0; i < MAX_AMOUNT_CELLS; ++i) { for (int i = 0; i < MAX_AMOUNT_CELLS; ++i) {
@ -729,7 +690,8 @@ static uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_
return crc; return crc;
} }
void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus void KiaEGmpBattery::
update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
#ifdef ESTIMATE_SOC_FROM_CELLVOLTAGE #ifdef ESTIMATE_SOC_FROM_CELLVOLTAGE
// Use the simplified pack-based SOC estimation with proper compensation // Use the simplified pack-based SOC estimation with proper compensation
@ -850,7 +812,7 @@ void update_values_battery() { //This function maps all the values fetched via
#endif #endif
} }
void handle_incoming_can_frame_battery(CAN_frame rx_frame) { void KiaEGmpBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
startedUp = true; startedUp = true;
switch (rx_frame.ID) { switch (rx_frame.ID) {
case 0x055: case 0x055:
@ -1082,7 +1044,7 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
} }
} }
void transmit_can_battery(unsigned long currentMillis) { void KiaEGmpBattery::transmit_can(unsigned long currentMillis) {
if (startedUp) { if (startedUp) {
//Send Contactor closing message loop //Send Contactor closing message loop
// Check if we still have messages to send // Check if we still have messages to send
@ -1128,7 +1090,7 @@ void transmit_can_battery(unsigned long currentMillis) {
} }
} }
void setup_battery(void) { // Performs one time setup at startup void KiaEGmpBattery::setup(void) { // Performs one time setup at startup
strncpy(datalayer.system.info.battery_protocol, "Kia/Hyundai EGMP platform", 63); strncpy(datalayer.system.info.battery_protocol, "Kia/Hyundai EGMP platform", 63);
datalayer.system.info.battery_protocol[63] = '\0'; datalayer.system.info.battery_protocol[63] = '\0';

View file

@ -3,27 +3,78 @@
#include <Arduino.h> #include <Arduino.h>
#include "../include.h" #include "../include.h"
#include "../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h" #include "../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
#include "CanBattery.h"
extern ACAN2517FD canfd; extern ACAN2517FD canfd;
#define ESTIMATE_SOC_FROM_CELLVOLTAGE #define ESTIMATE_SOC_FROM_CELLVOLTAGE
#define BATTERY_SELECTED #define BATTERY_SELECTED
#define MAX_PACK_VOLTAGE_DV 8064 //5000 = 500.0V #define SELECTED_BATTERY_CLASS KiaEGmpBattery
#define MIN_PACK_VOLTAGE_DV 4320
#define MAX_CELL_DEVIATION_MV 150
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value
#define MIN_CELL_VOLTAGE_MV 2950 //Battery is put into emergency stop if one cell goes below this value
#define MAXCHARGEPOWERALLOWED 10000
#define MAXDISCHARGEPOWERALLOWED 10000
#define RAMPDOWN_SOC 9000 // 90.00 SOC% to start ramping down from max charge power towards 0 at 100.00%
#define RAMPDOWNPOWERALLOWED 10000 // What power we ramp down from towards top balancing
// Used for SoC compensation - Define internal resistance value in milliohms for the entire pack class KiaEGmpBattery : public CanBattery {
// How to calculate: voltage_drop_under_known_load [Volts] / load [Amps] = Resistance public:
#define PACK_INTERNAL_RESISTANCE_MOHM 200 // 200 milliohms for the whole pack virtual void setup(void);
virtual void handle_incoming_can_frame(CAN_frame rx_frame);
virtual void update_values();
virtual void transmit_can(unsigned long currentMillis);
void setup_battery(void); private:
void transmit_can_frame(CAN_frame* tx_frame, int interface); uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps);
void set_voltage_minmax_limits();
static const int MAX_PACK_VOLTAGE_DV = 8064; //5000 = 500.0V
static const int MIN_PACK_VOLTAGE_DV = 4320;
static const int MAX_CELL_DEVIATION_MV = 150;
static const int MAX_CELL_VOLTAGE_MV = 4250; //Battery is put into emergency stop if one cell goes over this value
static const int MIN_CELL_VOLTAGE_MV = 2950; //Battery is put into emergency stop if one cell goes below this value
static const int MAXCHARGEPOWERALLOWED = 10000;
static const int MAXDISCHARGEPOWERALLOWED = 10000;
static const int RAMPDOWN_SOC = 9000; // 90.00 SOC% to start ramping down from max charge power towards 0 at 100.00%
static const int RAMPDOWNPOWERALLOWED = 10000; // What power we ramp down from towards top balancing
// Used for SoC compensation - Define internal resistance value in milliohms for the entire pack
// How to calculate: voltage_drop_under_known_load [Volts] / load [Amps] = Resistance
static const int PACK_INTERNAL_RESISTANCE_MOHM = 200; // 200 milliohms for the whole pack
unsigned long previousMillis200ms = 0; // will store last time a 200ms CAN Message was send
unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send
uint16_t inverterVoltageFrameHigh = 0;
uint16_t inverterVoltage = 0;
uint16_t soc_calculated = 0;
uint16_t SOC_BMS = 0;
uint16_t SOC_Display = 0;
uint16_t SOC_estimated_lowest = 0;
uint16_t SOC_estimated_highest = 0;
uint16_t batterySOH = 1000;
uint16_t CellVoltMax_mV = 3700;
uint16_t CellVoltMin_mV = 3700;
uint16_t batteryVoltage = 6700;
int16_t leadAcidBatteryVoltage = 120;
int16_t batteryAmps = 0;
int16_t temperatureMax = 0;
int16_t temperatureMin = 0;
int16_t allowedDischargePower = 0;
int16_t allowedChargePower = 0;
int16_t poll_data_pid = 0;
uint8_t CellVmaxNo = 0;
uint8_t CellVminNo = 0;
uint8_t batteryManagementMode = 0;
uint8_t BMS_ign = 0;
uint8_t batteryRelay = 0;
uint8_t waterleakageSensor = 164;
bool startedUp = false;
bool ok_start_polling_battery = false;
uint8_t counter_200 = 0;
uint8_t KIA_7E4_COUNTER = 0x01;
int8_t temperature_water_inlet = 0;
int8_t powerRelayTemperature = 0;
int8_t heatertemp = 0;
bool set_voltage_limits = false;
uint8_t ticks_200ms_counter = 0;
uint8_t EGMP_1CF_counter = 0;
uint8_t EGMP_3XF_counter = 0;
};
#endif #endif