Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
The output is basically the dec representation of the bytes. and the hardware connected to serial port send it in these format E0 ,F2 ,device id ,2 bytes length,current date,current time(store both current date and current time in more than 2 bytes by right shifting and some other data)

I am receiving data in chunks sometimes 4 bytes, sometimes 8 bytes.What i want to do is 1.I want to check first what i have received in that data packet like header 2.then when i received next data block i do not want to check for header but for next information like date and time and so on..

basically i want to parse the incoming packet.

can anyone please give an small example.It will be really helpful.

Thanks.

What I have tried:

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SerialPortHexCommunication
{
public class Program
{
    static void Main(string[] args)
    {

        SerialPort port = new SerialPort();
        port.PortName = "COM5";
        port.Parity = Parity.None;
        port.BaudRate = 9600;
        port.DataBits = 8;
        port.StopBits = StopBits.One;

        if (port.IsOpen)

        {
            port.Close();
            port.Dispose();
        }
         port.Open();

        byte[] bytesToSend = new byte[6] { 0xD0, 0xF2, 0xFF, 0x00, 0x06, 0xC7 };

        port.Write(bytesToSend, 0, bytesToSend.Length);


        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        Console.ReadKey();
        port.Close();
        port.Dispose();




    }

    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        Console.WriteLine("Data receive at time "+ DateTime.Now.TimeOfDay);
        SerialPort port = (SerialPort)sender;

        int bytes = port.BytesToRead;
        byte[] buffer = new byte[bytes];

        if (port.BytesToRead > 1)
        {
            port.Read(buffer, 0, bytes);
        }

        foreach (byte item in buffer)
        {
            Console.WriteLine(item);

        }


    }
}
Posted
Updated 3-Jun-18 22:08pm

Receiving serial data is an asynchronous operation and you usually get not all data from a packet with a single event.

So you have to create at least the receive buffer and an index as (private) class members to store the received data by appending until you know that a complete package has been received. The buffer must be large enough to store the largest possible package size.

A very simple example from scratch:
C#
// Private class members.
// Note that these are used by the receive handler which is executed 
//  in another thread
bool newData = false;
int rxOffset = 0;
byte[] rxBuffer = new byte[MAX_PACKAGE_LENGTH];
// To hold a package after it has been received
byte[] rxPackage = new byte[MAX_PACKAGE_LENGTH];

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort port = (SerialPort)sender;
    int bytes = port.BytesToRead;
    port.Read(rxBuffer, rxOffset, bytes);
    rxOffset += bytes;
    // Check here if a complete package has been received
    if (HasCompletePackage())
    {
        rxBuffer.CopyTo(rxPackage, 0);
        rxOffset = 0;
        // Or signal the main thread that a new package is available
        newData = true;
    }
}
Note that the above does not include additional checks like overflow of the receive buffer, detection of incomplete packages (e.g. at startup) and locking access to shared variables (here: newData and rxPackage).
 
Share this answer
 
v2
Comments
Nishikant Tayade 4-Jun-18 4:14am    
Thanks @JochenArndt.I can work on this now.
Serial data is called that because it arrives in a serial fashion, byte by byte instead of as a "managed packet" of information: each byte can cause a separate DataReceived event to fire.
So store it in a buffer and process the buffer to decide what to do.
I'd start with a basic state machine: "Waiting for header", "Building message" as a minimum.
You start in "Waiting", and process each byte as it is received until you get the code which indicates the start of actual data. Then you switch to "Building" and store the message until you get to the end - at which point it's back to "Waiting" and you can process the whole data block you have stored.
 
Share this answer
 
Comments
Nishikant Tayade 4-Jun-18 1:59am    
@OriginalGriff Thanks for the response,but what do you meant by building state machine?Could you please give an code snippet,so that it will be better to understand.
OriginalGriff 4-Jun-18 2:11am    
A basic state machine is just an enum and a variable to test and find out what you should be doing when you get the event!

For more advanced version, check wiki!
Nishikant Tayade 4-Jun-18 2:30am    
I know its like spoon feeding but as a noob its little bit confusing,I googled but it is all over the places.please give an code snippets.
OriginalGriff 4-Jun-18 3:33am    
You know what an enum is, yes?
You know what a variable is, yes?
You know what an "if" and / or "switch" statement is yes?

If you can't put those three together without help, then serial communications are way too advanced for you to be getting into! :laugh:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900