mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 09:49:32 +02:00
Add BMW i3 CAN mappings from DBC
This commit is contained in:
parent
5bbc1669cb
commit
b373a15ea1
2 changed files with 108 additions and 21 deletions
|
@ -2,6 +2,10 @@
|
|||
#include "ESP32CAN.h"
|
||||
#include "CAN_config.h"
|
||||
|
||||
//TODO before using
|
||||
// Map the final values in update_values_i3_battery, set some to static values if not available (current, discharge max , charge max)
|
||||
// Check if I3 battery stays alive with only 10B and 512. If not, add 12F. If that doesn't help, add more from CAN log (ask Dala)
|
||||
|
||||
/* Do not change code below unless you are sure what you are doing */
|
||||
static unsigned long previousMillis20 = 0; // will store last time a 20ms CAN Message was send
|
||||
static unsigned long previousMillis600 = 0; // will store last time a 600ms CAN Message was send
|
||||
|
@ -13,55 +17,103 @@ static uint8_t CANstillAlive = 12; //counter for checking if CAN is still alive
|
|||
#define LB_MIN_SOC 0 //BMS never goes below this value. We use this info to rescale SOC% sent to Inverter
|
||||
|
||||
CAN_frame_t BMW_10B = {.FIR = {.B = {.DLC = 3,.FF = CAN_frame_std,}},.MsgID = 0x10B,.data = {0xCD, 0x01, 0xFC}};
|
||||
CAN_frame_t BMW_512 = {.FIR = {.B = {.DLC = 8,.FF = CAN_frame_std,}},.MsgID = 0x512,.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12}};
|
||||
CAN_frame_t BMW_512 = {.FIR = {.B = {.DLC = 8,.FF = CAN_frame_std,}},.MsgID = 0x512,.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12}}; //0x512 Network management edme VCU
|
||||
//CAN_frame_t BMW_12F //Might be needed, Wake up ,VCU 100ms
|
||||
//These CAN messages need to be sent towards the battery to keep it alive
|
||||
|
||||
static const uint8_t BMW_10B_0[15] = {0xCD,0x19,0x94,0x6D,0xE0,0x34,0x78,0xDB,0x97,0x43,0x0F,0xF6,0xBA,0x6E,0x81};
|
||||
static const uint8_t BMW_10B_1[15] = {0x01,0x02,0x33,0x34,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x00};
|
||||
static uint8_t BMW_10B_counter = 0;
|
||||
|
||||
|
||||
static int BMS_SOC = 0;
|
||||
static int16_t Battery_Current = 0;
|
||||
static uint16_t Battery_Capacity_kWh = 0;
|
||||
static uint16_t Voltage_Setpoint = 0;
|
||||
static uint16_t Low_SOC = 0;
|
||||
static uint16_t High_SOC = 0;
|
||||
static uint16_t Display_SOC = 0;
|
||||
static uint16_t Calculated_SOC = 0;
|
||||
static uint16_t Battery_Volts = 0;
|
||||
static uint16_t HVBatt_SOC = 0;
|
||||
static uint16_t Battery_Status = 0;
|
||||
static uint16_t DC_link = 0;
|
||||
static int16_t Battery_Power = 0;
|
||||
|
||||
void update_values_i3_battery()
|
||||
{ //This function maps all the values fetched via CAN to the correct parameters used for modbus
|
||||
bms_status = ACTIVE; //Startout in active mode
|
||||
|
||||
SOC;
|
||||
//Calculate the SOC% value to send to inverter
|
||||
Calculated_SOC = (Display_SOC * 10); //Increase decimal amount
|
||||
Calculated_SOC = LB_MIN_SOC + (LB_MAX_SOC - LB_MIN_SOC) * (Calculated_SOC - MINPERCENTAGE) / (MAXPERCENTAGE - MINPERCENTAGE);
|
||||
if (Calculated_SOC < 0)
|
||||
{ //We are in the real SOC% range of 0-20%, always set SOC sent to inverter as 0%
|
||||
Calculated_SOC = 0;
|
||||
}
|
||||
if (Calculated_SOC > 1000)
|
||||
{ //We are in the real SOC% range of 80-100%, always set SOC sent to inverter as 100%
|
||||
Calculated_SOC = 1000;
|
||||
}
|
||||
SOC = (Calculated_SOC * 10); //increase LB_SOC range from 0-100.0 -> 100.00
|
||||
|
||||
battery_voltage;
|
||||
battery_voltage = Battery_Volts; //Unit V+1 (5000 = 500.0V)
|
||||
|
||||
battery_current;
|
||||
battery_current = Battery_Current;
|
||||
|
||||
capacity_Wh = BATTERY_WH_MAX;
|
||||
|
||||
remaining_capacity_Wh;
|
||||
remaining_capacity_Wh = (Battery_Capacity_kWh * 1000);
|
||||
|
||||
max_target_discharge_power;
|
||||
if(SOC > 9900) //If Soc is over 99%, stop charging
|
||||
{
|
||||
max_target_charge_power = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_target_charge_power = 5000; //Hardcoded value for testing. TODO, read real value from battery when discovered
|
||||
}
|
||||
|
||||
max_target_charge_power;
|
||||
if(SOC < 500) //If Soc is under 5%, stop dicharging
|
||||
{
|
||||
max_target_discharge_power = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_target_discharge_power = 5000; //Hardcoded value for testing. TODO, read real value from battery when discovered
|
||||
}
|
||||
|
||||
stat_batt_power;
|
||||
Battery_Power = (Battery_Current * (Battery_Volts/10));
|
||||
|
||||
temperature_min;
|
||||
stat_batt_power = Battery_Power; //TODO, is mapping OK?
|
||||
|
||||
temperature_min; //hardcoded to 5*C in startup, TODO, find from battery CAN later
|
||||
|
||||
temperature_max;
|
||||
temperature_max; //hardcoded to 6*C in startup, TODO, find from battery CAN later
|
||||
|
||||
/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
|
||||
if(!CANstillAlive)
|
||||
{
|
||||
bms_status = FAULT;
|
||||
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
|
||||
bms_status = FAULT;
|
||||
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
|
||||
}
|
||||
else
|
||||
{
|
||||
CANstillAlive--;
|
||||
CANstillAlive--;
|
||||
}
|
||||
|
||||
if(printValues)
|
||||
{ //values heading towards the inverter
|
||||
Serial.print("SOC%: ");
|
||||
Serial.println(BMS_SOC);
|
||||
Serial.print("SOC% battery: ");
|
||||
Serial.print(Display_SOC);
|
||||
Serial.print(" SOC% sent to inverter: ");
|
||||
Serial.print(SOC);
|
||||
Serial.print(" Battery voltage: ");
|
||||
Serial.print(battery_voltage);
|
||||
Serial.print(" Remaining Wh: ");
|
||||
Serial.print(remaining_capacity_Wh);
|
||||
Serial.print(" Max charge power: ");
|
||||
Serial.print(max_target_charge_power);
|
||||
Serial.print(" Max discharge power: ");
|
||||
Serial.print(max_target_discharge_power);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,9 +122,44 @@ void receive_can_i3_battery(CAN_frame_t rx_frame)
|
|||
CANstillAlive = 12;
|
||||
switch (rx_frame.MsgID)
|
||||
{
|
||||
case 0x431: //Battery capacity
|
||||
case 0x431: //Battery capacity [200ms]
|
||||
Battery_Capacity_kWh = (((rx_frame.data.u8[1] & 0x0F) << 8 | rx_frame.data.u8[5])) / 50;
|
||||
break;
|
||||
case 0x432: //SOC% charged
|
||||
case 0x432: //SOC% charged [200ms]
|
||||
Voltage_Setpoint = ((rx_frame.data.u8[1] << 4 | rx_frame.data.u8[0] >> 4)) / 10;
|
||||
Low_SOC = (rx_frame.data.u8[2] / 2);
|
||||
High_SOC = (rx_frame.data.u8[3] / 2);
|
||||
Display_SOC = (rx_frame.data.u8[4] / 2);
|
||||
break;
|
||||
case 0x112: //BMS status [10ms]
|
||||
CANstillAlive = 12;
|
||||
Battery_Current = ((rx_frame.data.u8[1] << 8 | rx_frame.data.u8[0]) / 10) - 819; //Amps
|
||||
Battery_Volts = (rx_frame.data.u8[3] << 8 | rx_frame.data.u8[2]); //500.0 V
|
||||
HVBatt_SOC = ((rx_frame.data.u8[5] & 0x0F) << 4 | rx_frame.data.u8[4]) / 10;
|
||||
Battery_Status = (rx_frame.data.u8[6] & 0x0F);
|
||||
DC_link = rx_frame.data.u8[7];
|
||||
break;
|
||||
case 0x430:
|
||||
break;
|
||||
case 0x1FA:
|
||||
break;
|
||||
case 0x40D:
|
||||
break;
|
||||
case 0x2FF:
|
||||
break;
|
||||
case 0x239:
|
||||
break;
|
||||
case 0x2BD:
|
||||
break;
|
||||
case 0x2F5:
|
||||
break;
|
||||
case 0x3EB:
|
||||
break;
|
||||
case 0x363:
|
||||
break;
|
||||
case 0x507:
|
||||
break;
|
||||
case 0x41C:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* Select battery used */
|
||||
//#define BATTERY_TYPE_LEAF // See NISSAN-LEAF-BATTERY.h for more LEAF battery settings
|
||||
#define BATTERY_TYPE_LEAF // See NISSAN-LEAF-BATTERY.h for more LEAF battery settings
|
||||
//#define TESLA_MODEL_3_BATTERY // See TESLA-MODEL-3-BATTERY.h for more Tesla battery settings
|
||||
//#define RENAULT_ZOE_BATTERY // See RENAULT-ZOE-BATTERY.h for more Zoe battery settings
|
||||
#define BMW_I3_BATTERY // See BMW-I3-BATTERY.h for more i3 battery settings
|
||||
//#define BMW_I3_BATTERY // See BMW-I3-BATTERY.h for more i3 battery settings
|
||||
//#define IMIEV_ION_CZERO_BATTERY // See IMIEV-CZERO-ION-BATTERY.h for more triplet battery settings
|
||||
//#define KIA_HYUNDAI_64_BATTERY // See KIA-HYUNDAI-64-BATTERY.h for more battery settings
|
||||
//#define CHADEMO // See CHADEMO.h for more Chademo related settings
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue