一组RS485设备操作命令
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 = ;
RunCount = ;
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 % ) != )
{
throw new Exception("命令字符窜长度必须是2的倍数!");
}
cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
var cmdBytes = new byte[cmd.Length / ];
for (int i = ; i < cmd.Length; i = i + )
{
cmdBytes[i / ] = byte.Parse(cmd.Substring(i, ), System.Globalization.NumberStyles.HexNumber);
}
return cmdBytes;
} protected virtual bool VerifyResult()
{ if (ReturnBytes.Count <= )
{
Err=new Exception("零长度返回!");
ErrCount++;
return false; }
if (ReturnBytes.Count <= )
{
Err = new Exception("返回字节少于2!");
ErrCount++;
return false;
} //CRC Check\
var len = ReturnBytes.Count;
var crc = CRC(ReturnBytes.ToArray(), len-);
if (crc[] != ReturnBytes[len - ] || crc[] != ReturnBytes[len - ])
{
Err = new Exception("CRC校验错误!");
ErrCount++;
return false;
} if (ReturnBytes[] != Addr)
{
Err = new Exception("非期望的设备地址!");
ErrCount++;
return false;
}
if (ReturnBytes[] != CmdBytes[])
{
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 % ) != )
{
throw new Exception("命令字符窜长度必须是2的倍数!");
}
cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
var cmdBytes = new byte[cmd.Length / ];
for (int i = ; i < cmd.Length; i = i + )
{
cmdBytes[i / ] = byte.Parse(cmd.Substring(i, ), System.Globalization.NumberStyles.HexNumber);
} var lenV = (byte)(cmdBytes.Length + ); //添加命令长度
return new byte[] { lenV }.Concat(cmdBytes).ToArray(); } protected override bool VerifyResult()
{ if (ReturnBytes.Count <= )
{
Err = new Exception("零长度返回!");
ErrCount++;
return false; }
if (ReturnBytes.Count <= )
{
Err = new Exception("返回字节少于5!");
ErrCount++;
return false;
} //CRC Check\
var len = ReturnBytes.Count;
var crc = CRC(ReturnBytes.ToArray(), len - );
if (crc[] != ReturnBytes[len - ] || crc[] != ReturnBytes[len - ])
{
Err = new Exception("CRC校验错误!");
ErrCount++;
return false;
} if (ReturnBytes[] != Addr)
{
Err = new Exception("非期望的设备地址!");
ErrCount++;
return false;
}
if (ReturnBytes[] != CmdBytes[])
{
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 = "";
CmdBytes = ParserCmd();
Name = "开关-状态";
} public override bool ParserReturn()
{
bool flag = false;
flag = base.VerifyResult();
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = ReturnBytes[] == ? "Off" : "On";
ErrCount = ;
Err = null; } return flag; }
} public class PowerSwitchOn : CommandBase
{
public PowerSwitchOn(byte addr)
{
Addr = addr;
CmdText = "";
CmdBytes = ParserCmd();
Name = "开关-打开";
}
} public class PowerSwitchOff : CommandBase
{
public PowerSwitchOff(byte addr)
{
Addr = addr;
CmdText = "";
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 > && flag)
{ var vhex = BitConverter.ToString(new byte[] { ReturnBytes[], ReturnBytes[], ReturnBytes[], ReturnBytes[] });
var value = int.Parse(vhex.Replace("-", ""), NumberStyles.HexNumber);
Result = value;
ErrCount = ;
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 >= )
{
flag = true;
Result = BitConverter.ToString(ReturnBytes.ToArray(), );
Console.WriteLine(Result.ToString()); var tempArr = new byte[];
ReturnBytes.CopyTo(, tempArr, , tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), ) * 0.1; ErrCount = ;
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 >= )
{
flag = true;
Result = BitConverter.ToString(ReturnBytes.ToArray(), );
Console.WriteLine(Result.ToString());
// ===========
var tempArr = new byte[];
ReturnBytes.CopyTo(, tempArr, , tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), ) * 0.01; ErrCount = ;
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 >= )
{
flag = true;
Result = BitConverter.ToString(ReturnBytes.ToArray(), );
Console.WriteLine(Result.ToString());
// ===========
var tempArr = new byte[];
ReturnBytes.CopyTo(, tempArr, , tempArr.Length); Result = BitConverter.ToUInt32(tempArr.Reverse().ToArray(), ) * 0.01; ErrCount = ;
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 >= )
{
flag = true;
Result = BitConverter.ToString(ReturnBytes.ToArray(), );
Console.WriteLine(Result.ToString());
// ===========
var tempArr = new byte[];
ReturnBytes.CopyTo(, tempArr, , tempArr.Length); Result = BitConverter.ToUInt16(tempArr.Reverse().ToArray(), ) * 0.01; ErrCount = ;
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 = "";
CmdBytes = ParserCmd();
Name = "标签-获取读卡器信息"; } public override bool ParserReturn()
{ bool flag = true;
flag = base.VerifyResult();
var RetArr=ReturnBytes.ToArray();
var status = BitConverter.ToString(RetArr,,);
if (ReturnBytes[] != 0x00)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x00));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = BitConverter.ToString(RetArr, );
//Console.WriteLine(Result.ToString()); Power = RetArr[0x0A];
CmdDelay = RetArr[0x0B]; ErrCount = ;
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 = ;
LblList.Clear(); bool flag = true;
flag = base.VerifyResult();
var RetArr=ReturnBytes.ToArray();
var status = BitConverter.ToString(RetArr,,);
if (ReturnBytes[] != 0x01)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = BitConverter.ToString(RetArr, );
//Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[];
int offset=;
for (int i = ; i < LblNum; i++)
{
var lblLen=ReturnBytes[offset];
var tmpArr=new byte[lblLen];
var startIndex=offset +;
Array.Copy(RetArr, startIndex, tmpArr, , lblLen);
LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
offset += lblLen + ; } ErrCount = ;
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 = "";
LblList = new List<string>();
LblBytesList = new List<List<byte>>();
CmdBytes = ParserCmd();
Name = "标签-查询EPC"; } public override bool ParserReturn()
{
LblNum = ;
LblList.Clear(); bool flag = true;
flag = base.VerifyResult();
var RetArr = ReturnBytes.ToArray();
var status = BitConverter.ToString(RetArr, , );
if (ReturnBytes[] != 0x01)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = BitConverter.ToString(RetArr, );
//Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[];
int offset = ;
for (int i = ; i < LblNum; i++)
{
var lblLen = ReturnBytes[offset];
var tmpArr = new byte[lblLen];
var startIndex = offset + ;
Array.Copy(RetArr, startIndex, tmpArr, , lblLen);
LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
LblBytesList.Add(tmpArr.ToList());
offset += lblLen + ; } ErrCount = ;
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 = ;
LblList.Clear(); bool flag = true;
flag = base.VerifyResult();
var RetArr=ReturnBytes.ToArray();
var status = BitConverter.ToString(RetArr,,);
if (ReturnBytes[] != 0x01)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}",status,0x01));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = BitConverter.ToString(RetArr, );
//Console.WriteLine(Result.ToString()); LblNum = ReturnBytes[];
int offset=;
for (int i = ; i < LblNum; i++)
{
var lblLen=ReturnBytes[offset];
var tmpArr=new byte[lblLen];
var startIndex=offset +;
Array.Copy(RetArr, startIndex, tmpArr, , lblLen);
LblList.Add(BitConverter.ToString(tmpArr).Replace("-", ""));
offset += lblLen + ; } ErrCount = ;
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, , );
if (ReturnBytes[] != 0x00)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x01));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true;
Result = "成功"; ErrCount = ;
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 = "";
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 / ];
for (int i = ; i < epc.Length; i = i + )
{
epcdBytes[i / ] = byte.Parse(epc.Substring(i, ), 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 % ) != )
{
throw new Exception("命令字符窜长度必须是2的倍数!");
}
cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
var cmdBytes = new byte[cmd.Length / ];
for (int i = ; i < cmd.Length; i = i + )
{
cmdBytes[i / ] = byte.Parse(cmd.Substring(i, ), System.Globalization.NumberStyles.HexNumber);
}
//构建命令的data部分
var data=new List<byte>();
data.Add((byte)(EPC.Count / ));//ENum
data.AddRange(EPC);//EPC
data.Add(0x03);//Mem
data.Add(WordPtr);
data.Add(Num);
data.AddRange(new byte[] { , , , });//Pwd
#region 掩模
//一字节为单位
//不设置表示对整个EPC序列进行匹配
//设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配
//如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________
//即只匹配前三个字节
//data.AddRange(new byte[] { 0x0B, 0x01 });
#endregion var lenV = (byte)(cmdBytes.Length + data.Count+ ); //添加命令长度
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, , );
if (ReturnBytes[] != 0x00)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, 0x00));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= ( + (Num * ) +))
{
flag = true; var tmpArr = new byte[Num * ];
Array.Copy(RetArr, , tmpArr, , tmpArr.Length);
ResultBytes.AddRange(tmpArr);
Result = BitConverter.ToString(tmpArr); ErrCount = ;
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 = "";
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 % ) != )
{
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 / ];
for (int i = ; i < epc.Length; i = i + )
{
epcdBytes[i / ] = byte.Parse(epc.Substring(i, ), 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 % ) != )
{
throw new Exception("命令字符窜长度必须是2的倍数!");
}
cmd = BitConverter.ToString(new byte[] { Addr }) + cmd;
var cmdBytes = new byte[cmd.Length / ];
for (int i = ; i < cmd.Length; i = i + )
{
cmdBytes[i / ] = byte.Parse(cmd.Substring(i, ), System.Globalization.NumberStyles.HexNumber);
}
//构建命令的data部分
var data = new List<byte>();
var dataWords =(Data.Length / ) ;
data.Add((byte)dataWords);//WNUM
data.Add((byte)(EPC.Count / ));//ENum
data.AddRange(EPC);//EPC
data.Add(0x03);//Mem,0x03是用户区
data.Add(WordPtr);
data.AddRange(Data);
data.AddRange(new byte[] { , , , });//Pwd
#region 掩模
//一字节为单位
//不设置表示对整个EPC序列进行匹配
//设置后,只对设置指定的开始位置到设定的字节数个字节进行匹配
//如设置0开始,3字节,则进行的匹配是 xx-xx-xx-_________________
//即只匹配前三个字节
//data.AddRange(new byte[] { 0x0B, 0x01 });
#endregion var lenV = (byte)(cmdBytes.Length + data.Count + ); //添加命令长度 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, , );
if (ReturnBytes[] != 0x00)
{
Err = new Exception(string.Format("返回的命令状态是{0},非期望的{1}", status, "0x00"));
ErrCount++;
return false;
}
if (flag && ReturnBytes.Count >= )
{
flag = true; Result = "写入成功!"; ErrCount = ;
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 = ;
byte ucCRCHi = 0xFF;
byte ucCRCLo = 0xFF;
UInt16 iIndex = 0x0000; while (usLen-- > )
{
iIndex = (UInt16)(ucCRCLo ^ pucFrame[i++]);
ucCRCLo = (byte)(ucCRCHi ^ aucCRCHi[iIndex]);
ucCRCHi = aucCRCLo[iIndex];
} var tmpArr = BitConverter.GetBytes((ucCRCHi << | ucCRCLo));
var bytes = new byte[] { tmpArr[], tmpArr[] };
return bytes; } public static byte[] CRC16ForRFID(byte[] datas, int len)
{
uint i, j;
uint crc16 = 0xffff;
for (i = ; i < len; i++)
{
crc16 ^= datas[i];
for (j = ; j < ; j++)
{
if ((crc16 & 0x01) == )
{
//标准crc16使用0xA001,RFID里使用0x8408
//crc16 = (crc16 >> 1) ^ 0xA001;
crc16 = (crc16 >> ) ^ 0x8408;
}
else
{
crc16 = crc16 >> ;
}
}
}
var bs = BitConverter.GetBytes(crc16);
return new byte[] { bs[], bs[] };
} public static byte[] Crc16(byte[] datas, int length)
{
uint i, j;
uint crc16 = 0xffff;
for (i = ; i < length; i++)
{
crc16 ^= datas[i];
for (j = ; j < ; j++)
{
if ((crc16 & 0x01) == )
{ crc16 = (crc16 >> ) ^ 0xA001; }
else
{
crc16 = crc16 >> ;
}
}
}
var bs = BitConverter.GetBytes(crc16);
return new byte[] { bs[], bs[] };
} 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 % ) != )
{
throw new Exception("命令字符窜长度必须是2的倍数!");
} var cmdBytes = new byte[cmd.Length / ];
for (int i = ; i < cmd.Length; i = i + )
{
cmdBytes[i / ] = byte.Parse(cmd.Substring(i, ), 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", , Parity.None, , StopBits.One);
COMPort.Encoding = Encoding.ASCII;
COMPort.ReadTimeout = ;
COMPort.WriteTimeout = ;
COMPort.ReadBufferSize = ;
COMPort.WriteBufferSize = ; //COMPort.DtrEnable = true;
}
if (!COMPort.IsOpen)
{
COMPort.Open();
}
Thread.Sleep();
}
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 = ;
if ((writeBytes.Count % ) == )
{
readWords = writeBytes.Count / ;
}
else
{
readWords = (writeBytes.Count / ) + ;
writeBytes.Add(0x00);
}
Console.WriteLine(BitConverter.ToString(writeBytes.ToArray())); cmds.Add(new RFIDWriteUserArea(, CRCUtil.ParserHexStr("E20040807212025312409A77"), , writeBytes.ToArray()));
cmds.Add(new RFIDReadUserArea(, "E20040807212025312409A77", , (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(), , cmd.CmdBytes.Count);
Thread.Sleep( * ); int len = COMPort.Read(buffer, , 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(), ));
Console.WriteLine(dt.ToString());
Console.WriteLine("UTF-8:" + Encoding.UTF8.GetString(t.ResultBytes.ToArray(), ,t.ResultBytes.Count - ));
}
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( * ); }
}
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;
}
}
}
一组RS485设备操作命令的更多相关文章
- 多个rs485设备怎样跟上位机通讯?
http://bbs.hcbbs.com/thread-819457-1-1.html 多个rs485设备怎样跟上位机通讯? [复制链接] |关注本帖 fdemeng 签到天数: 1228 天 ...
- 多个RS-485设备怎么连接到一台电脑上?可以设置地址,有协议
计算机都是RS232的,所以要给计算机串口配一个232/485转换器,然后给所有485设备设置一个地址. 计算机用查询方式,根据设备地址查询指定设备. 比如,计算机发送5个自节 01 03 04 FF ...
- 【STM32H7教程】第31章 STM32H7的USART应用之RS485
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第31章 STM32H7的USART应用之RS48 ...
- Linux字符设备驱动框架
字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...
- register_chrdev_region/alloc_chrdev_region和cdev注册字符设备驱动
内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region().alloc_chrdev_region() 和 register_chrdev(). (1 ...
- 字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev() (转载)
1. 字符设备结构体 内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里.该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下: static ...
- 字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()
1. 字符设备结构体 内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里.该散列表中的每一个元素是一个 char_device_struct 结构,它的定义如下: static ...
- 3.1 PCI设备BAR空间的初始化
在PCI Agent设备进行数据传送之前,系统软件需要初始化PCI Agent设备的BAR0~5寄存器和PCI桥的Base.Limit寄存器.系统软件使用DFS算法对PCI总线进行遍历时,完成这些寄存 ...
- Linux 设备驱动之字符设备
参考转载博客:http://blog.chinaunix.net/uid-26833883-id-4369060.html https://www.cnblogs.com/xiaojiang1025/ ...
随机推荐
- php解析url并得到url中的参数
<?php $url = 'http://www.baidu.com/index.php?m=content&c=index&a=lists&catid=6&ar ...
- setdeamon 设置 线程为守护线程, (lock线程锁, BoundedSemaphore,rlock递归锁 ) 三种锁
1.setdeamon 当主程序执行完时,子程序自动被销毁 ,内存自动被收回 例一: import threading, time def run(n): print('run %s'%n) time ...
- 基于OpenGL编写一个简易的2D渲染框架-12 重构渲染器-BlockAllocator
BlockAllocator 的内存管理情况可以用下图表示 整体思路是,先分配一大块内存 Chunk,然后将 Chunk 分割成小块 Block.由于 Block 是链表的一个结点,所以可以通过链表的 ...
- Eclipse 工程使用相对路径导入Jar包设置
环境:MyEclipse 6.5 问题:MyEclipse 工程使用相对路径导入Jar包 我们在导入工程时,往往添加Jar都是使用的绝对路径,但这带来了一个问题,不同的用户使用工程都得重新配置Buil ...
- ServiceLoader实现原理
在java中根据一个子类获取其父类或接口信息非常方便,但是根据一个接口获取该接口的所有实现类却没那么容易. 有一种比较笨的办法就是扫描classpath所有的class与jar包中的class,然后用 ...
- storm集群相关资料
1. Storm集群组件 Storm集群中包含两类节点:主控节点(Master Node)和工作节点(Work Node).其分别对应的角色如下: 主控节点(Master Node)上运行一个被称为N ...
- Kotlin语言学习笔记(4)
函数 // 函数定义及调用 fun double(x: Int): Int { return 2*x } val result = double(2) // 调用方法 Sample().foo() / ...
- [转]谈谈前端渲染 VS 后端渲染
首先,预编译跟前后端没有关系,预编译一样可以用于后端渲染. 看看下面的测试时间,单位: ms 模板字符串: var s = '{{#datas}}{{name}} abcdefg {{type}} { ...
- java 解析命令行参数
下载地址: https://jcenter.bintray.com/org/apache/commons/com.springsource.org.apache.commons.cli/1.2.0/ ...
- Musle比对软件
下载地址:http://www.drive5.com/muscle/downloads.htm 1)运行: win+R然后输入cmd,然后cd进入muscle目录 2) 比对: muscle3.8.3 ...