简体   繁体   中英

Serial port data receive handling

I have a form in which I am able to receive data and show it in a richtextbox, but what I need is to read the data that is coming continuously from serial port and decode accordingly.

For ex: I am receiving data in bytes in the format as 36 0 0 0 1 0 0...., 36 is used to indicate start of frame n rest are the data through which an event will be fired.

My code:

 private void serialPort1_DataReceived(object sender,  System.IO.Ports.SerialDataReceivedEventArgs e)
 {
        // get number off bytes in buffer 
        Bytenumber = serialPort1.BytesToRead;

        // read one byte from buffer 
        ByteToRead = serialPort1.ReadByte();                     

        this.Invoke(new EventHandler(DoUpdate));            
    }

Above code is used to receive data and fire an event. The code for the event is as follows:

 int w=0;

 public void DoUpdate(object sender, System.EventArgs e)
 {
        byte[] t = new byte[Bytenumber];

        for(int g=0; g<Bytenumber;g++)
        {
           t[g] = Convert.ToByte(ByteToRead);
        }

        w++;

       // richTextBox1.Text += ByteToRead;
        if (ByteToRead == 36)
        {
            for (int r = 0; r <= 73; r++)
            {
                if (ByteToRead == 0x01)
                {   
                    timer1.Start();
                    w++;
                }
            }
        }
      }

In the data received event handler I am looking for 36 (ie, start of frame) once I get that I am looking for 1s from the buffer. The problem is when I get 36 (ie, start of frame) the same data is retained in the if loop and tries to compare with 1 which will not be true @ any case. All I need is to read the next bytes of data coming from the buffer once I get 36.

I can spot a few problems. A little code-review:

    Bytenumber = serialPort1.BytesToRead;

ByteNumber is the Bytes-to-Read at this moment. It is not thread-safe to keep this in a member field.

    ByteToRead = serialPort1.ReadByte();    

This only reads 1 Byte. And then, on another thread:

    byte[] t = new byte[Bytenumber];   // ByteNumber may have changed already
    for(int g=0; g<Bytenumber;g++)
    {
        t[g] = Convert.ToByte(ByteToRead);   // store the _same_ byte in all elements
    }

What you should do (not complete code):

private void serialPort1_DataReceived(object sender,  System.IO.Ports.SerialDataReceivedEventArgs e)
{
    // get number off bytes in buffer 
    int n = serialPort1.BytesToRead;

    byte[] buffer = new byte[n];

    // read one byte from buffer 
    int bytesToProcess = serialPort1.Read(buffer, 0, n);                     

    this.Invoke(UpdateMethod, buffer, bytesToProcess);            

}

But do search the internet for working code. I just made this up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM