首页 文章

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

提问于
浏览
0

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

作为第一步,我想从读卡器接收数据并将其显示在一个文本框中,我可以立即看到它变化(以确保已发送数据)...

读卡器发送的数据(如我以前用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

3 回答

  • 0

    您需要实际读取 serialPort_DataReceived 中的数据 . 你're not doing anything here. Also: There'是 button1_Click 事件和 button1_Click_1 事件 . button1 正在调用哪一个?如果未调用第一个,则根本不打开串行端口 .

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

  • 0

    我在这里看到两个问题:

    • 您没有从端口读取数据..

    • 我认为你将在更新表单时遇到问题,因为它将从另一个线程调用 .

    为了让你去,你可以添加一个计时器,并在计时器滴答事件中读取数据,如果端口有任何数据:

    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#?

  • 0

    update

    运行 updateTextBox() manualy(将其添加到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
        }
    

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

    Update2 好的,试试这段代码吧,阅读我的评论 .

    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(); 
            }
        }
    }
    

    your problem 您有一个 SerialPort 类的实例 . 实例名称为 s1 . 您已配置它,但您尝试从新的 serialPort 对象中读取数据 . 显然那里没有数据 .

    Serial ports details

相关问题