Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data
Serial port (com port) reading data Serial port (com port) reading data
Serial port (com port) reading data
Go Back  Xtreme Visual Basic Talk > > > Serial port (com port) reading data


Reply
 
Thread Tools Display Modes
  #1  
Old 09-14-2013, 11:43 AM
StealthRT's Avatar
StealthRT StealthRT is offline
Contributor
 
Join Date: Aug 2002
Posts: 785
Exclamation Serial port (com port) reading data


I have a valentine 1 radar and also the V1Connect (bluetooth adaptor) for it hooked to my PC via a Virtual Serial Port (COM 16).

I am trying to read the data coming from it but all i am getting is gibberish.

My VB.net code is this:
Code:
    Private pendingMsg As New stringbuilder

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each s In System.IO.Ports.SerialPort.GetPortNames()
            lstPorts.Items.Add(s)
        Next s
    End Sub

    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim completedMsg As String
        completedMsg = String.Empty
        pendingMsg.Append(SerialPort1.BytesToRead())

        If pendingMsg.Length >= 24 Then
            completedMsg = pendingMsg.ToString
            Debug.Print(completedMsg)
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        SerialPort1.BaudRate = 57600
        SerialPort1.DataBits = 8
        SerialPort1.Parity = IO.Ports.Parity.None
        SerialPort1.StopBits = IO.Ports.StopBits.One
        SerialPort1.PortName = "COM16" 'lstPorts.SelectedItem.ToString
        SerialPort1.Open()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SerialPort1.Close()
        txtReceived.Text = ""
    End Sub
and the gibberish output is this:
Code:
71919383957767795114129133
71919383957767795114129133152
71919383957767795114129133152167
71919383957767795114129133152167171
71919383957767795114129133152167171190
71919383957767795114129133152167171190191
71919383957767795114129133152167171190191209
71919383957767795114129133152167171190191209228
71919383957767795114129133152167171190191209228229
71919383957767795114129133152167171190191209228229247
71919383957767795114129133152167171190191209228229247266
71919383957767795114129133152167171190191209228229247266280
71919383957767795114129133152167171190191209228229247266280285
71919383957767795114129133152167171190191209228229247266280285304
71919383957767795114129133152167171190191209228229247266280285304311
71919383957767795114129133152167171190191209228229247266280285304311323
71919383957767795114129133152167171190191209228229247266280285304311323342
71919383957767795114129133152167171190191209228229247266280285304311323342343
71919383957767795114129133152167171190191209228229247266280285304311323342343361
71919383957767795114129133152167171190191209228229247266280285304311323342343361380
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382399
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382399418
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382399418419
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382399418419437
71919383957767795114129133152167171190191209228229247266280285304311323342343361380382399418419437456
The datasheets for the V1 are:
http://i.stack.imgur.com/IMIG2.jpg

http://i.stack.imgur.com/UnKUU.jpg

http://i.stack.imgur.com/vJpe6.jpg

http://i.stack.imgur.com/bJFar.jpg

http://i.stack.imgur.com/cTnhn.jpg

The full PDF for the ESP can be found http://www.valentine1.com/eula/eula.asp?d
Reply With Quote
  #2  
Old 09-14-2013, 06:56 PM
passel's Avatar
passelSerial port (com port) reading data passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

Don't have time to test what String Builder does when appending bytes from a serial port, but I assume it isn't that useful.
The documentation indicates you will be getting messages made up of various number of bytes depending on the message id, so as a minimum you should be reading the serial data into a byte array, and then look for the framing bytes and when you have a complete message, framed by the SOF (AA hex, which would be 170 decimal) and EOF (AB hex, 171 decimal) and then byte offset 3 within the mesage would identify the packet ID, and 4 the length (so you would use the byte values directly as numbers, not as a character). You would then decode the rest of the bytes in the packet in accordance to the specification.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #3  
Old 09-14-2013, 07:23 PM
StealthRT's Avatar
StealthRT StealthRT is offline
Contributor
 
Join Date: Aug 2002
Posts: 785
Default

This is my current code:
Code:
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim b As Integer

        SerialPort1.ReadTimeout = 50

        Try
            Do While SerialPort1.BytesToRead > 0
                b = SerialPort1.ReadByte
                Me.BeginInvoke(New mydel(AddressOf txt_out), b)
            Loop
        Catch ex As Exception

        End Try
    End Sub

    Private Sub txt_out(ByVal i As Integer)
        txtReceived.AppendText("&H" & i.ToString("X2") & " ")
    End Sub
