900 lines
47 KiB
C#
900 lines
47 KiB
C#
using System;
|
|
|
|
using LFP_Manager.DataStructure;
|
|
using LFP_Manager.Utils;
|
|
|
|
namespace LFP_Manager.Function
|
|
{
|
|
// 1. Define the data type
|
|
public struct PACKET_HEADER
|
|
{
|
|
public byte Index; // 3
|
|
public byte R; // 1
|
|
public byte DP; // 1
|
|
public byte PF; // 8
|
|
public byte PS; // 8
|
|
public byte SA; // 8
|
|
}
|
|
|
|
class csCanCommFunction
|
|
{
|
|
public static void CanRxProcess(ref CommConfig aConfig, int sId, UInt32 ExID, byte[] data, ref DeviceSystemData rSystemData, DateTime rTime)
|
|
{
|
|
PACKET_HEADER PacketHeader = CovertPtoH(ExID);
|
|
|
|
if (PacketHeader.SA == (200 + sId))
|
|
{
|
|
if (data.Length > 0)
|
|
{
|
|
int REF = 0;
|
|
|
|
rSystemData.CommFail = false;
|
|
rSystemData.ShelfCommFail = false;
|
|
rSystemData.LastRxTime = rTime;
|
|
|
|
switch (PacketHeader.PF)
|
|
{
|
|
case 201: // Device heartbeat
|
|
rSystemData.heatbeat = (UInt32)((data[0] << 24)
|
|
| (data[1] << 16)
|
|
| (data[2] << 8)
|
|
| (data[3] << 0));
|
|
rSystemData.OneBuffTime = (data[4] << 8) | data[5];
|
|
rSystemData.AllBuffTime = (data[6] << 8) | data[7];
|
|
break;
|
|
case 1: // Send data 0x01
|
|
break;
|
|
case 11: // Module Voltage, Current
|
|
rSystemData.ValueData.voltageOfPack = (short)((data[0] * 256) + data[1]);
|
|
//rSystemData.ValueData.rSOC = (short)(data[2]);
|
|
rSystemData.CalibriationData.ForcedBalancing.AutoB = (data[3] == 0x01) ? true : false;
|
|
rSystemData.StatusData.warning = (short)((data[4] << 8) | data[5]);
|
|
rSystemData.StatusData.protect = (short)((data[6] << 8) | data[7]);
|
|
break;
|
|
case 12: // Status code 2, Software version
|
|
rSystemData.StatusData.batteryStatusA = (short)((data[0] << 8) | data[1]);
|
|
rSystemData.StatusData.status = (short)(data[2]); // Op Status
|
|
|
|
rSystemData.ValueData.fw_ver[0] = (byte)((((data[6] * 256) + data[7]) >> 12) & 0xf);
|
|
rSystemData.ValueData.fw_ver[1] = (byte)((((data[6] * 256) + data[7]) >> 8) & 0xf);
|
|
rSystemData.ValueData.fw_ver[2] = (byte)((((data[6] * 256) + data[7]) >> 4) & 0xf);
|
|
rSystemData.ValueData.fw_ver[3] = (byte)((((data[6] * 256) + data[7]) >> 0) & 0xf);
|
|
break;
|
|
case 13: // Status code 3
|
|
rSystemData.StatusData.batteryStatusB = (short)((data[0] << 8) | data[1]); // Battery Status 1
|
|
rSystemData.StatusData.protect1 = (short)((data[2] << 8) | data[3]); // Protection 1
|
|
break;
|
|
|
|
case 15: // Balancing Status - Active Balancing
|
|
rSystemData.StatusData.BalanceEnable = (uint)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3] << 0));
|
|
rSystemData.StatusData.BalanceMode = (uint)((data[4] << 24) | (data[5] << 16) | (data[6] << 8) | (data[7] << 0));
|
|
break;
|
|
|
|
case 31: // Cell Temperature #1 ~ #4
|
|
case 32: // Cell Temperature #5 ~ #8
|
|
case 33: // Cell Temperature #9 ~ #12
|
|
case 34: // Cell Temperature #13 ~ #16
|
|
REF = PacketHeader.PF - 31;
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (((REF * 4) + i) < rSystemData.tempQty)
|
|
rSystemData.ValueData.CellTemperature[(REF * 4) + i] = (short)(((data[(i * 2)] * 256) + data[(i * 2) + 1]) - 800);
|
|
}
|
|
MakeMaxAvgMinTemperature(ref rSystemData);
|
|
break;
|
|
case 41:
|
|
rSystemData.ValueData.rSOC = (short)((data[0] << 8) | data[1]);
|
|
break;
|
|
case 191: // Cell Voltage 1 ~ 4
|
|
case 192: // Cell Voltage 5 ~ 8
|
|
case 193: // Cell Voltage 9 ~ 12
|
|
case 194: // Cell Voltage 13 ~ 16
|
|
case 195: // Cell Voltage 17 ~ 20
|
|
case 196: // Cell Voltage 21 ~ 24
|
|
case 197: // Cell Voltage 25 ~ 28
|
|
case 198: // Cell Voltage 29 ~ 32
|
|
case 199: // Cell Voltage 33 ~ 36
|
|
REF = PacketHeader.PF - 191;
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (((REF * 4) + i) < rSystemData.cellQty)
|
|
rSystemData.ValueData.CellVoltage[(REF * 4) + i] = (ushort)((data[(i * 2)] * 256) + data[(i * 2) + 1]);
|
|
}
|
|
rSystemData = MakeMaxAvgMinCellVoltage(rSystemData);
|
|
break;
|
|
case 111: // Cell Balancing Status
|
|
switch (aConfig.TargetModelIndex)
|
|
{
|
|
case 0: // PR-57150
|
|
rSystemData.StatusData.cellBalanceValue = (ushort)((data[0] << 8) + data[1]);
|
|
rSystemData.StatusData.cellBalanceEndGap = (short)(data[2]);
|
|
rSystemData.StatusData.cellBalanceFlag = (short)(data[3]);
|
|
rSystemData.StatusData.cellBallanceStatusLv = (uint)((data[4] << 0) | (data[5] << 8) | (data[6] << 16));
|
|
rSystemData.StatusData.cellBalanceInterval = (short)(data[7]);
|
|
break;
|
|
case 3: // PR-102150
|
|
rSystemData.StatusData.cellBalanceValue = (ushort)((data[0] << 8) + data[1]);
|
|
rSystemData.StatusData.cellBalanceEndGap = (short)(data[2] & 0x7F);
|
|
rSystemData.StatusData.cellBalanceFlag = (short)((data[2] >> 7) & 0x01);
|
|
rSystemData.StatusData.cellBalanceInterval = (short)(data[3]);
|
|
rSystemData.StatusData.cellBallanceStatusLv = (uint)((data[4] << 0) | (data[5] << 8)
|
|
| (data[6] << 16) | (data[7] << 24));
|
|
break;
|
|
case 4: // PR-115300
|
|
rSystemData.StatusData.cellBalanceValue = (ushort)((data[0] << 8) + data[1]);
|
|
rSystemData.StatusData.cellBalanceEndGap = (short)(data[2] & 0x7F);
|
|
rSystemData.StatusData.cellBalanceFlag = (short)((data[2] >> 7) & 0x01);
|
|
rSystemData.StatusData.cellBalanceInterval = (short)(data[3]);
|
|
rSystemData.StatusData.cellBallanceStatusLv = (uint)((data[4] << 0) | (data[5] << 8)
|
|
| (data[6] << 16) | (data[7] << 24));
|
|
break;
|
|
case 5: // PR-67150
|
|
rSystemData.StatusData.cellBalanceValue = (ushort)((data[0] << 8) + data[1]);
|
|
rSystemData.StatusData.cellBalanceEndGap = (short)(data[2] * 10);
|
|
rSystemData.StatusData.cellBalanceFlag = (short)((data[3] >> 7) & 0x01);
|
|
rSystemData.StatusData.cellBallanceStatusLv = (uint)((data[4] << 0) | (data[5] << 8) | (data[6] << 16));
|
|
rSystemData.StatusData.cellBalanceInterval = (short)(data[7]);
|
|
break;
|
|
default:
|
|
rSystemData.StatusData.cellBalanceValue = (ushort)((data[0] << 8) + data[1]);
|
|
rSystemData.StatusData.cellBalanceFlag = (short)((data[2] >> 7) & 0x01);
|
|
rSystemData.StatusData.cellBalanceEndGap = (short)((data[2] & 0x7F) * 10);
|
|
rSystemData.StatusData.cellBalanceInterval = (short)(data[3]);
|
|
rSystemData.StatusData.cellBallanceStatusLv = (uint)((data[4] << 0) | (data[5] << 8) | (data[6] << 16) | (data[7] << 24));
|
|
break;
|
|
}
|
|
break;
|
|
case 112: // Cell Balancing Status
|
|
rSystemData.StatusData.cellBallanceStatusHv = (uint)((data[0] << 0) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24));
|
|
break;
|
|
case 51: // Cell Voltage Parameter
|
|
rSystemData.ParamData.CellUnderVoltageWarning = (short)((data[0] * 256) + data[1]);
|
|
rSystemData.ParamData.CellUnderVoltageTrip = (short)((data[2] * 256) + data[3]);
|
|
rSystemData.ParamData.CellOverVoltageWarning = (short)((data[4] * 256) + data[5]);
|
|
rSystemData.ParamData.CellOverVoltageTrip = (short)((data[6] * 256) + data[7]);
|
|
break;
|
|
case 71: // System Voltage Parameter
|
|
rSystemData.ParamData.SysUnderVoltageWarning = (short)((data[0] * 256) + data[1]);
|
|
rSystemData.ParamData.SysUnderVoltageTrip = (short)((data[2] * 256) + data[3]);
|
|
rSystemData.ParamData.SysOverVoltageWarning = (short)((data[4] * 256) + data[5]);
|
|
rSystemData.ParamData.SysOverVoltageTrip = (short)((data[6] * 256) + data[7]);
|
|
break;
|
|
case 61: // Temperature Parameter
|
|
rSystemData.ParamData.ChaLowTempWarning = (short)(data[0] - 80);
|
|
rSystemData.ParamData.ChaLowTempTrip = (short)(data[1] - 80);
|
|
rSystemData.ParamData.ChaHighTempWarning = (short)(data[2] - 80);
|
|
rSystemData.ParamData.ChaHighTempTrip = (short)(data[3] - 80);
|
|
rSystemData.ParamData.DchLowTempWarning = (short)(data[4] - 80);
|
|
rSystemData.ParamData.DchLowTempTrip = (short)(data[5] - 80);
|
|
rSystemData.ParamData.DchHighTempWarning = (short)(data[6] - 80);
|
|
rSystemData.ParamData.DchHighTempTrip = (short)(data[7] - 80);
|
|
break;
|
|
case 141: // Soc Parameter, System Voltage Calibration K, B
|
|
rSystemData.ParamData.LowSocWarning = (short)(data[0]);
|
|
rSystemData.ParamData.LowSocRelease = (short)(data[1]);
|
|
rSystemData.CalibriationData.SystemVoltage.Calibration_K = (short)((data[4] * 256) + data[5]);
|
|
rSystemData.CalibriationData.SystemVoltage.Calibration_B = (short)((data[6] * 256) + data[7]);
|
|
break;
|
|
case 151: // Battery Option Parameter - Cell Voltage Offset
|
|
rSystemData.CalibriationData.CellVoltge.CvOffsetLow = (short)((data[0] << 8) | data[1]);
|
|
rSystemData.CalibriationData.CellVoltge.CvOffsetHigh = (short)((data[2] << 8) | data[3]);
|
|
break;
|
|
case 221: // Over Current Parameter
|
|
rSystemData.ParamData.ChaOverCurrentWarning = (short)((data[0] * 256) + data[1] - 30000);
|
|
rSystemData.ParamData.ChaOverCurrentTrip = (short)((data[2] * 256) + data[3] - 30000);
|
|
rSystemData.ParamData.DchOverCurrentWarning = (short)((data[4] * 256) + data[5] - 30000);
|
|
rSystemData.ParamData.DchOverCurrentTrip = (short)((data[6] * 256) + data[7] - 30000);
|
|
break;
|
|
case 231: // Voltage release Parameter
|
|
rSystemData.ParamData.CellUnderVoltageRelease = (short)((data[0] * 256) + data[1]);
|
|
rSystemData.ParamData.CellOverVoltageRelease = (short)((data[2] * 256) + data[3]);
|
|
rSystemData.ParamData.SysUnderVoltageRelease = (short)((data[4] * 256) + data[5]);
|
|
rSystemData.ParamData.SysOverVoltageRelease = (short)((data[6] * 256) + data[7]);
|
|
break;
|
|
case 241: // Temperature, Current release Parameter
|
|
rSystemData.ParamData.ChaLowTempRelease = (short)(data[0] - 80);
|
|
rSystemData.ParamData.ChaHighTempRelease = (short)(data[1] - 80);
|
|
rSystemData.ParamData.DchLowTempRelease = (short)(data[2] - 80);
|
|
rSystemData.ParamData.DchHighTempRelease = (short)(data[3] - 80);
|
|
|
|
rSystemData.ParamData.ChaOverCurrentRelease = (short)((data[4] * 256) + data[5] - 30000);
|
|
rSystemData.ParamData.DchOverCurrentRelease = (short)((data[6] * 256) + data[7] - 30000);
|
|
break;
|
|
|
|
case 81: // Battery Parameter
|
|
rSystemData.CalibriationData.Battery.CellQty = (short)(data[0]);
|
|
rSystemData.CalibriationData.Battery.TempQty = (short)(data[1]);
|
|
rSystemData.CalibriationData.Battery.Capacity = (UInt32)((data[2] * 256) + data[3]);
|
|
break;
|
|
case 91: // Device Address Setting
|
|
rSystemData.CalibriationData.SystemInfo.devAddr = (ushort)((data[0] * 256) + data[1]);
|
|
break;
|
|
case 171: // Cell Balancing Paramwter
|
|
rSystemData.CalibriationData.CbParam.Threadhold = (short)((data[0] * 256) + data[1]);
|
|
rSystemData.CalibriationData.CbParam.Window = (short)((data[2] * 256) + data[3]);
|
|
rSystemData.CalibriationData.CbParam.Min = (short)(data[4]);
|
|
rSystemData.CalibriationData.CbParam.Interval = (short)(data[5]);
|
|
break;
|
|
case 211:
|
|
DateTime dev = new DateTime(data[0] + 1970
|
|
, data[1]
|
|
, data[2]
|
|
, data[3]
|
|
, data[4]
|
|
, data[5]
|
|
);
|
|
rSystemData.CalibriationData.SystemInfo.devTime = dev;
|
|
break;
|
|
case 21: // Cell Voltage Difference Parameter
|
|
rSystemData.ParamData.CellVoltageDifferenceTrip = (short)((data[0] * 256) + data[1]);
|
|
rSystemData.ParamData.CellVoltageDifferenceWarning = (short)((data[2] * 256) + data[3]);
|
|
rSystemData.ParamData.CellVoltageDifferenceRelease = (short)((data[4] * 256) + data[5]);
|
|
rSystemData.ParamData.CellVoltageDifferenceTime = (short)((data[6] * 256) + data[7]);
|
|
break;
|
|
}
|
|
}
|
|
if (rSystemData.StatusData.protect != 0)
|
|
rSystemData.StatusData.alarm = 2;
|
|
else if (rSystemData.StatusData.warning != 0)
|
|
rSystemData.StatusData.alarm = 1;
|
|
else
|
|
rSystemData.StatusData.alarm = 0;
|
|
}
|
|
}
|
|
public static void CanInvRxProcess(int sId, UInt32 exID, byte[] rData, ref DeviceSystemData aSystemData, DateTime rTime)
|
|
{
|
|
PACKET_HEADER PacketHeader = CovertPtoH(exID);
|
|
|
|
if (PacketHeader.SA == (200 + sId))
|
|
{
|
|
if (rData.Length > 0)
|
|
{
|
|
aSystemData.CommFail = false;
|
|
aSystemData.ShelfCommFail = false;
|
|
aSystemData.LastRxTime = rTime;
|
|
|
|
switch (PacketHeader.PF)
|
|
{
|
|
case 11: // Device ManufactureDate
|
|
aSystemData.Information.ManufactureDate = (UInt32)((rData[0] << 24)
|
|
| (rData[1] << 16)
|
|
| (rData[2] << 8)
|
|
| (rData[3] << 0));
|
|
break;
|
|
case 21: // Device Serial Number MSB
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
aSystemData.Information.pcb_sn[i] = rData[i];
|
|
}
|
|
break;
|
|
case 31: // Device Serial Number LSB
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
aSystemData.Information.pcb_sn[i + 8] = rData[i];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static PACKET_HEADER CovertPtoH(UInt32 id)
|
|
{
|
|
PACKET_HEADER hdr = new PACKET_HEADER();
|
|
|
|
hdr.Index = (byte)((id >> 26) & 0x07);
|
|
hdr.R = (byte)((id >> 25) & 0x01);
|
|
hdr.DP = (byte)((id >> 24) & 0x01);
|
|
hdr.PF = (byte)((id >> 16) & 0xFF);
|
|
hdr.PS = (byte)((id >> 8) & 0xFF);
|
|
hdr.SA = (byte)((id >> 0) & 0xFF);
|
|
|
|
return hdr;
|
|
}
|
|
|
|
public static UInt32 CovertHtoP(PACKET_HEADER hdr)
|
|
{
|
|
UInt32 Packet = 0;
|
|
|
|
Packet = (((UInt32)hdr.Index << 26)
|
|
| ((UInt32)hdr.R << 25)
|
|
| ((UInt32)hdr.DP << 24)
|
|
| ((UInt32)hdr.PF << 16)
|
|
| ((UInt32)hdr.PS << 8)
|
|
| ((UInt32)hdr.SA << 0)
|
|
);
|
|
return Packet;
|
|
}
|
|
|
|
public static byte[] MakeSocRecoveryCanData(byte nSoc)
|
|
{
|
|
byte[] result = new byte[8];
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
result[i] = 0xFF;
|
|
|
|
result[0] = 0;
|
|
result[1] = nSoc;
|
|
|
|
return result;
|
|
}
|
|
|
|
public static byte[] MakeCanData(int mode, int flag, int dcp, ref DeviceParamData aParam, ref DeviceCalibration aCalib)
|
|
{
|
|
byte[] result = new byte[8];
|
|
short temp = 0;
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{ result[i] = 0xFF; }
|
|
|
|
switch (mode)
|
|
{
|
|
case 1: // Status Req
|
|
result[6] = (byte)dcp;
|
|
break;
|
|
//case 10: // Cell Balancing set
|
|
// aCalib.CellBalancingVoltage = 3600;
|
|
// aCalib.CellBalancingVoltageEndGap = 100;
|
|
// aCalib.CellBalancingVoltageInterval = 5;
|
|
// result[0] = (byte)(aCalib.CellBalancingVoltage >> 8);
|
|
// result[1] = (byte)(aCalib.CellBalancingVoltage >> 0);
|
|
// result[2] = (byte)(aCalib.CellBalancingVoltageEndGap / 10);
|
|
// result[3] = (byte)(aCalib.CellBalancingVoltageInterval << 1);
|
|
|
|
// int ss = Convert.ToInt32(String.Format("{0:ss}", DateTime.Now));
|
|
// if (ss == 0)
|
|
// {
|
|
// result[3] |= 1;
|
|
// UInt32 nTime = (UInt32)csUtils.UnixTimeNow();
|
|
// result[4] = (byte)(nTime >> 24);
|
|
// result[5] = (byte)(nTime >> 16);
|
|
// result[6] = (byte)(nTime >> 8);
|
|
// result[7] = (byte)(nTime >> 0);
|
|
// }
|
|
// break;
|
|
//case 17:
|
|
// if (aCalib.Current.SelectSubItem != 2)
|
|
// result[7] = (byte)aCalib.Current.ChaAndDchSelect;
|
|
// break;
|
|
}
|
|
|
|
// Parameter Set
|
|
if (flag == 1)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case 25:
|
|
result[0] = (byte)1;
|
|
break;
|
|
case 10: // Cell Balancing set
|
|
result[0] = (byte)(aCalib.CellBalancingVoltage >> 8);
|
|
result[1] = (byte)(aCalib.CellBalancingVoltage >> 0);
|
|
result[2] = (byte)(aCalib.CellBalancingVoltageEndGap / 10);
|
|
result[3] = (byte)(aCalib.CellBalancingVoltageInterval << 1);
|
|
|
|
int ss = Convert.ToInt32(String.Format("{0:ss}", DateTime.Now));
|
|
if (ss == 0)
|
|
{
|
|
result[3] = 1;
|
|
UInt32 nTime = (UInt32)csUtils.UnixTimeNow();
|
|
result[4] = (byte)(nTime >> 24);
|
|
result[5] = (byte)(nTime >> 16);
|
|
result[6] = (byte)(nTime >> 8);
|
|
result[7] = (byte)(nTime >> 0);
|
|
}
|
|
break;
|
|
case 5: // Cell Voltage Warning and Fault Parameter
|
|
result[0] = (byte)(aParam.CellUnderVoltageWarning >> 8);
|
|
result[1] = (byte)(aParam.CellUnderVoltageWarning >> 0);
|
|
|
|
result[2] = (byte)(aParam.CellUnderVoltageTrip >> 8);
|
|
result[3] = (byte)(aParam.CellUnderVoltageTrip >> 0);
|
|
|
|
result[4] = (byte)(aParam.CellOverVoltageWarning >> 8);
|
|
result[5] = (byte)(aParam.CellOverVoltageWarning >> 0);
|
|
|
|
result[6] = (byte)(aParam.CellOverVoltageTrip >> 8);
|
|
result[7] = (byte)(aParam.CellOverVoltageTrip >> 0);
|
|
break;
|
|
case 6: // Temperature Warning and Fault Parameter
|
|
result[0] = (byte)(aParam.ChaLowTempWarning + 80);
|
|
result[1] = (byte)(aParam.ChaLowTempTrip + 80);
|
|
|
|
result[2] = (byte)(aParam.ChaHighTempWarning + 80);
|
|
result[3] = (byte)(aParam.ChaHighTempTrip + 80);
|
|
|
|
result[4] = (byte)(aParam.DchLowTempWarning + 80);
|
|
result[5] = (byte)(aParam.DchLowTempTrip + 80);
|
|
|
|
result[6] = (byte)(aParam.DchHighTempWarning + 80);
|
|
result[7] = (byte)(aParam.DchHighTempTrip + 80);
|
|
break;
|
|
case 7: // System Voltage Warning and Fault Parameter
|
|
result[0] = (byte)(aParam.SysUnderVoltageWarning >> 8);
|
|
result[1] = (byte)(aParam.SysUnderVoltageWarning >> 0);
|
|
|
|
result[2] = (byte)(aParam.SysUnderVoltageTrip >> 8);
|
|
result[3] = (byte)(aParam.SysUnderVoltageTrip >> 0);
|
|
|
|
result[4] = (byte)(aParam.SysOverVoltageWarning >> 8);
|
|
result[5] = (byte)(aParam.SysOverVoltageWarning >> 0);
|
|
|
|
result[6] = (byte)(aParam.SysOverVoltageTrip >> 8);
|
|
result[7] = (byte)(aParam.SysOverVoltageTrip >> 0);
|
|
break;
|
|
case 14: // SOC Warning and System Voltage Calibration K, B Parameter
|
|
result[0] = (byte)(aParam.LowSocWarning);
|
|
result[1] = (byte)(aParam.LowSocRelease);
|
|
result[2] = 0;
|
|
result[3] = 0;
|
|
result[4] = (byte)(aCalib.SystemVoltage.Calibration_K >> 8);
|
|
result[5] = (byte)(aCalib.SystemVoltage.Calibration_K >> 0);
|
|
result[6] = (byte)(aCalib.SystemVoltage.Calibration_B >> 8);
|
|
result[7] = (byte)(aCalib.SystemVoltage.Calibration_K >> 0);
|
|
break;
|
|
case 22: // Current Warning and Fault Parameter
|
|
temp = (short)(aParam.ChaOverCurrentWarning + 30000);
|
|
result[0] = (byte)(temp >> 8);
|
|
result[1] = (byte)(temp >> 0);
|
|
|
|
temp = (short)(aParam.ChaOverCurrentTrip + 30000);
|
|
result[2] = (byte)(temp >> 8);
|
|
result[3] = (byte)(temp >> 0);
|
|
|
|
temp = (short)(aParam.DchOverCurrentWarning + 30000);
|
|
result[4] = (byte)(temp >> 8);
|
|
result[5] = (byte)(temp >> 0);
|
|
|
|
temp = (short)(aParam.DchOverCurrentTrip + 30000);
|
|
result[6] = (byte)(temp >> 8);
|
|
result[7] = (byte)(temp >> 0);
|
|
break;
|
|
case 23: // Cell and System Voltage Release Parameter
|
|
result[0] = (byte)(aParam.CellUnderVoltageRelease >> 8);
|
|
result[1] = (byte)(aParam.CellUnderVoltageRelease >> 0);
|
|
|
|
result[2] = (byte)(aParam.CellOverVoltageRelease >> 8);
|
|
result[3] = (byte)(aParam.CellOverVoltageRelease >> 0);
|
|
|
|
result[4] = (byte)(aParam.SysUnderVoltageRelease >> 8);
|
|
result[5] = (byte)(aParam.SysUnderVoltageRelease >> 0);
|
|
|
|
result[6] = (byte)(aParam.SysOverVoltageRelease >> 8);
|
|
result[7] = (byte)(aParam.SysOverVoltageRelease >> 0);
|
|
break;
|
|
case 24: // Cell and System Voltage Release Parameter
|
|
result[0] = (byte)(aParam.ChaLowTempRelease + 80);
|
|
result[1] = (byte)(aParam.ChaHighTempRelease + 80);
|
|
|
|
result[2] = (byte)(aParam.DchLowTempRelease + 80);
|
|
result[3] = (byte)(aParam.DchHighTempRelease + 80);
|
|
|
|
temp = (short)(aParam.ChaOverCurrentRelease + 30000);
|
|
result[4] = (byte)(temp >> 8);
|
|
result[5] = (byte)(temp >> 0);
|
|
|
|
temp = (short)(aParam.DchOverCurrentRelease + 30000);
|
|
result[6] = (byte)(temp >> 8);
|
|
result[7] = (byte)(temp >> 0);
|
|
break;
|
|
case 9:
|
|
result[0] = (byte)(aCalib.SystemInfo.devAddr >> 8);
|
|
result[1] = (byte)(aCalib.SystemInfo.devAddr >> 0);
|
|
break;
|
|
case 1: // Auto Cell Balancing Set Data (0: Off. 1: On)
|
|
//result[6] = (byte)((aCalib.ForcedBalancing.DCP) ? 0x01 : 0x00);
|
|
result[7] = (byte)((aCalib.ForcedBalancing.AutoB) ? 0x01 : 0x00);
|
|
break;
|
|
case 12: // Forced Cell Balancing
|
|
result[0] = (byte)(aCalib.ForcedBalancing2.Control);
|
|
result[1] = (byte)(aCalib.ForcedBalancing2.CellNo);
|
|
result[2] = (byte)(aCalib.ForcedBalancing2.Mode);
|
|
result[3] = (byte)(aCalib.ForcedBalancing2.Enable);
|
|
break;
|
|
case 8: // Battery Paramter
|
|
result[0] = (byte)(aCalib.Battery.CellQty);
|
|
result[1] = (byte)(aCalib.Battery.TempQty);
|
|
result[2] = (byte)(aCalib.Battery.Capacity >> 8);
|
|
result[3] = (byte)(aCalib.Battery.Capacity >> 0);
|
|
break;
|
|
case 17: // Cell Balancing Parameter
|
|
result[0] = (byte)(aCalib.CbParam.Threadhold >> 8);
|
|
result[1] = (byte)(aCalib.CbParam.Threadhold >> 0);
|
|
result[2] = (byte)(aCalib.CbParam.Window >> 8);
|
|
result[3] = (byte)(aCalib.CbParam.Window >> 0);
|
|
result[4] = (byte)(aCalib.CbParam.Min >> 0);
|
|
result[5] = (byte)(aCalib.CbParam.Interval >> 0);
|
|
break;
|
|
case 21: // System Information (Device Address)
|
|
result[0] = (byte)(aCalib.SystemInfo.devAddr >> 8);
|
|
result[1] = (byte)(aCalib.SystemInfo.devAddr >> 0);
|
|
break;
|
|
case 13: // Soc Calibration
|
|
result[0] = (byte)(aCalib.SocCalib.CellNo);
|
|
result[1] = (byte)(aCalib.SocCalib.SocValue);
|
|
break;
|
|
case 15: // Parameter Option
|
|
result[0] = (byte)(aCalib.CellVoltge.CvOffsetLow >> 8);
|
|
result[1] = (byte)(aCalib.CellVoltge.CvOffsetLow >> 0);
|
|
result[2] = (byte)(aCalib.CellVoltge.CvOffsetHigh >> 8);
|
|
result[3] = (byte)(aCalib.CellVoltge.CvOffsetHigh >> 0);
|
|
|
|
result[7] = (byte)(0x01);
|
|
break;
|
|
case 16: // Default Parameter
|
|
result[0] = (byte)(aParam.DefalutParamOption);
|
|
break;
|
|
case 2: // Default Parameter
|
|
result[0] = (byte)(aParam.CellVoltageDifferenceTrip >> 8);
|
|
result[1] = (byte)(aParam.CellVoltageDifferenceTrip >> 0);
|
|
result[2] = (byte)(aParam.CellVoltageDifferenceWarning >> 8);
|
|
result[3] = (byte)(aParam.CellVoltageDifferenceWarning >> 0);
|
|
result[4] = (byte)(aParam.CellVoltageDifferenceRelease >> 8);
|
|
result[5] = (byte)(aParam.CellVoltageDifferenceRelease >> 0);
|
|
result[6] = (byte)(aParam.CellVoltageDifferenceTime >> 8);
|
|
result[7] = (byte)(aParam.CellVoltageDifferenceTime >> 0);
|
|
break;
|
|
case 900:
|
|
result[0] = (byte)(aCalib.InvData.ManufactureDate >> 24);
|
|
result[1] = (byte)(aCalib.InvData.ManufactureDate >> 16);
|
|
result[2] = (byte)(aCalib.InvData.ManufactureDate >> 8);
|
|
result[3] = (byte)(aCalib.InvData.ManufactureDate >> 0);
|
|
|
|
result[7] = (byte)(1);
|
|
break;
|
|
case 901:
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
result[i] = (byte)(aCalib.InvData.pcb_sn[i]);
|
|
}
|
|
break;
|
|
case 902:
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
result[i] = (byte)(aCalib.InvData.pcb_sn[i + 8]);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static DeviceSystemData MakeMaxAvgMinCellVoltage(DeviceSystemData rSystemData)
|
|
{
|
|
DeviceSystemData result = rSystemData;
|
|
int Max, Avg, Min, Sum;
|
|
int MaxNo, MinNo;
|
|
|
|
Max = Avg = Min = Sum = 0;
|
|
MaxNo = MinNo = 0;
|
|
for (int i = 0; i < rSystemData.cellQty; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
Max = Min = rSystemData.ValueData.CellVoltage[i];
|
|
}
|
|
Sum += rSystemData.ValueData.CellVoltage[i];
|
|
|
|
if (Max < rSystemData.ValueData.CellVoltage[i])
|
|
{
|
|
Max = rSystemData.ValueData.CellVoltage[i];
|
|
MaxNo = i;
|
|
}
|
|
if (Min > rSystemData.ValueData.CellVoltage[i])
|
|
{
|
|
Min = rSystemData.ValueData.CellVoltage[i];
|
|
MinNo = i;
|
|
}
|
|
}
|
|
if (rSystemData.cellQty > 0)
|
|
Avg = Sum / rSystemData.cellQty;
|
|
|
|
result.AvgData.avgCellVoltage = (ushort)Avg;
|
|
result.AvgData.maxCellVoltage = (ushort)Max;
|
|
result.AvgData.maxCellNum = (short)(MaxNo + 1);
|
|
result.AvgData.minCellVoltage = (ushort)Min;
|
|
result.AvgData.minCellNum = (short)(MinNo + 1);
|
|
result.AvgData.diffCellVoltage = (ushort)(Max - Min);
|
|
|
|
return result;
|
|
}
|
|
|
|
private static void MakeMaxAvgMinTemperature(ref DeviceSystemData rSystemData)
|
|
{
|
|
int Max, Avg, Min, Sum;
|
|
int MaxNo, MinNo;
|
|
|
|
Max = Avg = Min = Sum = 0;
|
|
MaxNo = MinNo = 0;
|
|
for (int i = 0; i < rSystemData.tempQty; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
Max = Min = rSystemData.ValueData.CellTemperature[i];
|
|
}
|
|
Sum += rSystemData.ValueData.CellTemperature[i];
|
|
|
|
if (Max < rSystemData.ValueData.CellTemperature[i])
|
|
{
|
|
Max = rSystemData.ValueData.CellTemperature[i];
|
|
MaxNo = i;
|
|
}
|
|
if (Min > rSystemData.ValueData.CellTemperature[i])
|
|
{
|
|
Min = rSystemData.ValueData.CellTemperature[i];
|
|
MinNo = i;
|
|
}
|
|
}
|
|
if (rSystemData.tempQty > 0)
|
|
Avg = Sum / rSystemData.tempQty;
|
|
|
|
rSystemData.AvgData.avgTemp = (short)Avg;
|
|
rSystemData.AvgData.maxTemp = (short)Max;
|
|
rSystemData.AvgData.maxTempNum = (short)(MaxNo + 1);
|
|
rSystemData.AvgData.minTemp = (short)Min;
|
|
rSystemData.AvgData.minTempNum = (short)(MinNo + 1);
|
|
rSystemData.AvgData.diffTemp = (short)(Max - Min);
|
|
}
|
|
|
|
private static DeviceSystemData MakeAlarmTripData(int id, short ndata, DeviceSystemData rSystemData)
|
|
{
|
|
bool[] aData = csUtils.Int16ToBitArray(ndata);
|
|
short bFault = rSystemData.StatusData.protect;
|
|
short bWarning = rSystemData.StatusData.warning;
|
|
int i = 0;
|
|
|
|
switch (id)
|
|
{
|
|
case 0: // Status Code 1
|
|
if (aData[i++]) bWarning |= (1 << 4); // 00 Cell Over Voltage Warning
|
|
else bWarning &= ~(1 << 4);
|
|
if (aData[i++]) bWarning |= (1 << 5); // 01 Cell Under Voltage Warning
|
|
else bWarning &= ~(1 << 5);
|
|
if (aData[i++]) bWarning |= (1 << 0); // 02 High Temperature Warning
|
|
else bWarning &= ~(1 << 0);
|
|
if (aData[i++]) bWarning |= (1 << 1); // 03 Low Temperature Warning
|
|
else bWarning &= ~(1 << 1);
|
|
if (aData[i++]) bWarning |= (1 << 2); // 04 Module Over Voltage Warning
|
|
else bWarning &= ~(1 << 2);
|
|
if (aData[i++]) bWarning |= (1 << 3); // 05 Module Under Voltage Warning
|
|
else bWarning &= ~(1 << 3);
|
|
if (aData[i++]) bWarning |= (1 << 9); // 06 Cell Voltage Difference Warning
|
|
else bWarning &= ~(1 << 9);
|
|
i++; // 07 Reserved
|
|
|
|
if (aData[i++]) bFault |= (1 << 4); // 08 Cell Over Voltage Fault
|
|
else bFault &= ~(1 << 4);
|
|
if (aData[i++]) bFault |= (1 << 5); // 09 Cell Under Voltage Fault
|
|
else bFault &= ~(1 << 5);
|
|
if (aData[i++]) bFault |= (1 << 0); // 10 High Temperature Warning
|
|
else bFault &= ~(1 << 0);
|
|
if (aData[i++]) bFault |= (1 << 1); // 11 Low Temperature Warning
|
|
else bFault &= ~(1 << 1);
|
|
if (aData[i++]) bFault |= (1 << 2); // 12 Module Over Voltage Warning
|
|
else bFault &= ~(1 << 2);
|
|
if (aData[i++]) bFault |= (1 << 3); // 13 Module Under Voltage Warning
|
|
else bFault &= ~(1 << 3);
|
|
if (aData[i++]) bFault |= (1 << 9); // 14 Cell Voltage Difference Fault
|
|
else bFault &= ~(1 << 9);
|
|
|
|
break;
|
|
case 1: // Status Code 2
|
|
i++; // 00 High SOC Warning
|
|
i++; // 01 High SOC Fault
|
|
if (aData[i++]) bWarning |= (1 << 11); // 02 Low SOC Warning
|
|
else bWarning &= ~(1 << 11);
|
|
i++; // 03 Low SOC Fault
|
|
i++; // 04 Reserved
|
|
i++; // 05 Reserved
|
|
i++; // 06 Reserved
|
|
i++; // 07 Reserved
|
|
if (aData[i++]) bWarning |= (1 << 6); // 08 Charge Over Current Warning
|
|
else bWarning &= ~(1 << 6);
|
|
if (aData[i++]) bFault |= (1 << 6); // 09 Charge Over Current Fault
|
|
else bFault &= ~(1 << 6);
|
|
if (aData[i++]) bWarning |= (1 << 7); // 10 Discharge Over Current Warning
|
|
else bWarning &= ~(1 << 7);
|
|
if (aData[i++]) bFault |= (1 << 7); // 11 Discharge Over Current Fault
|
|
else bFault &= ~(1 << 7);
|
|
break;
|
|
}
|
|
|
|
rSystemData.StatusData.protect = bFault;
|
|
rSystemData.StatusData.warning = bWarning;
|
|
|
|
return rSystemData;
|
|
}
|
|
|
|
private static DeviceSystemData MakeWarningAlarmData(int id, short ndata, DeviceSystemData rSystemData)
|
|
{
|
|
bool[] aData = csUtils.Int16ToBitArray(ndata);
|
|
short bFault = rSystemData.StatusData.protect;
|
|
short bWarning = rSystemData.StatusData.warning;
|
|
int i = 0;
|
|
|
|
switch (id)
|
|
{
|
|
case 0: // Status Code 1
|
|
if (aData[i++]) bWarning |= (1 << 4); // 00 Cell Over Voltage Warning
|
|
else bWarning &= ~(1 << 4);
|
|
if (aData[i++]) bWarning |= (1 << 5); // 01 Cell Under Voltage Warning
|
|
else bWarning &= ~(1 << 5);
|
|
if (aData[i++]) bWarning |= (1 << 0); // 02 High Temperature Warning
|
|
else bWarning &= ~(1 << 0);
|
|
if (aData[i++]) bWarning |= (1 << 1); // 03 Low Temperature Warning
|
|
else bWarning &= ~(1 << 1);
|
|
if (aData[i++]) bWarning |= (1 << 2); // 04 Module Over Voltage Warning
|
|
else bWarning &= ~(1 << 2);
|
|
if (aData[i++]) bWarning |= (1 << 3); // 05 Module Under Voltage Warning
|
|
else bWarning &= ~(1 << 3);
|
|
if (aData[i++]) bWarning |= (1 << 9); // 06 Cell Voltage Difference Warning
|
|
else bWarning &= ~(1 << 9);
|
|
i++; // 07 Reserved
|
|
|
|
if (aData[i++]) bFault |= (1 << 4); // 08 Cell Over Voltage Fault
|
|
else bFault &= ~(1 << 4);
|
|
if (aData[i++]) bFault |= (1 << 5); // 09 Cell Under Voltage Fault
|
|
else bFault &= ~(1 << 5);
|
|
if (aData[i++]) bFault |= (1 << 0); // 10 High Temperature Warning
|
|
else bFault &= ~(1 << 0);
|
|
if (aData[i++]) bFault |= (1 << 1); // 11 Low Temperature Warning
|
|
else bFault &= ~(1 << 1);
|
|
if (aData[i++]) bFault |= (1 << 2); // 12 Module Over Voltage Warning
|
|
else bFault &= ~(1 << 2);
|
|
if (aData[i++]) bFault |= (1 << 3); // 13 Module Under Voltage Warning
|
|
else bFault &= ~(1 << 3);
|
|
if (aData[i++]) bFault |= (1 << 9); // 14 Cell Voltage Difference Fault
|
|
else bFault &= ~(1 << 9);
|
|
|
|
break;
|
|
case 1: // Status Code 2
|
|
i++; // 00 High SOC Warning
|
|
i++; // 01 High SOC Fault
|
|
if (aData[i++]) bWarning |= (1 << 11); // 02 Low SOC Warning
|
|
else bWarning &= ~(1 << 11);
|
|
i++; // 03 Low SOC Fault
|
|
i++; // 04 Reserved
|
|
i++; // 05 Reserved
|
|
i++; // 06 Reserved
|
|
i++; // 07 Reserved
|
|
if (aData[i++]) bWarning |= (1 << 6); // 08 Charge Over Current Warning
|
|
else bWarning &= ~(1 << 6);
|
|
if (aData[i++]) bFault |= (1 << 6); // 09 Charge Over Current Fault
|
|
else bFault &= ~(1 << 6);
|
|
if (aData[i++]) bWarning |= (1 << 7); // 10 Discharge Over Current Warning
|
|
else bWarning &= ~(1 << 7);
|
|
if (aData[i++]) bFault |= (1 << 7); // 11 Discharge Over Current Fault
|
|
else bFault &= ~(1 << 7);
|
|
break;
|
|
}
|
|
|
|
rSystemData.StatusData.protect = bFault;
|
|
rSystemData.StatusData.warning = bWarning;
|
|
|
|
return rSystemData;
|
|
}
|
|
|
|
public static string PacketToMsg(UInt32 exID, byte[] rData, int flag)
|
|
{
|
|
string result = "";
|
|
PACKET_HEADER PacketHeader = CovertPtoH(exID);
|
|
|
|
if (flag == 0) result = "RD: ";
|
|
else result = "TD: ";
|
|
result += String.Format(" ID:0x{0:X4}", exID);
|
|
result += String.Format("[PF({3:000}) PS({4:000}) SA({5:000})]"
|
|
, PacketHeader.Index
|
|
, PacketHeader.R
|
|
, PacketHeader.DP
|
|
, PacketHeader.PF
|
|
, PacketHeader.PS
|
|
, PacketHeader.SA
|
|
);
|
|
|
|
result += String.Format("Data({0}): ", rData.Length);
|
|
|
|
for (int i = 0; i < rData.Length; i++)
|
|
{
|
|
result += String.Format("{0:X2} ", rData[i]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
unsafe public static string PacketToMsg(VCI_CAN_OBJ obj, int flag)
|
|
{
|
|
PACKET_HEADER PacketHeader = CovertPtoH(obj.ID);
|
|
string str;
|
|
|
|
if (flag == 0) str = "RD: ";
|
|
else str = "TD: ";
|
|
str += String.Format(" ID:0x{0}", obj.ID.ToString("X4"));
|
|
//str += String.Format("[I({0}) R({1}) DP({2}) PF({3}) PS({4}) SA({5})]"
|
|
// , PacketHeader.Index
|
|
// , PacketHeader.R
|
|
// , PacketHeader.DP
|
|
// , PacketHeader.PF
|
|
// , PacketHeader.PS
|
|
// , PacketHeader.SA
|
|
// );
|
|
str += String.Format("[PF({3:000}) PS({4:000}) SA({5:000})]"
|
|
, PacketHeader.Index
|
|
, PacketHeader.R
|
|
, PacketHeader.DP
|
|
, PacketHeader.PF
|
|
, PacketHeader.PS
|
|
, PacketHeader.SA
|
|
);
|
|
|
|
str += " Frame:";
|
|
if (obj.RemoteFlag == 0)
|
|
str += "D-Frame ";
|
|
else
|
|
str += "R-Frame ";
|
|
//if (obj.ExternFlag == 0)
|
|
// str += "Std-Frame ";
|
|
//else
|
|
// str += "Ext-Frame ";
|
|
|
|
//////////////////////////////////////////
|
|
if (obj.RemoteFlag == 0)
|
|
{
|
|
byte len = (byte)(obj.DataLen % 9);
|
|
|
|
str += String.Format("Data({0}): ", len);
|
|
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
str += String.Format("{0} ", obj.Data[i].ToString("X2"));
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
unsafe public static string PacketToMsg1(VCI_CAN_OBJ obj)
|
|
{
|
|
string str;
|
|
|
|
str = "Received data: ";
|
|
str += " Frame ID:0x" + System.Convert.ToString((Int32)obj.ID, 16);
|
|
str += " Frame format:";
|
|
if (obj.RemoteFlag == 0)
|
|
str += "Data Frame ";
|
|
else
|
|
str += "Remote frame ";
|
|
if (obj.ExternFlag == 0)
|
|
str += "Standard frame ";
|
|
else
|
|
str += "Extended frame ";
|
|
|
|
//////////////////////////////////////////
|
|
if (obj.RemoteFlag == 0)
|
|
{
|
|
str += "Data: ";
|
|
byte len = (byte)(obj.DataLen % 9);
|
|
byte j = 0;
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[0], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[1], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[2], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[3], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[4], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[5], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[6], 16);
|
|
if (j++ < len)
|
|
str += " " + System.Convert.ToString(obj.Data[7], 16);
|
|
|
|
}
|
|
|
|
return str;
|
|
}
|
|
}
|
|
}
|