在串口的DataReceived事件中没有收到数据字节? [英] Data bytes not received at DataReceived event of serial port?

查看:92
本文介绍了在串口的DataReceived事件中没有收到数据字节?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小型应用程序,当端口(在我的情况下为COM10)接收数据时它不接收完整字节,并且有时它接收一些字节并再次接收一些字节时,它在串行端口上工作。为什么会这样?我想一次接收所有字节,以便我可以进行进一步处理,我只是猜测dataReceived事件在每个字节触发,但我想只在完整数据到来时触发它。如果可能,请给我建议并编辑我的代码。

谢谢大家!



这是我的代码,



  public   void  _serialPort_DataReceived(< span class =code-keyword> object  sender,SerialDataReceivedEventArgs e)
{

for int p = 0 ; p > = < span class =code-digit> 0 ; p ++)
{
int dataLength = _serialPort.BytesToRead;
byte [] data = new byte < /跨度> [DATALENGTH];

int nbrDataRead = _serialPort.Read(data, 0 ,dataLength);

if (nbrDataRead == 0
返回;
// 向感兴趣的人发送数据
if (NewSerialDataRecieved!= null
{
NewSerialDataRecieved( new SerialDataEventArgs(data));
}

for int i = 0 ; i < nbrDataRead; i ++)
{
Convert.ToChar(data [i] );
}

解决方案

通常的方法是收集中可用的所有字节DataReceived 处理程序,并将它们附加到'接收缓冲区',您可以在其中处理它们。


您需要继续检查输入端的可用数据。当您收到一些字节时,将它们附加到缓冲区,然后重试。当您收到正确的字节数或一些指示数据结束的特殊字节时,您将其传递下来进行处理。


您可以使用几个选项,具体取决于如果你想以字节流或字符串形式读取数据。



选项1,读作字节

(非常粗略结束字符后不考虑额外数据的方式)

  //  用于在事件之间保持接收数据的缓冲区 
private List< byte> receivedData = new List< byte>();
private void serialPort1_DataReceived( object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
{
// 读取可用字节并检查是否存在结束字节
byte [] buffer = new byte [serialPort1.BytesToRead];
serialPort1.Read(buffer, 0 ,buffer.Length);
receivedData.AddRange(buffer);
if (receivedData.Contains(0x03)) // 只有结束字节的示例
{
if (NewSerialDataRecieved!= null
{
NewSerialDataRecieved( this new SerialDataEventArgs(receivedData));
receivedData.Clear();
}
}
}





选项2,使用NewLine属性



假设您要从COM端口读取字符串,并且您的字符串用例如CR + LF分隔。

然后您需要设置代码中某处的NewLine属性。

 serialPort1.NewLine =   \\\\ n; 



然后只需逐行阅读并触发每行的事件。

  private   void  serialPort1_DataReceived( object  sender,System.IO.Ports.SerialDataReceivedEventArgs e)
{
string receivedData = serialPort1.ReadLine();
if (NewSerialDataRecieved!= null
{
NewSerialDataRecieved( this new SerialDataEventArgs(receivedData));
}
}





当然,您也可以使用这些示例的几种变体。


I am writing a small application which works on serial port when port ("COM10" in my case) receives data it doesn't receive full byte and sometimes it receives some bytes and again receives some bytes. Why it happened?? I want to receive all bytes at one time so that i can do further processing , I just guessed that dataReceived event triggers at every byte but I want to trigger it only when full data comes. please give me suggestions and edit my code if possible .
Thanks everyone!

Here is my code,

public void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {

          for (int p = 0; p >= 0; p++)
          {
                 int dataLength = _serialPort.BytesToRead;
                byte[]  data = new byte[dataLength];

              int nbrDataRead = _serialPort.Read(data, 0, dataLength);

              if (nbrDataRead == 0)
                  return;
              // Send data to whom ever interested
              if (NewSerialDataRecieved != null)
              {
                  NewSerialDataRecieved(this, new SerialDataEventArgs(data));
              }

              for (int i = 0; i < nbrDataRead; i++)
              {
                  Convert.ToChar(data[i]);
              }

解决方案

The usual approach is gathering all the bytes available in the DataReceived handler, and append them to a 'receive buffer' where you can process them.


You need to keep checking for data available at the input end. When you receive some bytes, you append them to your buffer, and try again. When you have received the correct number of bytes, or some special byte that indicates 'end of data', then you pass it off to be processed.


There are several options you can use depending if you want to read the data as a stream of bytes or as a string.

Option 1, read as bytes
(Very crude way that doesn't consider extra data read after end character)

// Buffer used to keep received data between events
private List<byte> receivedData = new List<byte>();
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    // Read available bytes and check for presence of a end byte
    byte[] buffer = new byte[serialPort1.BytesToRead];
    serialPort1.Read(buffer, 0, buffer.Length);
    receivedData.AddRange(buffer);
    if (receivedData.Contains(0x03)) // Only an example of an end byte
    {
        if (NewSerialDataRecieved != null)
        {
            NewSerialDataRecieved(this, new SerialDataEventArgs(receivedData));
            receivedData.Clear();
        }
    }
}



Option 2, Use the NewLine property

Let's say that you want to read strings from the COM port and your strings are separated with, for example, CR+LF.
Then you need to set the NewLine property somewhere in the code.

serialPort1.NewLine = "\r\n";


Then just read line by line and trigger your event for each line.

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string receivedData = serialPort1.ReadLine();
    if (NewSerialDataRecieved != null)
    {
        NewSerialDataRecieved(this, new SerialDataEventArgs(receivedData));
    }
}



There are of course several variants of these examples that you can use as well.


这篇关于在串口的DataReceived事件中没有收到数据字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