分享串口通讯之被动接收且实时查找关键字的方法-TerminalWaiter By C#

背景:有些下位机通过串口显示交互信息(可能是一次性,可能开机自动触发),上位机需要从中查找指定定关键字。这个时候就需要有一个能够实时接收并显示,并能够实时“等待”某个关键字,TerminalWaiter就是为此而来。

软件界面如下:

下面不会直接贴全部源代码,只贴关键部分.

实时被动接收比较好实现:(初始化的时候添加DataReceived事件)

public SerialPort ComPort = new SerialPort();

ComPort.DataReceived += new SerialDataReceivedEventHandler(DebugUI.ComPort_DataReceived);

   下面的DeviceUI是自定义控件

public SerialPort ComPort = new SerialPort(); 

public EMoudle()
        {        
            DeviceUI = new Dev_UI();
            DeviceUI.EMoudleInstance = this;
            DebugUI = new Dbg_UI();
            DebugUI.EMoudleInstance = this;                     
            ComPort.BaudRate = 115200;
            ComPort.ReadTimeout = 500;
            ComPort.NewLine = "\r\n";
            try
            {
                ComPort.PortName = DeviceUI.drpComList.Text;
                ComPort.Open();
            }
            catch (Exception ex)
            {
                Console.WriteLine(MoudleConnString+ " Exception: " + ex.Message);
            }                      
            ComPort.DataReceived += new SerialDataReceivedEventHandler(DebugUI.ComPort_DataReceived);
        }

ComPort_DataReceived方法写在DebugUI(另外一个自定义控件)里面,用的是判断缓存里的bytesToRead 大于0 的方法,好处是可以一个一个字符的动态显示,实时效果很好,EmoudleInstace就是上面EModule的实例。然后MyLib.COMMFunc.AppendText 是我自己写的一个委托显示。(效果和richTextBox.Append()一样,只不过非UI线程要实时显示控件需要用委托。)

  internal void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (IsStoppingDataReceive) return;
            int n = EMoudleInstance.ComPort.BytesToRead;
            string rst = "";
            if (n > 0)
            {
                byte[] buf = new byte[n];
                EMoudleInstance.ComPort.Read(buf, 0, n);
                rst = Encoding.ASCII.GetString(buf);
                MyLib.COMMFunc.AppendText(richTextBox1, rst);
            }

等待关键字的方法在自定义控件DebugUI里面:

   private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                richTextBox1.AppendText("Textbox content can not be null!\r\n");
                textBox1.Focus();
                return;
            }
            Thread thd = new Thread(new ThreadStart(Test));
            thd.Start();

        }

        private void Test()
        {
            IsStoppingDataReceive = true;
            bool rst = COMWaitStr(textBox1.Text, (int)(numericUpDown1.Value * 1000));
            IsStoppingDataReceive = false;
            Console.WriteLine("rst: " + rst);
        }

 public bool COMWaitStr(string WaitStr, int ms_TimeOut)
        {
            MyLib.COMMFunc.AppendText(richTextBox1, "\r\nWAIT " + WaitStr + " ...\r\n\r\n");
            int i = 0;
            while (i < ms_TimeOut / 200)
            {
                string Readrst = "";
                if (CHKComPortRead(WaitStr, out Readrst)) return true;
                Thread.Sleep(100);
                i++;
            }
            MyLib.COMMFunc.AppendText(richTextBox1, "\r\nWAIT " + WaitStr + " TimeOut=" + ms_TimeOut + " ms\r\n\r\n");
            return false;
        }

   internal bool CHKComPortRead(string CHKStr,out string Readrst )
        {
            Readrst = ""; string temp = "";
            if (!EMoudleInstance.CHKComPortOpen()) return false;
            while (true)
            {
                int i = 0;
                int n = 0;
                while ((n = EMoudleInstance.ComPort.BytesToRead) == 0)
                {
                    Thread.Sleep(50);
                    i++;
                    if (i >= 3) break;
                }
                if ((n = EMoudleInstance.ComPort.BytesToRead) == 0) break;
                byte[] buf = new byte[n];
                EMoudleInstance.ComPort.Read(buf, 0, n);
                temp = Encoding.ASCII.GetString(buf);                 
                MyLib.COMMFunc.AppendText(richTextBox1, temp);
                Readrst += temp;
                if (temp.Contains(CHKStr))
                {
                    MyLib.COMMFunc.AppendText(richTextBox1, "\r\nWAIT " + CHKStr + " OK\r\n\r\n");
                    return true;
                }
            }
            if (Readrst.Contains(CHKStr))
            {
                MyLib.COMMFunc.AppendText(richTextBox1, "\r\nWAIT " + CHKStr + " OK\r\n\r\n");
                return true;
            }else
            {              
                return false;
            }
           
        }

最关键的函数是 CHKComPortRead() 调用它前面需要设置 IsStoppingDataReceive = true;(在Test()函数里面)这样被动接收和主动接收就可以实时切换。为什么要切换到主动接收,因为点击WAIT String 按钮是主动点击事件,可以实现任意时刻触发WAIT方法。

以上,如果还是不明白的可以评论留言。

有兴趣的可以下载示例程序实验一下。如果示例程序好用,我再教大家怎么把示例程序引用到自己程序中。

如果有人需要全部源代码,我再上传。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值