通过串行连接从智能卡读卡器接收数据(C#)
Posted
技术标签:
【中文标题】通过串行连接从智能卡读卡器接收数据(C#)【英文标题】:receiving data from smart card reader through serial connection (C#) 【发布时间】:2012-05-02 11:24:01 【问题描述】:我必须设计一个与智能卡读卡器通信的软件..
作为第一步,我想从读卡器接收数据并将它们显示在一个文本框中,当它发生变化时我可以立即看到它(以确保已发送数据)..
读卡器发送的数据(我用PLC编程)是一个256字节的数组
我确实执行了相同的方法,但我的richtextbox 中没有显示任何内容..
我希望你看看我的代码并告诉我有什么问题:
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.IO;
namespace mycard
public partial class Form1 : Form
byte[] memo = new byte[256];
byte[] buffer = new byte[255];
private SerialPort serialPort = new SerialPort();
public Form1()
InitializeComponent();
private void Form1_Load(object sender, EventArgs e)
serialPort.DataReceived +=
new SerialDataReceivedEventHandler(serialPort_DataReceived);
//open port
private void button1_Click(object sender, EventArgs e)
if (s1.IsOpen)
s1.Close();
s1.Open();
//Eject order which is working fine
private void button1_Click_1(object sender, EventArgs e)
byte[] data= new byte[4];
memo[0]=0x60;
memo[1]=0x00;
memo[2]=0x02;
memo[3]=0x43;
memo[4]=0x31; //32
memo[5]=0x10; //13
s1.Write(memo,0,6);
//close port
private void button2_Click(object sender, EventArgs e)
s1.Close();
private void button3_Click(object sender, EventArgs e)
txtDataReceived.Text = "\r\n";
public delegate void myDelegate();
public void updateTextBox()
byte[] buffer = new byte[255];
serialPort.Read(buffer, 0, 4);
txtDataReceived.Text = (buffer[0].ToString() + Environment.NewLine
+ buffer[1].ToString() + Environment.NewLine
+ buffer[2].ToString() + Environment.NewLine
+ buffer[3].ToString() + Environment.NewLine);
// i have tried the following code as well but i got nothing as well
// txtDataReceived.AppendText(serialPort.ReadExisting());
// txtDataReceived.ScrollToCaret();
我希望在创建的 Richtextbox 中得到以下输出,如下所示 .. 其中出现了整个消息,并且缓冲区数组的每个字节的 xxx 值根据智能卡读卡器的状态(或换句话说根据读卡器发送的内容)...
例如(我在上面的代码中一直在尝试做的事情).. 当有连接并且卡插入读卡器时,缓冲区 [0]、[1]、[2] 和 [ 3] 值应立即从 0 变为 48,48,48,48(由读卡器发送).. 等等..
buffer:
[0]=xxx
[1]=xxx
[2]=xxx
[3]=xxx
[4]=xxx
[5]=xxx
[6]=xxx
...
...
...
[255]=xxx
相反,盒子是空的……
希望我的概率。很清楚..我真的很想在这里找到解决方案..这对我来说是一件非常重要的事情..我花了很多时间尝试但没有任何成功
智能卡读卡器类型:KDM9650
【问题讨论】:
什么是 s1?为什么不使用serialPort? 你真的收到什么了吗?在 DataReceived 处理程序上设置断点并从那里进行调试。设置 Handshake 属性时,不获取 any 数据是一个常见错误。当您将其设置为 None 时,您必须自己将 DtrEnable 和 RtsEnable 设置为 true。 【参考方案1】:您需要实际读取serialPort_DataReceived
中的数据。你在这里什么都没做。另外:还有一个button1_Click
事件和一个button1_Click_1
事件。 button1
呼叫的是哪一个?如果第一个没有被调用,则串口根本没有打开。
另外请注意:DataReceived
事件在其自己的线程中调用,因此在更新 UI 之前,您需要使用 this.Invoke
(WinForms) 或 this.Dispatcher.Invoke
(WPF) 更改为 UI 线程。
【讨论】:
【参考方案2】:我在这里看到两个问题:
你没有从端口读取数据..
我认为您会在委托更新表单时遇到问题,因为它将从另一个线程调用。
为了让您继续前进,您可以添加一个计时器,并在计时器滴答事件中读取数据(如果端口有数据):
private void timer1_Tick(object sender, EventArgs e)
if (s1.BytesToRead > 0)
//write text to text box
//e.g. maybe as a start try
txtDataReceived.Text += s1.ReadExisting();
一个 另一个关于从另一个线程更新表单的问题:
How to update the GUI from another thread in C#?
【讨论】:
真的……发生了什么事?是否设置了断点来查看代码是否正在运行?【参考方案3】:更新
手动运行updateTextBox()
(将其添加到ButtonClick EventHandler)
public void updateTextBox()
byte[] buffer = new byte[255];
serialPort.Read(buffer, 0, 4);
var i = 0; //Press F9 here, it will put a breakpoint here
然后运行您的应用程序,并在断点处停止后检查缓冲区是否为空?
更新2 好的,试试这段代码,然后阅读我的 cmets。
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.IO;
namespace mycard
public partial class Form1 : Form
byte[] memo = new byte[256];
byte[] buffer = new byte[255];
//private SerialPort serialPort = new SerialPort();
//We don't need this object. We never configure it, it's not the
//same object which you use to write 'eject bytes'!
public Form1()
InitializeComponent();
private void Form1_Load(object sender, EventArgs e)
//subscribe on data received event here. IMPORTANT: we 'listen' s1 object here!
s1.DataReceived +=
new SerialDataReceivedEventHandler(serialPort_DataReceived);
//open port
private void button1_Click(object sender, EventArgs e)
if (s1.IsOpen)
s1.Close();
s1.Open();
//Eject order which is working fine
private void button1_Click_1(object sender, EventArgs e)
byte[] data= new byte[4];
memo[0]=0x60;
memo[1]=0x00;
memo[2]=0x02;
memo[3]=0x43;
memo[4]=0x31; //32
memo[5]=0x10; //13
s1.Write(memo,0,6);
//close port
private void button2_Click(object sender, EventArgs e)
s1.Close();
private void button3_Click(object sender, EventArgs e)
txtDataReceived.Text = "\r\n";
public void updateTextBox()
byte[] buffer = new byte[255];
//we must read from s1, not from serealPort!!!
s1.Read(buffer, 0, 4);
txtDataReceived.Text = (buffer[0].ToString() + Environment.NewLine
+ buffer[1].ToString() + Environment.NewLine
+ buffer[2].ToString() + Environment.NewLine
+ buffer[3].ToString() + Environment.NewLine);
//data received, let's read it!
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
updateTextBox();
您的问题
您有一个 SerialPort
类的实例。实例名称为s1
。您已配置它,但您尝试从新的serialPort
对象读取数据。显然那里没有数据。
Serial ports details
【讨论】:
做了它并尝试了其他类似的功能,但它没有工作..端口已打开,我提到我设法将数据写入读卡器..因为我可以发送卡-弹出序列.. 我试过了,但是程序从来没有停止过..我猜这意味着文本框永远不会更新..对! 这意味着你永远不会调用 updateTextBox() 方法。您是否将 updateTextBox() 调用添加到 serialPort_DataReceived() 中?你能在 serialPort_DataReceived() 中设置一个断点吗?程序是否在其中停止? 请在方法中更改:Form1_Load(object sender, EventArgs e) //serialPort.DataReceived += ... s1.DataReceived += ...以上是关于通过串行连接从智能卡读卡器接收数据(C#)的主要内容,如果未能解决你的问题,请参考以下文章