mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 19:42:08 +02:00
Merge branch 'main' into feature/RELION-LV-protocol
This commit is contained in:
commit
dd21ff6ce1
26 changed files with 1926 additions and 629 deletions
|
@ -90,6 +90,8 @@ const char* name_for_battery_type(BatteryType type) {
|
|||
return KiaEGmpBattery::Name;
|
||||
case BatteryType::KiaHyundai64:
|
||||
return KiaHyundai64Battery::Name;
|
||||
case BatteryType::Kia64FD:
|
||||
return Kia64FDBattery::Name;
|
||||
case BatteryType::KiaHyundaiHybrid:
|
||||
return KiaHyundaiHybridBattery::Name;
|
||||
case BatteryType::Meb:
|
||||
|
@ -189,6 +191,8 @@ Battery* create_battery(BatteryType type) {
|
|||
return new ImievCZeroIonBattery();
|
||||
case BatteryType::JaguarIpace:
|
||||
return new JaguarIpaceBattery();
|
||||
case BatteryType::Kia64FD:
|
||||
return new Kia64FDBattery();
|
||||
case BatteryType::KiaEGmp:
|
||||
return new KiaEGmpBattery();
|
||||
case BatteryType::KiaHyundai64:
|
||||
|
|
|
@ -29,6 +29,7 @@ void setup_can_shunt();
|
|||
#include "HYUNDAI-IONIQ-28-BATTERY.h"
|
||||
#include "IMIEV-CZERO-ION-BATTERY.h"
|
||||
#include "JAGUAR-IPACE-BATTERY.h"
|
||||
#include "KIA-64FD-BATTERY.h"
|
||||
#include "KIA-E-GMP-BATTERY.h"
|
||||
#include "KIA-HYUNDAI-64-BATTERY.h"
|
||||
#include "KIA-HYUNDAI-HYBRID-BATTERY.h"
|
||||
|
|
|
@ -136,6 +136,16 @@ uint16_t estimateSOCstandard(uint16_t packVoltage) { // Linear interpolation fu
|
|||
return 0; // Default return for safety, should never reach here
|
||||
}
|
||||
|
||||
uint8_t compute441Checksum(const uint8_t* u8) // Computes the 441 checksum byte
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
sum += u8[i];
|
||||
}
|
||||
uint8_t lsb = static_cast<uint8_t>(sum & 0xFF);
|
||||
return static_cast<uint8_t>(~lsb & 0xFF);
|
||||
}
|
||||
|
||||
void BydAttoBattery::
|
||||
update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
|
||||
|
||||
|
@ -383,6 +393,7 @@ void BydAttoBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
|||
datalayer_battery->status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
battery_voltage = ((rx_frame.data.u8[1] & 0x0F) << 8) | rx_frame.data.u8[0];
|
||||
//battery_temperature_something = rx_frame.data.u8[7] - 40; resides in frame 7
|
||||
BMS_voltage_available = true;
|
||||
break;
|
||||
case 0x445:
|
||||
datalayer_battery->status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
|
@ -532,10 +543,17 @@ void BydAttoBattery::transmit_can(unsigned long currentMillis) {
|
|||
}
|
||||
|
||||
if (counter_100ms > 3) {
|
||||
ATTO_3_441.data.u8[4] = 0x9D;
|
||||
ATTO_3_441.data.u8[5] = 0x01;
|
||||
ATTO_3_441.data.u8[6] = 0xFF;
|
||||
ATTO_3_441.data.u8[7] = 0xF5;
|
||||
if (BMS_voltage_available) { // Transmit battery voltage back to BMS when confirmed it's available, this closes the contactors
|
||||
ATTO_3_441.data.u8[4] = (uint8_t)(battery_voltage - 1);
|
||||
ATTO_3_441.data.u8[5] = ((battery_voltage - 1) >> 8);
|
||||
ATTO_3_441.data.u8[6] = 0xFF;
|
||||
ATTO_3_441.data.u8[7] = compute441Checksum(ATTO_3_441.data.u8);
|
||||
} else {
|
||||
ATTO_3_441.data.u8[4] = 0x0C;
|
||||
ATTO_3_441.data.u8[5] = 0x00;
|
||||
ATTO_3_441.data.u8[6] = 0xFF;
|
||||
ATTO_3_441.data.u8[7] = 0x87;
|
||||
}
|
||||
}
|
||||
|
||||
transmit_can_frame(&ATTO_3_441);
|
||||
|
|
|
@ -98,6 +98,7 @@ class BydAttoBattery : public CanBattery {
|
|||
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
|
||||
unsigned long previousMillis200 = 0; // will store last time a 200ms CAN Message was send
|
||||
bool SOC_method = false;
|
||||
bool BMS_voltage_available = false;
|
||||
uint8_t counter_50ms = 0;
|
||||
uint8_t counter_100ms = 0;
|
||||
uint8_t frame6_counter = 0xB;
|
||||
|
|
|
@ -45,7 +45,8 @@ enum class BatteryType {
|
|||
MgHsPhev = 37,
|
||||
SamsungSdiLv = 38,
|
||||
HyundaiIoniq28 = 39,
|
||||
RelionBattery = 40,
|
||||
Kia64FD = 40,
|
||||
RelionBattery = 41,
|
||||
Highest
|
||||
};
|
||||
|
||||
|
|
423
Software/src/battery/KIA-64FD-BATTERY.cpp
Normal file
423
Software/src/battery/KIA-64FD-BATTERY.cpp
Normal file
|
@ -0,0 +1,423 @@
|
|||
#include "KIA-64FD-BATTERY.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
#include "../devboard/utils/logging.h"
|
||||
#include "../system_settings.h"
|
||||
|
||||
// Function to estimate SOC based on cell voltage
|
||||
uint16_t Kia64FDBattery::estimateSOCFromCell(uint16_t cellVoltage) {
|
||||
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]) {
|
||||
// Cast to float for proper 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
|
||||
}
|
||||
|
||||
// Simplified version of the pack-based SOC estimation with compensation
|
||||
uint16_t Kia64FDBattery::estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps) {
|
||||
|
||||
if (cellCount == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert pack voltage (decivolts) to millivolts
|
||||
uint32_t packVoltageMv = packVoltage * 100;
|
||||
|
||||
// Apply internal resistance compensation
|
||||
// Current is in deciamps (-150 = -15.0A, 150 = 15.0A)
|
||||
// Resistance is in milliohms
|
||||
int32_t voltageDrop = (currentAmps * PACK_INTERNAL_RESISTANCE_MOHM) / 10;
|
||||
|
||||
// Compensate the pack voltage (add the voltage drop)
|
||||
uint32_t compensatedPackVoltageMv = packVoltageMv + voltageDrop;
|
||||
|
||||
// Calculate average cell voltage in millivolts
|
||||
uint16_t avgCellVoltage = compensatedPackVoltageMv / cellCount;
|
||||
|
||||
// Use the cell voltage lookup table to estimate SOC
|
||||
return estimateSOCFromCell(avgCellVoltage);
|
||||
}
|
||||
|
||||
// Fix: Change parameter types to uint16_t to match SOC values
|
||||
uint16_t Kia64FDBattery::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
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
void write_cell_voltages(CAN_frame rx_frame, int start, int length, int startCell) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if ((rx_frame.data.u8[start + i] * 20) > 1000) {
|
||||
datalayer.battery.status.cell_voltages_mV[startCell + i] = (rx_frame.data.u8[start + i] * 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Kia64FDBattery::calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_value) {
|
||||
uint8_t crc = initial_value;
|
||||
for (uint8_t j = 1; j < length; j++) { //start at 1, since 0 is the CRC
|
||||
crc = crc8_table[(crc ^ static_cast<uint8_t>(rx_frame.data.u8[j])) % 256];
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
void Kia64FDBattery::update_values() {
|
||||
|
||||
#ifdef ESTIMATE_SOC_FROM_CELLVOLTAGE
|
||||
// Use the simplified pack-based SOC estimation with proper compensation
|
||||
datalayer.battery.status.real_soc = estimateSOC(batteryVoltage, datalayer.battery.info.number_of_cells, batteryAmps);
|
||||
|
||||
// For comparison or fallback, we can still calculate from min/max cell voltages
|
||||
SOC_estimated_lowest = estimateSOCFromCell(CellVoltMin_mV);
|
||||
SOC_estimated_highest = estimateSOCFromCell(CellVoltMax_mV);
|
||||
#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%
|
||||
|
||||
datalayer.battery.status.voltage_dV = batteryVoltage; //value is *10 (3700 = 370.0)
|
||||
|
||||
datalayer.battery.status.current_dA = -batteryAmps; //value is *10 (150 = 15.0)
|
||||
|
||||
datalayer.battery.status.remaining_capacity_Wh = static_cast<uint32_t>(
|
||||
(static_cast<double>(datalayer.battery.status.real_soc) / 10000) * datalayer.battery.info.total_capacity_Wh);
|
||||
|
||||
//datalayer.battery.status.max_charge_power_W = (uint16_t)allowedChargePower * 10; //From kW*100 to Watts
|
||||
//The allowed charge power is not available. We estimate this value for now
|
||||
if (datalayer.battery.status.real_soc > 9900) {
|
||||
datalayer.battery.status.max_charge_power_W = 0;
|
||||
} else if (datalayer.battery.status.real_soc >
|
||||
RAMPDOWN_SOC) { // When real SOC is between 90-99%, ramp the value between Max<->0
|
||||
datalayer.battery.status.max_charge_power_W =
|
||||
RAMPDOWNPOWERALLOWED * (1 - (datalayer.battery.status.real_soc - RAMPDOWN_SOC) / (10000.0 - RAMPDOWN_SOC));
|
||||
} else { // No limits, max charging power allowed
|
||||
datalayer.battery.status.max_charge_power_W = MAXCHARGEPOWERALLOWED;
|
||||
}
|
||||
|
||||
//datalayer.battery.status.max_discharge_power_W = (uint16_t)allowedDischargePower * 10; //From kW*100 to Watts
|
||||
//The allowed discharge power is not available. We hardcode this value for now
|
||||
datalayer.battery.status.max_discharge_power_W = MAXDISCHARGEPOWERALLOWED;
|
||||
|
||||
datalayer.battery.status.temperature_min_dC = (int8_t)temperatureMin * 10; //Increase decimals, 17C -> 17.0C
|
||||
|
||||
datalayer.battery.status.temperature_max_dC = (int8_t)temperatureMax * 10; //Increase decimals, 18C -> 18.0C
|
||||
|
||||
datalayer.battery.status.cell_max_voltage_mV = CellVoltMax_mV;
|
||||
|
||||
datalayer.battery.status.cell_min_voltage_mV = CellVoltMin_mV;
|
||||
|
||||
if (leadAcidBatteryVoltage < 110) {
|
||||
set_event(EVENT_12V_LOW, leadAcidBatteryVoltage);
|
||||
}
|
||||
}
|
||||
|
||||
void Kia64FDBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
||||
startedUp = true;
|
||||
switch (rx_frame.ID) {
|
||||
case 0x055:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x150:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x1F5:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x215:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x21A:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x235:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x245:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x25A:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x275:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x2FA:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x325:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x330:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x335:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x360:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x365:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x3BA:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x3F5:
|
||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||
break;
|
||||
case 0x7EC:
|
||||
// print_canfd_frame(frame);
|
||||
switch (rx_frame.data.u8[0]) {
|
||||
case 0x10: //"PID Header"
|
||||
// logging.println ("Send ack");
|
||||
poll_data_pid = rx_frame.data.u8[4];
|
||||
// if (rx_frame.data.u8[4] == poll_data_pid) {
|
||||
transmit_can_frame(&KIA64FD_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) {
|
||||
allowedChargePower = ((rx_frame.data.u8[3] << 8) + rx_frame.data.u8[4]);
|
||||
allowedDischargePower = ((rx_frame.data.u8[5] << 8) + rx_frame.data.u8[6]);
|
||||
SOC_BMS = rx_frame.data.u8[2] * 5; //100% = 200 ( 200 * 5 = 1000 )
|
||||
|
||||
} else if (poll_data_pid == 2) {
|
||||
// set cell voltages data, start bite, data length from start, start cell
|
||||
write_cell_voltages(rx_frame, 2, 6, 0);
|
||||
} else if (poll_data_pid == 3) {
|
||||
write_cell_voltages(rx_frame, 2, 6, 32);
|
||||
} else if (poll_data_pid == 4) {
|
||||
write_cell_voltages(rx_frame, 2, 6, 64);
|
||||
} else if (poll_data_pid == 0x0A) {
|
||||
write_cell_voltages(rx_frame, 2, 6, 96);
|
||||
} else if (poll_data_pid == 0x0B) {
|
||||
write_cell_voltages(rx_frame, 2, 6, 128);
|
||||
} else if (poll_data_pid == 0x0C) {
|
||||
write_cell_voltages(rx_frame, 2, 6, 160);
|
||||
}
|
||||
break;
|
||||
case 0x22: //Second datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
batteryVoltage = (rx_frame.data.u8[3] << 8) + rx_frame.data.u8[4];
|
||||
batteryAmps = (rx_frame.data.u8[1] << 8) + rx_frame.data.u8[2];
|
||||
temperatureMax = rx_frame.data.u8[5];
|
||||
temperatureMin = rx_frame.data.u8[6];
|
||||
// temp1 = rx_frame.data.u8[7];
|
||||
} else if (poll_data_pid == 2) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 6);
|
||||
} else if (poll_data_pid == 3) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 38);
|
||||
} else if (poll_data_pid == 4) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 70);
|
||||
} else if (poll_data_pid == 0x0A) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 102);
|
||||
} else if (poll_data_pid == 0x0B) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 134);
|
||||
} else if (poll_data_pid == 0x0C) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 166);
|
||||
} else if (poll_data_pid == 6) {
|
||||
batteryManagementMode = rx_frame.data.u8[5];
|
||||
}
|
||||
break;
|
||||
case 0x23: //Third datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
temperature_water_inlet = rx_frame.data.u8[6];
|
||||
CellVoltMax_mV = (rx_frame.data.u8[7] * 20); //(volts *50) *20 =mV
|
||||
// temp2 = rx_frame.data.u8[1];
|
||||
// temp3 = rx_frame.data.u8[2];
|
||||
// temp4 = rx_frame.data.u8[3];
|
||||
} else if (poll_data_pid == 2) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 13);
|
||||
} else if (poll_data_pid == 3) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 45);
|
||||
} else if (poll_data_pid == 4) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 77);
|
||||
} else if (poll_data_pid == 0x0A) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 109);
|
||||
} else if (poll_data_pid == 0x0B) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 141);
|
||||
} else if (poll_data_pid == 0x0C) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 173);
|
||||
} else if (poll_data_pid == 5) {
|
||||
// ac = rx_frame.data.u8[3];
|
||||
// Vdiff = rx_frame.data.u8[4];
|
||||
|
||||
// airbag = rx_frame.data.u8[6];
|
||||
heatertemp = rx_frame.data.u8[7];
|
||||
}
|
||||
break;
|
||||
case 0x24: //Fourth datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
CellVmaxNo = rx_frame.data.u8[1];
|
||||
CellVoltMin_mV = (rx_frame.data.u8[2] * 20); //(volts *50) *20 =mV
|
||||
CellVminNo = rx_frame.data.u8[3];
|
||||
// fanMod = rx_frame.data.u8[4];
|
||||
// fanSpeed = rx_frame.data.u8[5];
|
||||
leadAcidBatteryVoltage = rx_frame.data.u8[6]; //12v Battery Volts
|
||||
//cumulative_charge_current[0] = rx_frame.data.u8[7];
|
||||
} else if (poll_data_pid == 2) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 20);
|
||||
} else if (poll_data_pid == 3) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 52);
|
||||
} else if (poll_data_pid == 4) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 84);
|
||||
} else if (poll_data_pid == 0x0A) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 116);
|
||||
} else if (poll_data_pid == 0x0B) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 148);
|
||||
} else if (poll_data_pid == 0x0C) {
|
||||
write_cell_voltages(rx_frame, 1, 7, 180);
|
||||
} else if (poll_data_pid == 5) {
|
||||
batterySOH = ((rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3]);
|
||||
// maxDetCell = rx_frame.data.u8[4];
|
||||
// minDet = (rx_frame.data.u8[5] << 8) + rx_frame.data.u8[6];
|
||||
// minDetCell = rx_frame.data.u8[7];
|
||||
}
|
||||
break;
|
||||
case 0x25: //Fifth datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
//cumulative_charge_current[1] = rx_frame.data.u8[1];
|
||||
//cumulative_charge_current[2] = rx_frame.data.u8[2];
|
||||
//cumulative_charge_current[3] = rx_frame.data.u8[3];
|
||||
//cumulative_discharge_current[0] = rx_frame.data.u8[4];
|
||||
//cumulative_discharge_current[1] = rx_frame.data.u8[5];
|
||||
//cumulative_discharge_current[2] = rx_frame.data.u8[6];
|
||||
//cumulative_discharge_current[3] = rx_frame.data.u8[7];
|
||||
//set_cumulative_charge_current();
|
||||
//set_cumulative_discharge_current();
|
||||
} else if (poll_data_pid == 2) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 27);
|
||||
} else if (poll_data_pid == 3) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 59);
|
||||
} else if (poll_data_pid == 4) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 91);
|
||||
} else if (poll_data_pid == 0x0A) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 123);
|
||||
} else if (poll_data_pid == 0x0B) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 155);
|
||||
} else if (poll_data_pid == 0x0C) {
|
||||
write_cell_voltages(rx_frame, 1, 5, 187);
|
||||
//set_cell_count();
|
||||
} else if (poll_data_pid == 5) {
|
||||
// datalayer.battery.info.number_of_cells = 98;
|
||||
SOC_Display = rx_frame.data.u8[1] * 5;
|
||||
}
|
||||
break;
|
||||
case 0x26: //Sixth datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
//cumulative_energy_charged[0] = rx_frame.data.u8[1];
|
||||
// cumulative_energy_charged[1] = rx_frame.data.u8[2];
|
||||
//cumulative_energy_charged[2] = rx_frame.data.u8[3];
|
||||
//cumulative_energy_charged[3] = rx_frame.data.u8[4];
|
||||
//cumulative_energy_discharged[0] = rx_frame.data.u8[5];
|
||||
//cumulative_energy_discharged[1] = rx_frame.data.u8[6];
|
||||
//cumulative_energy_discharged[2] = rx_frame.data.u8[7];
|
||||
// set_cumulative_energy_charged();
|
||||
}
|
||||
break;
|
||||
case 0x27: //Seventh datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
//cumulative_energy_discharged[3] = rx_frame.data.u8[1];
|
||||
|
||||
//opTimeBytes[0] = rx_frame.data.u8[2];
|
||||
//opTimeBytes[1] = rx_frame.data.u8[3];
|
||||
//opTimeBytes[2] = rx_frame.data.u8[4];
|
||||
//opTimeBytes[3] = rx_frame.data.u8[5];
|
||||
|
||||
BMS_ign = rx_frame.data.u8[6];
|
||||
inverterVoltageFrameHigh = rx_frame.data.u8[7]; // BMS Capacitoir
|
||||
|
||||
// set_cumulative_energy_discharged();
|
||||
// set_opTime();
|
||||
}
|
||||
break;
|
||||
case 0x28: //Eighth datarow in PID group
|
||||
if (poll_data_pid == 1) {
|
||||
inverterVoltage = (inverterVoltageFrameHigh << 8) + rx_frame.data.u8[1]; // BMS Capacitoir
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Kia64FDBattery::transmit_can(unsigned long currentMillis) {
|
||||
if (startedUp) {
|
||||
//Send Contactor closing message loop
|
||||
// Check if we still have messages to send
|
||||
if (messageIndex < sizeof(messageDelays) / sizeof(messageDelays[0])) {
|
||||
|
||||
// Check if it's time to send the next message
|
||||
if (currentMillis - startMillis >= messageDelays[messageIndex]) {
|
||||
|
||||
// Transmit the current message
|
||||
transmit_can_frame(messages[messageIndex]);
|
||||
|
||||
// Move to the next message
|
||||
messageIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (messageIndex >= 63) {
|
||||
startMillis = currentMillis; // Start over!
|
||||
messageIndex = 0;
|
||||
}
|
||||
|
||||
//Send 200ms CANFD message
|
||||
if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) {
|
||||
previousMillis200ms = currentMillis;
|
||||
|
||||
KIA64FD_7E4.data.u8[3] = KIA_7E4_COUNTER;
|
||||
|
||||
if (ok_start_polling_battery) {
|
||||
transmit_can_frame(&KIA64FD_7E4);
|
||||
}
|
||||
|
||||
KIA_7E4_COUNTER++;
|
||||
if (KIA_7E4_COUNTER > 0x0D) { // gets up to 0x010C before repeating
|
||||
KIA_7E4_COUNTER = 0x01;
|
||||
}
|
||||
}
|
||||
//Send 10s CANFD message
|
||||
if (currentMillis - previousMillis10s >= INTERVAL_10_S) {
|
||||
previousMillis10s = currentMillis;
|
||||
|
||||
ok_start_polling_battery = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Kia64FDBattery::setup(void) { // Performs one time setup at startup
|
||||
strncpy(datalayer.system.info.battery_protocol, Name, 63);
|
||||
datalayer.system.info.battery_protocol[63] = '\0';
|
||||
datalayer.system.status.battery_allows_contactor_closing = true;
|
||||
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;
|
||||
datalayer.battery.info.min_cell_voltage_mV = MIN_CELL_VOLTAGE_MV;
|
||||
datalayer.battery.info.max_cell_voltage_deviation_mV = MAX_CELL_DEVIATION_MV;
|
||||
}
|
635
Software/src/battery/KIA-64FD-BATTERY.h
Normal file
635
Software/src/battery/KIA-64FD-BATTERY.h
Normal file
|
@ -0,0 +1,635 @@
|
|||
#ifndef KIA_64_FD_BATTERY_H
|
||||
#define KIA_64_FD_BATTERY_H
|
||||
#include <Arduino.h>
|
||||
#include "CanBattery.h"
|
||||
|
||||
#define ESTIMATE_SOC_FROM_CELLVOLTAGE
|
||||
|
||||
#ifdef KIA_HYUNDAI_64_FD_BATTERY
|
||||
#define SELECTED_BATTERY_CLASS Kia64FDBattery
|
||||
#endif
|
||||
|
||||
class Kia64FDBattery : public CanBattery {
|
||||
public:
|
||||
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);
|
||||
static constexpr const char* Name = "Kia 64kWh FD battery";
|
||||
|
||||
private:
|
||||
uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps);
|
||||
uint16_t estimateSOCFromCell(uint16_t cellVoltage);
|
||||
uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_value);
|
||||
uint16_t selectSOC(uint16_t SOC_low, uint16_t SOC_high);
|
||||
|
||||
static const int MAX_PACK_VOLTAGE_DV = 4032; //5000 = 500.0V
|
||||
static const int MIN_PACK_VOLTAGE_DV = 2400;
|
||||
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 = 0;
|
||||
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;
|
||||
bool startedUp = false;
|
||||
bool ok_start_polling_battery = false;
|
||||
uint8_t KIA_7E4_COUNTER = 0x01;
|
||||
int8_t temperature_water_inlet = 0;
|
||||
int8_t heatertemp = 0;
|
||||
unsigned long startMillis = 0;
|
||||
uint8_t messageIndex = 0;
|
||||
|
||||
const unsigned char crc8_table[256] = {
|
||||
// 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, 0xF7,
|
||||
0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE,
|
||||
0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2,
|
||||
0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC,
|
||||
0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78,
|
||||
0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44,
|
||||
0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, 0x52,
|
||||
0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
|
||||
0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73,
|
||||
0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED,
|
||||
0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8,
|
||||
0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95,
|
||||
0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31,
|
||||
0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4};
|
||||
|
||||
// Define the data points for %SOC depending on cell voltage
|
||||
const uint8_t numPoints = 100;
|
||||
|
||||
const uint16_t SOC[101] = {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[101] = {
|
||||
4200, 4173, 4148, 4124, 4102, 4080, 4060, 4041, 4023, 4007, 3993, 3980, 3969, 3959, 3953, 3950, 3941,
|
||||
3932, 3924, 3915, 3907, 3898, 3890, 3881, 3872, 3864, 3855, 3847, 3838, 3830, 3821, 3812, 3804, 3795,
|
||||
3787, 3778, 3770, 3761, 3752, 3744, 3735, 3727, 3718, 3710, 3701, 3692, 3684, 3675, 3667, 3658, 3650,
|
||||
3641, 3632, 3624, 3615, 3607, 3598, 3590, 3581, 3572, 3564, 3555, 3547, 3538, 3530, 3521, 3512, 3504,
|
||||
3495, 3487, 3478, 3470, 3461, 3452, 3444, 3435, 3427, 3418, 3410, 3401, 3392, 3384, 3375, 3367, 3358,
|
||||
3350, 3338, 3325, 3313, 3299, 3285, 3271, 3255, 3239, 3221, 3202, 3180, 3156, 3127, 3090, 3000};
|
||||
/* These messages are needed for contactor closing */
|
||||
uint8_t messageDelays[63] = {0, 0, 5, 10, 10, 15, 19, 19, 20, 20, 25, 30, 30, 35, 40, 40,
|
||||
45, 49, 49, 50, 50, 52, 53, 53, 54, 55, 60, 60, 65, 67, 67, 70,
|
||||
70, 75, 77, 77, 80, 80, 85, 90, 90, 95, 100, 100, 105, 110, 110, 115,
|
||||
119, 119, 120, 120, 125, 130, 130, 135, 140, 140, 145, 149, 149, 150, 150};
|
||||
static constexpr CAN_frame message_1 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x62, 0x36, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_2 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd4, 0x1b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_3 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x24, 0x9b, 0x7b, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_4 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x24, 0x6f, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_5 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x92, 0x42, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_6 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xd7, 0x05, 0x7c, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_7 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xb1, 0xe0, 0x26, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x18, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
|
||||
static constexpr CAN_frame message_8 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0xc6, 0xab, 0x26, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_9 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xee, 0x84, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_10 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x58, 0xa9, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_11 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x91, 0x5c, 0x7d, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_12 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xa8, 0xdd, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_13 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1e, 0xf0, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_14 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5b, 0xb7, 0x7e, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_15 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xec, 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_16 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x5a, 0x40, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_17 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x1d, 0xee, 0x7f, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_18 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xbd, 0xb2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_19 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0xc1, 0xf2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_20 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xaa, 0x34, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_21 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1c, 0x19, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_22 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2D5,
|
||||
.data = {0x79, 0xfb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_23 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2EA,
|
||||
.data = {0x6e, 0xbb, 0xa0, 0x0d, 0x04, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_24 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x306,
|
||||
.data = {0x00, 0x00, 0x00, 0xd2, 0x06, 0x92, 0x05, 0x34, 0x07, 0x8e, 0x08, 0x73, 0x05, 0x80, 0x05, 0x83,
|
||||
0x05, 0x73, 0x05, 0x80, 0x05, 0xed, 0x01, 0xdd, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_25 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x308,
|
||||
.data = {0xbe, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x75, 0x6c, 0x86, 0x0d, 0xfb, 0xdf, 0x03, 0x36, 0xc3, 0x86, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_26 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x6b, 0xa2, 0x80, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_27 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x60, 0xdf, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_28 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd6, 0xf2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_29 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x2d, 0xfb, 0x81, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_30 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x33A,
|
||||
.data = {0x1a, 0x23, 0x26, 0x10, 0x27, 0x4f, 0x06, 0x00, 0xf8, 0x1b, 0x19, 0x04, 0x30, 0x01, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x2e, 0x2d, 0x81, 0x25, 0x20, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_31 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x350,
|
||||
.data = {0x26, 0x82, 0x26, 0xf4, 0x01, 0x00, 0x00, 0x50, 0x90, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_32 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x26, 0x86, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_33 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x90, 0xab, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_34 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xe7, 0x10, 0x82, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_35 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E5,
|
||||
.data = {0x69, 0x8a, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_36 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x3B5,
|
||||
.data = {0xa3, 0xc8, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_37 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd5, 0x18, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_38 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x63, 0x35, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_39 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xa1, 0x49, 0x83, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_40 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x93, 0x41, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_41 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x25, 0x6c, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_42 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x52, 0xd7, 0x84, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_43 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x59, 0xaa, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_44 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xef, 0x87, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_45 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x14, 0x8e, 0x85, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_46 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x1f, 0xf3, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_47 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa9, 0xde, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_48 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xde, 0x65, 0x86, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_49 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xd3, 0x11, 0x27, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x19, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
|
||||
static constexpr CAN_frame message_50 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0x80, 0xf2, 0x27, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_51 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x9e, 0x87, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_52 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x28, 0xaa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_53 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x98, 0x3c, 0x87, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_54 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd8, 0xde, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_55 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x6e, 0xf3, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_56 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x19, 0x48, 0x88, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_57 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x12, 0x35, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_58 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa4, 0x18, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_59 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5f, 0x11, 0x89, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_60 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xfb, 0xeb, 0x43, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_61 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2C0,
|
||||
.data = {0xcc, 0xcd, 0xa2, 0x21, 0x00, 0xa1, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_62 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0x87, 0xab, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_63 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x54, 0x6c, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
const CAN_frame* messages[64] = {
|
||||
&message_1, &message_2, &message_3, &message_4, &message_5, &message_6, &message_7, &message_8,
|
||||
&message_9, &message_10, &message_11, &message_12, &message_13, &message_14, &message_15, &message_16,
|
||||
&message_17, &message_18, &message_19, &message_20, &message_21, &message_22, &message_23, &message_24,
|
||||
&message_25, &message_26, &message_27, &message_28, &message_29, &message_30, &message_31, &message_32,
|
||||
&message_33, &message_34, &message_35, &message_36, &message_37, &message_38, &message_39, &message_40,
|
||||
&message_41, &message_42, &message_43, &message_44, &message_45, &message_46, &message_47, &message_48,
|
||||
&message_49, &message_50, &message_51, &message_52, &message_53, &message_54, &message_55, &message_56,
|
||||
&message_57, &message_58, &message_59, &message_60, &message_61, &message_62, &message_63};
|
||||
|
||||
/* PID polling messages */
|
||||
CAN_frame KIA64FD_7E4 = {.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x03, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 01
|
||||
CAN_frame KIA64FD_ack = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Ack frame, correct PID is returned
|
||||
};
|
||||
|
||||
#endif
|
|
@ -6,45 +6,8 @@
|
|||
#include "../devboard/utils/logging.h"
|
||||
#include "../system_settings.h"
|
||||
|
||||
const unsigned char crc8_table[256] =
|
||||
{ // 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,
|
||||
0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0,
|
||||
0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23,
|
||||
0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
|
||||
0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B,
|
||||
0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B,
|
||||
0x08, 0x15, 0x32, 0x2F, 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8,
|
||||
0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
|
||||
0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC,
|
||||
0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B,
|
||||
0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C,
|
||||
0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
|
||||
0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47,
|
||||
0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0,
|
||||
0xE3, 0xFE, 0xD9, 0xC4};
|
||||
|
||||
// Define the data points for %SOC depending on cell voltage
|
||||
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, 4173, 4148, 4124, 4102, 4080, 4060, 4041, 4023, 4007, 3993, 3980, 3969, 3959, 3953,
|
||||
3950, 3941, 3932, 3924, 3915, 3907, 3898, 3890, 3881, 3872, 3864, 3855, 3847, 3838, 3830,
|
||||
3821, 3812, 3804, 3795, 3787, 3778, 3770, 3761, 3752, 3744, 3735, 3727, 3718, 3710, 3701,
|
||||
3692, 3684, 3675, 3667, 3658, 3650, 3641, 3632, 3624, 3615, 3607, 3598, 3590, 3581, 3572,
|
||||
3564, 3555, 3547, 3538, 3530, 3521, 3512, 3504, 3495, 3487, 3478, 3470, 3461, 3452, 3444,
|
||||
3435, 3427, 3418, 3410, 3401, 3392, 3384, 3375, 3367, 3358, 3350, 3338, 3325, 3313, 3299,
|
||||
3285, 3271, 3255, 3239, 3221, 3202, 3180, 3156, 3127, 3090, 3000};
|
||||
|
||||
// Function to estimate SOC based on cell voltage
|
||||
uint16_t estimateSOCFromCell(uint16_t cellVoltage) {
|
||||
uint16_t KiaEGmpBattery::estimateSOCFromCell(uint16_t cellVoltage) {
|
||||
if (cellVoltage >= voltage[0]) {
|
||||
return SOC[0];
|
||||
}
|
||||
|
@ -111,7 +74,7 @@ uint16_t KiaEGmpBattery::estimateSOC(uint16_t packVoltage, uint16_t cellCount, i
|
|||
}
|
||||
|
||||
// Fix: Change parameter types to uint16_t to match SOC values
|
||||
uint16_t selectSOC(uint16_t SOC_low, uint16_t SOC_high) {
|
||||
uint16_t KiaEGmpBattery::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
|
||||
}
|
||||
|
@ -121,534 +84,7 @@ uint16_t selectSOC(uint16_t SOC_low, uint16_t SOC_high) {
|
|||
return (SOC_low < SOC_high) ? SOC_low : SOC_high; // Otherwise, return the lowest value
|
||||
}
|
||||
|
||||
/* These messages are needed for contactor closing */
|
||||
unsigned long startMillis = 0;
|
||||
uint8_t messageIndex = 0;
|
||||
uint8_t messageDelays[63] = {0, 0, 5, 10, 10, 15, 19, 19, 20, 20, 25, 30, 30, 35, 40, 40,
|
||||
45, 49, 49, 50, 50, 52, 53, 53, 54, 55, 60, 60, 65, 67, 67, 70,
|
||||
70, 75, 77, 77, 80, 80, 85, 90, 90, 95, 100, 100, 105, 110, 110, 115,
|
||||
119, 119, 120, 120, 125, 130, 130, 135, 140, 140, 145, 149, 149, 150, 150};
|
||||
static constexpr CAN_frame message_1 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x62, 0x36, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_2 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd4, 0x1b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_3 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x24, 0x9b, 0x7b, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_4 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x24, 0x6f, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_5 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x92, 0x42, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_6 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xd7, 0x05, 0x7c, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_7 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xb1, 0xe0, 0x26, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x18, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
|
||||
static constexpr CAN_frame message_8 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0xc6, 0xab, 0x26, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_9 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xee, 0x84, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_10 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x58, 0xa9, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_11 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x91, 0x5c, 0x7d, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_12 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xa8, 0xdd, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_13 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1e, 0xf0, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_14 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5b, 0xb7, 0x7e, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_15 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xec, 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_16 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x5a, 0x40, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_17 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x1d, 0xee, 0x7f, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_18 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xbd, 0xb2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_19 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0xc1, 0xf2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_20 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xaa, 0x34, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_21 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1c, 0x19, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_22 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2D5,
|
||||
.data = {0x79, 0xfb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_23 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2EA,
|
||||
.data = {0x6e, 0xbb, 0xa0, 0x0d, 0x04, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_24 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x306,
|
||||
.data = {0x00, 0x00, 0x00, 0xd2, 0x06, 0x92, 0x05, 0x34, 0x07, 0x8e, 0x08, 0x73, 0x05, 0x80, 0x05, 0x83,
|
||||
0x05, 0x73, 0x05, 0x80, 0x05, 0xed, 0x01, 0xdd, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_25 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x308,
|
||||
.data = {0xbe, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x75, 0x6c, 0x86, 0x0d, 0xfb, 0xdf, 0x03, 0x36, 0xc3, 0x86, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_26 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x6b, 0xa2, 0x80, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_27 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x60, 0xdf, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_28 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd6, 0xf2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_29 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x2d, 0xfb, 0x81, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_30 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x33A,
|
||||
.data = {0x1a, 0x23, 0x26, 0x10, 0x27, 0x4f, 0x06, 0x00, 0xf8, 0x1b, 0x19, 0x04, 0x30, 0x01, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x2e, 0x2d, 0x81, 0x25, 0x20, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_31 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x350,
|
||||
.data = {0x26, 0x82, 0x26, 0xf4, 0x01, 0x00, 0x00, 0x50, 0x90, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_32 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x26, 0x86, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_33 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x90, 0xab, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_34 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xe7, 0x10, 0x82, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_35 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E5,
|
||||
.data = {0x69, 0x8a, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_36 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x3B5,
|
||||
.data = {0xa3, 0xc8, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_37 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd5, 0x18, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_38 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x63, 0x35, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_39 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xa1, 0x49, 0x83, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_40 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x93, 0x41, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_41 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x25, 0x6c, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_42 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x52, 0xd7, 0x84, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_43 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x59, 0xaa, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_44 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xef, 0x87, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_45 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x14, 0x8e, 0x85, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_46 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x1f, 0xf3, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_47 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa9, 0xde, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_48 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xde, 0x65, 0x86, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_49 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xd3, 0x11, 0x27, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x19, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
|
||||
static constexpr CAN_frame message_50 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0x80, 0xf2, 0x27, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_51 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x9e, 0x87, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_52 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x28, 0xaa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_53 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x98, 0x3c, 0x87, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_54 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd8, 0xde, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_55 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x6e, 0xf3, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_56 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x19, 0x48, 0x88, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_57 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x12, 0x35, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_58 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa4, 0x18, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_59 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5f, 0x11, 0x89, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_60 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xfb, 0xeb, 0x43, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_61 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2C0,
|
||||
.data = {0xcc, 0xcd, 0xa2, 0x21, 0x00, 0xa1, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_62 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0x87, 0xab, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
static constexpr CAN_frame message_63 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x54, 0x6c, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static const CAN_frame* messages[] = {
|
||||
&message_1, &message_2, &message_3, &message_4, &message_5, &message_6, &message_7, &message_8,
|
||||
&message_9, &message_10, &message_11, &message_12, &message_13, &message_14, &message_15, &message_16,
|
||||
&message_17, &message_18, &message_19, &message_20, &message_21, &message_22, &message_23, &message_24,
|
||||
&message_25, &message_26, &message_27, &message_28, &message_29, &message_30, &message_31, &message_32,
|
||||
&message_33, &message_34, &message_35, &message_36, &message_37, &message_38, &message_39, &message_40,
|
||||
&message_41, &message_42, &message_43, &message_44, &message_45, &message_46, &message_47, &message_48,
|
||||
&message_49, &message_50, &message_51, &message_52, &message_53, &message_54, &message_55, &message_56,
|
||||
&message_57, &message_58, &message_59, &message_60, &message_61, &message_62, &message_63};
|
||||
/* PID polling messages */
|
||||
CAN_frame EGMP_7E4 = {.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x03, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 01
|
||||
static constexpr CAN_frame EGMP_7E4_ack = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Ack frame, correct PID is returned
|
||||
|
||||
void set_cell_voltages(CAN_frame rx_frame, int start, int length, int startCell) {
|
||||
void KiaEGmpBattery::set_cell_voltages(CAN_frame rx_frame, int start, int length, int startCell) {
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if ((rx_frame.data.u8[start + i] * 20) > 1000) {
|
||||
datalayer.battery.status.cell_voltages_mV[startCell + i] = (rx_frame.data.u8[start + i] * 20);
|
||||
|
@ -682,7 +118,7 @@ void KiaEGmpBattery::set_voltage_minmax_limits() {
|
|||
}
|
||||
}
|
||||
|
||||
static uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_value) {
|
||||
uint8_t KiaEGmpBattery::calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_value) {
|
||||
uint8_t crc = initial_value;
|
||||
for (uint8_t j = 1; j < length; j++) { //start at 1, since 0 is the CRC
|
||||
crc = crc8_table[(crc ^ static_cast<uint8_t>(rx_frame.data.u8[j])) % 256];
|
||||
|
@ -690,8 +126,7 @@ static uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_
|
|||
return crc;
|
||||
}
|
||||
|
||||
void KiaEGmpBattery::
|
||||
update_values() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
|
||||
void KiaEGmpBattery::update_values() {
|
||||
|
||||
#ifdef ESTIMATE_SOC_FROM_CELLVOLTAGE
|
||||
// Use the simplified pack-based SOC estimation with proper compensation
|
||||
|
|
|
@ -30,6 +30,10 @@ class KiaEGmpBattery : public CanBattery {
|
|||
private:
|
||||
KiaEGMPHtmlRenderer renderer;
|
||||
uint16_t estimateSOC(uint16_t packVoltage, uint16_t cellCount, int16_t currentAmps);
|
||||
uint16_t selectSOC(uint16_t SOC_low, uint16_t SOC_high);
|
||||
uint16_t estimateSOCFromCell(uint16_t cellVoltage);
|
||||
uint8_t calculateCRC(CAN_frame rx_frame, uint8_t length, uint8_t initial_value);
|
||||
void set_cell_voltages(CAN_frame rx_frame, int start, int length, int startCell);
|
||||
void set_voltage_minmax_limits();
|
||||
|
||||
static const int MAX_PACK_VOLTAGE_DV = 8064; //5000 = 500.0V
|
||||
|
@ -81,9 +85,510 @@ class KiaEGmpBattery : public CanBattery {
|
|||
int8_t powerRelayTemperature = 10;
|
||||
int8_t heatertemp = 20;
|
||||
bool set_voltage_limits = false;
|
||||
uint8_t ticks_200ms_counter = 0;
|
||||
uint8_t EGMP_1CF_counter = 0;
|
||||
uint8_t EGMP_3XF_counter = 0;
|
||||
|
||||
const unsigned char crc8_table[256] = {
|
||||
// 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, 0xF7,
|
||||
0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE,
|
||||
0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2,
|
||||
0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC,
|
||||
0x8F, 0x92, 0xB5, 0xA8, 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78,
|
||||
0x65, 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, 0x59, 0x44,
|
||||
0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, 0x26, 0x3B, 0x1C, 0x01, 0x52,
|
||||
0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
|
||||
0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73,
|
||||
0x6E, 0x3D, 0x20, 0x07, 0x1A, 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED,
|
||||
0xCA, 0xD7, 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, 0xF8,
|
||||
0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, 0xB2, 0xAF, 0x88, 0x95,
|
||||
0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31,
|
||||
0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4};
|
||||
// Define the data points for %SOC depending on cell voltage
|
||||
const uint8_t numPoints = 100;
|
||||
|
||||
const uint16_t SOC[101] = {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[101] = {
|
||||
4200, 4173, 4148, 4124, 4102, 4080, 4060, 4041, 4023, 4007, 3993, 3980, 3969, 3959, 3953, 3950, 3941,
|
||||
3932, 3924, 3915, 3907, 3898, 3890, 3881, 3872, 3864, 3855, 3847, 3838, 3830, 3821, 3812, 3804, 3795,
|
||||
3787, 3778, 3770, 3761, 3752, 3744, 3735, 3727, 3718, 3710, 3701, 3692, 3684, 3675, 3667, 3658, 3650,
|
||||
3641, 3632, 3624, 3615, 3607, 3598, 3590, 3581, 3572, 3564, 3555, 3547, 3538, 3530, 3521, 3512, 3504,
|
||||
3495, 3487, 3478, 3470, 3461, 3452, 3444, 3435, 3427, 3418, 3410, 3401, 3392, 3384, 3375, 3367, 3358,
|
||||
3350, 3338, 3325, 3313, 3299, 3285, 3271, 3255, 3239, 3221, 3202, 3180, 3156, 3127, 3090, 3000};
|
||||
/* These messages are needed for contactor closing */
|
||||
unsigned long startMillis = 0;
|
||||
uint8_t messageIndex = 0;
|
||||
uint8_t messageDelays[63] = {0, 0, 5, 10, 10, 15, 19, 19, 20, 20, 25, 30, 30, 35, 40, 40,
|
||||
45, 49, 49, 50, 50, 52, 53, 53, 54, 55, 60, 60, 65, 67, 67, 70,
|
||||
70, 75, 77, 77, 80, 80, 85, 90, 90, 95, 100, 100, 105, 110, 110, 115,
|
||||
119, 119, 120, 120, 125, 130, 130, 135, 140, 140, 145, 149, 149, 150, 150};
|
||||
static constexpr CAN_frame message_1 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x62, 0x36, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_2 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd4, 0x1b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_3 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x24, 0x9b, 0x7b, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_4 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x24, 0x6f, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_5 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x92, 0x42, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_6 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xd7, 0x05, 0x7c, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_7 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xb1, 0xe0, 0x26, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x18, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
static constexpr CAN_frame message_8 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0xc6, 0xab, 0x26, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_9 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xee, 0x84, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_10 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x58, 0xa9, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_11 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x91, 0x5c, 0x7d, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_12 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xa8, 0xdd, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_13 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1e, 0xf0, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_14 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5b, 0xb7, 0x7e, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_15 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xec, 0x6d, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_16 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x5a, 0x40, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_17 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x1d, 0xee, 0x7f, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_18 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xbd, 0xb2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_19 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0xc1, 0xf2, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_20 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xaa, 0x34, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_21 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x1c, 0x19, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_22 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2D5,
|
||||
.data = {0x79, 0xfb, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_23 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2EA,
|
||||
.data = {0x6e, 0xbb, 0xa0, 0x0d, 0x04, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_24 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x306,
|
||||
.data = {0x00, 0x00, 0x00, 0xd2, 0x06, 0x92, 0x05, 0x34, 0x07, 0x8e, 0x08, 0x73, 0x05, 0x80, 0x05, 0x83,
|
||||
0x05, 0x73, 0x05, 0x80, 0x05, 0xed, 0x01, 0xdd, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_25 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x308,
|
||||
.data = {0xbe, 0x84, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x75, 0x6c, 0x86, 0x0d, 0xfb, 0xdf, 0x03, 0x36, 0xc3, 0x86, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_26 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x6b, 0xa2, 0x80, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_27 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x60, 0xdf, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_28 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xd6, 0xf2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_29 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x2d, 0xfb, 0x81, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_30 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x33A,
|
||||
.data = {0x1a, 0x23, 0x26, 0x10, 0x27, 0x4f, 0x06, 0x00, 0xf8, 0x1b, 0x19, 0x04, 0x30, 0x01, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x2e, 0x2d, 0x81, 0x25, 0x20, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_31 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x350,
|
||||
.data = {0x26, 0x82, 0x26, 0xf4, 0x01, 0x00, 0x00, 0x50, 0x90, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_32 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x26, 0x86, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_33 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x90, 0xab, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_34 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xe7, 0x10, 0x82, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_35 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E5,
|
||||
.data = {0x69, 0x8a, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_36 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x3B5,
|
||||
.data = {0xa3, 0xc8, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_37 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd5, 0x18, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_38 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x63, 0x35, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_39 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xa1, 0x49, 0x83, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_40 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x93, 0x41, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_41 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x25, 0x6c, 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_42 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x52, 0xd7, 0x84, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_43 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x59, 0xaa, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_44 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xef, 0x87, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_45 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x14, 0x8e, 0x85, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_46 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x1f, 0xf3, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_47 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa9, 0xde, 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_48 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0xde, 0x65, 0x86, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_49 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x30A,
|
||||
.data = {0xd3, 0x11, 0x27, 0x08, 0x54, 0x01, 0x04, 0x15, 0x00, 0x1a, 0x76, 0x00, 0x25, 0x01, 0x10, 0x27,
|
||||
0x4f, 0x06, 0x19, 0x04, 0x33, 0x15, 0x34, 0x28, 0x00, 0x00, 0x10, 0x06, 0x21, 0x00, 0x4b, 0x06}};
|
||||
static constexpr CAN_frame message_50 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x320,
|
||||
.data = {0x80, 0xf2, 0x27, 0x41, 0x00, 0x00, 0x01, 0x3c, 0xac, 0x0d, 0x40, 0x20, 0x05, 0xc8, 0xa0, 0x03,
|
||||
0x40, 0x20, 0x2b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_51 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x9e, 0x87, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_52 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x28, 0xaa, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_53 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x98, 0x3c, 0x87, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_54 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0xd8, 0xde, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_55 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0x6e, 0xf3, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_56 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x19, 0x48, 0x88, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_57 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x12, 0x35, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_58 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x120,
|
||||
.data = {0xa4, 0x18, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x37, 0x35, 0x37, 0x37,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_59 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x19A,
|
||||
.data = {0x5f, 0x11, 0x89, 0x55, 0x44, 0x64, 0xd8, 0x1b, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x11, 0x52,
|
||||
0x00, 0x12, 0x02, 0x64, 0x00, 0x00, 0x00, 0x08, 0x13, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_60 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2B5,
|
||||
.data = {0xfb, 0xeb, 0x43, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x00, 0x2b, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0xfa, 0xd0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_61 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2C0,
|
||||
.data = {0xcc, 0xcd, 0xa2, 0x21, 0x00, 0xa1, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_62 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x2E0,
|
||||
.data = {0x87, 0xab, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x70, 0x01, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
static constexpr CAN_frame message_63 = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 32,
|
||||
.ID = 0x10A,
|
||||
.data = {0x54, 0x6c, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0x00, 0x00, 0x36, 0x39, 0x35, 0x35,
|
||||
0xc9, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
const CAN_frame* messages[63] = {
|
||||
&message_1, &message_2, &message_3, &message_4, &message_5, &message_6, &message_7, &message_8,
|
||||
&message_9, &message_10, &message_11, &message_12, &message_13, &message_14, &message_15, &message_16,
|
||||
&message_17, &message_18, &message_19, &message_20, &message_21, &message_22, &message_23, &message_24,
|
||||
&message_25, &message_26, &message_27, &message_28, &message_29, &message_30, &message_31, &message_32,
|
||||
&message_33, &message_34, &message_35, &message_36, &message_37, &message_38, &message_39, &message_40,
|
||||
&message_41, &message_42, &message_43, &message_44, &message_45, &message_46, &message_47, &message_48,
|
||||
&message_49, &message_50, &message_51, &message_52, &message_53, &message_54, &message_55, &message_56,
|
||||
&message_57, &message_58, &message_59, &message_60, &message_61, &message_62, &message_63};
|
||||
/* PID polling messages */
|
||||
CAN_frame EGMP_7E4 = {.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x03, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00}}; //Poll PID 03 22 01 01
|
||||
static constexpr CAN_frame EGMP_7E4_ack = {
|
||||
.FD = true,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x7E4,
|
||||
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //Ack frame, correct PID is returned
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -55,7 +55,7 @@ class VolvoSpaHtmlRenderer : public BatteryHtmlRenderer {
|
|||
default:
|
||||
content += String("Closed");
|
||||
}
|
||||
content += "<h4>Positive contactor status: ";
|
||||
content += "<h4>Precharge contactor status: ";
|
||||
switch (datalayer_extended.VolvoPolestar.HVILstatusBits & 0x08) {
|
||||
case 0x08:
|
||||
content += String("Open");
|
||||
|
@ -63,7 +63,7 @@ class VolvoSpaHtmlRenderer : public BatteryHtmlRenderer {
|
|||
default:
|
||||
content += String("Closed");
|
||||
}
|
||||
content += "<h4>Precharge Contactor status: ";
|
||||
content += "<h4>Positive Contactor status: ";
|
||||
switch (datalayer_extended.VolvoPolestar.HVILstatusBits & 0x10) {
|
||||
case 0x10:
|
||||
content += String("Open");
|
||||
|
|
|
@ -96,6 +96,13 @@ void init_stored_settings() {
|
|||
user_selected_min_pack_voltage_dV = settings.getUInt("BATTPVMIN", 0);
|
||||
user_selected_max_cell_voltage_mV = settings.getUInt("BATTCVMAX", 0);
|
||||
user_selected_min_cell_voltage_mV = settings.getUInt("BATTCVMIN", 0);
|
||||
user_selected_inverter_cells = settings.getUInt("INVCELLS", 0);
|
||||
user_selected_inverter_modules = settings.getUInt("INVMODULES", 0);
|
||||
user_selected_inverter_cells_per_module = settings.getUInt("INVCELLSPER", 0);
|
||||
user_selected_inverter_voltage_level = settings.getUInt("INVVLEVEL", 0);
|
||||
user_selected_inverter_ah_capacity = settings.getUInt("INVAHCAPACITY", 0);
|
||||
user_selected_inverter_battery_type = settings.getUInt("INVBTYPE", 0);
|
||||
user_selected_inverter_ignore_contactors = settings.getBool("INVICNT", false);
|
||||
|
||||
auto readIf = [](const char* settingName) {
|
||||
auto batt1If = (comm_interface)settings.getUInt(settingName, (int)comm_interface::CanNative);
|
||||
|
@ -193,10 +200,7 @@ void store_settings() {
|
|||
if (!settings.putUInt("TARGETDISCHVOLT", datalayer.battery.settings.max_user_set_discharge_voltage_dV)) {
|
||||
set_event(EVENT_PERSISTENT_SAVE_INFO, 11);
|
||||
}
|
||||
if (!settings.putUInt("SOFAR_ID", datalayer.battery.settings.sofar_user_specified_battery_id)) {
|
||||
set_event(EVENT_PERSISTENT_SAVE_INFO, 12);
|
||||
}
|
||||
if (!settings.putUInt("BMSRESETDUR", datalayer.battery.settings.sofar_user_specified_battery_id)) {
|
||||
if (!settings.putUInt("BMSRESETDUR", datalayer.battery.settings.user_set_bms_reset_duration_ms)) {
|
||||
set_event(EVENT_PERSISTENT_SAVE_INFO, 13);
|
||||
}
|
||||
|
||||
|
|
|
@ -468,6 +468,38 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
|
|||
return String(datalayer.charger.charger_setpoint_HV_IDC, 1);
|
||||
}
|
||||
|
||||
if (var == "SOFAR_ID") {
|
||||
return String(settings.getUInt("SOFAR_ID", 0));
|
||||
}
|
||||
|
||||
if (var == "INVCELLS") {
|
||||
return String(settings.getUInt("INVCELLS", 0));
|
||||
}
|
||||
|
||||
if (var == "INVMODULES") {
|
||||
return String(settings.getUInt("INVMODULES", 0));
|
||||
}
|
||||
|
||||
if (var == "INVCELLSPER") {
|
||||
return String(settings.getUInt("INVCELLSPER", 0));
|
||||
}
|
||||
|
||||
if (var == "INVVLEVEL") {
|
||||
return String(settings.getUInt("INVVLEVEL", 0));
|
||||
}
|
||||
|
||||
if (var == "INVCAPACITY") {
|
||||
return String(settings.getUInt("INVCAPACITY", 0));
|
||||
}
|
||||
|
||||
if (var == "INVBTYPE") {
|
||||
return String(settings.getUInt("INVBTYPE", 0));
|
||||
}
|
||||
|
||||
if (var == "INVICNT") {
|
||||
return settings.getBool("INVICNT") ? "checked" : "";
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
|
@ -527,10 +559,6 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
function editPassword(){var value=prompt('Enter new password:');if(value!==null){var xhr=new
|
||||
XMLHttpRequest();xhr.onload=editComplete;xhr.onerror=editError;xhr.open('GET','/updatePassword?value='+encodeURIComponent(value),true);xhr.send();}}
|
||||
|
||||
function editSofarID(){var value=prompt('For double battery setups. Which battery ID should this emulator send? Remember to reboot after configuring this! Enter new value between (0-15):');
|
||||
if(value!==null){if(value>=0&&value<=15){var xhr=new XMLHttpRequest();xhr.onload=editComplete;xhr.onerror=editError;xhr.open('GET','/updateSofarID?value='+value,true);xhr.send();}
|
||||
else {alert('Invalid value. Please enter a value between 0 and 15.');}}}
|
||||
|
||||
function editWh(){var value=prompt('How much energy the battery can store. Enter new Wh value (1-400000):');
|
||||
if(value!==null){if(value>=1&&value<=400000){var xhr=new
|
||||
XMLHttpRequest();xhr.onload=editComplete;xhr.onerror=editError;xhr.open('GET','/updateBatterySize?value='+value,true);xhr.send();}else{
|
||||
|
@ -663,6 +691,21 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
display: contents;
|
||||
}
|
||||
|
||||
form .if-sofar { display: none; }
|
||||
form[data-inverter="17"] .if-sofar {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-pylonish { display: none; }
|
||||
form[data-inverter="4"] .if-pylonish, form[data-inverter="10"] .if-pylonish, form[data-inverter="19"] .if-pylonish {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-solax { display: none; }
|
||||
form[data-inverter="18"] .if-solax {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
form .if-mqtt { display: none; }
|
||||
form[data-mqttenabled="true"] .if-mqtt {
|
||||
display: contents;
|
||||
|
@ -726,6 +769,40 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="if-sofar">
|
||||
<label>Sofar Battery ID (0-15): </label>
|
||||
<input name='SOFAR_ID' type='text' value="%SOFAR_ID%" pattern="^[0-9]{1,2}$" />
|
||||
</div>
|
||||
|
||||
<div class="if-pylonish">
|
||||
<label>Reported cell count (0 for default): </label>
|
||||
<input name='INVCELLS' type='text' value="%INVCELLS%" pattern="^[0-9]+$" />
|
||||
</div>
|
||||
|
||||
<div class="if-pylonish if-solax">
|
||||
<label>Reported module count (0 for default): </label>
|
||||
<input name='INVMODULES' type='text' value="%INVMODULES%" pattern="^[0-9]+$" />
|
||||
</div>
|
||||
|
||||
<div class="if-pylonish">
|
||||
<label>Reported cells per module (0 for default): </label>
|
||||
<input name='INVCELLSPER' type='text' value="%INVCELLSPER%" pattern="^[0-9]+$" />
|
||||
|
||||
<label>Reported voltage level (0 for default): </label>
|
||||
<input name='INVVLEVEL' type='text' value="%INVVLEVEL%" pattern="^[0-9]+$" />
|
||||
|
||||
<label>Reported Ah capacity (0 for default): </label>
|
||||
<input name='INVCAPACITY' type='text' value="%INVCAPACITY%" pattern="^[0-9]+$" />
|
||||
</div>
|
||||
|
||||
<div class="if-solax">
|
||||
<label>Reported battery type (in decimal): </label>
|
||||
<input name='INVBTYPE' type='text' value="%INVBTYPE%" pattern="^[0-9]+$" />
|
||||
|
||||
<label>Inverter should ignore contactors: </label>
|
||||
<input type='checkbox' name='INVICNT' value='on' style='margin-left: 0;' %INVICNT% />
|
||||
</div>
|
||||
|
||||
<label>Charger: </label><select name='charger'>
|
||||
%CHGTYPE%
|
||||
</select>
|
||||
|
@ -826,8 +903,6 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
<h4 style='color: white;' class="%BATTERY2CLASS%">Battery interface: <span id='Battery2'>%BATTERY2INTF%</span></h4>
|
||||
|
||||
<h4 style='color: white;' class="%INVCLASS%">Inverter interface: <span id='Inverter'>%INVINTF%</span></h4>
|
||||
|
||||
<h4 style='color: white;' class="%INVBIDCLASS%">Battery ID: <span>%INVBID%</span> <button onclick='editSofarID()'>Edit</button></h4>
|
||||
|
||||
<h4 style='color: white;' class="%SHUNTCLASS%">Shunt interface: <span id='Inverter'>%SHUNTINTF%</span></h4>
|
||||
|
||||
|
|
|
@ -414,7 +414,7 @@ void init_webserver() {
|
|||
|
||||
const char* boolSettingNames[] = {
|
||||
"DBLBTR", "CNTCTRL", "CNTCTRLDBL", "PWMCNTCTRL", "PERBMSRESET", "REMBMSRESET",
|
||||
"CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS",
|
||||
"CANFDASCAN", "WIFIAPENABLED", "MQTTENABLED", "HADISC", "MQTTTOPICS", "INVICNT",
|
||||
};
|
||||
|
||||
// Handles the form POST from UI to save settings of the common image
|
||||
|
@ -494,6 +494,27 @@ void init_webserver() {
|
|||
settings.saveString("MQTTDEVICENAME", p->value().c_str());
|
||||
} else if (p->name() == "HADEVICEID") {
|
||||
settings.saveString("HADEVICEID", p->value().c_str());
|
||||
} else if (p->name() == "SOFAR_ID") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("SOFAR_ID", type);
|
||||
} else if (p->name() == "INVCELLS") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVCELLS", type);
|
||||
} else if (p->name() == "INVMODULES") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVMODULES", type);
|
||||
} else if (p->name() == "INVCELLSPER") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVCELLSPER", type);
|
||||
} else if (p->name() == "INVVLEVEL") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVVLEVEL", type);
|
||||
} else if (p->name() == "INVCAPACITY") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVCAPACITY", type);
|
||||
} else if (p->name() == "INVBTYPE") {
|
||||
auto type = atoi(p->value().c_str());
|
||||
settings.saveUInt("INVBTYPE", (int)type);
|
||||
}
|
||||
|
||||
for (auto& boolSetting : boolSettings) {
|
||||
|
@ -579,10 +600,6 @@ void init_webserver() {
|
|||
update_string_setting(route, [setter](String value) { setter(value.toInt()); });
|
||||
};
|
||||
|
||||
// Route for editing Sofar ID
|
||||
update_int_setting("/updateSofarID",
|
||||
[](int value) { datalayer.battery.settings.sofar_user_specified_battery_id = value; });
|
||||
|
||||
// Route for editing Wh
|
||||
update_int_setting("/updateBatterySize", [](int value) { datalayer.battery.info.total_capacity_Wh = value; });
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "FERROAMP-CAN.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../inverter/INVERTERS.h"
|
||||
|
||||
//#define SEND_0 //If defined, the messages will have ID ending with 0 (useful for some inverters)
|
||||
#define SEND_1 //If defined, the messages will have ID ending with 1 (useful for some inverters)
|
||||
|
@ -364,3 +365,38 @@ void FerroampCanInverter::send_system_data() { //System equipment information
|
|||
transmit_can_frame(&PYLON_4291);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FerroampCanInverter::setup() {
|
||||
if (user_selected_inverter_cells > 0) {
|
||||
PYLON_7320.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
PYLON_7320.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
PYLON_7321.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
PYLON_7321.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_modules > 0) {
|
||||
PYLON_7320.data.u8[2] = user_selected_inverter_modules;
|
||||
PYLON_7321.data.u8[2] = user_selected_inverter_modules;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_cells_per_module > 0) {
|
||||
PYLON_7320.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
PYLON_7321.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_voltage_level > 0) {
|
||||
PYLON_7320.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
PYLON_7320.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
PYLON_7321.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
PYLON_7321.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_ah_capacity > 0) {
|
||||
PYLON_7320.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
PYLON_7320.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
PYLON_7321.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
PYLON_7321.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
class FerroampCanInverter : public CanInverterProtocol {
|
||||
public:
|
||||
const char* name() override { return Name; }
|
||||
bool setup() override;
|
||||
void update_values();
|
||||
void transmit_can(unsigned long currentMillis);
|
||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||
|
|
|
@ -4,6 +4,17 @@ InverterProtocol* inverter = nullptr;
|
|||
|
||||
InverterProtocolType user_selected_inverter_protocol = InverterProtocolType::BydModbus;
|
||||
|
||||
// Some user-configurable settings that can be used by inverters. These
|
||||
// inverters should use sensible defaults if the corresponding user_selected
|
||||
// value is zero.
|
||||
uint16_t user_selected_inverter_cells = 0;
|
||||
uint16_t user_selected_inverter_modules = 0;
|
||||
uint16_t user_selected_inverter_cells_per_module = 0;
|
||||
uint16_t user_selected_inverter_voltage_level = 0;
|
||||
uint16_t user_selected_inverter_ah_capacity = 0;
|
||||
uint16_t user_selected_inverter_battery_type = 0;
|
||||
bool user_selected_inverter_ignore_contactors = false;
|
||||
|
||||
std::vector<InverterProtocolType> supported_inverter_protocols() {
|
||||
std::vector<InverterProtocolType> types;
|
||||
|
||||
|
|
|
@ -36,4 +36,12 @@ extern InverterProtocol* inverter;
|
|||
// Call to initialize the build-time selected inverter. Safe to call even though inverter was not selected.
|
||||
bool setup_inverter();
|
||||
|
||||
extern uint16_t user_selected_inverter_cells;
|
||||
extern uint16_t user_selected_inverter_modules;
|
||||
extern uint16_t user_selected_inverter_cells_per_module;
|
||||
extern uint16_t user_selected_inverter_voltage_level;
|
||||
extern uint16_t user_selected_inverter_ah_capacity;
|
||||
extern uint16_t user_selected_inverter_battery_type;
|
||||
extern bool user_selected_inverter_ignore_contactors;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,27 +5,27 @@
|
|||
|
||||
enum class InverterProtocolType {
|
||||
None = 0,
|
||||
AforeCan,
|
||||
BydCan,
|
||||
BydModbus,
|
||||
FerroampCan,
|
||||
Foxess,
|
||||
GrowattHv,
|
||||
GrowattLv,
|
||||
GrowattWit,
|
||||
Kostal,
|
||||
Pylon,
|
||||
PylonLv,
|
||||
Schneider,
|
||||
SmaBydH,
|
||||
SmaBydHvs,
|
||||
SmaLv,
|
||||
SmaTripower,
|
||||
Sofar,
|
||||
Solax,
|
||||
Solxpow,
|
||||
SolArkLv,
|
||||
Sungrow,
|
||||
AforeCan = 1,
|
||||
BydCan = 2,
|
||||
BydModbus = 3,
|
||||
FerroampCan = 4,
|
||||
Foxess = 5,
|
||||
GrowattHv = 6,
|
||||
GrowattLv = 7,
|
||||
GrowattWit = 8,
|
||||
Kostal = 9,
|
||||
Pylon = 10,
|
||||
PylonLv = 11,
|
||||
Schneider = 12,
|
||||
SmaBydH = 13,
|
||||
SmaBydHvs = 14,
|
||||
SmaLv = 15,
|
||||
SmaTripower = 16,
|
||||
Sofar = 17,
|
||||
Solax = 18,
|
||||
Solxpow = 19,
|
||||
SolArkLv = 20,
|
||||
Sungrow = 21,
|
||||
Highest
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "PYLON-CAN.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../inverter/INVERTERS.h"
|
||||
|
||||
#define SEND_0 //If defined, the messages will have ID ending with 0 (useful for some inverters)
|
||||
//#define SEND_1 //If defined, the messages will have ID ending with 1 (useful for some inverters)
|
||||
|
@ -351,3 +352,38 @@ void PylonInverter::send_system_data() { //System equipment information
|
|||
transmit_can_frame(&PYLON_4291);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PylonInverter::setup() {
|
||||
if (user_selected_inverter_cells > 0) {
|
||||
PYLON_7320.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
PYLON_7320.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
PYLON_7321.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
PYLON_7321.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_modules > 0) {
|
||||
PYLON_7320.data.u8[2] = user_selected_inverter_modules;
|
||||
PYLON_7321.data.u8[2] = user_selected_inverter_modules;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_cells_per_module > 0) {
|
||||
PYLON_7320.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
PYLON_7321.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_voltage_level > 0) {
|
||||
PYLON_7320.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
PYLON_7320.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
PYLON_7321.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
PYLON_7321.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_ah_capacity > 0) {
|
||||
PYLON_7320.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
PYLON_7320.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
PYLON_7321.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
PYLON_7321.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
class PylonInverter : public CanInverterProtocol {
|
||||
public:
|
||||
const char* name() override { return Name; }
|
||||
bool setup() override;
|
||||
void update_values();
|
||||
void transmit_can(unsigned long currentMillis);
|
||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||
|
|
|
@ -4,11 +4,7 @@
|
|||
#include "../datalayer/datalayer.h"
|
||||
#include "../devboard/utils/events.h"
|
||||
#include "../devboard/utils/logging.h"
|
||||
|
||||
#define NUMBER_OF_MODULES 0
|
||||
#define BATTERY_TYPE 0x50
|
||||
// If you are having BattVoltFault issues, configure the above values according to wiki page
|
||||
// https://github.com/dalathegreat/Battery-Emulator/wiki/Solax-inverters
|
||||
#include "../inverter/INVERTERS.h"
|
||||
|
||||
// __builtin_bswap64 needed to convert to ESP32 little endian format
|
||||
// Byte[4] defines the requested contactor state: 1 = Closed , 0 = Open
|
||||
|
@ -18,7 +14,7 @@
|
|||
void SolaxInverter::
|
||||
update_values() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||
// If not receiveing any communication from the inverter, open contactors and return to battery announce state
|
||||
if (millis() - LastFrameTime >= SolaxTimeout) {
|
||||
if (millis() - LastFrameTime >= SolaxTimeout && !configured_ignore_contactors) {
|
||||
datalayer.system.status.inverter_allows_contactor_closing = false;
|
||||
STATE = BATTERY_ANNOUNCE;
|
||||
}
|
||||
|
@ -73,8 +69,8 @@ void SolaxInverter::
|
|||
//BMS_Status
|
||||
SOLAX_1875.data.u8[0] = (uint8_t)temperature_average;
|
||||
SOLAX_1875.data.u8[1] = (temperature_average >> 8);
|
||||
SOLAX_1875.data.u8[2] = (uint8_t)NUMBER_OF_MODULES; // Number of slave batteries
|
||||
SOLAX_1875.data.u8[4] = (uint8_t)0; // Contactor Status 0=off, 1=on.
|
||||
SOLAX_1875.data.u8[2] = (uint8_t)configured_number_of_modules; // Number of slave batteries
|
||||
SOLAX_1875.data.u8[4] = (uint8_t)0; // Contactor Status 0=off, 1=on.
|
||||
|
||||
//BMS_PackTemps (strange name, since it has voltages?)
|
||||
SOLAX_1876.data.u8[0] = (int8_t)datalayer.battery.status.temperature_max_dC;
|
||||
|
@ -88,8 +84,8 @@ void SolaxInverter::
|
|||
SOLAX_1876.data.u8[7] = (datalayer.battery.status.cell_min_voltage_mV >> 8);
|
||||
|
||||
//Unknown
|
||||
SOLAX_1877.data.u8[4] = (uint8_t)BATTERY_TYPE; // Battery type (Default 0x50)
|
||||
SOLAX_1877.data.u8[6] = (uint8_t)0x22; // Firmware version?
|
||||
SOLAX_1877.data.u8[4] = (uint8_t)configured_battery_type; // Battery type (Default 0x50)
|
||||
SOLAX_1877.data.u8[6] = (uint8_t)0x22; // Firmware version?
|
||||
SOLAX_1877.data.u8[7] =
|
||||
(uint8_t)0x02; // The above firmware version applies to:02 = Master BMS, 10 = S1, 20 = S2, 30 = S3, 40 = S4
|
||||
|
||||
|
@ -129,6 +125,26 @@ void SolaxInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
|||
if (rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x01) ||
|
||||
rx_frame.ID == 0x1871 && rx_frame.data.u8[0] == (0x02)) {
|
||||
LastFrameTime = millis();
|
||||
|
||||
if (configured_ignore_contactors) {
|
||||
// Skip the state machine since we're not going to open/close contactors,
|
||||
// and the Solax would otherwise wait forever for us to do so.
|
||||
|
||||
datalayer.system.status.inverter_allows_contactor_closing = true;
|
||||
SOLAX_1875.data.u8[4] = (0x01); // Inform Inverter: Contactor 0=off, 1=on.
|
||||
transmit_can_frame(&SOLAX_187E);
|
||||
transmit_can_frame(&SOLAX_187A);
|
||||
transmit_can_frame(&SOLAX_1872);
|
||||
transmit_can_frame(&SOLAX_1873);
|
||||
transmit_can_frame(&SOLAX_1874);
|
||||
transmit_can_frame(&SOLAX_1875);
|
||||
transmit_can_frame(&SOLAX_1876);
|
||||
transmit_can_frame(&SOLAX_1877);
|
||||
transmit_can_frame(&SOLAX_1878);
|
||||
transmit_can_frame(&SOLAX_100A001);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (STATE) {
|
||||
case (BATTERY_ANNOUNCE):
|
||||
#ifdef DEBUG_LOG
|
||||
|
@ -208,7 +224,26 @@ void SolaxInverter::map_can_frame_to_variable(CAN_frame rx_frame) {
|
|||
}
|
||||
}
|
||||
|
||||
bool SolaxInverter::setup(void) { // Performs one time setup at startup
|
||||
datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first
|
||||
bool SolaxInverter::setup(void) { // Performs one time setup at startup
|
||||
// Use user selected values if nonzero, otherwise use defaults
|
||||
if (user_selected_inverter_modules > 0) {
|
||||
configured_number_of_modules = user_selected_inverter_modules;
|
||||
} else {
|
||||
configured_number_of_modules = NUMBER_OF_MODULES;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_battery_type > 0) {
|
||||
configured_battery_type = user_selected_inverter_battery_type;
|
||||
} else {
|
||||
configured_battery_type = BATTERY_TYPE;
|
||||
}
|
||||
|
||||
configured_ignore_contactors = user_selected_inverter_ignore_contactors;
|
||||
|
||||
if (!configured_ignore_contactors) {
|
||||
// Only prevent closing if we're not ignoring contactors
|
||||
datalayer.system.status.inverter_allows_contactor_closing = false; // The inverter needs to allow first
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ class SolaxInverter : public CanInverterProtocol {
|
|||
static constexpr const char* Name = "SolaX Triple Power LFP over CAN bus";
|
||||
|
||||
private:
|
||||
static const int NUMBER_OF_MODULES = 0;
|
||||
static const int BATTERY_TYPE = 0x50;
|
||||
// If you are having BattVoltFault issues, configure the above values according to wiki page
|
||||
// https://github.com/dalathegreat/Battery-Emulator/wiki/Solax-inverters
|
||||
|
||||
// Timeout in milliseconds
|
||||
static const int SolaxTimeout = 2000;
|
||||
|
||||
|
@ -34,6 +39,13 @@ class SolaxInverter : public CanInverterProtocol {
|
|||
uint16_t capped_capacity_Wh;
|
||||
uint16_t capped_remaining_capacity_Wh;
|
||||
|
||||
int configured_number_of_modules = 0;
|
||||
int configured_battery_type = 0;
|
||||
// If true, the integration will ignore the inverter's requests to open the
|
||||
// battery contactors. Useful for batteries that can't open contactors on
|
||||
// request.
|
||||
bool configured_ignore_contactors = false;
|
||||
|
||||
//CAN message translations from this amazing repository: https://github.com/rand12345/solax_can_bus
|
||||
|
||||
CAN_frame SOLAX_1801 = {.FD = false,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "SOLXPOW-CAN.h"
|
||||
#include "../communication/can/comm_can.h"
|
||||
#include "../datalayer/datalayer.h"
|
||||
#include "../inverter/INVERTERS.h"
|
||||
|
||||
#define SEND_0 //If defined, the messages will have ID ending with 0 (useful for some inverters)
|
||||
//#define SEND_1 //If defined, the messages will have ID ending with 1 (useful for some inverters)
|
||||
|
@ -353,3 +354,38 @@ void SolxpowInverter::send_system_data() { //System equipment information
|
|||
transmit_can_frame(&SOLXPOW_4291);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SolxpowInverter::setup() {
|
||||
if (user_selected_inverter_cells > 0) {
|
||||
SOLXPOW_7320.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
SOLXPOW_7320.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
SOLXPOW_7321.data.u8[0] = user_selected_inverter_cells & 0xff;
|
||||
SOLXPOW_7321.data.u8[1] = (uint8_t)(user_selected_inverter_cells >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_modules > 0) {
|
||||
SOLXPOW_7320.data.u8[2] = user_selected_inverter_modules;
|
||||
SOLXPOW_7321.data.u8[2] = user_selected_inverter_modules;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_cells_per_module > 0) {
|
||||
SOLXPOW_7320.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
SOLXPOW_7321.data.u8[3] = user_selected_inverter_cells_per_module;
|
||||
}
|
||||
|
||||
if (user_selected_inverter_voltage_level > 0) {
|
||||
SOLXPOW_7320.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
SOLXPOW_7320.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
SOLXPOW_7321.data.u8[4] = user_selected_inverter_voltage_level & 0xff;
|
||||
SOLXPOW_7321.data.u8[5] = (uint8_t)(user_selected_inverter_voltage_level >> 8);
|
||||
}
|
||||
|
||||
if (user_selected_inverter_ah_capacity > 0) {
|
||||
SOLXPOW_7320.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
SOLXPOW_7320.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
SOLXPOW_7321.data.u8[6] = user_selected_inverter_ah_capacity & 0xff;
|
||||
SOLXPOW_7321.data.u8[7] = (uint8_t)(user_selected_inverter_ah_capacity >> 8);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
class SolxpowInverter : public CanInverterProtocol {
|
||||
public:
|
||||
const char* name() override { return Name; }
|
||||
bool setup() override;
|
||||
void update_values();
|
||||
void transmit_can(unsigned long currentMillis);
|
||||
void map_can_frame_to_variable(CAN_frame rx_frame);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue