Skip to content

Commit

Permalink
added status and module voltages reading for Pylon HV BMS
Browse files Browse the repository at this point in the history
  • Loading branch information
ai-republic committed Feb 11, 2024
1 parent 21a06b8 commit 50dd4a1
Show file tree
Hide file tree
Showing 14 changed files with 246 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private void getCellBalanceState(final DalyMessage msg, final BMS bms) throws IO
private void getFailureCodes(final DalyMessage msg, final BMS bms) throws IOException // 0x98
{
final BatteryPack battery = bms.getBatteryPack();
byte byteValue = msg.data.get();
byte byteValue = msg.data.get(0);
/* 0x00 */
battery.alarms.levelOneCellVoltageTooHigh.value = bitRead(byteValue, 0);
battery.alarms.levelTwoCellVoltageTooHigh.value = bitRead(byteValue, 1);
Expand Down Expand Up @@ -425,7 +425,7 @@ private void getFailureCodes(final DalyMessage msg, final BMS bms) throws IOExce
battery.alarms.failureOfEEPROMStorageModule.value = bitRead(byteValue, 3);
battery.alarms.failureOfRealtimeClockModule.value = bitRead(byteValue, 4);
battery.alarms.failureOfPrechargeModule.value = bitRead(byteValue, 5);
battery.alarms.failureOfVehicleCommunicationModule.value = bitRead(byteValue, 6);
battery.alarms.failureOfInternalCommunicationModule.value = bitRead(byteValue, 6);
battery.alarms.failureOfIntranetCommunicationModule.value = bitRead(byteValue, 7);

/* 0x06 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void readAlarms(final BatteryPack pack, final ByteBuffer data) {

// external communication failure
bits = read2Bits(value, 2);
pack.alarms.failureOfVehicleCommunicationModule.value = bits != 0;
pack.alarms.failureOfInternalCommunicationModule.value = bits != 0;

// internal communication failure
bits = read2Bits(value, 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void readAlarms(final BatteryPack pack, final ByteBuffer data) {

// external communication failure
bits = read2Bits(value, 2);
pack.alarms.failureOfVehicleCommunicationModule.value = bits != 0;
pack.alarms.failureOfInternalCommunicationModule.value = bits != 0;

// internal communication failure
bits = read2Bits(value, 4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.airepublic.bmstoinverter.core.BMS;
import com.airepublic.bmstoinverter.core.Port;
import com.airepublic.bmstoinverter.core.bms.data.BatteryPack;
import com.airepublic.bmstoinverter.core.util.Util;

/**
* The class to handle CAN messages from a Pylon {@link BMS}.
Expand Down Expand Up @@ -96,19 +97,19 @@ private void readBatteryVoltage(final BatteryPack pack, final ByteBuffer data) {
private void requestChargeDischargeConfigChange(final BatteryPack pack, final ByteBuffer data) {
final byte bits = data.get();

if (bitRead(bits, 4)) {
if (Util.bit(bits, 4)) {
// request force-charge II
}

if (bitRead(bits, 5)) {
if (Util.bit(bits, 5)) {
// request force-charge I
}

if (bitRead(bits, 6)) {
if (Util.bit(bits, 6)) {
// request discharge enable
}

if (bitRead(bits, 7)) {
if (Util.bit(bits, 7)) {
// request charge enable
}
}
Expand Down Expand Up @@ -155,22 +156,22 @@ private void readAlarms(final BatteryPack pack, final ByteBuffer data) {
int value = data.getInt();

// protection alarms
pack.alarms.levelTwoCellVoltageTooHigh.value = bitRead(value, 1);
pack.alarms.levelTwoCellVoltageTooLow.value = bitRead(value, 2);
pack.alarms.levelTwoDischargeTempTooHigh.value = bitRead(value, 3);
pack.alarms.levelTwoDischargeTempTooLow.value = bitRead(value, 4);
pack.alarms.levelTwoDischargeCurrentTooHigh.value = bitRead(value, 7);
pack.alarms.levelTwoChargeCurrentTooHigh.value = bitRead(value, 8);
pack.alarms.levelTwoCellVoltageTooHigh.value = Util.bit(value, 1);
pack.alarms.levelTwoCellVoltageTooLow.value = Util.bit(value, 2);
pack.alarms.levelTwoDischargeTempTooHigh.value = Util.bit(value, 3);
pack.alarms.levelTwoDischargeTempTooLow.value = Util.bit(value, 4);
pack.alarms.levelTwoDischargeCurrentTooHigh.value = Util.bit(value, 7);
pack.alarms.levelTwoChargeCurrentTooHigh.value = Util.bit(value, 8);

// warning alarms
pack.alarms.levelOneCellVoltageTooHigh.value = bitRead(value, 17);
pack.alarms.levelOneCellVoltageTooLow.value = bitRead(value, 18);
pack.alarms.levelOneChargeTempTooHigh.value = bitRead(value, 19);
pack.alarms.levelOneChargeTempTooLow.value = bitRead(value, 20);
pack.alarms.levelOneDischargeCurrentTooHigh.value = bitRead(value, 23);
pack.alarms.levelOneChargeCurrentTooHigh.value = bitRead(value, 24);
pack.alarms.failureOfIntranetCommunicationModule.value = bitRead(value, 27);
pack.alarms.levelTwoCellVoltageDifferenceTooHigh.value = bitRead(value, 28);
pack.alarms.levelOneCellVoltageTooHigh.value = Util.bit(value, 17);
pack.alarms.levelOneCellVoltageTooLow.value = Util.bit(value, 18);
pack.alarms.levelOneChargeTempTooHigh.value = Util.bit(value, 19);
pack.alarms.levelOneChargeTempTooLow.value = Util.bit(value, 20);
pack.alarms.levelOneDischargeCurrentTooHigh.value = Util.bit(value, 23);
pack.alarms.levelOneChargeCurrentTooHigh.value = Util.bit(value, 24);
pack.alarms.failureOfIntranetCommunicationModule.value = Util.bit(value, 27);
pack.alarms.levelTwoCellVoltageDifferenceTooHigh.value = Util.bit(value, 28);

pack.numberOfCells = data.get();

Expand All @@ -184,9 +185,4 @@ private void readAlarms(final BatteryPack pack, final ByteBuffer data) {

}


private boolean bitRead(final int value, final int index) {
return (value >> index & 1) == 1;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.airepublic.bmstoinverter.core.bms.data.BatteryPack;
import com.airepublic.bmstoinverter.core.bms.data.EnergyStorage;
import com.airepublic.bmstoinverter.core.protocol.can.CANPort;
import com.airepublic.bmstoinverter.core.util.Util;

import jakarta.inject.Inject;

Expand Down Expand Up @@ -189,57 +190,85 @@ private void readCellTemperature(final BatteryPack pack, final ByteBuffer data)

private void readAlarms(final BatteryPack pack, final ByteBuffer data) {
// Basic status
data.get();
final byte status = data.get();

switch (Util.bits(status, 0, 3)) {
case 0:
pack.chargeDischargeStatus = "Sleep";
break;
case 1:
pack.chargeDischargeStatus = "Charge";
break;
case 2:
pack.chargeDischargeStatus = "Discharge";
break;
case 3:
pack.chargeDischargeStatus = "Idle";
break;
default:
pack.chargeDischargeStatus = null;
}

pack.forceCharge = Util.bit(status, 3);
pack.cellBalanceActive = Util.bit(status, 4);

// Cycle period
data.getShort();

// Error
final byte error = data.get();
final byte fault = data.get();
pack.alarms.failureOfVoltageSensorModule.value = Util.bit(fault, 0);
pack.alarms.failureOfTemperatureSensorModule.value = Util.bit(fault, 1);
pack.alarms.failureOfInternalCommunicationModule.value = Util.bit(fault, 2);
pack.alarms.failureOfMainVoltageSensorModule.value = Util.bit(fault, 3);
pack.alarms.failureOfAFEAcquisitionModule.value = Util.bit(fault, 4);
pack.alarms.failureOfChargeFETTBreaker.value = Util.bit(fault, 5);

// Alarm
final short alarms = data.getShort();
pack.alarms.levelOneCellVoltageTooLow.value = Util.bit(alarms, 0);
pack.alarms.levelOneCellVoltageTooHigh.value = Util.bit(alarms, 1);
pack.alarms.levelOneStateOfChargeTooLow.value = Util.bit(alarms, 2);
pack.alarms.levelOneStateOfChargeTooHigh.value = Util.bit(alarms, 3);
pack.alarms.levelOneChargeTempTooLow.value = Util.bit(alarms, 4);
pack.alarms.levelOneChargeTempTooHigh.value = Util.bit(alarms, 5);
pack.alarms.levelOneDischargeTempTooLow.value = Util.bit(alarms, 6);
pack.alarms.levelOneDischargeTempTooHigh.value = Util.bit(alarms, 7);
pack.alarms.levelOneChargeCurrentTooHigh.value = Util.bit(alarms, 8);
pack.alarms.levelOneDischargeCurrentTooHigh.value = Util.bit(alarms, 9);
pack.alarms.levelOnePackVoltageTooLow.value = Util.bit(alarms, 10);
pack.alarms.levelOnePackVoltageTooHigh.value = Util.bit(alarms, 11);

// Protection
final short protection = data.getShort();

pack.alarms.levelTwoCellVoltageTooLow.value = Util.bit(alarms, 0);
pack.alarms.levelTwoCellVoltageTooHigh.value = Util.bit(alarms, 1);
pack.alarms.levelTwoStateOfChargeTooLow.value = Util.bit(alarms, 2);
pack.alarms.levelTwoStateOfChargeTooHigh.value = Util.bit(alarms, 3);
pack.alarms.levelTwoChargeTempTooLow.value = Util.bit(alarms, 4);
pack.alarms.levelTwoChargeTempTooHigh.value = Util.bit(alarms, 5);
pack.alarms.levelTwoDischargeTempTooLow.value = Util.bit(alarms, 6);
pack.alarms.levelTwoDischargeTempTooHigh.value = Util.bit(alarms, 7);
pack.alarms.levelTwoChargeCurrentTooHigh.value = Util.bit(alarms, 8);
pack.alarms.levelTwoDischargeCurrentTooHigh.value = Util.bit(alarms, 9);
pack.alarms.levelTwoPackVoltageTooLow.value = Util.bit(alarms, 10);
pack.alarms.levelTwoPackVoltageTooHigh.value = Util.bit(alarms, 11);
}


private void readModuleVoltage(final BatteryPack pack, final ByteBuffer data) {
// maximum module voltage (0.001V)
energyStorage.maxModulemV = data.getShort();
// minimum module voltage (0.001V)
energyStorage.minModulemV = data.getShort();
// pack number with maximum module voltage
energyStorage.maxModulemVNum = data.getShort();
// pack number with minimum module voltage
energyStorage.minModulemVNum = data.getShort();
}


private void readModuleTemperature(final BatteryPack pack, final ByteBuffer data) {
}


private static int read2Bits(final byte value, final int index) {
String str = Integer.toBinaryString(value);
System.out.println("Str to parse: " + str);

// remove leading bits
if (str.length() > 8) {
str = str.substring(str.length() - 8);
}

// pad leading 0's
while (str.length() < 8) {
str = "0" + str;
}

System.out.println("Padded str: " + str);
final String bits = str.substring(index, 2);
System.out.println("Read 2bits: " + bits);

switch (bits) {
case "00":
return 0;
case "01":
return 1;
case "10":
return 2;
case "11":
return 3;
}

return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ private List<String> getAlarmState(final BatteryPack pack) {
if (alarms.failureOfPrechargeModule.value == true) {
activeAlarms.add(alarms.failureOfPrechargeModule.key);
}
if (alarms.failureOfVehicleCommunicationModule.value == true) {
activeAlarms.add(alarms.failureOfVehicleCommunicationModule.key);
if (alarms.failureOfInternalCommunicationModule.value == true) {
activeAlarms.add(alarms.failureOfInternalCommunicationModule.key);
}
if (alarms.failureOfIntranetCommunicationModule.value == true) {
activeAlarms.add(alarms.failureOfIntranetCommunicationModule.key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class Alarms {
public Alarm failureOfEEPROMStorageModule = new Alarm("failureOfEEPROMStorageModule", false);
public Alarm failureOfRealtimeClockModule = new Alarm("failureOfRealtimeClockModule", false);
public Alarm failureOfPrechargeModule = new Alarm("failureOfPrechargeModule", false);
public Alarm failureOfVehicleCommunicationModule = new Alarm("failureOfVehicleCommunicationModule", false);
public Alarm failureOfInternalCommunicationModule = new Alarm("failureOfInternalCommunicationModule", false);
public Alarm failureOfIntranetCommunicationModule = new Alarm("failureOfIntranetCommunicationModule", false);

/* 0x06 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public class BatteryPack {
public boolean chargeMOSState;
/** discharge MOSFET state */
public boolean disChargeMOSState;
/** force charging */
public boolean forceCharge;

/** BMS life (0~255 cycles)? */
public int bmsHeartBeat;
/** residual capacity mAH */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
public class EnergyStorage {
private transient final static Gson gson = new Gson();
private BatteryPack[] batteryPacks;
/** The maximum module voltage (0.001V) of a pack */
public short maxModulemV;
/** The minimum module voltage (0.001V) of a pack */
public short minModulemV;
/** The number of the pack with the maximum voltage */
public short maxModulemVNum;
/** The number of the pack with the minimum voltage */
public short minModulemVNum;

/**
* Constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,30 @@ public static void updateSystemProperties(final Path config) {
}
}
}


/**
* Reads the bit at the specified index of the value.
*
* @param value the value
* @param index the index of the bit
* @return true if the bit is 1, otherwise false
*/
public static boolean bit(final int value, final int index) {
return (value >> index & 1) == 1;
}


/**
* Reads the specified number of bits starting at the specified index.
*
* @param value the value to read from
* @param index the index of the first bit to read in the value
* @param length the number of bits to read
* @return the value represented by the returned bits
*/
public static int bits(final int value, final int index, final int length) {
return value >> index & (1 << length) - 1;
}

}
Loading

0 comments on commit 50dd4a1

Please sign in to comment.