mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 02:39:57 +02:00
Add safeguards to avoid div0
This commit is contained in:
parent
2c434624c6
commit
eda565f29b
4 changed files with 67 additions and 46 deletions
|
@ -116,22 +116,27 @@ static bool initialDataSent = 0;
|
||||||
|
|
||||||
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||||
//Calculate values
|
//Calculate values
|
||||||
charge_current =
|
|
||||||
((datalayer.battery.status.max_charge_power_W * 10) /
|
if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
charge_current =
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
((datalayer.battery.status.max_charge_power_W * 10) /
|
||||||
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
//The above calculation results in (30 000*10)/3700=81A
|
||||||
|
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
|
||||||
|
discharge_current =
|
||||||
|
((datalayer.battery.status.max_discharge_power_W * 10) /
|
||||||
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
//The above calculation results in (30 000*10)/3700=81A
|
||||||
|
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
}
|
||||||
|
|
||||||
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
||||||
charge_current =
|
charge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
||||||
}
|
}
|
||||||
|
|
||||||
discharge_current =
|
|
||||||
((datalayer.battery.status.max_discharge_power_W * 10) /
|
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
|
||||||
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
|
||||||
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
||||||
discharge_current =
|
discharge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
|
|
|
@ -105,22 +105,24 @@ static uint16_t ampere_hours_remaining = 0;
|
||||||
|
|
||||||
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the correct CAN messages
|
||||||
//Calculate values
|
//Calculate values
|
||||||
charge_current =
|
|
||||||
((datalayer.battery.status.max_charge_power_W * 10) /
|
if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
discharge_current =
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
((datalayer.battery.status.max_discharge_power_W * 10) /
|
||||||
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
charge_current =
|
||||||
|
((datalayer.battery.status.max_charge_power_W * 10) /
|
||||||
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
}
|
||||||
|
|
||||||
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
||||||
charge_current =
|
charge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
||||||
}
|
}
|
||||||
|
|
||||||
discharge_current =
|
|
||||||
((datalayer.battery.status.max_discharge_power_W * 10) /
|
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
|
||||||
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
|
||||||
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
||||||
discharge_current =
|
discharge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
|
@ -130,8 +132,10 @@ void update_values_can_inverter() { //This function maps all the values fetched
|
||||||
temperature_average =
|
temperature_average =
|
||||||
((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2);
|
((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2);
|
||||||
|
|
||||||
ampere_hours_remaining = ((datalayer.battery.status.remaining_capacity_Wh / datalayer.battery.status.voltage_dV) *
|
if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0
|
||||||
100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah)
|
ampere_hours_remaining = ((datalayer.battery.status.remaining_capacity_Wh / datalayer.battery.status.voltage_dV) *
|
||||||
|
100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah)
|
||||||
|
}
|
||||||
|
|
||||||
//Map values to CAN messages
|
//Map values to CAN messages
|
||||||
//Maxvoltage (eg 400.0V = 4000 , 16bits long)
|
//Maxvoltage (eg 400.0V = 4000 , 16bits long)
|
||||||
|
|
|
@ -163,22 +163,24 @@ InvInitState invInitState = SYSTEM_FREQUENCY;
|
||||||
|
|
||||||
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the inverter CAN
|
void update_values_can_inverter() { //This function maps all the values fetched from battery CAN to the inverter CAN
|
||||||
//Calculate values
|
//Calculate values
|
||||||
charge_current =
|
|
||||||
((datalayer.battery.status.max_charge_power_W * 10) /
|
if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
charge_current =
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
((datalayer.battery.status.max_charge_power_W * 10) /
|
||||||
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
charge_current = (charge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
discharge_current =
|
||||||
|
((datalayer.battery.status.max_discharge_power_W * 10) /
|
||||||
|
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
||||||
|
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
||||||
|
}
|
||||||
|
|
||||||
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
if (charge_current > datalayer.battery.info.max_charge_amp_dA) {
|
||||||
charge_current =
|
charge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
.max_charge_amp_dA; //Cap the value to the max allowed Amp. Some inverters cannot handle large values.
|
||||||
}
|
}
|
||||||
|
|
||||||
discharge_current =
|
|
||||||
((datalayer.battery.status.max_discharge_power_W * 10) /
|
|
||||||
datalayer.battery.status.voltage_dV); //Charge power in W , max volt in V+1decimal (P=UI, solve for I)
|
|
||||||
//The above calculation results in (30 000*10)/3700=81A
|
|
||||||
discharge_current = (discharge_current * 10); //Value needs a decimal before getting sent to inverter (81.0A)
|
|
||||||
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
if (discharge_current > datalayer.battery.info.max_discharge_amp_dA) {
|
||||||
discharge_current =
|
discharge_current =
|
||||||
datalayer.battery.info
|
datalayer.battery.info
|
||||||
|
|
|
@ -136,28 +136,38 @@ void update_values_can_inverter() { //This function maps all the values fetched
|
||||||
((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2);
|
((datalayer.battery.status.temperature_max_dC + datalayer.battery.status.temperature_min_dC) / 2);
|
||||||
|
|
||||||
//datalayer.battery.status.max_charge_power_W (30000W max)
|
//datalayer.battery.status.max_charge_power_W (30000W max)
|
||||||
if (datalayer.battery.status.reported_soc > 9999) //99.99%
|
if (datalayer.battery.status.reported_soc > 9999) { // 99.99%
|
||||||
{ //Additional safety incase SOC% is 100, then do not charge battery further
|
// Additional safety incase SOC% is 100, then do not charge battery further
|
||||||
max_charge_rate_amp = 0;
|
max_charge_rate_amp = 0;
|
||||||
} else { //We can pass on the battery charge rate (in W) to the inverter (that takes A)
|
} else { // We can pass on the battery charge rate (in W) to the inverter (that takes A)
|
||||||
if (datalayer.battery.status.max_charge_power_W >= 30000) {
|
if (datalayer.battery.status.max_charge_power_W >= 30000) {
|
||||||
max_charge_rate_amp = 75; //Incase battery can take over 30kW, cap value to 75A
|
max_charge_rate_amp = 75; // Incase battery can take over 30kW, cap value to 75A
|
||||||
} else { //Calculate the W value into A
|
} else { // Calculate the W value into A
|
||||||
max_charge_rate_amp =
|
if (datalayer.battery.status.voltage_dV > 10) {
|
||||||
(datalayer.battery.status.max_charge_power_W / (datalayer.battery.status.voltage_dV * 0.1)); // P/U = I
|
max_charge_rate_amp =
|
||||||
|
datalayer.battery.status.max_charge_power_W / (datalayer.battery.status.voltage_dV * 0.1); // P/U=I
|
||||||
|
} else { // We avoid dividing by 0 and crashing the board
|
||||||
|
// If we have no voltage, something has gone wrong, do not allow charging
|
||||||
|
max_charge_rate_amp = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//datalayer.battery.status.max_discharge_power_W (30000W max)
|
//datalayer.battery.status.max_discharge_power_W (30000W max)
|
||||||
if (datalayer.battery.status.reported_soc < 100) //1.00%
|
if (datalayer.battery.status.reported_soc < 100) { // 1.00%
|
||||||
{ //Additional safety incase SOC% is below 1, then do not charge battery further
|
// Additional safety in case SOC% is below 1, then do not discharge battery further
|
||||||
max_discharge_rate_amp = 0;
|
max_discharge_rate_amp = 0;
|
||||||
} else { //We can pass on the battery discharge rate to the inverter
|
} else { // We can pass on the battery discharge rate to the inverter
|
||||||
if (datalayer.battery.status.max_discharge_power_W >= 30000) {
|
if (datalayer.battery.status.max_discharge_power_W >= 30000) {
|
||||||
max_discharge_rate_amp = 75; //Incase battery can be charged with over 30kW, cap value to 75A
|
max_discharge_rate_amp = 75; // Incase battery can be charged with over 30kW, cap value to 75A
|
||||||
} else { //Calculate the W value into A
|
} else { // Calculate the W value into A
|
||||||
max_discharge_rate_amp =
|
if (datalayer.battery.status.voltage_dV > 10) {
|
||||||
(datalayer.battery.status.max_discharge_power_W / (datalayer.battery.status.voltage_dV * 0.1)); // P/U = I
|
max_discharge_rate_amp =
|
||||||
|
datalayer.battery.status.max_discharge_power_W / (datalayer.battery.status.voltage_dV * 0.1); // P/U=I
|
||||||
|
} else { // We avoid dividing by 0 and crashing the board
|
||||||
|
// If we have no voltage, something has gone wrong, do not allow discharging
|
||||||
|
max_discharge_rate_amp = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue