C# 从串口读取数据 - 如何只获取新的/当前数据?

Posted

技术标签:

【中文标题】C# 从串口读取数据 - 如何只获取新的/当前数据?【英文标题】:C# Reading data from a serial port - How to only get new/current data? 【发布时间】:2019-11-16 10:30:01 【问题描述】:

我正在用 ASP.NET 开发一个项目,其背后的代码是用 C# 编写的。如果秤上显示的重量在您在实际秤上设置的两个数字范围内,我一直在从向我发送“是”或“不是”的秤中读取数据。据我所知,这两个字符串是秤可以发送的唯一数据。现在,页面上的一个按钮读取数据并将标签更改为“好工作”或“错误”(Pretty 现在只是在处理功能)。但是,当我单击按钮时,我一直在获取较旧的数据,例如,我会单击它两次,而秤上什么都没有,然后得到“NOT”,标签会变成“错误”,但是一旦我在秤上放了一些东西在限制内而不是得到“是”我会得到类似“NOTYES”的东西。

我在串口上有一个 ReadTimeout,我有一个线程,但我对线程不熟悉这是我第一次做这样的事情。我在串口上加了一个 DiscardInBuffer() ,似乎有点帮助,但不是太多,我也不太清楚该放在哪里。

我也一直在打印到控制台,以便查看实际读取的数据。它不断发送数据,所以我会有一个有点不可预测的巨大字符串,比如“NOT\nNOT\nNot\n...”,这就是我清理数据的原因。

该按钮具有自动回发功能,并且标签位于更新面板中,因此它运行 loadPage(),然后是 read(),然后是 buttonClick() - 这在这一点上基本上没用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

namespace ScaleTest


    public partial class WebForm1 : System.Web.UI.Page
    
        public SerialPort port;
        public string scaleData = "";

        protected void Page_Load(object sender, EventArgs e)
        

            if (IsPostBack)
            
                Thread readThread = new Thread(Read);
                port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
                port.ReadTimeout = 1000;
                if (port.IsOpen == false)
                    try
                    
                        port.Open();
                    
                    catch (Exception oex)
                    
                        Debug.WriteLine(oex);
                    
                readThread.Start();
                readThread.Join();
                port.Close();
            
        

        public void Read()
        
            try
            
                string message;
                string scaleData = port.ReadLine();
                port.DiscardInBuffer();
                Debug.WriteLine(scaleData);
                scaleData = scaleData.Trim().Replace("\r", string.Empty).Replace("\n", string.Empty);
                scaleData = String.Join("", scaleData.Distinct());


                Debug.WriteLine(scaleData);


                if (scaleData == "YES")
                
                    message = "Good Job!";
                
                else if (scaleData == "NOT")
                
                    message = "WRONG!";
                
                else
                
                    message = "Try Again.";
                
                ScaleLabel.Text = message;

            
            catch (TimeoutException)  
        

        protected void ButtonClick(object sender, EventArgs e)
        
        

    

如果我从秤上的任何东西开始,运行程序并按下按钮,scaleData 将是“NOT”,标签将变为错误,这是正确的。但是,如果我在限制范围内将某些东西放在秤上并再次按下按钮,我通常必须按下按钮几次才能获得“是”,因为它正在获取旧数据并给我诸如“NOTYES”之类的东西。

【问题讨论】:

数据被缓冲,你必须读取直到你清除缓冲区。 尝试使用DataReceived 事件。 docs.microsoft.com/en-us/dotnet/api/… 看看这个***.com/a/13755084/891715 【参考方案1】:

你可以试试这个link中的示例代码,它使用ReadLine()方法

public static void Main()

     _serialPort = new SerialPort();
     _serialPort.BaudRate = 115200;
     _serialPort.PortName = "COM7";
     _serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);


private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)

    try
    
        SerialPort sp = (SerialPort)sender;
        if (!sp.IsOpen) return;

        string indata = _serialPort.ReadLine();
        Console.WriteLine(indata);
    
    catch (Exception) ;

【讨论】:

以上是关于C# 从串口读取数据 - 如何只获取新的/当前数据?的主要内容,如果未能解决你的问题,请参考以下文章

c#从串口读取数据怎样读一个就清空缓存

c#如何获取串口的句柄?

C#串口读取?

matlab串口接收数据的问题

怎么从接口里获取数据、、

nodejs 获取串口数据