C# - 从串口缓冲区读取

发布于 2024-08-04 07:40:47 字数 183 浏览 4 评论 0原文

我正在尝试从 RS-232 端口读取数据。有谁有一个例子说明我如何从端口/缓冲区获取数据并确保我拥有所有数据,因为它可以是多行数据。

我只是简单地读如下吗?

string Rxstring = port.ReadLine();
Console.WriteLine(Rxstring);

I am trying to read data from an RS-232 port. Does anyone have an example of how I get the data from the port/buffer and make sure that I have all the data as it can be multiline data.

Do I simply read it as follows ?

string Rxstring = port.ReadLine();
Console.WriteLine(Rxstring);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

请你别敷衍 2024-08-11 07:40:47

问:如何从端口/缓冲区获取日期,或从连接的设备输入数据。并确保您拥有所有数据。

答:我广泛使用 .net 串行端口类驱动程序,负责创建可靠、健壮的代码。这意味着被测连接设备必须在很长一段时间内运行并且不会出现故障。串行端口可能并且确实会丢失数据!别忘了这一点。

//from top of the head;

using System.Port.IO;
using System.Port;

private class mywindowsForm: Form
{
      StringBuilder sbReceived = new StringBuilder();
      string Received = string.Empty;
      int byteCOUNT = 0;

      System.Windows.Timers.Timer serialTimer;

      //Default constructor 
      myWindowsForm()
      {
         //assume that you clicked and dragged serial port in
          serialPort1 = new SerialPort();//create new serial port instance 
          serialPort1.Baud = 9600;
          serialPort1.DataReceived+=<Tab><Enter>
          //serial port timer 
          serialTimer = new System.Windows.Timers.Timer(500);//set to 500ms time delay
          serialTimer.Elapsed+=<TAB><ENTER>
      }

      void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
           //serial port has detected input data
           //however, we only want to get serial data so,
           if(e.EventType !=SerialData.Chars) return;
           //good design practice dictates that we have an event handler that we invoke
            this.BeginInvoke(new eventhandler(AddReceive));//beginInvoke is designed to deal with asynchronous processes like serial port data. 
      }

      private void AddReceive(object s, EventArg e)
      {
            byteCOUNT=serialPort1.BytesToRead;//count the number of bytes in RX buffer
            if(byteCOUNT > 0) 
             {
                 string ST = serialPort1.ReadTo("\n");//lets get one line at a time 
                 sbReceived.Append(ST);//add whatever has been RX'd to our container. 
                 serialPort1.Interval =100;
                 serialPort1.Start();//to be sure we have all data, check to see for stragglers.
              }
      }

       void serialTimer(object Sender, TimerElapsedEventArgs e)
       {
            serialTimer.Stop();
            this.BeginInvoke(new EventHandler(ReadData));
        }

       void ReadData(object Sender, EventArgs e)
       {
            //parse output for required data and output to terminal display (build one using rich text box)
             Received = sbReceived.ToString();
             //and if we have ANY MORE incoming data left over in serial buffer
              if(Received.Length > 0)
              {
                  //your data 
              }
       }
}

这应该足以帮助您入门。这是多年来用 C# 创建定制终端模拟器的结果。还有其他事情可以做,特别是如果您有大量 I/O 数据,您需要与设备建立握手。您必须让设备以设备满意的速度进行处理。在必须传输较大数据的情况下,请考虑设置一个简单的数据包传递协议和命令信号量构造 - 或使用控制器/设备设计使用的协议。

Q: how to get the date from the port/buffer, or input data from your connected device. AND make sure that you have all the data.

A: i have worked extensively with .net serial port class drivers where i was tasked to create reliable, robust code. this means that a connected device under test has to run and NOT fail over a LONG period of time. Serial port can AND does lose data! don't forget that.

//from top of the head;

using System.Port.IO;
using System.Port;

private class mywindowsForm: Form
{
      StringBuilder sbReceived = new StringBuilder();
      string Received = string.Empty;
      int byteCOUNT = 0;

      System.Windows.Timers.Timer serialTimer;

      //Default constructor 
      myWindowsForm()
      {
         //assume that you clicked and dragged serial port in
          serialPort1 = new SerialPort();//create new serial port instance 
          serialPort1.Baud = 9600;
          serialPort1.DataReceived+=<Tab><Enter>
          //serial port timer 
          serialTimer = new System.Windows.Timers.Timer(500);//set to 500ms time delay
          serialTimer.Elapsed+=<TAB><ENTER>
      }

      void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
           //serial port has detected input data
           //however, we only want to get serial data so,
           if(e.EventType !=SerialData.Chars) return;
           //good design practice dictates that we have an event handler that we invoke
            this.BeginInvoke(new eventhandler(AddReceive));//beginInvoke is designed to deal with asynchronous processes like serial port data. 
      }

      private void AddReceive(object s, EventArg e)
      {
            byteCOUNT=serialPort1.BytesToRead;//count the number of bytes in RX buffer
            if(byteCOUNT > 0) 
             {
                 string ST = serialPort1.ReadTo("\n");//lets get one line at a time 
                 sbReceived.Append(ST);//add whatever has been RX'd to our container. 
                 serialPort1.Interval =100;
                 serialPort1.Start();//to be sure we have all data, check to see for stragglers.
              }
      }

       void serialTimer(object Sender, TimerElapsedEventArgs e)
       {
            serialTimer.Stop();
            this.BeginInvoke(new EventHandler(ReadData));
        }

       void ReadData(object Sender, EventArgs e)
       {
            //parse output for required data and output to terminal display (build one using rich text box)
             Received = sbReceived.ToString();
             //and if we have ANY MORE incoming data left over in serial buffer
              if(Received.Length > 0)
              {
                  //your data 
              }
       }
}

this should be plenty to get you started. this is result of years of creating customized terminal emulators in c#. there are other things that can be done, particularly if you have large amount of i/o data you need to set up handshaking with device. you have to let the device handle at a rate that the device is happy with. in cases where larger data has to be transferred consider setting up a simple packet passing protocol and command semaphore construct - or use a protocol as defined that the controller / device is designed to work with.

情场扛把子 2024-08-11 07:40:47

试试这个:

using System.IO.Ports;
...

private SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);

Console.WriteLine(port.ReadExisting());

详细信息可以在 Coad 代码

Try this:

using System.IO.Ports;
...

private SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);

Console.WriteLine(port.ReadExisting());

Details can be found at Coad's Code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文