I am now getting this:
Code:
&H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F
 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
&HE6 &H7F &H7F &H0F 
&HAA &HD8
I see the &HAA(start) and the &HD8(end) but how do i separate each of those start and ends without keep adding to it?

Last edited by passel; 09-15-2013 at 02:26 PM. Reason: Wrap the long line to make page more managable
Reply With Quote
  #4  
Old 09-15-2013, 08:31 AM
AtmaWeapon's Avatar
AtmaWeaponSerial port (com port) reading data AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Imagine your StringBuilder is a bucket. And the data coming from the serial port is yummy fruit juice, a different flavor every time. You hold the bucket under the spigot, then look to see what you got. Apple juice! Then you put the bucket (still half-full of apple juice) back under the spigot. OK, now you have a mix of apple and cranberry juice; that was harder to identify but still possible. 10 samples later, you can't tell what the heck's going on.

This is what you're doing when constantly appending data to the StringBuilder. The simple (and wrong) answer to, "How do I identify the separate start and end sections" would be, "Write code that loops over each byte and finds each start/end marker." Why is that wrong? It's like saying to our metaphorical spigot bucket guy, "You fool! Your fruit juice bucket needs these hundreds of little dividers so you can separate all the juices!"

Empty the bucket. StringBuilder has a Clear() method or something similar. Take one sample, do something with it, then clear your buffer. If you approach the spigot with an empty bucket, it's easy to see what is in it.

(Incidentally, neither approach is really wrong. Sometimes you want to take one sample at a time. In that case it's best to use a new bucket each time. Other times you want to take many samples and process them later. That's *why* there's a start/end section in the protocol: so you can take one stream of bytes and figure out how to divide it up. But in your example program, there's no reason to keep the old data around.)
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #5  
Old 09-15-2013, 03:34 PM
passel's Avatar
passelSerial port (com port) reading data passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

Since you're not dealing with character data, I don't think that discussing the StringBuilder class is really useful here. I admit I haven't used it a lot, but I suspect it is not real useful for dealing with collecting and decoding the numeric bytes and discrete bits necessary when dealing with a hardware interface protocol.

Since the hardware will most likely be already transmitting when you start your application, you may start receiving data in the middle of the stream (as your dump indicates), and data can be corrupted, so you pretty much have to continually verify that you are sync'd to the packets and have verified they are complete and correct before processing them. If a check fails, you ignore that packet and move on to the next.
This is especially important since your SOF value AA, could appear in the data payload as well as your EOF value of AB, so you can't just assume that because you found an AA and an AB, that they do frame a valid packet.

The task of dealing with a serial stream of interface packets like this I usually divided into at least two parts (but more likely into several parts to handle decoding the packets at various levels of detail, i.e. a task to receive and buffer the incoming stream, a task to identify, verify and perhaps extract a complete packet, a task to parse the given packet, and a task to process the parse data and act on it).
But, at the highest level, the two parts would be:
1. Buffer the incoming data, identify and verify a proper packet structure, and
2. call a parser to process the packet.

Once you get in sync with the packet traffic, there is the chance that there may be sufficient time between messages that you can safely clear a buffer and start receiving a new packet at the beginning of a new packet, but usually this is not something to count on when dealing with a serial interface. My preference is to use a ring buffer so that the receiver is adding bytes to the buffer, and the packet processor is removing bytes from the buffer in a simple to implement cycle, rather than using multiple buffers to copy and shuffle bytes around.
Since your dump is showing an extra four (unidentified at this point) bytes between packets that you'll probably ignore at this point, is all the more reason to find and verify the packets that you are interested in and ignore the rest.

