Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/bmw i3 messages #299

Merged
merged 7 commits into from
May 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 81 additions & 37 deletions Software/src/battery/BMW-I3-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ static uint8_t BMW_13E_counter = 0;
static uint8_t BMW_380_counter = 0;
static uint32_t BMW_328_counter = 0;
static bool battery_awake = false;
static bool battery_info_available = false;

static uint32_t battery_serial_number = 0;
static uint32_t battery_available_power_shortterm_charge = 0;
Expand Down Expand Up @@ -417,6 +418,9 @@ static uint8_t increment_alive_counter(uint8_t counter) {
}

void update_values_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
if (!battery_awake) {
return;
}

datalayer.battery.status.real_soc = (battery_HVBatt_SOC * 10);

Expand Down Expand Up @@ -447,44 +451,57 @@ void update_values_battery() { //This function maps all the values fetched via

datalayer.battery.status.temperature_max_dC = battery_temperature_max * 10; // Add a decimal

datalayer.battery.status.cell_min_voltage_mV = datalayer.battery.status.cell_voltages_mV[0];
datalayer.battery.status.cell_max_voltage_mV = datalayer.battery.status.cell_voltages_mV[1];

battery_cell_deviation_mV =
(datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV);
if (datalayer.battery.status.cell_voltages_mV[0] > 0 && datalayer.battery.status.cell_voltages_mV[2] > 0) {
datalayer.battery.status.cell_min_voltage_mV = datalayer.battery.status.cell_voltages_mV[0];
datalayer.battery.status.cell_max_voltage_mV = datalayer.battery.status.cell_voltages_mV[2];

// Start checking safeties. First up, cellvoltages!
if (battery_cell_deviation_mV > MAX_CELL_DEVIATION_MV) {
set_event(EVENT_CELL_DEVIATION_HIGH, 0);
battery_cell_deviation_mV =
(datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV);
} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
battery_cell_deviation_mV = 0;
}
if (detectedBattery == BATTERY_60AH) {
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_60AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_60AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_60AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_60AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
} else if (detectedBattery == BATTERY_94AH) {
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_94AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_94AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_94AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_94AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
} else { // BATTERY_120AH
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_120AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_120AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_120AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);

if (battery_info_available) {
// Start checking safeties. First up, cellvoltages!
if (battery_cell_deviation_mV > MAX_CELL_DEVIATION_MV) {
uint8_t report_value = 0;
if (battery_cell_deviation_mV <= 20 * 254) {
report_value = battery_cell_deviation_mV / 20;
} else {
report_value = 255;
}

set_event(EVENT_CELL_DEVIATION_HIGH, report_value);
Copy link
Owner

@dalathegreat dalathegreat May 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I mentioned in the other PR, It would be good enough to just do
set_event(EVENT_CELL_DEVIATION_HIGH, battery_cell_deviation_mV);

here, since we raise an alarm if it goes over 250mv. And 250 fits into the u8, barely :)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@odlg Anyways, I approved this PR, we can handle that discussion in the other PR!

} else {
clear_event(EVENT_CELL_DEVIATION_HIGH);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_120AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
if (detectedBattery == BATTERY_60AH) {
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_60AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_60AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_60AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_60AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
} else if (detectedBattery == BATTERY_94AH) {
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_94AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_94AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_94AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_94AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
} else { // BATTERY_120AH
datalayer.battery.info.max_design_voltage_dV = MAX_PACK_VOLTAGE_120AH;
datalayer.battery.info.min_design_voltage_dV = MIN_PACK_VOLTAGE_120AH;
if (datalayer.battery.status.cell_max_voltage_mV >= MAX_CELL_VOLTAGE_120AH) {
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (datalayer.battery.status.cell_min_voltage_mV <= MIN_CELL_VOLTAGE_120AH) {
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
}
}

Expand Down Expand Up @@ -694,6 +711,7 @@ void receive_can_battery(CAN_frame_t rx_frame) {
case SOH:
if (next_data >= 4) {
battery_soh = message_data[3];
battery_info_available = true;
}
break;
case SOC:
Expand Down Expand Up @@ -825,6 +843,26 @@ void send_can_battery() {

BMW_433.data.u8[1] = 0x01; // First 433 message byte1 we send is unique, once we sent initial value send this
BMW_3E8.data.u8[0] = 0xF1; // First 3E8 message byte0 we send is unique, once we sent initial value send this

next_data = 0;
switch (cmdState) {
case SOC:
ESP32Can.CANWriteFrame(&BMW_6F1_CELL);
cmdState = CELL_VOLTAGE;
break;
case CELL_VOLTAGE:
ESP32Can.CANWriteFrame(&BMW_6F1_SOH);
cmdState = SOH;
break;
case SOH:
ESP32Can.CANWriteFrame(&BMW_6F1_CELL_VOLTAGE_AVG);
cmdState = CELL_VOLTAGE_AVG;
break;
case CELL_VOLTAGE_AVG:
ESP32Can.CANWriteFrame(&BMW_6F1_SOC);
cmdState = SOC;
break;
}
}
// Send 5000ms CAN Message
if (currentMillis - previousMillis5000 >= INTERVAL_5_S) {
Expand Down Expand Up @@ -854,11 +892,17 @@ void send_can_battery() {
ESP32Can.CANWriteFrame(&BMW_3E4);
ESP32Can.CANWriteFrame(&BMW_37B);

next_data = 0;
ESP32Can.CANWriteFrame(&BMW_6F1_CELL);

BMW_3E5.data.u8[0] = 0xFD; // First 3E5 message byte0 we send is unique, once we sent initial value send this
}
} else {
previousMillis20 = currentMillis;
previousMillis100 = currentMillis;
previousMillis200 = currentMillis;
previousMillis500 = currentMillis;
previousMillis640 = currentMillis;
previousMillis1000 = currentMillis;
previousMillis5000 = currentMillis;
previousMillis10000 = currentMillis;
}
}

Expand Down
Loading