【问题标题】:reading data from serial port at certain interval?以一定的间隔从串口读取数据?
【发布时间】:2011-02-27 11:23:57
【问题描述】:

我有一个带串口的磁卡读卡器。

我使用以下 C#.net 代码向读卡器发送命令。

System.IO.Ports.SerialPort myport = new System.IO.Ports.Serialport("COM1", 9600, Parity.Nonek, 8, StopBits.One);
myport.Open();
// initiates the card reader to read.
myport.write("command to initiate card reader");

// Once the card is swiped it shows the read data.
MessageBox.Show(myport.ReadExisting());
myport.Close();

当我在 Messagebox 之前有一些暂停时,上面的代码会很好地工作。但我不想暂停。而是我想在刷卡时启动消息框。

我们该怎么做?

我正在用户登录系统中实现这个。

【问题讨论】:

    标签: c# serial-port


    【解决方案1】:

    我假设您有某种 GUI 想要在刷卡时更新。我假设您有一个表单,其中包含一个名为“textBox1”的文本框和一个标记为“开始”的按钮 (button1)。

    using System;
    using System.Windows.Forms;
    using System.IO;
    using System.IO.Ports;
    
    namespace SerialPortExample {
        public partial class Form1 : Form {
    
            SerialPort myport;
    
            public Form1() {
                InitializeComponent();
    
                myport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
                myport.DataReceived += new SerialDataReceivedEventHandler(myport_DataReceived);
                myport.ErrorReceived += new SerialErrorReceivedEventHandler(myport_ErrorReceived);
            }
    
            delegate void SerialDataReceivedDelegate(object sender, SerialDataReceivedEventArgs e);
            delegate void SerialErrorReceivedDelegate(object sender, SerialErrorReceivedEventArgs e);
    
            void myport_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) {
                if (this.InvokeRequired) {
                    this.Invoke(new SerialErrorReceivedDelegate(myport_ErrorReceived_Client), sender, e);
                } else {
                    myport_ErrorReceived_Client(sender, e);
                }
            }
    
            void myport_ErrorReceived_Client(object sender, SerialErrorReceivedEventArgs e) {
                MessageBox.Show("Error recieved: " + e.EventType);
            }
    
    
    
            void myport_DataReceived(object sender, SerialDataReceivedEventArgs e) {
                if (this.InvokeRequired) {
                    this.Invoke(new SerialDataReceivedDelegate(myport_DataRecieved_Client), sender, e);
                } else {
                    myport_DataRecieved_Client(sender, e);
                }
            }
    
            void myport_DataRecieved_Client(object sender, SerialDataReceivedEventArgs e) {
                textBox1.Text = myport.ReadExisting();
            }
    
            private void button1_Click(object sender, EventArgs e) {
                try {
                    if (myport.IsOpen) {
                        myport.Close();
                        button1.Text = "Start";
                    } else {
                        myport.Open();
                        button1.Text = "Stop";
                    }
                } catch (IOException ex) {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
    

    我没有串行设备来测试此代码,但它应该是正确的。

    分解它,重要的部分是方法myport_DataRecieved。只要数据到达串口,即刷卡时,就会调用该方法。

    其他感兴趣的领域是 Form1 构造函数,我们在其中初始化 SerialPort(但尚未打开它),以及方法 button1_Click 用于打开/关闭端口(并更改按钮的文本以反映这一点. 我们也会处理异常,以防由于某种原因无法打开端口。

    编辑:感谢汉斯的评论,我已经更新了答案。您不能直接从数据事件访问 UI 控件,因为它们在不同的线程上运行。我将事件方法分成两半,这样我就可以对它们调用Invoke,并在适当的上下文中运行它们。

    【讨论】:

    • 代码非常错误,您无法从运行 DataReceived 事件处理程序的线程池线程访问 UI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多