mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-06 03:50:13 +02:00
Add reverse engineered PID polls
This commit is contained in:
parent
a37b621e99
commit
95aca19120
2 changed files with 171 additions and 3 deletions
|
@ -34,11 +34,32 @@ CAN_frame CMFA_3D3 = {.FD = false,
|
||||||
.data = {0x47, 0x30, 0x00, 0x02, 0x5D, 0x80, 0x5D, 0xE7}};
|
.data = {0x47, 0x30, 0x00, 0x02, 0x5D, 0x80, 0x5D, 0xE7}};
|
||||||
CAN_frame CMFA_59B = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x59B, .data = {0x00, 0x02, 0x00}};
|
CAN_frame CMFA_59B = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x59B, .data = {0x00, 0x02, 0x00}};
|
||||||
|
|
||||||
|
CAN_frame CMFA_ACK = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x79B,
|
||||||
|
.data = {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
CAN_frame CMFA_POLLING_FRAME = {.FD = false,
|
||||||
|
.ext_ID = false,
|
||||||
|
.DLC = 8,
|
||||||
|
.ID = 0x79B,
|
||||||
|
.data = {0x30, 0x22, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
|
||||||
|
static uint32_t average_voltage_of_cells = 270000;
|
||||||
|
static uint16_t highest_cell_voltage_mv = 3700;
|
||||||
|
static uint16_t leadAcidBatteryVoltage = 12000;
|
||||||
|
static uint16_t highest_cell_voltage_number = 0;
|
||||||
|
static uint16_t lowest_cell_voltage_number = 0;
|
||||||
|
static uint64_t cumulative_energy_when_discharging = 0; // Wh
|
||||||
|
static uint16_t pack_voltage_polled = 2700;
|
||||||
|
static uint32_t poll_pid = PID_POLL_PACKVOLTAGE;
|
||||||
|
static uint16_t pid_reply = 0;
|
||||||
static uint8_t counter_10ms = 0;
|
static uint8_t counter_10ms = 0;
|
||||||
static uint8_t content_125[16] = {0x07, 0x0C, 0x01, 0x06, 0x0B, 0x00, 0x05, 0x0A,
|
static uint8_t content_125[16] = {0x07, 0x0C, 0x01, 0x06, 0x0B, 0x00, 0x05, 0x0A,
|
||||||
0x0F, 0x04, 0x09, 0x0E, 0x03, 0x08, 0x0D, 0x02};
|
0x0F, 0x04, 0x09, 0x0E, 0x03, 0x08, 0x0D, 0x02};
|
||||||
static uint8_t content_135[16] = {0x85, 0xD5, 0x25, 0x75, 0xC5, 0x15, 0x65, 0xB5,
|
static uint8_t content_135[16] = {0x85, 0xD5, 0x25, 0x75, 0xC5, 0x15, 0x65, 0xB5,
|
||||||
0x05, 0x55, 0xA5, 0xF5, 0x45, 0x95, 0xE5, 0x35};
|
0x05, 0x55, 0xA5, 0xF5, 0x45, 0x95, 0xE5, 0x35};
|
||||||
|
static unsigned long previousMillis200ms = 0;
|
||||||
static unsigned long previousMillis100ms = 0;
|
static unsigned long previousMillis100ms = 0;
|
||||||
static unsigned long previousMillis10ms = 0;
|
static unsigned long previousMillis10ms = 0;
|
||||||
|
|
||||||
|
@ -60,7 +81,7 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
datalayer.battery.status.current_dA = current * 10;
|
datalayer.battery.status.current_dA = current * 10;
|
||||||
|
|
||||||
datalayer.battery.status.voltage_dV = pack_voltage;
|
datalayer.battery.status.voltage_dV = average_voltage_of_cells / 100;
|
||||||
|
|
||||||
datalayer.battery.info.total_capacity_Wh = 27000;
|
datalayer.battery.info.total_capacity_Wh = 27000;
|
||||||
|
|
||||||
|
@ -76,9 +97,13 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
datalayer.battery.status.temperature_max_dC = (highest_cell_temperature * 10);
|
datalayer.battery.status.temperature_max_dC = (highest_cell_temperature * 10);
|
||||||
|
|
||||||
datalayer.battery.status.cell_min_voltage_mV;
|
datalayer.battery.status.cell_min_voltage_mV = highest_cell_voltage_mv; //Placeholder until we can find minimum
|
||||||
|
|
||||||
datalayer.battery.status.cell_max_voltage_mV;
|
datalayer.battery.status.cell_max_voltage_mV = highest_cell_voltage_mv;
|
||||||
|
|
||||||
|
if (leadAcidBatteryVoltage < 11000) { //11.000V
|
||||||
|
set_event(EVENT_12V_LOW, leadAcidBatteryVoltage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
|
void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
|
||||||
|
@ -126,6 +151,43 @@ void handle_incoming_can_frame_battery(CAN_frame rx_frame) {
|
||||||
break;
|
break;
|
||||||
case 0x5E1:
|
case 0x5E1:
|
||||||
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE;
|
||||||
|
break;
|
||||||
|
case 0x7BB: // Reply from battery
|
||||||
|
if (rx_frame.data.u8[0] == 0x10) { //PID header
|
||||||
|
transmit_can_frame(&CMFA_ACK, can_config.battery);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_reply = (rx_frame.data.u8[2] << 8) + rx_frame.data.u8[3];
|
||||||
|
|
||||||
|
switch (pid_reply) {
|
||||||
|
case PID_POLL_PACKVOLTAGE:
|
||||||
|
pack_voltage_polled =
|
||||||
|
(uint16_t)((rx_frame.data.u8[5] << 8) | rx_frame.data.u8[4]); //Hmm, not same LSB as others
|
||||||
|
break;
|
||||||
|
case PID_POLL_AVERAGE_VOLTAGE_OF_CELLS:
|
||||||
|
average_voltage_of_cells =
|
||||||
|
(uint16_t)((rx_frame.data.u8[5] << 16) | (rx_frame.data.u8[6] << 8) | (rx_frame.data.u8[7]));
|
||||||
|
break;
|
||||||
|
case PID_POLL_HIGHEST_CELL_VOLTAGE:
|
||||||
|
highest_cell_voltage_mv = (uint16_t)((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]);
|
||||||
|
break;
|
||||||
|
case PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE:
|
||||||
|
highest_cell_voltage_number = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE:
|
||||||
|
lowest_cell_voltage_number = rx_frame.data.u8[4];
|
||||||
|
break;
|
||||||
|
case PID_POLL_12V_BATTERY:
|
||||||
|
leadAcidBatteryVoltage = (uint16_t)((rx_frame.data.u8[4] << 8) | rx_frame.data.u8[5]);
|
||||||
|
break;
|
||||||
|
case PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING:
|
||||||
|
cumulative_energy_when_discharging = (uint64_t)((rx_frame.data.u8[4] << 24) | (rx_frame.data.u8[5] << 16) |
|
||||||
|
(rx_frame.data.u8[6] << 8) | (rx_frame.data.u8[7]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -157,6 +219,53 @@ void transmit_can_battery() {
|
||||||
transmit_can_frame(&CMFA_59B, can_config.battery);
|
transmit_can_frame(&CMFA_59B, can_config.battery);
|
||||||
transmit_can_frame(&CMFA_3D3, can_config.battery);
|
transmit_can_frame(&CMFA_3D3, can_config.battery);
|
||||||
}
|
}
|
||||||
|
//Send 200ms message
|
||||||
|
if (currentMillis - previousMillis200ms >= INTERVAL_200_MS) {
|
||||||
|
previousMillis200ms = currentMillis;
|
||||||
|
|
||||||
|
switch (poll_pid) {
|
||||||
|
case PID_POLL_PACKVOLTAGE:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_PACKVOLTAGE >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_PACKVOLTAGE;
|
||||||
|
poll_pid = PID_POLL_AVERAGE_VOLTAGE_OF_CELLS;
|
||||||
|
break;
|
||||||
|
case PID_POLL_AVERAGE_VOLTAGE_OF_CELLS:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_AVERAGE_VOLTAGE_OF_CELLS >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_AVERAGE_VOLTAGE_OF_CELLS;
|
||||||
|
poll_pid = PID_POLL_HIGHEST_CELL_VOLTAGE;
|
||||||
|
break;
|
||||||
|
case PID_POLL_HIGHEST_CELL_VOLTAGE:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_HIGHEST_CELL_VOLTAGE >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_HIGHEST_CELL_VOLTAGE;
|
||||||
|
poll_pid = PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE;
|
||||||
|
break;
|
||||||
|
case PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE;
|
||||||
|
poll_pid = PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE;
|
||||||
|
break;
|
||||||
|
case PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE;
|
||||||
|
poll_pid = PID_POLL_12V_BATTERY;
|
||||||
|
break;
|
||||||
|
case PID_POLL_12V_BATTERY:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_12V_BATTERY >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_12V_BATTERY;
|
||||||
|
poll_pid = PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING;
|
||||||
|
break;
|
||||||
|
case PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING:
|
||||||
|
CMFA_POLLING_FRAME.data.u8[2] = (uint8_t)(PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING >> 8);
|
||||||
|
CMFA_POLLING_FRAME.data.u8[3] = (uint8_t)PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING;
|
||||||
|
poll_pid = PID_POLL_PACKVOLTAGE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
poll_pid = PID_POLL_PACKVOLTAGE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
transmit_can_frame(&CMFA_POLLING_FRAME, can_config.battery);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_battery(void) { // Performs one time setup at startup
|
void setup_battery(void) { // Performs one time setup at startup
|
||||||
|
|
|
@ -9,6 +9,65 @@
|
||||||
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value
|
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value
|
||||||
#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value
|
#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value
|
||||||
|
|
||||||
|
// OBD2 PID polls
|
||||||
|
/*
|
||||||
|
#define PID_POLL_UNKNOWN1 0x9001 //122 in log
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9002 //5531 (Possible SOC candidate)
|
||||||
|
*/
|
||||||
|
#define PID_POLL_PACKVOLTAGE 0x9003 //Best guess, not confirmed
|
||||||
|
#define PID_POLL_AVERAGE_VOLTAGE_OF_CELLS 0x9006 //Guaranteed pack voltage
|
||||||
|
#define PID_POLL_HIGHEST_CELL_VOLTAGE 0x9007 //Best guess, not confirmed
|
||||||
|
#define PID_POLL_CELL_NUMBER_HIGHEST_VOLTAGE 0x9008 // Cell number with highest voltage
|
||||||
|
#define PID_POLL_CELL_NUMBER_LOWEST_VOLTAGE 0x900A // Cell number with the lowest voltage
|
||||||
|
//#define PID_POLL_UNKNOWNX 0x900D
|
||||||
|
#define PID_POLL_12V_BATTERY 0x9011 //Confirmed 12v lead acid battery
|
||||||
|
/*
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9012 //749 in log
|
||||||
|
#define PID_POLL_UNKNOWN3 0x9013 //736 in log
|
||||||
|
#define PID_POLL_UNKNOWN4 0x9014 //752 in log
|
||||||
|
#define PID_POLL_UNKNOWN4 0x901B // Multi frame message, lots of values ranging between 0x30 - 0x52
|
||||||
|
#define PID_POLL_UNKNOWNX 0x912F // Multi frame message, empty
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9129
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9131
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9132
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9133
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9134
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9135
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9136
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9137
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9138
|
||||||
|
#define PID_POLL_UNKNOWNX 0x9139
|
||||||
|
#define PID_POLL_UNKNOWNX 0x913A
|
||||||
|
#define PID_POLL_UNKNOWNX 0x913B
|
||||||
|
#define PID_POLL_UNKNOWNX 0x913C
|
||||||
|
#define PID_POLL_UNKNOWN5 0x912F
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91B7
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91C1
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91CD
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91CF
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91F6
|
||||||
|
#define PID_POLL_UNKNOWNX 0x91F7
|
||||||
|
#define PID_POLL_UNKNOWNX 0x920F
|
||||||
|
#define PID_POLL_UNKNOWNx 0x9242
|
||||||
|
#define PID_POLL_UNKNOWNx 0x9243
|
||||||
|
*/
|
||||||
|
#define PID_POLL_CUMULATIVE_ENERGY_WHEN_DISCHARGING 0x9245 //OK
|
||||||
|
/*
|
||||||
|
#define PID_POLL_UNKNOWNx 0x9256
|
||||||
|
#define PID_POLL_UNKNOWNx 0x9261
|
||||||
|
#define PID_POLL_UNKNOWN7 0x9284
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF012
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF1A0
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF182
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF187
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF188
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF18A
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF18C
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF191
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF194
|
||||||
|
#define PID_POLL_UNKNOWNx 0xF195
|
||||||
|
*/
|
||||||
|
|
||||||
void setup_battery(void);
|
void setup_battery(void);
|
||||||
void transmit_can_frame(CAN_frame* tx_frame, int interface);
|
void transmit_can_frame(CAN_frame* tx_frame, int interface);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue