|
|
using HighWayIot.Rfid;
|
|
|
using HighWayIot.Rfid.Entity;
|
|
|
using HighWayIot.TouchSocket;
|
|
|
using RFIDTest.entity;
|
|
|
using System.Text;
|
|
|
using static System.Net.Mime.MediaTypeNames;
|
|
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
|
|
|
|
namespace RFIDTest
|
|
|
{
|
|
|
public partial class RFIDTest : Form
|
|
|
{
|
|
|
TouchSocketTcpClient _tcpClient = TouchSocketTcpClient.Instance;
|
|
|
|
|
|
RfidDataAnalyse rfidDataAnalyse = new RfidDataAnalyse();
|
|
|
|
|
|
public RFIDTest()
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
_tcpClient.GetMessageAction += ReciveDataRoute;
|
|
|
}
|
|
|
|
|
|
|
|
|
private void StartReadButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
_tcpClient.Send(IPTextBox.Text, rfidDataAnalyse.Send11H());
|
|
|
ResultTestbox.Text = string.Empty;
|
|
|
PCResultTextbox.Text = string.Empty;
|
|
|
//MessageBox.Show("开始盘点");
|
|
|
}
|
|
|
|
|
|
private void WriteButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
if (!int.TryParse(SelectAddressTextbox.Text, out int selectAddress))
|
|
|
{
|
|
|
MessageBox.Show("选择地址错误");
|
|
|
}
|
|
|
if (!int.TryParse(SelectLengthTextbox.Text, out int selectLength))
|
|
|
{
|
|
|
MessageBox.Show("选择数据长度错误");
|
|
|
}
|
|
|
if (!int.TryParse(WriteAddressTextbox.Text, out int writeAddress))
|
|
|
{
|
|
|
MessageBox.Show("写入地址错误");
|
|
|
}
|
|
|
if (!int.TryParse(WriteLengthTextbox.Text, out int writeLength))
|
|
|
{
|
|
|
MessageBox.Show("写入地址长度错误");
|
|
|
}
|
|
|
Base03HENtity entity = new Base03HENtity()
|
|
|
{
|
|
|
TimeOut = IntToBytes(2, 1000),
|
|
|
AccessPassword = IntToBytes(4, 0),
|
|
|
SelectBank = 01,
|
|
|
SelectAddress = IntToBytes(4, selectAddress),
|
|
|
SelectLength = (byte)selectLength,
|
|
|
SelectData = HexStringToBytes(EPCTextbox.Text),
|
|
|
WriteBank = 01,
|
|
|
WriteAddress = IntToBytes(4, writeAddress),
|
|
|
WordCount = (byte)writeLength,
|
|
|
WriteData = HexStringToBytes(ContentTextbox.Text)
|
|
|
};
|
|
|
byte[] data = rfidDataAnalyse.Send03H(entity);
|
|
|
_tcpClient.Send(IPTextBox.Text, data);
|
|
|
}
|
|
|
|
|
|
|
|
|
private void ConnectButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
if (_tcpClient.CreateTcpClient(IPTextBox.Text, PortTextBox.Text))
|
|
|
{
|
|
|
MessageBox.Show("连接成功");
|
|
|
_tcpClient.Send(IPTextBox.Text, rfidDataAnalyse.SendBFH(5));
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MessageBox.Show("连接失败");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 对接收到的数据进行初步解析分发到各个报文类型的解析类中
|
|
|
/// </summary>
|
|
|
public void ReciveDataRoute(byte[] bytes, string ip)
|
|
|
{
|
|
|
BaseReciveDataEntity reciveData = BaseRFIDDataAnalyse.BaseReceiveAnalyse(bytes);
|
|
|
|
|
|
if (reciveData == null)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
switch (reciveData.Code)
|
|
|
{
|
|
|
case 0x12: //停止盘点
|
|
|
MessageBox.Show("停止盘点");
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
ReadStateLabel.Text = "停止";
|
|
|
}));
|
|
|
break;
|
|
|
case 0x11: //盘点结果
|
|
|
if (reciveData.Status == 00)
|
|
|
{
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
ReadStateLabel.Text = "盘点中";
|
|
|
}));
|
|
|
}
|
|
|
break;
|
|
|
case 0x01: //读标签结果
|
|
|
if (reciveData.Status == 40)
|
|
|
{
|
|
|
this.Invoke(new Action(() => ResultTestbox.Text = "无数据帧"));
|
|
|
}
|
|
|
else if (reciveData.Status == 00)
|
|
|
{
|
|
|
var res = rfidDataAnalyse.Receive11H(reciveData.Data);
|
|
|
string PC = BytesToHexString(res.PC);
|
|
|
string data = BytesToHexString(res.EPC);
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
ResultTestbox.Text = data;
|
|
|
PCResultTextbox.Text = PC;
|
|
|
ReadStateLabel.Text = "停止";
|
|
|
|
|
|
EPCTextbox.Text = data;
|
|
|
ContentTextbox.Text = PC + " " + data;
|
|
|
|
|
|
SelectAddressTextbox.Text = "32";
|
|
|
SelectLengthTextbox.Text = (res.EPC.Count() * 8).ToString();
|
|
|
WriteAddressTextbox.Text = "1";
|
|
|
WriteLengthTextbox.Text = ((res.EPC.Count() / 2) + 1).ToString();
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
case 0xBF: //心跳信号
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
HeartBeatTimeLabel.Text = DateTime.Now.ToString("HH:mm:ss");
|
|
|
}));
|
|
|
break;
|
|
|
case 0x03:
|
|
|
if (reciveData.Status == 00)
|
|
|
{
|
|
|
MessageBox.Show("写入成功");
|
|
|
}
|
|
|
else if (reciveData.Status == 46)
|
|
|
{
|
|
|
MessageBox.Show("写入失败");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MessageBox.Show("未知代码");
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void DisconnectButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
if (_tcpClient.DisposeClient(IPTextBox.Text))
|
|
|
{
|
|
|
MessageBox.Show("断开连接");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MessageBox.Show("断开连接失败");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void StopReadButton_Click(object sender, EventArgs e)
|
|
|
{
|
|
|
_tcpClient.Send(IPTextBox.Text, rfidDataAnalyse.Send12H());
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将byte数组转换为十六进制字符串(格式:00 0A 0B)
|
|
|
/// </summary>
|
|
|
public string BytesToHexString(byte[] bytes)
|
|
|
{
|
|
|
if (bytes == null || bytes.Length == 0)
|
|
|
return string.Empty;
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
|
{
|
|
|
sb.Append(bytes[i].ToString("X2"));
|
|
|
if (i < bytes.Length - 1)
|
|
|
sb.Append(" ");
|
|
|
}
|
|
|
|
|
|
return sb.ToString();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将十六进制字符串转换回byte数组
|
|
|
/// </summary>
|
|
|
public byte[] HexStringToBytes(string hexString)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(hexString))
|
|
|
{
|
|
|
MessageBox.Show("传入数据为空");
|
|
|
return new byte[0];
|
|
|
}
|
|
|
|
|
|
// 移除所有空格
|
|
|
hexString = hexString.Replace(" ", "");
|
|
|
|
|
|
// 检查长度是否为偶数
|
|
|
if (hexString.Length % 2 != 0)
|
|
|
MessageBox.Show("格式不正确16进制字符串必须为偶数");
|
|
|
|
|
|
byte[] bytes = new byte[hexString.Length / 2];
|
|
|
|
|
|
try
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
|
{
|
|
|
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
|
|
|
}
|
|
|
}
|
|
|
catch { MessageBox.Show("格式不正确"); }
|
|
|
|
|
|
|
|
|
return bytes;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将整数转换为指定位数的byte数组(大端序)
|
|
|
/// </summary>
|
|
|
/// <param name="length">目标byte数组长度</param>
|
|
|
/// <param name="num">要转换的整数</param>
|
|
|
/// <returns>指定长度的byte数组</returns>
|
|
|
public static byte[] IntToBytes(int length, int num)
|
|
|
{
|
|
|
if (length <= 0)
|
|
|
throw new ArgumentException("长度必须大于0", nameof(length));
|
|
|
|
|
|
byte[] result = new byte[length];
|
|
|
|
|
|
// 从最高位开始填充
|
|
|
for (int i = 0; i < length; i++)
|
|
|
{
|
|
|
// 计算当前字节的位置(从高位到低位)
|
|
|
// 例如 length=2, i=0 时,移位 8 位;i=1 时,移位 0 位
|
|
|
int shift = (length - 1 - i) * 8;
|
|
|
result[i] = (byte)((num >> shift) & 0xFF);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将byte数组转换为整数(大端序)
|
|
|
/// </summary>
|
|
|
public static int BytesToInt(byte[] bytes)
|
|
|
{
|
|
|
if (bytes == null || bytes.Length == 0)
|
|
|
MessageBox.Show("字节数组不能为空");
|
|
|
|
|
|
if (bytes.Length > 4)
|
|
|
MessageBox.Show("字节数组长度不能超过4(int最大4字节)");
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
// 从高位到低位组合(大端序)
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
|
{
|
|
|
result = (result << 8) | bytes[i];
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将byte数组转换为整数(小端序)
|
|
|
/// </summary>
|
|
|
public static int BytesToIntLittleEndian(byte[] bytes)
|
|
|
{
|
|
|
if (bytes == null || bytes.Length == 0)
|
|
|
throw new ArgumentException("字节数组不能为空", nameof(bytes));
|
|
|
|
|
|
if (bytes.Length > 4)
|
|
|
throw new ArgumentException("字节数组长度不能超过4(int最大4字节)", nameof(bytes));
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
// 从低位到高位组合(小端序)
|
|
|
for (int i = 0; i < bytes.Length; i++)
|
|
|
{
|
|
|
result |= (bytes[i] << (i * 8));
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
}
|