读取IDTech读卡器/写卡器C#Com端口

时间:2016-02-19 18:01:19

标签: c#

我正在使用visual studio 2015中的C#项目。对于这个项目,我必须读取/写入高分辨率磁卡的数据。作者I的使用模型是IDTECH IDWA-336133B读写器。

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

我附上了我的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();
        }
    }
}

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

以下是包含所有十六进制代码和响应等的manual的一部分:

  

命令&回应简介

     

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

     

命令:复位缓冲器
命令代码:< ESC> a十六进制代码:1B   61
响应:无
说明:该命令用于复位EzWriter   缓冲到初始状态。编码设置不受此影响   命令。

     

命令:读取
命令代码:< ESC> r
十六进制代码:1B 72
  响应:[数据块]< ESC> [状态字节]
说明:这个   命令请求EzWriter读取刷卡并响应   数据读取。

     

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

     

命令:通信测试
命令代码:< ESC> e十六进制   代码:1B 65
响应:< ESC> [1B] [79]
描述:   此命令用于验证之间的通信链接   电脑和EzWriter很好用。

1 个答案:

答案 0 :(得分:0)

串行端口类在向其发送数据时触发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
    }
}

如果你想将数据读入一个字节数组,或者只是删除返回的数据,还有一些关于如何读取数据的选项。

有关串口类的更多信息:Here

有关从其他线程更新UI元素的信息:Here

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