Eduardo Estevão
Eduardo Estevão

Reputation: 41

C# Serial Port Data, Format received data

So I'm reading data from the serial port, so far so good, but the data coming from the serial port is chunked, I've this protocol that states that every messages begin with SOH (\u0001 byte) and ends with EOT(\u0004), I tried to split the message by the SOH byte, but still having issues with that. There's a more elegant and safe way to do this?

private  void RecebendoDados(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        var id_prova = Form1._Form1.IDPROVA;
        var serie = Form1._Form1.SERIE;
        var fase = Form1._Form1.FASE;

        var http = new ComunicacaoWeb();
        var sp = (SerialPort)sender;
        var indata = sp.ReadExisting();
        Console.WriteLine(indata+"\n\r");

        if (!sp.IsOpen) {
            sp.Open();
        }

        var pacotes = indata.Split(new[] { "\u0004" }, StringSplitOptions.None);

Upvotes: 0

Views: 999

Answers (1)

Mong Zhu
Mong Zhu

Reputation: 23732

1

Theres a more elegant and safe way to do this?

If your message end with the EOT control code then SerialPort allows you to read exactly up to the first occurrence of this char.

SerialPort sp = (SerialPort)sender;
// this lines converts the hex-code of EOT to a char and read the incoming
// message only up to this point
string indata = sp.ReadTo(Convert.ToChar(0x04));

now you need only to get rid of the SOT:

indata = indata.TrimStart(Convert.ToChar(0x01));

at this point you should have on clean message.

The property BytesToRead will tell you whether there is still data in the buffer:

int stillToBeRead = sp.BytesToRead;

you can check it and repeat the reading procedure if necessary.

2.

Theres a more ellegant and safe way to do this?

if you try to read from a closed port then it will fail with a System.InvalidOperationException. By this logic the if-condition in your code will never be entered to reopen the port.

var sp = (SerialPort)sender;
var indata = sp.ReadExisting();

if (!sp.IsOpen) {
    // this will never be executed
    sp.Open();
}

you should check whether the port is open and there is data to read before attempting to read from it. I guess RecebendoDados is the DataReceived event, so the probability of having a closed port and no data to read is low, but still: the devil sleeps in the detail ;)

Upvotes: 1

Related Questions