首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过串行连接(C#)从智能卡读卡器接收数据

通过串行连接(C#)从智能卡读卡器接收数据
EN

Stack Overflow用户
提问于 2012-05-02 11:24:01
回答 3查看 4.1K关注 0票数 0

我必须设计一个软件来与智能卡读卡器通信。

作为第一步,我希望从读卡器接收数据,并将它们显示在文本框中,当文本框发生变化时,我可以立即看到这些数据(以确保已经发送了数据)。

由读卡器发送的数据(我用来用PLC编程)是一个256字节的数组。

我确实执行了相同的方法,但是在我的富文本框中没有显示任何内容。

我想让你看看我的代码,告诉我出了什么问题:

代码语言:javascript
运行
复制
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值根据智能卡读取器的状态进行更改(换句话说,根据读卡器发送的内容).

例如(我在上面的代码中试图做的事情) ..当有连接,卡被插入读卡器时,缓冲区1,2和3的值应立即从0变为48,48,48,48,48,48,48,48,48,48,48,48(由读卡器发送)。以此类推。

代码语言:javascript
运行
复制
buffer:
[0]=xxx
[1]=xxx
[2]=xxx
[3]=xxx
[4]=xxx
[5]=xxx
[6]=xxx
...
...
...
[255]=xxx

相反,盒子是空的。

希望是我的前奏。很清楚..。我真的很想在这里找到解决办法。这对我来说是件很重要的事。我花了很多时间去尝试却没有成功

智能卡读卡器类型: KDM9650

EN

回答 3

Stack Overflow用户

发布于 2012-05-02 11:28:25

更新

手动运行updateTextBox() (将其添加到ButtonClick EventHandler)

代码语言:javascript
运行
复制
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
    }

然后运行您的应用程序,在它停止后,在断点上检查缓冲区是否为空?

Update2 Ok,试试这段代码,并阅读我的评论。

代码语言:javascript
运行
复制
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对象读取数据。显然那里没有数据。

串行端口详细信息

票数 0
EN

Stack Overflow用户

发布于 2012-05-02 11:29:59

您需要实际读取serialPort_DataReceived中的数据。你在这里什么都没做。还有:有一个button1_Click事件和一个button1_Click_1事件。button1叫哪一个?如果没有调用第一个端口,则根本不会打开串行端口。

另外,请注意:DataReceived事件是在它自己的线程中调用的,因此在更新UI之前,您需要使用this.Invoke (WinForms)或this.Dispatcher.Invoke (WPF)更改为UI线程。

票数 0
EN

Stack Overflow用户

发布于 2012-05-02 11:39:01

我在这里看到两个问题:

  1. 您不能从端口读取数据。
  2. 我认为您将遇到委托更新表单的问题,因为它将从另一个线程调用。

为了让您开始工作,您可以添加一个计时器,如果端口上有数据,可以在事件中读取数据:

代码语言:javascript
运行
复制
    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();
        }
    }

还有一个关于从另一个线程更新表单的问题:

如何从C#中的另一个线程更新GUI?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10412751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档