Given what you have, you should do the following to identify and verify you have a properly formatted packet.
1. Find the AA byte. (Note what offset in your buffer you find the AA)
2. Verify you have at least 5 bytes after the AA (the shortest packet you can have would be 6 bytes, including the SOF and EOF. If you don't have at least five bytes after the AA, you can't possibly have a full packet so it is a waste to verify anything now, leave a "pointer", i.e. index pointing to your AA, and when you receive more data, start again from 1 (your code will find the AA at the first byte pointed to)
3. You have enough bytes, so read the fifth byte (fourth after the AA) to get the length of the packet. Add that number to your pointer and if you have enough bytes in your buffer, read the byte from that location. If you don't have enough bytes in the buffer, just leave and try again after you've received more data.
4. The byte read in step 3 (AA + len) should be your EOF byte AB. If it is not, then this is not a proper frame. Increment the pointer pointing to the AA byte to advance to the next byte and start at step 1, searching for the next AA byte in your buffer.
5. Once you've found the AA byte, and the AB byte at the proper offset specified in the packet, then if this packet has a checksum byte (determined from the packet ID), you can loop through bytes generate the checksum and compare it to the one from the packet. If they agree you can process the packet, otherwise increment you pointer and start searching again.

Now since whether there is a checksum or not depends on the packet ID, you may not want to have that information at this level of the process, i.e. you want the packet finder/verifier to know about SOF, EOF, and where to find the length of the packet, but not have to know the details of which packet formats have checksums, and which don't.
You may just want to send the "packet" as verified by SOF,EOF and length to a routine that handles processing the packet id, and selecting the decoding processor. That task can do the checksum calculation and choose to process the packet (checksum matches), or drop it.

I edited your post above to separate the stream into sections, mostly so we don't have a tremendously long line to make the web page harder to deal with, but also it kind of represents what you will need to do in code, and that is to identify the packets in the stream.
Since you printed the values in hex, we can fairly easily hand decode a packet to see what it is. The process used to hand decode the packet should give you insight into what you need your code to do to parse the packet.
Code:
&H7F &H0F 

&HAA		SOF (Start of Frame) 

&HD8		Destination ID:		8 	(General Broadcast)
&HEA 		Originator ID:		10      (Valentine One with checksums)
&H31            Packet Identifier:	0x31    (InfDisplayData) "all the information needed to rebuild thr front panel display. plus status bytes"
&H09            Payload Length:		9 bytes
&H00            Bogey Counter Image 1 :	bits to drive 7 segement display
&H00            Bogey Counter Image 2 :	bits to drive 7 segement display
&H00		Signal Strength Bar   : bits drive 8 block bar graph
&H00 		Band and Arrow Image 1: bits represent discretes to drive various indicators
&H00 		Band and Arrow Image 2: same bit definition as image1
&H0A 		Aux0		      : 0X0A decoded bits: Display On, TS Holdoff
&H00            Aux1		      : Reserved for futurer use
&H00            Aux2		      : Reserved for futurer use
&HB0		Checksum

&HAB		EOF
 
&H1A &H7F &H7F &H0F 

&HAA &HD8 &HEA &H31 &H09 &H00 &H00 &H00 &H00 &H00 &H0A &H00 &H00 &HB0 &HAB 
&H1A &H7F &H7F &H0F
'.....
'                         Here you see the two 7 segment display drivers
'                         now have the value 0x73 in them. If 7 segment drive bits are fairly standard
'                         then I would interpret the display to be like "PP", see attached png file. 
&HAA &HD8 &HEA &H31 &H09 &H73 &H73 &H00 &H00 &H00 &H0A &H00 &H00 &H96 &HAB 
The bits from 0 to 7 represent segments A - G and dp
'0X73 = 01110011 binary
'       dGFEDCBA segments
'       p
Attached Images
File Type: png 7SegmentDisplay_73.png (4.6 KB, 3 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 09-15-2013 at 03:48 PM.
Reply With Quote
  #6  
Old 09-15-2013, 04:45 PM
StealthRT's Avatar
StealthRT StealthRT is offline
Contributor
 
Join Date: Aug 2002
Posts: 785
Default

I've tried doing this:
Code:
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim b As Integer

        SerialPort1.ReadTimeout = 50

        Try
            Do While SerialPort1.BytesToRead > 0
                b = SerialPort1.ReadByte

                If b = 127 Then Debug.Print(b.ToString("X2"))
                Me.BeginInvoke(New mydel(AddressOf txt_out), b)
            Loop
        Catch ex As Exception

        End Try
    End Sub

    Private Sub txt_out(ByVal i As Integer)
        If "&H" & i.ToString("X2") = "&HAA" And buildPacket = False Then
            buildPacket = True
            blah = "&H" & i.ToString("X2")
        ElseIf "&H" & i.ToString("X2") = "&HAB" Then
            buildPacket = False
            blah += blah & " &H" & i.ToString("X2")
            txtReceived.AppendText(blah)
            blah = ""
        ElseIf buildPacket Then
            blah += blah & " &H" & i.ToString("X2")
        End If

        'txtReceived.AppendText("&H" & i.ToString("X2") & " ")
    End Sub
But that doesnt seem to break up the data in the packets..

I ran another scan and this is what its outputting with the original code:
Code:
&H7F &H0F 

&HAA 
&HD8 
&HEA 
&H31 
&H09 
&H77 
&H77 
&H00 
&H00 
&H00 
&H0C 
&H00 
&H00 
&HA0 
&HAB 
&HFA 

&H7F &H7F &H0F 
&HAA 
&HD8 
&HEA 
&H31 
&H09 
&H77 
&H77 
&H00 
&H00 
&H00 
&H0C 
&H00 
&H00 
&HA0 
&HAB 
&HFA

Last edited by StealthRT; 09-15-2013 at 04:58 PM.
Reply With Quote
  #7  
Old 09-15-2013, 09:10 PM
passel's Avatar
passelSerial port (com port) reading data passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,021
Default

Well, one thing I said incorrectly is that you would read the Message ID to determine if the message had a checksum, but in looking at the document again (and it was implied in the comment in my hand decoded packet), is that the Originating ID of 10 (0xE0 + 10 = 0xEA) indicates that the packets will use a checksum byte. If the Originating ID was 9 (0xE0 + 9 = E9) then the packets would not have a checksum byte.

I wouldn't do nearly as much string conversions as you do. Generally the only time to convert numbers to strings is when you have to display them, not to compare them, or collect them or operate on them.

Why not create an array of bytes to act as a temporary buffer. You can use the Read method of the Serial port to read data into that array at a given offset, so you can real all the available bytes into the array in one swoop, and accumulate the bytes by keeping track of the next position in the array to be written to, and reading future bytes into that array at an offset that "appends" the new data to the previous data.
Now that you have an array of bytes, you can start looking for your message, and you don't have to convert the numbers to strings.
I'm tired and heading to bed, so some example of using the byte array would be like the code below, but I'm not going to exhaustively proof it, so there could be an error.
Not shown is getting the data into the buffer and updating "used" (which would be done by the serial data reader). Also didn't add a calculate checksum function to generate a checksum to compare to the checksum byte in the packet.
Code:
  Dim Buffer(1000) As Byte   'Array of bytes to use as a buffer
  Dim Used as Integer
  Dim Ptr as Integer

' Assume you've read and accumulated a number of bytes in Buffer, and set Used to the last index filled
  Private Function extractPacketFromBuffer(ByRef pkt() As Byte) As Boolean  'note pkt() passed by reference so we can redim
    Dim success As Boolean = True
    Dim looking As Boolean = True
    Dim payloadLen As Integer

    Do While (looking)
      If used > 4 Then                  'can't have have a packet with less than six bytes
        If Buffer(Ptr) = &HAA Then         '  If we've found an 0xAA then
          payloadLen = Buffer(Ptr + 4)            '    Get the packet payload length
          If used > 4 + payloadLen Then '    if we have enough bytes in the buffer for a full message then
            If Buffer(ptr + 5 + payloadLen) = &HAB Then

              ReDim pkt(payloadLen + 5)
              Array.Copy(Buffer, ptr, pkt, 0, payloadLen + 6)
              looking = False 'no longer looking
              success = True  'we have a packet
              Dim unProcessedIdx = ptr + 6 + payloadLen        'Determine the first buffer byte index after the packet extracted
              If used > unProcessedIdx Then                    'If there are extra unprocessed bytes in the buffer
                Array.Copy(Buffer, unProcessedIdx, Buffer, 0, used - unProcessedIdx)  'move all the unprocessed bytes to the front
                Ptr = 0 'point to the front of the buffer for next time
              End If
              used -= unProcessedIdx  'adjust the used count down to account for all the processed bytes removed
            End If
          Else  'not enough bytes in the buffer for a full message, so leave for now
            looking = False  'no longer looking for a packet
            success = False  'no packet found this time
          End If
        Else
          ptr += 1
        End If
      Else
        looking = False
        success = False
      End If
    Loop


    Return success

  End Function

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim pkt() As Byte 'will be redimensioned by the function if a packet is retrieved
    If extractPacketFromBuffer(pkt) Then  'if we extracted a packet
      Debug.Print(pkt.Length)      'Parse the packet to extract data
    End If
  End Sub
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 09-16-2013 at 12:42 PM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data Serial port (com port) reading data
Serial port (com port) reading data
Serial port (com port) reading data
 
Serial port (com port) reading data
Serial port (com port) reading data
 
-->