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 2: // 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_B >> 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; } } }