从 IDTech 卡读卡器/写入器 C# COM 端口读取响应

本文关键字:COM 响应 读取 IDTech 读卡器 | 更新日期: 2023-09-27 18:35:28

我正在Visual Studio 2015中处理一个C#项目。对于这个项目,我必须将数据读/写到hi-co磁性ID卡上。我使用的写入器模型是IDTECH IDWA-336133B读写器。

该公司为您提供一组命令,通过模拟的rs232端口(物理USB端口)发送到设备。到目前为止,我已经发送了命令以打开和关闭设备上的 LED System.IO.Ports ,但我还没有弄清楚我应该如何从滑动中接收数据,或在滑动上写入数据。

正在附上我拥有的frmMain.cs文件和该单元的手册。您可以在我正在使用的手册上看到命令(以字节形式发送十六进制代码)。

所以我想知道的是:有没有办法有人可以向我展示正确的语法/方法来编写命令以从刷卡中读取数据?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace SerialPortCommunication
{
    public partial class Form1 : Form
    {
        static SerialPort _serialPort;

        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            _serialPort = new SerialPort();
            byte[] command = new byte[] { 0x1B, 0x81 };
            _serialPort.PortName = "COM4";

            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;
            _serialPort.Open();
            _serialPort.Write(command, 0, command.Length);
            _serialPort.Close();
            _serialPort.Dispose();
        }
        private void btnLedon_Click(object sender, EventArgs e)
        {
            _serialPort = new SerialPort();
            byte[] command = new byte[] { 0x1B, 0x84};
            _serialPort.PortName = "COM4";

            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;
            _serialPort.Open();
            _serialPort.Write(command, 0, command.Length);
            _serialPort.Close();
            _serialPort.Dispose();
        }
        private void btnRead_Click(object sender, EventArgs e)
        {
            _serialPort = new SerialPort();
            byte[] command = new byte[] { 0x1B, 0x52 };
            byte[] hico = new byte[] {0x1B, 0x78 };
            _serialPort.PortName = "COM4";
            _serialPort.ReadTimeout = 10000;
            _serialPort.WriteTimeout = 500;
            byte[] answer = new byte[] { };

            _serialPort.Open();
            // setting it to hico cards just incase
            _serialPort.Write(hico, 0, hico.Length);
            //sends command to read data
            _serialPort.Write(command, 0, command.Length);
            // I don't know if this is even remotely right
            String response =_serialPort.ReadExisting();
            lblReadData.Text = response;
            _serialPort.Close();
            _serialPort.Dispose();
        }
    }
}

我知道这是草率的代码,但我只是想让它工作,以便我可以将其迁移到真正的程序并正确执行。

这是手册的一部分,其中包含所有十六进制代码和响应等:

命令和响应介绍

EzWriter支持以下命令。 回应是 提供。

命令:

重置缓冲区
命令代码:A
十六进制代码:1B 61
响应:无
描述:此命令重置 EzWriter 缓冲区到初始状态。 编码设置不受此影响 命令。

命令:

读取
命令代码: r
十六进制代码:1B 72
响应:[数据块] [状态字节]
描述:此 命令请求 EzWriter 读取刷过的卡并响应 读取的数据。

命令:

写入
命令代码: w [数据块]
十六进制 代码:1B 77 [数据块]
响应:<电调> [状态字节]
描述:此命令请求 EzWriter 写入数据 阻止刷卡。

命令:通信测试
命令代码: e
十六进制 代码: 1B 65
响应: y [1B] [79]
描述: 此命令用于验证通信链路 计算机和EzWriter已经启动并且很好。

从 IDTech 卡读卡器/写入器 C# COM 端口读取响应

串行端口类在向其发送数据时触发 DataReceived 事件。请记住,此事件在其自己的线程上触发,与运行窗体 UI 的主线程分开。为了接收数据,您需要实现此事件。我做了一个简单的例子,但还没有测试过。

class Program
{
    private static SerialPort _SerialPort;
    private const int baudRate = 9600;
    private const string PortName = "Com4";
    static void Main(string[] args)
    {
        _SerialPort = new SerialPort(PortName, baudRate);
        _SerialPort.DataReceived += _readSerialPort_DataReceived;
        _SerialPort.Open();
       var command = new byte[] { 0x1B, 0x81 };
       Console.WriteLine("Sending {0} to device", command);
       sendData(command);
        Console.WriteLine("Press any key to continue...");
        Console.WriteLine();
        Console.ReadKey();
        _SerialPort.Close();
    }
    static void sendData(byte[] command)
    {
        _SerialPort.Write(command,0,command.Length);
    }
    static void _readSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var sp = (SerialPort) sender;
        // Edited following line. See comment
        var data = sp.ReadLine();
        Console.WriteLine("Data Received: {0}", data);
        //you may be able to do something like this as well but I am not sure if this is a blocking call
        var messageLength = 10;
        var buffer = new byte[messageLength];
        sp.Read(buffer, 0, buffer.Length);            
        //if you are going to update the UI you need to invoke a delegate method on the main thread
    }
}
如果您想将数据

读入字节数组或仅对返回的数据进行截取,则有几个关于如何读取数据的选项。

有关串行端口类的更多信息:此处

有关从另一个线程更新 UI 元素的信息:此处

串行端口 DataReceived 事件的 MSDN 示例:此处