Extend PID polling to cover version numbers

This commit is contained in:
Daniel Öster 2025-07-31 20:02:26 +03:00
parent a547fb201e
commit 436c3de1f7
4 changed files with 136 additions and 133 deletions

View file

@ -48,66 +48,9 @@ void KiaHyundai64Battery::
datalayer_battery_extended->batteryManagementMode = batteryManagementMode; datalayer_battery_extended->batteryManagementMode = batteryManagementMode;
datalayer_battery_extended->BMS_ign = BMS_ign; datalayer_battery_extended->BMS_ign = BMS_ign;
datalayer_battery_extended->batteryRelay = batteryRelay; datalayer_battery_extended->batteryRelay = batteryRelay;
datalayer_battery_extended->inverterVoltage = inverterVoltage;
//Perform logging if configured to do so memcpy(datalayer_battery_extended->ecu_serial_number, ecu_serial_number, sizeof(ecu_serial_number));
#ifdef DEBUG_LOG memcpy(datalayer_battery_extended->ecu_version_number, ecu_version_number, sizeof(ecu_version_number));
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) {
logging.print(" | BmsIgnition ON");
} else {
logging.print(" | BmsIgnition OFF");
}
if (bitRead((uint8_t)batteryRelay, 0) == 1) {
logging.print(" | PowerRelay ON");
} else {
logging.print(" | PowerRelay OFF");
}
logging.print(" | Inverter ");
logging.print(inverterVoltage);
logging.println(" Volts");
#endif
} }
void KiaHyundai64Battery::update_number_of_cells() { void KiaHyundai64Battery::update_number_of_cells() {
@ -129,6 +72,7 @@ void KiaHyundai64Battery::update_number_of_cells() {
void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) { void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
switch (rx_frame.ID) { switch (rx_frame.ID) {
case 0x4DE: case 0x4DE:
datalayer_battery->status.CAN_battery_still_alive = CAN_STILL_ALIVE;
startedUp = true; startedUp = true;
break; break;
case 0x542: //BMS SOC case 0x542: //BMS SOC
@ -168,65 +112,109 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
case 0x5D8: case 0x5D8:
startedUp = true; startedUp = true;
//PID data is polled after last message sent from battery every other time: //PID data is polled after last message sent from battery every other time this 0x5D8 message arrives:
if (holdPidCounter == true) { if (holdPidCounter == true) {
holdPidCounter = false; holdPidCounter = false;
} else { } else {
holdPidCounter = true; holdPidCounter = true;
if (poll_data_pid >= 6) { //polling one of six PIDs at 100ms*2, resolution = 1200ms
poll_data_pid = 0;
}
poll_data_pid++; poll_data_pid++;
if (poll_data_pid == 1) { if (poll_data_pid == 1) {
transmit_can_frame(&KIA64_7E4_id1); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_1 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_1 & 0x00FF);
} else if (poll_data_pid == 2) { } else if (poll_data_pid == 2) {
transmit_can_frame(&KIA64_7E4_id2); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_2 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_2 & 0x00FF);
} else if (poll_data_pid == 3) { } else if (poll_data_pid == 3) {
transmit_can_frame(&KIA64_7E4_id3); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_3 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_3 & 0x00FF);
} else if (poll_data_pid == 4) { } else if (poll_data_pid == 4) {
transmit_can_frame(&KIA64_7E4_id4); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_4 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_4 & 0x00FF);
} else if (poll_data_pid == 5) { } else if (poll_data_pid == 5) {
transmit_can_frame(&KIA64_7E4_id5); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_5 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_5 & 0x00FF);
} else if (poll_data_pid == 6) { } else if (poll_data_pid == 6) {
transmit_can_frame(&KIA64_7E4_id6); KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_GROUP_6 & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_GROUP_6 & 0x00FF);
} else if (poll_data_pid == 7) {
KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_ECU_SERIAL & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_ECU_SERIAL & 0x00FF);
} else if (poll_data_pid == 8) {
KIA64_7E4_poll.data.u8[2] = (uint8_t)((POLL_ECU_VERSION & 0xFF00) >> 8);
KIA64_7E4_poll.data.u8[3] = (uint8_t)(POLL_ECU_VERSION & 0x00FF);
poll_data_pid = 0;
} }
transmit_can_frame(&KIA64_7E4_poll);
} }
break; break;
case 0x7EC: //Data From polled PID group, BigEndian case 0x7EC: //Data From polled PID group, BigEndian
switch (rx_frame.data.u8[0]) {
case 0x10: //"PID Header" if (rx_frame.data.u8[0] < 0x10) { //One line response
if (rx_frame.data.u8[4] == poll_data_pid) { pid_reply = (rx_frame.data.u8[2] << 8) | rx_frame.data.u8[3];
transmit_can_frame(&KIA64_7E4_ack); //Send ack to BMS if the same frame is sent as polled }
if (rx_frame.data.u8[0] == 0x10) { //Multiframe response, send ACK
transmit_can_frame(&KIA64_7E4_ack);
pid_reply = (rx_frame.data.u8[3] << 8) | rx_frame.data.u8[4];
}
switch (rx_frame.data.u8[0]) { //Multiframe responses
case 0x10: //Header frame sometimes has data
if (pid_reply == POLL_ECU_SERIAL) {
ecu_serial_number[0] = rx_frame.data.u8[5];
ecu_serial_number[1] = rx_frame.data.u8[6];
ecu_serial_number[2] = rx_frame.data.u8[7];
} else if (pid_reply == POLL_ECU_VERSION) {
ecu_version_number[0] = rx_frame.data.u8[5];
ecu_version_number[1] = rx_frame.data.u8[6];
ecu_version_number[2] = rx_frame.data.u8[7];
} }
break; break;
case 0x21: //First frame in PID group case 0x21: //First frame in PID group
if (poll_data_pid == 1) { if (pid_reply == POLL_GROUP_1) {
batteryRelay = rx_frame.data.u8[7]; batteryRelay = rx_frame.data.u8[7];
} else if (poll_data_pid == 2) { } else if (pid_reply == POLL_GROUP_2) {
cellvoltages_mv[0] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[0] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[1] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[1] = (rx_frame.data.u8[3] * 20);
cellvoltages_mv[2] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[2] = (rx_frame.data.u8[4] * 20);
cellvoltages_mv[3] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[3] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[4] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[4] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[5] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[5] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (pid_reply == POLL_GROUP_3) {
cellvoltages_mv[32] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[32] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[33] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[33] = (rx_frame.data.u8[3] * 20);
cellvoltages_mv[34] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[34] = (rx_frame.data.u8[4] * 20);
cellvoltages_mv[35] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[35] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[36] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[36] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[37] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[37] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (pid_reply == POLL_GROUP_4) {
cellvoltages_mv[64] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[64] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[65] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[65] = (rx_frame.data.u8[3] * 20);
cellvoltages_mv[66] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[66] = (rx_frame.data.u8[4] * 20);
cellvoltages_mv[67] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[67] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[68] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[68] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[69] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[69] = (rx_frame.data.u8[7] * 20);
} else if (pid_reply == POLL_ECU_SERIAL) {
ecu_serial_number[3] = rx_frame.data.u8[1];
ecu_serial_number[4] = rx_frame.data.u8[2];
ecu_serial_number[5] = rx_frame.data.u8[3];
ecu_serial_number[6] = rx_frame.data.u8[4];
ecu_serial_number[7] = rx_frame.data.u8[5];
ecu_serial_number[8] = rx_frame.data.u8[6];
ecu_serial_number[9] = rx_frame.data.u8[7];
} else if (pid_reply == POLL_ECU_VERSION) {
ecu_version_number[3] = rx_frame.data.u8[1];
ecu_version_number[4] = rx_frame.data.u8[2];
ecu_version_number[5] = rx_frame.data.u8[3];
ecu_version_number[6] = rx_frame.data.u8[4];
ecu_version_number[7] = rx_frame.data.u8[5];
ecu_version_number[8] = rx_frame.data.u8[6];
ecu_version_number[9] = rx_frame.data.u8[7];
} }
break; break;
case 0x22: //Second datarow in PID group case 0x22: //Second datarow in PID group
if (poll_data_pid == 2) { if (pid_reply == POLL_GROUP_2) {
cellvoltages_mv[6] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[6] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[7] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[7] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[8] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[8] = (rx_frame.data.u8[3] * 20);
@ -234,7 +222,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[10] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[10] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[11] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[11] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[12] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[12] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (pid_reply == POLL_GROUP_3) {
cellvoltages_mv[38] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[38] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[39] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[39] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[40] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[40] = (rx_frame.data.u8[3] * 20);
@ -242,7 +230,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[42] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[42] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[43] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[43] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[44] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[44] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (pid_reply == POLL_GROUP_4) {
cellvoltages_mv[70] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[70] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[71] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[71] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[72] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[72] = (rx_frame.data.u8[3] * 20);
@ -250,15 +238,29 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[74] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[74] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[75] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[75] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[76] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[76] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 6) { } else if (pid_reply == POLL_GROUP_6) {
batteryManagementMode = rx_frame.data.u8[5]; batteryManagementMode = rx_frame.data.u8[5];
} else if (pid_reply == POLL_ECU_SERIAL) {
ecu_serial_number[10] = rx_frame.data.u8[1];
ecu_serial_number[11] = rx_frame.data.u8[2];
ecu_serial_number[12] = rx_frame.data.u8[3];
ecu_serial_number[13] = rx_frame.data.u8[4];
ecu_serial_number[14] = rx_frame.data.u8[5];
ecu_serial_number[15] = rx_frame.data.u8[6];
} else if (pid_reply == POLL_ECU_VERSION) {
ecu_version_number[10] = rx_frame.data.u8[1];
ecu_version_number[11] = rx_frame.data.u8[2];
ecu_version_number[12] = rx_frame.data.u8[3];
ecu_version_number[13] = rx_frame.data.u8[4];
ecu_version_number[14] = rx_frame.data.u8[5];
ecu_version_number[15] = rx_frame.data.u8[6];
} }
break; break;
case 0x23: //Third datarow in PID group case 0x23: //Third datarow in PID group
if (poll_data_pid == 1) { if (pid_reply == POLL_GROUP_1) {
temperature_water_inlet = rx_frame.data.u8[6]; temperature_water_inlet = rx_frame.data.u8[6];
CellVoltMax_mV = (rx_frame.data.u8[7] * 20); //(volts *50) *20 =mV CellVoltMax_mV = (rx_frame.data.u8[7] * 20); //(volts *50) *20 =mV
} else if (poll_data_pid == 2) { } else if (pid_reply == POLL_GROUP_2) {
cellvoltages_mv[13] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[13] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[14] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[14] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[15] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[15] = (rx_frame.data.u8[3] * 20);
@ -266,7 +268,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[17] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[17] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[18] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[18] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[19] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[19] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (pid_reply == POLL_GROUP_3) {
cellvoltages_mv[45] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[45] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[46] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[46] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[47] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[47] = (rx_frame.data.u8[3] * 20);
@ -274,7 +276,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[49] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[49] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[50] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[50] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[51] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[51] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (pid_reply == POLL_GROUP_4) {
cellvoltages_mv[77] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[77] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[78] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[78] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[79] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[79] = (rx_frame.data.u8[3] * 20);
@ -282,16 +284,16 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[81] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[81] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[82] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[82] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[83] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[83] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 5) { } else if (pid_reply == POLL_GROUP_5) {
heatertemp = rx_frame.data.u8[7]; heatertemp = rx_frame.data.u8[7];
} }
break; break;
case 0x24: //Fourth datarow in PID group case 0x24: //Fourth datarow in PID group
if (poll_data_pid == 1) { if (pid_reply == POLL_GROUP_1) {
CellVmaxNo = rx_frame.data.u8[1]; CellVmaxNo = rx_frame.data.u8[1];
CellVminNo = rx_frame.data.u8[3]; CellVminNo = rx_frame.data.u8[3];
CellVoltMin_mV = (rx_frame.data.u8[2] * 20); //(volts *50) *20 =mV CellVoltMin_mV = (rx_frame.data.u8[2] * 20); //(volts *50) *20 =mV
} else if (poll_data_pid == 2) { } else if (pid_reply == POLL_GROUP_2) {
cellvoltages_mv[20] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[20] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[21] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[21] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[22] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[22] = (rx_frame.data.u8[3] * 20);
@ -299,7 +301,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[24] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[24] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[25] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[25] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[26] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[26] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 3) { } else if (pid_reply == POLL_GROUP_3) {
cellvoltages_mv[52] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[52] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[53] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[53] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[54] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[54] = (rx_frame.data.u8[3] * 20);
@ -307,7 +309,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
cellvoltages_mv[56] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[56] = (rx_frame.data.u8[5] * 20);
cellvoltages_mv[57] = (rx_frame.data.u8[6] * 20); cellvoltages_mv[57] = (rx_frame.data.u8[6] * 20);
cellvoltages_mv[58] = (rx_frame.data.u8[7] * 20); cellvoltages_mv[58] = (rx_frame.data.u8[7] * 20);
} else if (poll_data_pid == 4) { } else if (pid_reply == POLL_GROUP_4) {
cellvoltages_mv[84] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[84] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[85] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[85] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[86] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[86] = (rx_frame.data.u8[3] * 20);
@ -317,24 +319,24 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
if (rx_frame.data.u8[7] > 4) { // Data only valid on 98S if (rx_frame.data.u8[7] > 4) { // Data only valid on 98S
cellvoltages_mv[90] = (rx_frame.data.u8[7] * 20); // Perform extra checks cellvoltages_mv[90] = (rx_frame.data.u8[7] * 20); // Perform extra checks
} }
} else if (poll_data_pid == 5) { } else if (pid_reply == POLL_GROUP_5) {
batterySOH = ((rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3]); batterySOH = ((rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3]);
} }
break; break;
case 0x25: //Fifth datarow in PID group case 0x25: //Fifth datarow in PID group
if (poll_data_pid == 2) { if (pid_reply == POLL_GROUP_2) {
cellvoltages_mv[27] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[27] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[28] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[28] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[29] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[29] = (rx_frame.data.u8[3] * 20);
cellvoltages_mv[30] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[30] = (rx_frame.data.u8[4] * 20);
cellvoltages_mv[31] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[31] = (rx_frame.data.u8[5] * 20);
} else if (poll_data_pid == 3) { } else if (pid_reply == POLL_GROUP_3) {
cellvoltages_mv[59] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[59] = (rx_frame.data.u8[1] * 20);
cellvoltages_mv[60] = (rx_frame.data.u8[2] * 20); cellvoltages_mv[60] = (rx_frame.data.u8[2] * 20);
cellvoltages_mv[61] = (rx_frame.data.u8[3] * 20); cellvoltages_mv[61] = (rx_frame.data.u8[3] * 20);
cellvoltages_mv[62] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[62] = (rx_frame.data.u8[4] * 20);
cellvoltages_mv[63] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[63] = (rx_frame.data.u8[5] * 20);
} else if (poll_data_pid == 4) { // Data only valid on 98S } else if (pid_reply == POLL_GROUP_4) { // Data only valid on 98S
if (rx_frame.data.u8[1] > 4) { // Perform extra checks if (rx_frame.data.u8[1] > 4) { // Perform extra checks
cellvoltages_mv[91] = (rx_frame.data.u8[1] * 20); cellvoltages_mv[91] = (rx_frame.data.u8[1] * 20);
} }
@ -350,7 +352,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
if (rx_frame.data.u8[5] > 4) { // Perform extra checks if (rx_frame.data.u8[5] > 4) { // Perform extra checks
cellvoltages_mv[95] = (rx_frame.data.u8[5] * 20); cellvoltages_mv[95] = (rx_frame.data.u8[5] * 20);
} }
} else if (poll_data_pid == 5) { // Data only valid on 98S } else if (pid_reply == 5) { // Data only valid on 98S
if (rx_frame.data.u8[4] > 4) { // Perform extra checks if (rx_frame.data.u8[4] > 4) { // Perform extra checks
cellvoltages_mv[96] = (rx_frame.data.u8[4] * 20); cellvoltages_mv[96] = (rx_frame.data.u8[4] * 20);
} }
@ -360,7 +362,7 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
} }
break; break;
case 0x26: //Sixth datarow in PID group case 0x26: //Sixth datarow in PID group
if (poll_data_pid == 5) { if (pid_reply == POLL_GROUP_5) {
//We have read all cells, check that content is valid: //We have read all cells, check that content is valid:
for (uint8_t i = 85; i < 97; ++i) { for (uint8_t i = 85; i < 97; ++i) {
if (cellvoltages_mv[i] < 300) { // Zero the value if it's below 300 if (cellvoltages_mv[i] < 300) { // Zero the value if it's below 300
@ -374,17 +376,20 @@ void KiaHyundai64Battery::handle_incoming_can_frame(CAN_frame rx_frame) {
} }
break; break;
case 0x27: //Seventh datarow in PID group case 0x27: //Seventh datarow in PID group
if (poll_data_pid == 1) { if (pid_reply == POLL_GROUP_1) {
BMS_ign = rx_frame.data.u8[6]; BMS_ign = rx_frame.data.u8[6];
inverterVoltageFrameHigh = rx_frame.data.u8[7]; inverterVoltageFrameHigh = rx_frame.data.u8[7];
} }
break; break;
case 0x28: //Eighth datarow in PID group case 0x28: //Eighth datarow in PID group
if (poll_data_pid == 1) { if (pid_reply == POLL_GROUP_1) {
inverterVoltage = (inverterVoltageFrameHigh << 8) + rx_frame.data.u8[1]; inverterVoltage = (inverterVoltageFrameHigh << 8) + rx_frame.data.u8[1];
} }
break; break;
default:
break;
} }
break; break;
default: default:
break; break;

View file

@ -79,7 +79,8 @@ class KiaHyundai64Battery : public CanBattery {
int16_t batteryAmps = 0; int16_t batteryAmps = 0;
int16_t temperatureMax = 0; int16_t temperatureMax = 0;
int16_t temperatureMin = 0; int16_t temperatureMin = 0;
int16_t poll_data_pid = 0; uint8_t poll_data_pid = 0;
uint16_t pid_reply = 0;
bool holdPidCounter = false; bool holdPidCounter = false;
uint8_t CellVmaxNo = 0; uint8_t CellVmaxNo = 0;
uint8_t CellVminNo = 0; uint8_t CellVminNo = 0;
@ -92,6 +93,8 @@ class KiaHyundai64Battery : public CanBattery {
int8_t heatertemp = 0; int8_t heatertemp = 0;
int8_t powerRelayTemperature = 0; int8_t powerRelayTemperature = 0;
bool startedUp = false; bool startedUp = false;
uint8_t ecu_serial_number[16] = {0};
uint8_t ecu_version_number[16] = {0};
CAN_frame KIA_HYUNDAI_200 = {.FD = false, CAN_frame KIA_HYUNDAI_200 = {.FD = false,
.ext_ID = false, .ext_ID = false,
@ -126,42 +129,25 @@ class KiaHyundai64Battery : public CanBattery {
.DLC = 8, .DLC = 8,
.ID = 0x2A1, .ID = 0x2A1,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame KIA64_7E4_id1 = {.FD = false, CAN_frame KIA64_7E4_poll = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x7E4, .ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 01 .data = {0x03, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}};
CAN_frame KIA64_7E4_id2 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 02
CAN_frame KIA64_7E4_id3 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 03
CAN_frame KIA64_7E4_id4 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 04
CAN_frame KIA64_7E4_id5 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 05
CAN_frame KIA64_7E4_id6 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7E4,
.data = {0x03, 0x22, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 06
CAN_frame KIA64_7E4_ack = { CAN_frame KIA64_7E4_ack = {
.FD = false, .FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x7E4, .ID = 0x7E4,
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Ack frame, correct PID is returned .data = {0x30, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Ack frame, correct PID is returned
static const int POLL_GROUP_1 = 0x0101;
static const int POLL_GROUP_2 = 0x0102;
static const int POLL_GROUP_3 = 0x0103;
static const int POLL_GROUP_4 = 0x0104;
static const int POLL_GROUP_5 = 0x0105;
static const int POLL_GROUP_6 = 0x0106;
static const int POLL_ECU_SERIAL = 0xF18C;
static const int POLL_ECU_VERSION = 0xF191;
}; };
#endif #endif

View file

@ -11,8 +11,16 @@ class KiaHyundai64HtmlRenderer : public BatteryHtmlRenderer {
String get_status_html() { String get_status_html() {
String content; String content;
auto print_hyundai = [&content](DATALAYER_INFO_KIAHYUNDAI64& data) { auto print_hyundai = [&content](DATALAYER_INFO_KIAHYUNDAI64& data) {
char readableSerialNumber[17]; // One extra space for null terminator
memcpy(readableSerialNumber, data.ecu_serial_number, sizeof(data.ecu_serial_number));
readableSerialNumber[16] = '\0'; // Null terminate the string
char readableVersionNumber[17]; // One extra space for null terminator
memcpy(readableVersionNumber, data.ecu_version_number, sizeof(data.ecu_version_number));
readableVersionNumber[16] = '\0'; // Null terminate the string
content += "<h4>BMS serial number: " + String(readableSerialNumber) + "</h4>";
content += "<h4>BMS software version: " + String(readableVersionNumber) + "</h4>";
content += "<h4>Cells: " + String(data.total_cell_count) + "S</h4>"; content += "<h4>Cells: " + String(data.total_cell_count) + "S</h4>";
content += "<h4>12V voltage: " + String(data.battery_12V / 10.0, 1) + "</h4>"; content += "<h4>12V voltage: " + String(data.battery_12V / 10.0, 1) + "</h4>";
content += "<h4>Waterleakage: " + String(data.waterleakageSensor) + "</h4>"; content += "<h4>Waterleakage: " + String(data.waterleakageSensor) + "</h4>";
@ -21,6 +29,7 @@ class KiaHyundai64HtmlRenderer : public BatteryHtmlRenderer {
content += "<h4>Batterymanagement mode: " + String(data.batteryManagementMode) + "</h4>"; content += "<h4>Batterymanagement mode: " + String(data.batteryManagementMode) + "</h4>";
content += "<h4>BMS ignition: " + String(data.BMS_ign) + "</h4>"; content += "<h4>BMS ignition: " + String(data.BMS_ign) + "</h4>";
content += "<h4>Battery relay: " + String(data.batteryRelay) + "</h4>"; content += "<h4>Battery relay: " + String(data.batteryRelay) + "</h4>";
content += "<h4>Inverter voltage: " + String(data.inverterVoltage) + "</h4>";
}; };
print_hyundai(*kia_datalayer); print_hyundai(*kia_datalayer);

View file

@ -351,6 +351,9 @@ typedef struct {
uint8_t batteryManagementMode = 0; uint8_t batteryManagementMode = 0;
uint8_t BMS_ign = 0; uint8_t BMS_ign = 0;
uint8_t batteryRelay = 0; uint8_t batteryRelay = 0;
uint16_t inverterVoltage = 0;
uint8_t ecu_serial_number[16] = {0};
uint8_t ecu_version_number[16] = {0};
} DATALAYER_INFO_KIAHYUNDAI64; } DATALAYER_INFO_KIAHYUNDAI64;
typedef struct { typedef struct {