using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ZNJM2.Win { public class CommandBase { public byte Addr { get; set; } public List<byte> CmdBytes { get; protected set; } public string Name { get; set; } public Object Result { get; set; } public DateTime? BTime { get; set; } public DateTime? ETime { get; set; } public int delayMillis { get; set; } protected Func<byte[], int, byte[]> CRC { get; set; } /// <summary> /// 执行次数 /// </summary> public long? RunCount { get; set; } /// <summary> /// 错误次数 /// 每次成功执行后设置成0 /// </summary> public long? ErrCount { get; set; } public Exception Err { get; set; } public List<byte> ReturnBytes { get; set; } /// <summary> /// 如 01 02, /// 01-02, /// 0102, /// 等形式 /// </summary> public string CmdText { get; set; } public string CmdHexString { get { return BitConverter.ToString(CmdBytes.ToArray()); } } public CommandBase() { CmdBytes=new List<byte>(); ReturnBytes = new List<byte>(); Addr = 0x01; ErrCount = 0; RunCount = 0; CRC = CRCUtil.CRC16; } #region 方法 /// <summary> /// 生成命令的字节数组 /// 如 01 02 /// 01-02 /// 0102 /// 等形式 /// </summary> /// <param name="cmd"></param> /// <returns></returns> public virtual List<byte> ParserCmd() { var cmdBytes = ParserCmdWithoutCRC(); var crc2 = CRC(cmdBytes, cmdBytes.Length); CmdBytes = new List<byte>(cmdBytes.Concat(crc2)); return CmdBytes; } protected virtual byte[] ParserCmdWithoutCRC() { string cmdText = CmdText; var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim(); if (string.IsNullOrWhiteSpace(cmd)) { throw new Exception("空字符串!"); } if ((cmd.Length % 2) != 0) { throw new Exception("命令字符窜长度必须是2的倍数!"); } cmd = BitConverter.ToString(new byte[] { Addr }) + cmd; var cmdBytes = new byte[cmd.Length / 2]; for (int i = 0; i < cmd.Length; i = i + 2) { cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } return cmdBytes; } protected virtual bool VerifyResult() { if (ReturnBytes.Count <= 0) { Err=new Exception("零长度返回!"); ErrCount++; return false; } if (ReturnBytes.Count <= 2) { Err = new Exception("返回字节少于2!"); ErrCount++; return false; } //CRC Check var len = ReturnBytes.Count; var crc = CRC(ReturnBytes.ToArray(), len-2); if (crc[0] != ReturnBytes[len - 2] || crc[1] != ReturnBytes[len - 1]) { Err = new Exception("CRC校验错误!"); ErrCount++; return false; } if (ReturnBytes[0] != Addr) { Err = new Exception("非期望的设备地址!"); ErrCount++; return false; } if (ReturnBytes[1] != CmdBytes[1]) { Err = new Exception("非期望的命令!"); ErrCount++; return false; } return true; } public virtual bool ParserReturn() { return VerifyResult(); } #endregion } public class RFIDCmdBase : CommandBase { public RFIDCmdBase() { CRC = CRCUtil.CRC16ForRFID; } /// <summary> /// 生成命令的字节数组 /// 如 01 02 /// 01-02 /// 0102 /// 等形式 /// </summary> /// <param name="cmd"></param> /// <returns></returns> public override List<byte> ParserCmd() { var cmdBytes = ParserCmdWithoutCRC(); var crc2 = CRC(cmdBytes, cmdBytes.Length); CmdBytes = new List<byte>(cmdBytes.Concat(crc2)); return CmdBytes; } protected override byte[] ParserCmdWithoutCRC() { string cmdText = CmdText; var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim(); if (string.IsNullOrWhiteSpace(cmd)) { throw new Exception("空字符串!"); } if ((cmd.Length % 2) != 0) { throw new Exception("命令字符窜长度必须是2的倍数!"); } cmd = BitConverter.ToString(new byte[] { Addr }) + cmd; var cmdBytes = new byte[cmd.Length / 2]; for (int i = 0; i < cmd.Length; i = i + 2) { cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } var lenV = (byte)(cmdBytes.Length + 2); //添加命令长度 return new byte[] { lenV }.Concat(cmdBytes).ToArray(); } protected override bool VerifyResult() { if (ReturnBytes.Count <= 0) { Err = new Exception("零长度返回!"); ErrCount++; return false; } if (ReturnBytes.Count <= 5) { Err = new Exception("返回字节少于5!"); ErrCount++; return false; } //CRC Check var len = ReturnBytes.Count; var crc = CRC(ReturnBytes.ToArray(), len - 2); if (crc[0] != ReturnBytes[len - 2] || crc[1] != ReturnBytes[len - 1]) { Err = new Exception("CRC校验错误!"); ErrCount++; return false; } if (ReturnBytes[1] != Addr) { Err = new Exception("非期望的设备地址!"); ErrCount++; return false; } if (ReturnBytes[2] != CmdBytes[2]) { Err = new Exception("非期望的命令!"); ErrCount++; return false; } return true; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; namespace ZNJM2.Win { #region 开关命令 public class PowerSwitchQuery : CommandBase { public PowerSwitchQuery(byte addr) { Addr = addr; CmdText = "03"; CmdBytes = ParserCmd(); Name = "开关-状态"; } public override bool ParserReturn() { bool flag = false; flag = base.VerifyResult(); if (flag && ReturnBytes.Count >= 5) { flag = true; Result = ReturnBytes[2] == 0 ? "Off" : "On"; ErrCount = 0; Err = null; } return flag; } } public class PowerSwitchOn : CommandBase { public PowerSwitchOn(byte addr) { Addr = addr; CmdText = "0601"; CmdBytes = ParserCmd(); Name = "开关-打开"; } } public class PowerSwitchOff : CommandBase { public PowerSwitchOff(byte addr) { Addr = addr; CmdText = "0600"; CmdBytes = ParserCmd(); Name = "开关-关闭"; } } #endregion #region 计米器 public class LengthCounterQuery : CommandBase { public LengthCounterQuery(byte addr) { Addr = addr; CmdText = "03 00 01"; ParserCmd(); Name = "计米器-读数"; } public override bool ParserReturn() { var flag=base.ParserReturn(); if (ReturnBytes.Count > 6 && flag) { var vhex = BitConverter.ToString(new byte[] { ReturnBytes[5], ReturnBytes[6], ReturnBytes[3], ReturnBytes[4] }); var value = int.Parse(vhex.Replace("-", ""), NumberStyles.HexNumber); Result = value; ErrCount = 0; Err = null; } return flag; } } //清空读数 public class LengthCounterCls : CommandBase { public LengthCounterCls(byte addr) { Addr = addr; CmdText = "06 00 0C 01"; ParserCmd(); Name = "计米器-清零"; } } #endregion #region 电表 //public class VoltageQuery : CommandBase //{ // public VoltageQuery(byte addr) // { // Addr = addr; // CmdText = "03-00-0C-00-02"; // CmdBytes = ParserCmd(); // Name = "电表-电压"; // } // public override bool ParserReturn() // { // bool flag = false; // flag = base.VerifyResult(); // if (flag && ReturnBytes.Count >= 7) // { // flag = true; // Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); // Console.WriteLine(Result.ToString()); // var tempArr = new byte[4]; // ReturnBytes.CopyTo(3, tempArr, 0, 4); // Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0); // ErrCount = 0; // Err = null; // } // return flag; // } //} //public class ElectricCurrent : CommandBase //{ // public ElectricCurrent(byte addr) // { // Addr = addr; // CmdText = "03-00-0A-00-02"; // CmdBytes = ParserCmd(); // Name = "电表-电流"; // } // public override bool ParserReturn() // { // bool flag = false; // flag = base.VerifyResult(); // if (flag && ReturnBytes.Count >= 7) // { // flag = true; // Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); // Console.WriteLine(Result.ToString()); // =========== // var tempArr = new byte[4]; // ReturnBytes.CopyTo(3, tempArr, 0, 4); // Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0); // ErrCount = 0; // Err = null; // } // return flag; // } //} //public class ElectricEnergy : CommandBase //{ // public ElectricEnergy(byte addr) // { // Addr = addr; // CmdText = "03-00-1A-00-02"; // CmdBytes = ParserCmd(); // Name = "电表-电能"; // } // public override bool ParserReturn() // { // bool flag = false; // flag = base.VerifyResult(); // if (flag && ReturnBytes.Count >= 7) // { // flag = true; // Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); // Console.WriteLine(Result.ToString()); // // =========== // var tempArr = new byte[4]; // ReturnBytes.CopyTo(3, tempArr, 0, 4); // Result = BitConverter.ToSingle(tempArr.Reverse().ToArray(), 0); // ErrCount = 0; // Err = null; // } // return flag; // } //} #endregion #region 电表DDS238-1Z系列 public class VoltageQuery : CommandBase { public VoltageQuery(byte addr) { Addr = addr; CmdText = "03-00-0C-00-01"; CmdBytes = ParserCmd(); Name = "电表-电压"; } public override bool ParserReturn() { bool flag = false; flag = base.VerifyResult(); if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); Console.WriteLine(Result.ToString()); var tempArr = new byte[2]; ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.1; ErrCount = 0; Err = null; } return flag; } } public class ElectricCurrent : CommandBase { public ElectricCurrent(byte addr) { Addr = addr; CmdText = "03-00-0d-00-01"; CmdBytes = ParserCmd(); Name = "电表-电流"; } public override bool ParserReturn() { bool flag = false; flag = base.VerifyResult(); if (flag && ReturnBytes.Count >= 5) { flag = true; Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); Console.WriteLine(Result.ToString()); // =========== var tempArr = new byte[2]; ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.01; ErrCount = 0; Err = null; } return flag; } } public class ElectricEnergy : CommandBase { public ElectricEnergy(byte addr) { Addr = addr; CmdText = "03-00-00-00-02"; CmdBytes = ParserCmd(); Name = "电表-电能"; } public override bool ParserReturn() { bool flag = false; flag = base.VerifyResult(); if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); Console.WriteLine(Result.ToString()); // =========== var tempArr = new byte[4]; ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length); Result = BitConverter.ToUInt32(tempArr.Reverse().ToArray(), 0) * 0.01; ErrCount = 0; Err = null; } return flag; } } public class ElectricFrequency : CommandBase { public ElectricFrequency(byte addr) { Addr = addr; CmdText = "03-00-11-00-01"; CmdBytes = ParserCmd(); Name = "电表-频率"; } public override bool ParserReturn() { bool flag = false; flag = base.VerifyResult(); if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(ReturnBytes.ToArray(), 0); Console.WriteLine(Result.ToString()); // =========== var tempArr = new byte[2]; ReturnBytes.CopyTo(3, tempArr, 0, tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), 0) * 0.01; ErrCount = 0; Err = null; } return flag; } } #endregion #region RFID指令 public class RFIDGetReaderInfo : RFIDCmdBase { /// <summary> /// 功率 /// </summary> public byte Power { get; set; } /// <summary> /// 命令最大响应时间 /// 单位100ms /// </summary> public byte CmdDelay { get; set; } public RFIDGetReaderInfo(byte addr) { Addr = addr; CmdText = "21"; CmdBytes = ParserCmd(); Name = "标签-获取读卡器信息"; } public override bool ParserReturn() { bool flag = true; flag = base.VerifyResult(); var RetArr=ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr,3,1); if (ReturnBytes[3] != 0x00) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x00)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(RetArr, 0); //Console.WriteLine(Result.ToString()); Power = RetArr[0x0A]; CmdDelay = RetArr[0x0B]; ErrCount = 0; Err = null; } return flag; } } public class RFIDQueryTID : RFIDCmdBase { public int? LblNum { get; set; } public List<String> LblList { get; set; } public RFIDQueryTID(byte addr) { Addr = addr; CmdText = "01 02 04"; LblList = new List<string>(); CmdBytes = ParserCmd(); Name = "标签-查询TID"; } public override bool ParserReturn() { LblNum = 0; LblList.Clear(); bool flag = true; flag = base.VerifyResult(); var RetArr=ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr,3,1); if (ReturnBytes[3] != 0x01) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(RetArr, 0); //Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[4]; int offset=5; for (int i = 0; i < LblNum; i++) { var lblLen=ReturnBytes[offset]; var tmpArr=new byte[lblLen]; var startIndex=offset +1; Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen); LblList.Add(BitConverter.ToString(tmpArr).Replace("-", "")); offset += lblLen + 1; } ErrCount = 0; Err = null; } return flag; } } public class RFIDQueryEPC : RFIDCmdBase { public int? LblNum { get; set; } public List<String> LblList { get; set; } public List<List<byte>> LblBytesList { get; set; } public RFIDQueryEPC(byte addr) { Addr = addr; CmdText = "01"; LblList = new List<string>(); LblBytesList = new List<List<byte>>(); CmdBytes = ParserCmd(); Name = "标签-查询EPC"; } public override bool ParserReturn() { LblNum = 0; LblList.Clear(); bool flag = true; flag = base.VerifyResult(); var RetArr = ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr, 3, 1); if (ReturnBytes[3] != 0x01) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(RetArr, 0); //Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[4]; int offset = 5; for (int i = 0; i < LblNum; i++) { var lblLen = ReturnBytes[offset]; var tmpArr = new byte[lblLen]; var startIndex = offset + 1; Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen); LblList.Add(BitConverter.ToString(tmpArr).Replace("-", "")); LblBytesList.Add(tmpArr.ToList()); offset += lblLen + 1; } ErrCount = 0; Err = null; } return flag; } } public class RFIDQueryTopOne : RFIDCmdBase { public int? LblNum { get; set; } public List<String> LblList { get; set; } public RFIDQueryTopOne(byte addr) { Addr = addr; CmdText = "0F"; LblList = new List<string>(); CmdBytes = ParserCmd(); Name = "标签-查询单张"; } public override bool ParserReturn() { LblNum = 0; LblList.Clear(); bool flag = true; flag = base.VerifyResult(); var RetArr=ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr,3,1); if (ReturnBytes[3] != 0x01) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 7) { flag = true; Result = BitConverter.ToString(RetArr, 0); //Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[4]; int offset=5; for (int i = 0; i < LblNum; i++) { var lblLen=ReturnBytes[offset]; var tmpArr=new byte[lblLen]; var startIndex=offset +1; Array.Copy(RetArr, startIndex, tmpArr, 0, lblLen); LblList.Add(BitConverter.ToString(tmpArr).Replace("-", "")); offset += lblLen + 1; } ErrCount = 0; Err = null; } return flag; } } public class RFIDSetPower : RFIDCmdBase { /// <summary> /// /// </summary> /// <param name="addr"></param> /// <param name="power">功率 1-30</param> public RFIDSetPower(byte addr,byte power) { Addr = addr; CmdText = "2f" + BitConverter.ToString(new byte[]{power}); CmdBytes = ParserCmd(); Name = "标签-设置功率"; } public override bool ParserReturn() { bool flag = true; flag = base.VerifyResult(); var RetArr = ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr, 3, 1); if (ReturnBytes[3] != 0x00) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 7) { flag = true; Result = "成功"; ErrCount = 0; Err = null; } return flag; } } public class RFIDReadUserArea : RFIDCmdBase { public List<byte> ResultBytes { get; private set; } public List<byte> EPC { get; set; } private byte WordPtr { get; set; } private byte Num { get; set; } private RFIDReadUserArea() { CmdText = "02"; ResultBytes = new List<byte>(); Name = "标签-查询用户区域数据"; } /// <summary> /// /// </summary> /// <param name="addr"></param> /// <param name="startAdd">开始位置(单位:字)</param> /// <param name="wordLen">字数,一个字二字节</param> public RFIDReadUserArea(byte addr,byte[] EPCArr,byte startAdd,byte wordLen):this() { Addr = addr; WordPtr = startAdd; Num = wordLen; if(EPCArr!=null)EPC = new List<byte>(EPCArr); CmdBytes = ParserCmd(); } /// <summary> /// /// </summary> /// <param name="addr"></param> /// <param name="startAdd">开始位置(单位:字)</param> /// <param name="wordLen">字数,一个字二字节</param> public RFIDReadUserArea(byte addr, string EPCStr, byte startAdd, byte wordLen):this() { Addr = addr; WordPtr = startAdd; Num = wordLen; #region EPC var epc = EPCStr.Replace("-", "").Replace(" ", ""); var epcdBytes = new byte[epc.Length / 2]; for (int i = 0; i < epc.Length; i = i + 2) { epcdBytes[i / 2] = byte.Parse(epc.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } EPC = new List<byte>(epcdBytes); #endregion CmdBytes = ParserCmd(); } protected override byte[] ParserCmdWithoutCRC() { string cmdText = CmdText; var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim(); if (string.IsNullOrWhiteSpace(cmd)) { throw new Exception("空字符串!"); } if ((cmd.Length % 2) != 0) { throw new Exception("命令字符窜长度必须是2的倍数!"); } cmd = BitConverter.ToString(new byte[] { Addr }) + cmd; var cmdBytes = new byte[cmd.Length / 2]; for (int i = 0; i < cmd.Length; i = i + 2) { cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } //构建命令的data部分 var data=new List<byte>(); data.Add((byte)(EPC.Count / 2));//ENum data.AddRange(EPC);//EPC data.Add(0x03);//Mem data.Add(WordPtr); data.Add(Num); data.AddRange(new byte[] { 00, 00, 00, 00 });//Pwd #region 掩模 //一字节为单位 //不设置表示对整个EPC序列进行匹配 //设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配 //如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________ //即只匹配前三个字节 //data.AddRange(new byte[] { 0x0B, 0x01 }); #endregion var lenV = (byte)(cmdBytes.Length + data.Count+ 2 ); //添加命令长度 return new byte[] { lenV }.Concat(cmdBytes).Concat(data).ToArray(); } public override bool ParserReturn() { ResultBytes.Clear(); bool flag = true; flag = base.VerifyResult(); var RetArr = ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr, 3, 1); if (ReturnBytes[3] != 0x00) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x00)); ErrCount++; return false; } if (flag && ReturnBytes.Count >= (4 + (Num * 2) +2)) { flag = true; var tmpArr = new byte[Num * 2]; Array.Copy(RetArr, 4, tmpArr, 0, tmpArr.Length); ResultBytes.AddRange(tmpArr); Result = BitConverter.ToString(tmpArr); ErrCount = 0; Err = null; } return flag; } } public class RFIDWriteUserArea : RFIDCmdBase { public List<byte> ResultBytes { get; set; } public List<byte> EPC { get; set; } private byte WordPtr { get; set; } private byte Num { get; set; } private byte[] Data { get; set; } private RFIDWriteUserArea() { CmdText = "03"; ResultBytes = new List<byte>(); Name = "标签-写用户区域数据"; } /// <summary> /// /// </summary> /// <param name="addr"></param> /// <param name="startAdd">开始位置(单位:字)</param> /// <param name="datas">要写入的字,一个字二字节,datas长度必须是2的整数倍</param> public RFIDWriteUserArea(byte addr, byte[] EPCArr, byte startAdd, byte[] datas) : this() { Addr = addr; WordPtr = startAdd; Data = datas; if ((datas.Length % 2) != 0) { throw new Exception("数据长度必须是2的整数倍!"); } if (EPCArr != null) EPC = new List<byte>(EPCArr); CmdBytes = ParserCmd(); } /// <summary> /// /// </summary> /// <param name="addr"></param> /// <param name="startAdd">开始位置(单位:字)</param> /// <param name="data">Unicode</param> public RFIDWriteUserArea(byte addr, string EPCStr, byte startAdd, string data) : this() { Addr = addr; WordPtr = startAdd; #region Data Data = Encoding.Unicode.GetBytes(data); #endregion #region EPC var epc = EPCStr.Replace("-", "").Replace(" ", ""); var epcdBytes = new byte[epc.Length / 2]; for (int i = 0; i < epc.Length; i = i + 2) { epcdBytes[i / 2] = byte.Parse(epc.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } EPC = new List<byte>(epcdBytes); #endregion CmdBytes = ParserCmd(); } protected override byte[] ParserCmdWithoutCRC() { string cmdText = CmdText; var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim(); if (string.IsNullOrWhiteSpace(cmd)) { throw new Exception("空字符串!"); } if ((cmd.Length % 2) != 0) { throw new Exception("命令字符窜长度必须是2的倍数!"); } cmd = BitConverter.ToString(new byte[] { Addr }) + cmd; var cmdBytes = new byte[cmd.Length / 2]; for (int i = 0; i < cmd.Length; i = i + 2) { cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } //构建命令的data部分 var data = new List<byte>(); var dataWords =(Data.Length / 2) ; data.Add((byte)dataWords);//WNUM data.Add((byte)(EPC.Count / 2));//ENum data.AddRange(EPC);//EPC data.Add(0x03);//Mem,0x03是用户区 data.Add(WordPtr); data.AddRange(Data); data.AddRange(new byte[] { 00, 00, 00, 00 });//Pwd #region 掩模 //一字节为单位 //不设置表示对整个EPC序列进行匹配 //设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配 //如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________ //即只匹配前三个字节 //data.AddRange(new byte[] { 0x0B, 0x01 }); #endregion var lenV = (byte)(cmdBytes.Length + data.Count + 2); //添加命令长度 return new byte[] { lenV }.Concat(cmdBytes).Concat(data).ToArray(); } public override bool ParserReturn() { ResultBytes.Clear(); bool flag = true; flag = base.VerifyResult(); var RetArr = ReturnBytes.ToArray(); var status = BitConverter.ToString(RetArr, 3, 1); if (ReturnBytes[3] != 0x00) { Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, "0x00")); ErrCount++; return false; } if (flag && ReturnBytes.Count >= 6) { flag = true; Result = "写入成功!"; ErrCount = 0; Err = null; } return flag; } } #endregion }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ZNJM2.Win { #region 校验 public static class CRCUtil { private static readonly byte[] aucCRCHi = { 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 }; private static readonly byte[] aucCRCLo = { 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 }; /// <summary> /// CRC效验 /// </summary> /// <param name="pucFrame">效验数据</param> /// <param name="usLen">数据长度</param> /// <returns>效验结果</returns> public static byte[] CRC16(byte[] pucFrame, int usLen) { int i = 0; byte ucCRCHi = 0xFF; byte ucCRCLo = 0xFF; UInt16 iIndex = 0x0000; while (usLen-- > 0) { iIndex = (UInt16)(ucCRCLo ^ pucFrame[i++]); ucCRCLo = (byte)(ucCRCHi ^ aucCRCHi[iIndex]); ucCRCHi = aucCRCLo[iIndex]; } var tmpArr = BitConverter.GetBytes((ucCRCHi << 8 | ucCRCLo)); var bytes = new byte[] { tmpArr[0], tmpArr[1] }; return bytes; } public static byte[] CRC16ForRFID(byte[] datas, int len) { uint i, j; uint crc16 = 0xffff; for (i = 0; i < len; i++) { crc16 ^= datas[i]; for (j = 0; j < 8; j++) { if ((crc16 & 0x01) == 1) { //标准crc16使用0xA001,RFID里使用0x8408 //crc16 = (crc16 >> 1) ^ 0xA001; crc16 = (crc16 >> 1) ^ 0x8408; } else { crc16 = crc16 >> 1; } } } var bs = BitConverter.GetBytes(crc16); return new byte[] { bs[0], bs[1] }; } public static byte[] Crc16(byte[] datas, int length) { uint i, j; uint crc16 = 0xffff; for (i = 0; i < length; i++) { crc16 ^= datas[i]; for (j = 0; j < 8; j++) { if ((crc16 & 0x01) == 1) { crc16 = (crc16 >> 1) ^ 0xA001; } else { crc16 = crc16 >> 1; } } } var bs = BitConverter.GetBytes(crc16); return new byte[] { bs[0], bs[1] }; } public static byte[] ParserHexStr(string str) { string cmdText = str; var cmd = cmdText.Replace(" ", "").Replace("-", "").Trim(); if (string.IsNullOrWhiteSpace(cmd)) { throw new Exception("空字符串!"); } if ((cmd.Length % 2) != 0) { throw new Exception("命令字符窜长度必须是2的倍数!"); } var cmdBytes = new byte[cmd.Length / 2]; for (int i = 0; i < cmd.Length; i = i + 2) { cmdBytes[i / 2] = byte.Parse(cmd.Substring(i, 2), System.Globalization.NumberStyles.HexNumber); } return cmdBytes; } } #endregion }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.Threading; using System.Net; namespace ZNJM2.Win { public partial class Form3 : Form { private bool Enable = false; public Form3() { InitializeComponent(); } public SerialPort COMPort { get; private set; } private void EnsureCOMPortOpen() { if (COMPort == null) { //配置COMPort COMPort = new SerialPort("COM2", 57600, Parity.None, 8, StopBits.One); COMPort.Encoding = Encoding.ASCII; COMPort.ReadTimeout = 1000; COMPort.WriteTimeout = 500; COMPort.ReadBufferSize = 512; COMPort.WriteBufferSize = 512; //COMPort.DtrEnable = true; } if (!COMPort.IsOpen) { COMPort.Open(); } Thread.Sleep(100); } private void button1_Click(object sender, EventArgs e) { Enable = true; ThreadPool.QueueUserWorkItem(o => { Do(); }, null); button1.Enabled = false; button2.Enabled = true; } public void Do() { try { EnsureCOMPortOpen(); Console.WriteLine("串口打开!"); byte[] buffer = new byte[COMPort.ReadBufferSize]; List<byte> myBuff=new List<byte>(); //D7-A3-88-40 4.27 //00 00 01 ab var cmds = new List<CommandBase>(); //cmds.Add(new VoltageQuery(01)); //cmds.Add(new ElectricCurrent(01)); //cmds.Add(new ElectricEnergy(01)); //cmds.Add(new ElectricFrequency(01)); //cmds.Add(new RFIDQueryTID(00)); //cmds.Add(new RFIDQueryEPC(00)); //cmds.Add(new RFIDSetPower(00, 5)); //cmds.Add(new RFIDQueryTopOne(00)); // cmds.Add(new RFIDGetReaderInfo(00)); string strV = "张三李四网无123456789abc"; var writeBytes = new List<byte>(); writeBytes.AddRange(BitConverter.GetBytes(DateTime.Now.Ticks)); writeBytes.AddRange(Encoding.UTF8.GetBytes(strV)); var readWords = 0; if ((writeBytes.Count % 2) == 0) { readWords = writeBytes.Count / 2; } else { readWords = (writeBytes.Count / 2) + 1; writeBytes.Add(0x00); } Console.WriteLine(BitConverter.ToString(writeBytes.ToArray())); cmds.Add(new RFIDWriteUserArea(00, CRCUtil.ParserHexStr("E20040807212025312409A77"), 00, writeBytes.ToArray())); cmds.Add(new RFIDReadUserArea(00, "E20040807212025312409A77", 00, (byte)readWords)); //cmds.Add(new RFIDReadUserArea(00, "E20040807212023812309C8B", 00, 1)); while (Enable) { foreach (var cmd in cmds) { Console.WriteLine("=========================="); Console.WriteLine(cmd.Name); COMPort.Write(cmd.CmdBytes.ToArray(), 0, cmd.CmdBytes.Count); Thread.Sleep(100 * 3); int len = COMPort.Read(buffer, 0, buffer.Length); byte[] tempArr = new byte[len]; Array.Copy(buffer, tempArr, len); cmd.ReturnBytes = new List<byte>(tempArr); Console.WriteLine("RAW:" +BitConverter.ToString(tempArr)); if (cmd.ParserReturn()) { #region if (cmd is RFIDReadUserArea) { var t = (RFIDReadUserArea)cmd; Console.WriteLine("ReadData:" +t.Result); var dt=new DateTime( BitConverter.ToInt64(t.ResultBytes.ToArray(), 0)); Console.WriteLine(dt.ToString()); Console.WriteLine("UTF-8:" + Encoding.UTF8.GetString(t.ResultBytes.ToArray(), 8,t.ResultBytes.Count -8 )); } if (cmd is RFIDWriteUserArea) { Console.WriteLine("ReadData:" + cmd.Result); } #endregion #region QueryTID if (cmd is RFIDQueryTID) { Console.WriteLine("LblNum:" + ((RFIDQueryTID)cmd).LblNum); foreach (var lbl in ((RFIDQueryTID)cmd).LblList) { Console.WriteLine(lbl); } } #endregion #region RFIDQueryEPC if (cmd is RFIDQueryEPC) { Console.WriteLine("LblNum:" + ((RFIDQueryEPC)cmd).LblNum); foreach (var lbl in ((RFIDQueryEPC)cmd).LblList) { Console.WriteLine(lbl); } } #endregion #region RFIDGetReaderInfo if (cmd is RFIDGetReaderInfo) { Console.WriteLine("Power:" + ((RFIDGetReaderInfo)cmd).Power); Console.WriteLine("CmdDelay:" + ((RFIDGetReaderInfo)cmd).CmdDelay); } #endregion if (cmd is RFIDQueryTopOne) { Console.WriteLine("LblNum:" + ((RFIDQueryTopOne)cmd).LblNum); foreach (var lbl in ((RFIDQueryTopOne)cmd).LblList) { Console.WriteLine(lbl); } } } else { Console.WriteLine(cmd.Err.ToString()); // COMPort.Read(buffer, 0, buffer.Length); } } //using (WebClient wc = new WebClient()) //{ // var url = string.Format(@"http://192.168.9.6:7896/Default.aspx?rnd={0}&m=U&V={1}&I={2}&E={3}", // DateTime.Now.Ticks, // cmds.OfType<VoltageQuery>().FirstOrDefault().Result, // cmds.OfType<ElectricCurrent>().FirstOrDefault().Result, // cmds.OfType<ElectricEnergy>().FirstOrDefault().Result // ); // Console.WriteLine(url); // wc.DownloadString(url); // wc.Dispose(); //} Thread.Sleep(1000 * 2); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (COMPort != null && COMPort.IsOpen) { COMPort.Close(); } if (Enable) { ThreadPool.QueueUserWorkItem(o => { Do(); }, null); } Console.WriteLine("结束!"); } } private void button2_Click(object sender, EventArgs e) { Enable = false; button1.Enabled = true; button2.Enabled = false; } } }