diff --git a/Software/src/inverter/BYD-CAN.cpp b/Software/src/inverter/BYD-CAN.cpp index 7d159119..0fdc837a 100644 --- a/Software/src/inverter/BYD-CAN.cpp +++ b/Software/src/inverter/BYD-CAN.cpp @@ -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 //Calculate values - 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) - //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) + + if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0 + 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) + //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) { charge_current = datalayer.battery.info .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) { discharge_current = datalayer.battery.info diff --git a/Software/src/inverter/SMA-CAN.cpp b/Software/src/inverter/SMA-CAN.cpp index 839be6c5..095bc99d 100644 --- a/Software/src/inverter/SMA-CAN.cpp +++ b/Software/src/inverter/SMA-CAN.cpp @@ -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 //Calculate values - 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) - //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) + + if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0 + 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) + 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) { charge_current = datalayer.battery.info .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) { discharge_current = datalayer.battery.info @@ -130,8 +132,10 @@ void update_values_can_inverter() { //This function maps all the values fetched temperature_average = ((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) * - 100); //(WH[10000] * V+1[3600])*100 = 270 (27.0Ah) + if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0 + 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 //Maxvoltage (eg 400.0V = 4000 , 16bits long) diff --git a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp index 916fbf1b..a7da471e 100644 --- a/Software/src/inverter/SMA-TRIPOWER-CAN.cpp +++ b/Software/src/inverter/SMA-TRIPOWER-CAN.cpp @@ -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 //Calculate values - 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) - //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) + + if (datalayer.battery.status.voltage_dV > 10) { // Only update value when we have voltage available to avoid div0 + 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) + 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) { charge_current = datalayer.battery.info .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) { discharge_current = datalayer.battery.info diff --git a/Software/src/inverter/SOLAX-CAN.cpp b/Software/src/inverter/SOLAX-CAN.cpp index 9b103e1b..9c352a90 100644 --- a/Software/src/inverter/SOLAX-CAN.cpp +++ b/Software/src/inverter/SOLAX-CAN.cpp @@ -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.max_charge_power_W (30000W max) - if (datalayer.battery.status.reported_soc > 9999) //99.99% - { //Additional safety incase SOC% is 100, then do not charge battery further + if (datalayer.battery.status.reported_soc > 9999) { // 99.99% + // Additional safety incase SOC% is 100, then do not charge battery further 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) { - max_charge_rate_amp = 75; //Incase battery can take over 30kW, cap value to 75A - } else { //Calculate the W value into A - max_charge_rate_amp = - (datalayer.battery.status.max_charge_power_W / (datalayer.battery.status.voltage_dV * 0.1)); // P/U = I + max_charge_rate_amp = 75; // Incase battery can take over 30kW, cap value to 75A + } else { // Calculate the W value into A + if (datalayer.battery.status.voltage_dV > 10) { + 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) - if (datalayer.battery.status.reported_soc < 100) //1.00% - { //Additional safety incase SOC% is below 1, then do not charge battery further + if (datalayer.battery.status.reported_soc < 100) { // 1.00% + // Additional safety in case SOC% is below 1, then do not discharge battery further 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) { - max_discharge_rate_amp = 75; //Incase battery can be charged with over 30kW, cap value to 75A - } else { //Calculate the W value into A - max_discharge_rate_amp = - (datalayer.battery.status.max_discharge_power_W / (datalayer.battery.status.voltage_dV * 0.1)); // P/U = I + max_discharge_rate_amp = 75; // Incase battery can be charged with over 30kW, cap value to 75A + } else { // Calculate the W value into A + if (datalayer.battery.status.voltage_dV > 10) { + 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; + } } }