3 Replies - 1435 Views - Last Post: 29 October 2012 - 02:23 PM Rate Topic: -----

#1 harrod159  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-October 12

parsing variable length serial data

Posted 29 October 2012 - 01:03 PM

Hi.

I have a program that will listen to the serial port for a string of binary data. the data has a fixed format but can have variable length like this:

source, length, destination, command, data0, datax, crc


each section is a single byte.
so far I have a basic idea of how to read the serial data, and the pseudo code i've got so far is this:

byte() = buffer contents
	
if byte(0) is valid source
	src = byte(0)
	len = byte(1)
	dest = byte(2)
	cmd = byte(3)
	data(len-3)
	for i = 0 to len - 3
		data(i) = byte(4 + i)
	next
	crc = byte(len + 2)
	write all these fields to the visual output.
else
	do something else
end if


I currently have this vb.net code

Private Sub SerialPort1_DataReceived1(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived


        'retrieve number of bytes in the buffer
        Dim bytes As Integer = SerialPort1.BytesToRead
        'create a byte array to hold the awaiting data
        If bytes >= 2 Then
            Dim comBuffer As Byte() = New Byte(bytes - 1) {}
            'read the data and store it
            SerialPort1.Read(comBuffer, 0, bytes)
            'display the data to the user
            _type = MessageType.Incoming
            _msg = ByteToHex(comBuffer) + "" + Environment.NewLine + ""
            DisplayRawData(txtRX, MessageType.Incoming, ByteToHex(comBuffer) + "" + Environment.NewLine + "")

            parseData(DataGridView1, comBuffer)
        End If
        
    End Sub


    Sub parseData(ByVal grid As DataGridView, ByVal data As Byte())
        If DataGridView1.InvokeRequired Then
            DataGridView1.Invoke(Sub() parseData(grid, data))
        Else
            Dim src As Byte
            Dim len As Byte
            Dim dest As Byte
            Dim cmd As Byte
            Dim datalen As Integer
            Dim crc As Byte

            '50    04   68   3B   21  26
            'src, len, dest, cmd, d0, crc
            Debug.Print(CInt(UBound(data)))
            src = data(0)
            len = data(1)
            datalen = CInt(len)
            Debug.Print("Len=" & CInt(len))
            dest = data(2)
            cmd = data(3)
            'datalen = 4
            Dim msg As Byte() = New Byte(datalen - 3) {}
            For i = 0 To datalen
                msg(i) = data(i + 4)
            Next
            crc = data(8)

            'check crc here

            dt.Rows.Add(New Object() {Now(), ByteToHex(data), src.ToString("X"), len.ToString("X"), dest.ToString("X"), cmd.ToString("X"), ByteToHex(msg), crc.ToString("X"), "OK"})
            DataGridView1.Refresh()
        End If
    End Sub


So, the question.
Am i going about this the right way? How do i ensure i get the start of the packet and not halfway through?
Any tips please?

Thanks!

Is This A Good Question/Topic? 0
  • +

Replies To: parsing variable length serial data

#2 lar3ry  Icon User is offline

  • Coding Geezer
  • member icon

Reputation: 310
  • View blog
  • Posts: 1,290
  • Joined: 12-September 12

Re: parsing variable length serial data

Posted 29 October 2012 - 01:35 PM

For ease of conversation, I'll call a sequence of src -> crc a packet.

Do you have any delimiters at the beginning or end of a packet?
Do you have any delimiters between any of the bytes?
Is src a fixed value? Is src one of a few possible values?
Is cmd one of a few fixed values?
Do you know how to calculate the CRC, and which bytes are included in the CRC?
Will there be fixed times between bytes in a packet, and a longer time between packets?

If any of these are true, you stand a good chance of figuring out the start of a packet.

Let us know.
Was This Post Helpful? 0
  • +
  • -

#3 harrod159  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 29-October 12

Re: parsing variable length serial data

Posted 29 October 2012 - 01:49 PM

View Postlar3ry, on 29 October 2012 - 01:35 PM, said:

For ease of conversation, I'll call a sequence of src -> crc a packet.

Do you have any delimiters at the beginning or end of a packet?
-Nope

Do you have any delimiters between any of the bytes?
-Nope

Is src a fixed value? Is src one of a few possible values?
Yep, the source byte is the address of the device sending the packet, so whilst in theory it could be 0x00 to 0xFF in reality there are only a few devices on the bus. I can have the program read a list of devices/addresses.

Is cmd one of a few fixed values?
-the cmd probably is a few fixed values, it would depend on the source and destination device. Unfortunately these are not in my control and are relatively unknown, so best to presume it could be anything.

Do you know how to calculate the CRC, and which bytes are included in the CRC?
crc is a simple XOR checksum of the entire packet, source to last data bit.
The computation of this is implemented.

Will there be fixed times between bytes in a packet, and a longer time between packets?
-unknown, but i would think the time between packets could be completely random because of the several devices on the bus.

If any of these are true, you stand a good chance of figuring out the start of a packet.
-so do i?!

Let us know.

Was This Post Helpful? 0
  • +
  • -

#4 lar3ry  Icon User is offline

  • Coding Geezer
  • member icon

Reputation: 310
  • View blog
  • Posts: 1,290
  • Joined: 12-September 12

Re: parsing variable length serial data

Posted 29 October 2012 - 02:23 PM

Try not to reply within the quoted text. It's very hard to read.

Another question. Do the packets arrive asynchronously without being requested by the program? If so, how do the devices know when it's clear to send a packet?

So, assuming arrival asynchronously and without being requested, there are a few ways you might want to look at.

1. If the devices send the packets with a fairly short time between bytes, read a byte, set a timer, and await a gap between packets that is at least 1.5-2 times longer than the byte-byte gap. Of course, you may end up missing the first few packets, if they are already arriving when your program starts.

2. Check for what looks like a valid src byte, then parse the possible packet out to the crc, and if the length and crc are as expected, there is a high probablility that the packet is complete.

3. After receiving the minumum number of bytes that a packet can contain, use the last byte to figure out if it's a crc, and calculate backward from byteX to see if it's a crc for that string of bytes, checking the length to see if that also matches.

If any of these can be done, you can now check each packet by assuming you are still in sync. If something after that doesn't match, you'll have to sync up again.

If you don't mind my asking, what sort of devices are they, and how do they know when it's clear to transmit?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1