Files
DT_BR_GUI/LFP_Manager/Function/csSerialCommFunction.cs
jkwoo 5b5a4b4c59 V1.0.1.7-1 -- 2025/12/17
* Datastructure improved
2025-12-17 16:19:26 +09:00

820 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LFP_Manager.DataStructure;
using LFP_Manager.Utils;
using LFP_Manager.Controls;
using System.Web.Services.Description;
using System.Data.Entity.Core.Common.CommandTrees;
using DevExpress.XtraRichEdit.Fields.Expression;
using DevExpress.XtraRichEdit.Layout;
using DevExpress.XtraPrinting.Native.LayoutAdjustment;
namespace LFP_Manager.Function
{
class csSerialCommFunction
{
static readonly byte[] auchCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,0x40
};
static readonly byte[] auchCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,0x40
};
public const byte READ_COIL_STATUS = 0x01;
public const byte READ_HOLDING_REG = 0x03;
public const byte READ_INPUT_REG = 0x04; //Byul 구문 추가 필요
public const byte FORCE_SINGLE_COIL = 0x05;
public const byte PRESET_SINGLE_REG = 0x06;
public const byte PRESET_MULTI_REG = 0x10;
public const byte WRITE_COIL_REG = 0x0F;
public const byte ERROR_REG = 0x90;
public const byte FW_FLASH_ERASE_CMD = 0x43;
public const byte FW_FLASH_WRITE_CMD = 0x31;
public const byte NO_CMD = 0xFF;
public static byte[] GetCRC(byte[] pby, int nSize)
{
ushort uIndex, i;
ushort crc;
byte uchCRCHi = 0xff;
byte uchCRCLo = 0xff;
byte[] result = new byte[2];
for (i = 0; i < nSize; i++)
{
uIndex = (ushort)((int)uchCRCLo ^ (int)pby[i]);
uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]);
uchCRCHi = auchCRCLo[uIndex];
}
crc = (ushort)((uchCRCHi << 8) | uchCRCLo);
result[0] = (byte)(crc >> 8);
result[1] = (byte)(crc >> 0);
return result;
}
static public byte[] MakeReadRegisterData(ushort DevID, ushort cmd, ushort ReadAddr, ushort Size)
{
byte[] result = new byte[8];
byte[] crc;
result[0] = (byte)DevID; // Device ID
result[1] = (byte)cmd; // Command
result[2] = (byte)(ReadAddr >> 8); // Register Address MSB
result[3] = (byte)(ReadAddr >> 0); // Register Address LSB
result[4] = (byte)(Size >> 8); // Count of Register MSB
result[5] = (byte)(Size >> 0); // Count of Register LSB
crc = GetCRC(result, 6);
result[6] = crc[1]; // CRCH
result[7] = crc[0]; // CRCL
return result;
}
static public byte[] MakeWriteCoilData(ushort DevID, ushort WriteAddr, short WriteData)
{
byte[] result = new byte[7 + (1 * 1) + 2];
byte[] crc;
ushort i = 0;
result[i++] = (byte)DevID; // Device ID
result[i++] = (byte)WRITE_COIL_REG; // Command
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
result[i++] = (byte)(1 >> 8); // Count of Register MSB
result[i++] = (byte)(1 >> 0); // Count of Register LSB
result[i++] = (byte)(1 * 1); // Byte Count - [2 * (Num of register)]
result[i++] = (byte)(WriteData >> 0);
crc = GetCRC(result, i);
result[i++] = crc[1]; // CRCH
result[i++] = crc[0]; // CRCL
return result;
}
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, short[] WriteData)
{
byte[] result = new byte[9 + (WriteData.Length * 2)];
byte[] crc;
ushort i = 0;
result[i++] = (byte)DevID; // Device ID
result[i++] = (byte)PRESET_MULTI_REG; // Command
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
result[i++] = (byte)(WriteData.Length >> 8); // Count of Register MSB
result[i++] = (byte)(WriteData.Length >> 0); // Count of Register LSB
result[i++] = (byte)(WriteData.Length * 2); // Byte Count - [2 * (Num of register)]
for (int j = 0; j < WriteData.Length; j++)
{
result[i++] = (byte)(WriteData[j] >> 8);
result[i++] = (byte)(WriteData[j] >> 0);
}
crc = GetCRC(result, i);
result[i++] = crc[1]; // CRCH
result[i++] = crc[0]; // CRCL
return result;
}
static short GetRegister(ushort reg_addr, ref DeviceParamData aParam)
{
short result = 0;
switch (reg_addr)
{
//case 19: result = (short)(0 >> 16); break; // 0021 : UTC TimeStamp MSB
//case 20: result = (short)(58 >> 0); break; // 0022 : UTC TimeStamp LSB
//case 21: result = (short)0x1000; break; // 0023 : Cell Balancing Flag
//case 22: result = (short)0x0000; break; // 0024 : Cell Balancing Voltage
//case 23: result = (short)15; break; // 0024 : Cell Balancing Time
case 0x4002: result = (short)aParam.CellUnderVoltageWarning; break; // 0061 : Low cell voltage warning data
//case 33: result = (short)param.sf1.voltage.CUV_Threshold; break; // 0062 : Low cell voltage protection data
//case 34: result = (short)param.sf1.voltage.CUV_Recovery; break; // 0063 : Low cell voltage recovery data
//case 35: result = (short)param.sf1.voltage.SUV_Warning; break; // 0064 : Low voltage warning data
//case 36: result = (short)param.sf1.voltage.SUV_Threshold; break; // 0065 : Low voltage protection data
//case 37: result = (short)param.sf1.voltage.SUV_Recovery; break; // 0066 : Low voltage recovery data
//case 38: result = (short)param.sf1.voltage.COV_Warning; break; // 0067 : Over cell voltage warning data
//case 39: result = (short)param.sf1.voltage.COV_Threshold; break; // 0068 : Over cell voltage protection data
//case 40: result = (short)param.sf1.voltage.COV_Recovery; break; // 0069 : Over cell voltage recovery data
//case 41: result = (short)param.sf1.voltage.SOV_Warning; break; // 0070 : Over voltage warning data
//case 42: result = (short)param.sf1.voltage.SOV_Threshold; break; // 0071 : Over voltage protection data
//case 43: result = (short)param.sf1.voltage.SOV_Recovery; break; // 0072 : Over voltage recovery data
//case 44: result = (short)param.sf1.temperature.OT_Chg_Warning; break; // 0044 : Charge over temperature warning data
//case 45: result = (short)param.sf1.temperature.OT_Chg_Threshold; break; // 0045 : Charge over temperature protection data
//case 46: result = (short)param.sf1.temperature.OT_Chg_Recovery; break; // 0046 : Charge over temperature recovery data
//case 47: result = (short)param.sf1.temperature.OT_Chg_Time; break; // 0047 : Charge over temperature time
//case 48: result = (short)param.sf1.temperature.OT_Dsg_Warning; break; // 0048 : Discharge over temperature warning data
//case 49: result = (short)param.sf1.temperature.OT_Dsg_Threshold; break; // 0049 : Discharge over temperature protection data
//case 50: result = (short)param.sf1.temperature.OT_Dsg_Recovery; break; // 0050 : Discharge over temperature recovery data
//case 51: result = (short)param.sf1.temperature.OT_Dsg_Time; break; // 0051 : Discharge over temperature time
}
return result;
}
static byte[] ModBusGetRegWordToBytes(ushort addr, ref DeviceParamData aParam)
{
short data;
byte[] result = new byte[2];
data = GetRegister(addr, ref aParam);
result[0] = (byte)(data >> 8);
result[1] = (byte)(data >> 0);
return result;
}
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, ushort reg_len, ref DeviceParamData aParam)
{
int tlen = (reg_len * 2) + 7 + 2;
byte[] result = new byte[tlen];
byte[] tmp;
byte[] crc;
result[0] = (byte)DevID; // Device ID
result[1] = (byte)PRESET_MULTI_REG; // Command
result[2] = (byte)(WriteAddr >> 8); // Register Address MSB
result[3] = (byte)(WriteAddr >> 0); // Register Address LSB
result[4] = (byte)(reg_len >> 8); // Count of Register MSB
result[5] = (byte)(reg_len >> 0); // Count of Register LSB
result[6] = (byte)(reg_len * 2); ; // Current Value MSB
for (int i = 0; i < reg_len; i++)
{
tmp = ModBusGetRegWordToBytes((ushort)(WriteAddr + i),ref aParam);
result[7 + (i * 2) + 0] = tmp[0];
result[7 + (i * 2) + 1] = tmp[1];
}
crc = GetCRC(result, 8);
result[tlen - 2] = crc[0]; // CRCH
result[tlen - 1] = crc[1]; // CRCL
return result;
}
public static byte[] MakeCheckSum(byte[] sData, int offset, int len, bool flag)
{
byte[] result = new byte[2];
int checksum = 0;
for (int i = 0; i < len; i++)
{
checksum += sData[i + offset];
}
checksum = ~checksum + 1;
result[0] = (byte)(checksum >> 8);
result[1] = (byte)checksum;
return result;
}
private static byte[] MakeTxPacket(byte[] sData, int len)
{
string str = "";
byte[] result;
char[] chrArray;
int checksum = 0;
string checksumStr = "";
char[] checksumChr;
str = "~";
for (int i = 0; i < len; i++)
{
str += sData[i].ToString("X2");
}
str += "\r";
chrArray = str.ToCharArray();
for (int i = 0; i < (chrArray.Length - 6); i++)
{
checksum += chrArray[i + 1];
}
checksum = ~checksum + 1;
checksumStr = String.Format("{0:X2}{1:X2}", (byte)(checksum >> 8), (byte)checksum);
checksumChr = checksumStr.ToCharArray();
for (int i = 0; i < 4; i++)
{
chrArray[chrArray.Length - 5 + i] = checksumChr[i];
}
result = new byte[chrArray.Length];
for (int i = 0; i < chrArray.Length; i++)
{
result[i] = (byte)chrArray[i];
}
return result;
}
public static byte[] LengthLchk(int sLen)
{
byte[] result = new byte[2];
int lchksum = 0;
lchksum = (~(((sLen >> 8) & 0xF) +
((sLen >> 4) & 0xF) +
((sLen >> 0) & 0xF)) + 1) % 16;
lchksum = ((lchksum << 12) | sLen);
result[0] = (byte)(lchksum >> 8);
result[1] = (byte)(lchksum >> 0);
return result;
}
public static byte[] MakeTxData(byte addr, byte cmd, int sLen)
{
int buffCh = 0;
byte[] sData;
byte[] lenId;
byte[] checksum;
sData = new byte[((sLen > 0) ? 11 : 10)];
sData[buffCh] = 0x7E; buffCh++; // SOI
sData[buffCh] = 0x25; buffCh++; // VER
sData[buffCh] = addr; buffCh++; // ADDR
sData[buffCh] = 0x46; buffCh++; // CID1
sData[buffCh] = cmd; buffCh++; // CID2 (CMD)
lenId = LengthLchk(sLen); // LENID
sData[buffCh] = lenId[0]; buffCh++; // LENID MSB
sData[buffCh] = lenId[1]; buffCh++; // LENID LSB
if (sLen > 0)
{
sData[buffCh] = (byte)(sLen / 2); buffCh++; // INFO
}
checksum = csSerialCommFunction.MakeCheckSum(sData, 1, sData.Length - 4, false);
sData[buffCh] = checksum[1]; buffCh++;
sData[buffCh] = checksum[0]; buffCh++;
sData[buffCh] = 0x0D; buffCh++; // EOI
return MakeTxPacket(sData, sData.Length);
}
public static int TbPacketCheck(byte[] rdata, int rlen)
{
int result = 0;
byte[] cdata;
byte[] checksum;
byte[] checksum1;
checksum = MakeCheckSum(rdata, 1, rlen - 6, false);
checksum1 = new byte[2];
checksum1[0] = csUtils.StrByte2toByte(rdata[rlen - 4], rdata[rlen - 5]);
checksum1[1] = csUtils.StrByte2toByte(rdata[rlen - 2], rdata[rlen - 3]);
if ((checksum[0] == checksum1[0]) && (checksum[1] == checksum1[1]))
{
cdata = csUtils.StrToByteArray(rdata, 0, rlen);
result = 1;
}
return result;
}
static public int ModbusPacketFromSlaveCheck(byte[] rdata, ushort rlen)
{
int result = 0;
byte[] cdata, crc;
ushort clen, bytecount;
if (rlen > 2)
{
cdata = rdata;
switch (cdata[1])
{
case READ_COIL_STATUS:
case READ_HOLDING_REG:
case READ_INPUT_REG:
bytecount = cdata[2];
clen = (ushort)(bytecount + 5); // header 3, tail 2
if (rlen >= clen)
{
crc = GetCRC(cdata, (ushort)(rlen - 2));
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
else result = -1;
}
break;
case PRESET_MULTI_REG:
case FORCE_SINGLE_COIL:
case PRESET_SINGLE_REG:
clen = 8;
if (rlen >= clen)
{
crc = GetCRC(cdata, (ushort)(rlen - 2));
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
else result = -1;
}
break;
case ERROR_REG:
clen = 6;
if (rlen >= clen)
{
crc = GetCRC(cdata, (ushort)(rlen - 2));
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
else result = -1;
}
break;
case FW_FLASH_ERASE_CMD:
clen = 5;
if (rlen >= clen)
{
crc = GetCRC(cdata, (ushort)(rlen - 2));
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
else result = -1;
}
break;
case FW_FLASH_WRITE_CMD:
clen = 5;
if (rlen >= clen)
{
crc = GetCRC(cdata, (ushort)(rlen - 2));
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
else result = -1;
}
break;
default:
result = -1;
break;
}
}
return result;
}
public static short[] SerialRxProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
{
short[] result = new short[2];
switch (rData[1])
{
case READ_COIL_STATUS:
ReadCoilRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
break;
case READ_HOLDING_REG:
ReadHoldRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
break;
case READ_INPUT_REG:
//ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
break;
//case READ_INPUT_REG:
// ReadRegister(rData, rRegAddr, rLen, ref rSystemData);
// break;
case PRESET_MULTI_REG:
// read_holding_reg_process(reverse16(rsp->start_addr, true), reverse16(rsp->qty_reg, true));
//result[0] = 1;
//result[1] = 1;
break;
case ERROR_REG:
result[0] = 2;
result[1] = (short)((rData[0] << 8) | rData[1]);
break;
}
return result;
}
private static void ReadCoilRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
{
int i, j;
short reg_count;
short reg_value;
i = 2;
reg_count = rData[i];
i++;
for (j = 0; j < reg_count; j++)
{
reg_value = (short)(rData[i + j]);
SetCoilRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
i++;
}
}
private static void ReadHoldRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
{
int i, j;
short reg_count;
short reg_value;
i = 2;
reg_count = (short)(rData[i] / 2); i += 1;
for (j = 0; j < reg_count; j++)
{
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
SetHoldRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
i += 2;
}
}
private static void SetCoilRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
{
switch (reg_addr)
{
case 0x3078:
rSystemData.StatusData.relayStatus = reg_value;
rSystemData.CalibrationData.FetCalib.FetStatus = reg_value;
break;
case 0x502E:
rSystemData.CalibrationData.ChaMode.Mode = reg_value;
break;
}
}
private static void SetHoldRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
{
int temp = 0;
switch (reg_addr)
{
case 0: rSystemData.ValueData.voltageOfPack = (short)(reg_value / 10); break; //Total Voltage
case 1: rSystemData.ValueData.current = (short)((reg_value) / 10); break; //Total Current
case 2: // Cell Voltage #1
case 3: // Cell Voltage #2
case 4: // Cell Voltage #3
case 5: // Cell Voltage #4
case 6: // Cell Voltage #5
case 7: // Cell Voltage #6
case 8: // Cell Voltage #7
case 9: // Cell Voltage #8'
case 10: // Cell Voltage #9
case 11: // Cell Voltage #10
case 12: // Cell Voltage #11
case 13: // Cell Voltage #12
case 14: // Cell Voltage #13
case 15: // Cell Voltage #14
case 16: // Cell Voltage #15
rSystemData.ValueData.CellVoltage[reg_addr - 2] = (ushort)(reg_value / 1);
csUtils.MakeMaxAvgMinCellVoltage(ref rSystemData, 15);
break; // 15 CellVoltage 1mV
case 17: break; // Cell Voltage #16 - Reserved
case 18: rSystemData.ValueData.Ext1Temperature = (short)((reg_value) * 10); break; //Ext1 Temperature (Temp of MOS-FET)
case 19: rSystemData.ValueData.Ext2Temperature = (short)((reg_value) * 10); break; //Ext2 Amb. PCB Temperature 1C
case 20: break; // Temp Max.
case 21: rSystemData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // Remaining Capacity
case 22: rSystemData.ValueData.MaxBattChargeCurr = reg_value / 1; break;
case 23: rSystemData.ValueData.stateOfHealth = (short)(reg_value * 10); break;
case 24: rSystemData.ValueData.rSOC = (short)(reg_value * 10); break; //SOC
case 25: rSystemData.StatusData.status = reg_value; break; //Operating Status
case 26: rSystemData.StatusData.warning = MakeUartWarningData(reg_value); break; //Warning Status
case 27: rSystemData.StatusData.protection = MakeUartTripData(reg_value); break; //Protection Status
case 28: // Error Code
// 0x0001Voltage error
// 0x0002Temperature error
// 0x0004: Current Check Error
// 0x0010Cell unbalance
break;
case 29: // Cycle count MSB
temp = rSystemData.ValueData.cycleCount;
rSystemData.ValueData.cycleCount = (temp & (0x0000FFFF)) | (reg_value << 16);
break;
case 30: // Cycle count LSB
temp = rSystemData.ValueData.cycleCount;
rSystemData.ValueData.cycleCount = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
break;
case 31: // fullChargeCapacity MSB
temp = rSystemData.ValueData.fullChargeCapacity;
rSystemData.ValueData.fullChargeCapacity = (temp & (0x0000FFFF)) | (reg_value << 16);
break;
case 32: // fullChargeCapacity LSB
temp = rSystemData.ValueData.fullChargeCapacity;
rSystemData.ValueData.fullChargeCapacity = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
break;
case 33:
case 34:
rSystemData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 0] = (short)(((reg_value >> 8) & 0xFF) * 10);
rSystemData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 1] = (short)(((reg_value >> 0) & 0xFF) * 10);
csUtils.MakeMaxAvgMinTemperature(ref rSystemData, 4);
break;
case 35: break; // Reserved
case 36: rSystemData.cellQty = reg_value; break; // Cell Qty
case 37: rSystemData.ValueData.designedCapacity = reg_value; break;
case 38: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
case 39: rSystemData.StatusData.specialAlarm = (short)(reg_value); break; // Special Alarm
//case 61: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
//45 ~ 99 : Reserved
case 45: rSystemData.BmsDateTimeShort1 = (ushort)reg_value; break; // DateTime
case 46: rSystemData.BmsDateTimeShort2 = (ushort)reg_value;
int yy, MM, dd, HH, mm, ss;
rSystemData.BmsDateTimeInt = (rSystemData.BmsDateTimeShort1 << 16) | (rSystemData.BmsDateTimeShort2);
yy = (rSystemData.BmsDateTimeInt >> 26) & 0x003F;
MM = ((rSystemData.BmsDateTimeInt >> 22) & 0x000F) % 13;
dd = ((rSystemData.BmsDateTimeInt >> 17) & 0x001F) % 32;
HH = ((rSystemData.BmsDateTimeInt >> 12) & 0x001F) % 24;
mm = ((rSystemData.BmsDateTimeInt >> 6) & 0x003F) % 60;
ss = ((rSystemData.BmsDateTimeInt >> 0) & 0x003F) % 60;
yy += 2000;
rSystemData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
, yy
, MM
, dd
, HH
, mm
, ss
);
break; // DateTime
case 47: rSystemData.CalibrationData.ChaMode.Mode = reg_value; break; // 0x2F
case 48: rSystemData.CalibrationData.ChaMode.Value = reg_value; break; // 0x2F
case 56: rSystemData.CalibrationData.BalCalib.Volt = reg_value; break; // Cell Balance Voltage
case 57: rSystemData.CalibrationData.BalCalib.Diff = reg_value; break; // Cell Balance Diff
case 58: rSystemData.ParamData.LowSocWarning = reg_value; break;
case 61: rSystemData.ParamData.CellUnderVoltageWarning = reg_value; break;
case 62: rSystemData.ParamData.CellUnderVoltageTrip = reg_value; break;
case 63: rSystemData.ParamData.CellUnderVoltageRelease = reg_value; break;
case 64: rSystemData.ParamData.SysUnderVoltageWarning = (short)(reg_value / 10); break;
case 65: rSystemData.ParamData.SysUnderVoltageTrip = (short)(reg_value / 10); break;
case 66: rSystemData.ParamData.SysUnderVoltageRelease = (short)(reg_value / 10); break;
case 67: rSystemData.ParamData.CellOverVoltageWarning = reg_value; break;
case 68: rSystemData.ParamData.CellOverVoltageTrip = reg_value; break;
case 69: rSystemData.ParamData.CellOverVoltageRelease = reg_value; break;
case 70: rSystemData.ParamData.SysOverVoltageWarning = (short)(reg_value / 10); break;
case 71: rSystemData.ParamData.SysOverVoltageTrip = (short)(reg_value / 10); break;
case 72: rSystemData.ParamData.SysOverVoltageRelease = (short)(reg_value / 10); break;
case 76: rSystemData.ParamData.ChaOverCurrentTimes = (short)(reg_value / 1); break;
case 77: rSystemData.ParamData.DchOverCurrentTimes = (short)(reg_value / 1); break;
case 78: rSystemData.ParamData.ChaOverCurrentReleaseTime = (short)(reg_value * 1); break;
case 79: rSystemData.ParamData.DchOverCurrentReleaseTime = (short)(reg_value * 1); break;
case 80: rSystemData.ParamData.ChaOverCurrentTrip1 = (short)(reg_value / 10); break;
case 81: rSystemData.ParamData.DchOverCurrentTrip1 = (short)(reg_value / 10); break;
case 82: rSystemData.ParamData.ShortCircuit = (short)(reg_value / 10); break; // Short Circuit Current = 300A
case 83: rSystemData.ParamData.ChaOverCurrentTrip2 = (short)(reg_value / 10); break;
case 84: rSystemData.ParamData.DchOverCurrentTrip2 = (short)(reg_value / 10); break;
case 85: rSystemData.ParamData.ChaOverCurrentDelay1 = (short)(reg_value / 1); break;
case 86: rSystemData.ParamData.ChaOverCurrentDelay2 = (short)(reg_value / 1); break;
case 87: rSystemData.ParamData.DchOverCurrentDelay1 = (short)(reg_value / 1); break;
case 88: rSystemData.ParamData.DchOverCurrentDelay2 = (short)(reg_value / 1); break;
case 90: rSystemData.ParamData.ChaLowTempWarning = (short)(reg_value - 50); break;
case 91: rSystemData.ParamData.ChaLowTempTrip = (short)(reg_value - 50); break;
case 92: rSystemData.ParamData.ChaLowTempRelease = (short)(reg_value - 50); break;
case 93: rSystemData.ParamData.ChaHighTempWarning = (short)(reg_value - 50); break;
case 94: rSystemData.ParamData.ChaHighTempTrip = (short)(reg_value - 50); break;
case 95: rSystemData.ParamData.ChaHighTempRelease = (short)(reg_value - 50); break;
case 96: rSystemData.ParamData.DchLowTempWarning = (short)(reg_value - 50); break;
case 97: rSystemData.ParamData.DchLowTempTrip = (short)(reg_value - 50); break;
case 98: rSystemData.ParamData.DchLowTempRelease = (short)(reg_value - 50); break;
case 99: rSystemData.ParamData.DchHighTempWarning = (short)(reg_value - 50); break;
case 100: rSystemData.ParamData.DchHighTempTrip = (short)(reg_value - 50); break;
case 101: rSystemData.ParamData.DchHighTempRelease = (short)(reg_value - 50); break;
case 102: break; // PCB High Temp Warning
case 103: break; // PCB High Temp Trip
case 104: break; // PCB High Temp Release
//100 ~111 : Model_Product Name
case 105:
case 106:
case 107:
case 108:
case 109:
case 110:
case 111:
case 112:
case 113:
case 114:
case 115:
case 116:
int mReg = reg_addr - 105;
rSystemData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
rSystemData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 116)
{
rSystemData.Information.ModelName = Encoding.Default.GetString(rSystemData.Information.Model_Byte).Trim('\0');
}
break;
//112 ~114 : FW Version
case 117:
case 118:
case 119:
int fReg = reg_addr - 117;
rSystemData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
rSystemData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 119)
{
rSystemData.Information.SwProductRev = Encoding.Default.GetString(rSystemData.Information.FwVer_Byte).Trim('\0');
}
break;
//115 ~ 122 : BMS Serial number
case 120:
case 121:
case 122:
case 123:
case 124:
case 125:
case 126:
case 127:
int snReg = reg_addr - 120;
rSystemData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
rSystemData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 127)
{
rSystemData.Information.HwSerialNumber = Encoding.Default.GetString(rSystemData.Information.BMS_SN).Trim('\0');
}
break;
case 130: rSystemData.ParamData.EnvLowTempWarning = (short)(reg_value - 50); break;
case 131: rSystemData.ParamData.EnvLowTempTrip = (short)(reg_value - 50); break;
case 132: rSystemData.ParamData.EnvLowTempRelease = (short)(reg_value - 50); break;
case 133: rSystemData.ParamData.EnvHighTempWarning = (short)(reg_value - 50); break;
case 134: rSystemData.ParamData.EnvHighTempTrip = (short)(reg_value - 50); break;
case 135: rSystemData.ParamData.EnvHighTempRelease = (short)(reg_value - 50); break;
case 136: // Anti-Theft Communication
rSystemData.CalibrationData.AntiTheft.Comm = reg_value;
break;
case 137: // Anti-Theft Gyro-Scope
rSystemData.CalibrationData.AntiTheft.GyroScope = reg_value;
break;
case 163: // 0xA3
case 164: // 0xA4
case 165: // 0xA5
case 166: // 0xA6
int ManuDateReg = reg_addr - 163;
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 0] = (byte)(reg_value >> 8);
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 166)
{
rSystemData.Information.ManufacturingDate = Encoding.Default.GetString(rSystemData.Information.ManuDate_Byte).Trim('\0');
}
break;
}
csMakeDataFunction.MakeAlarm(ref rSystemData);
}
public static short MakeUartWarningData(short rdata)
{
short result = 0;
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001Pack OV
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002Cell OV
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004Pack UV
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008Cell UV
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010Charging OC
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020Discharging OC
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x0200SOC Low
return result;
}
public static short MakeUartTripData(short rdata)
{
short result = 0;
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001Pack OV
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002Cell OV
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004Pack UV
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008Cell UV
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010Charging OC
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020Discharging OC
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
if (bAlarm[13] == true) result |= (short)(1 << 9); // 0x0200Short Circuit Protection
return result;
}
private static short MakeUartErrorData(short rdata, short cdata)
{
short result = cdata;
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
if (bAlarm[0] == true) result |= (short)(1 << 9); // 0x0001Voltage error
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002Temperature error
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010Cell unbalance
return result;
}
}
}