dcsimg
Results 1 to 11 of 11

Thread: VBnet serial port byte retrieval

  1. #1

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    VBnet serial port byte retrieval

    I'm working on a project, not by choice but still. I need to deal with serial data and I've been trying to work out a solution for hours and I'm slowly making progress. I hoping anyone can shed some light on it for me.
    I need to send a command then listen to the bus chatter and return the response at the moment I want to make sure I'm going about it the right way.
    I have it working, kind of 50% of the time it gets the response right but the other 50% it has the bytes mixed up
    the last byte of the response is a checksum (2's complement) I was thinking of calling the function in a loop until the checksum verification is good, but part of me is thinking that is a but dodgy

    Code:
    Public Shared Function Serial(ByVal SendFrame)
        ' --------------------------------------------------------------------------------------------------------------------
        ' Define Serial Port Params
        Dim SerialPort1 As SerialPort = New System.IO.Ports.SerialPort With {
            .BaudRate = 8192,
            .DataBits = 8,
            .Parity = IO.Ports.Parity.None,
            .StopBits = IO.Ports.StopBits.One,
            .PortName = GlobalVars.ComPort ' Add Read From Global Vars ***************
        }
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Define Arrays
        Dim ArrayBuffer As Byte() = New Byte(150) {}
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Open Serial Port
        SerialPort1.Open()
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Clear Buffer
        SerialPort1.DiscardInBuffer()
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Send Frame
        SerialPort1.Write(SendFrame, 0, SendFrame.Length)
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' n Chars of Bus into Buffer
        Dim x As Integer = 0
        Dim BufLen As Integer = ArrayBuffer.Length - 1
    
        While x <= ArrayBuffer.Length - 1
            ArrayBuffer(x) = SerialPort1.ReadByte
            x = x + 1
        End While
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Close Serial Port
        SerialPort1.Close()
    
        '-----------------------------------------------------------------------------------------------------------------------
        ' Create Response
        Dim i As Integer = 0
        Dim j As Integer = 0
        Dim ReceiveFrameLength As Integer
        Dim ReceiveFrameArray As Byte() = New Byte(45) {}
    
        For Each n As Byte In ArrayBuffer
            ' arraybuffer(i+1) hits end of array then +1 = throws out of index error
            Try
                If ArrayBuffer(i) = SendFrame(0) And (ArrayBuffer(i + 1)) <> SendFrame(1) Then
                    ReceiveFrameLength = (ArrayBuffer(i + 1) - &H55)
    
                    ' Add Response to Array Here
                    While j <= ReceiveFrameLength
                        ReceiveFrameArray(j) = ArrayBuffer(i + j)
                        j = j + 1
                    End While
    
                Else
                    i = i + 1
                    Continue For
                End If
            Catch
                Exit Try
            End Try
    
        Next
    
        Return ReceiveFrameArray
    End Function
    Last edited by megajuz3003; Feb 26th, 2018 at 08:10 PM. Reason: fix title

  2. #2
    Addicted Member
    Join Date
    Nov 2011
    Posts
    188

    Re: https://stackoverflow.com/questions/48971178/vb-net-serial-port-byte-retrieval

    Is the response always going to be 150 bytes (including the checksum)?

    EDIT the baud rate is non standard are you sure that the baud rate is correct?

  3. #3

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    Re: https://stackoverflow.com/questions/48971178/vb-net-serial-port-byte-retrieval

    the baud rate is correct, the response will vary from 5 to 40 bytes, the problem is the data bus is always communicating with multiple devices so i have to filter through that to find the response, but the arraybuffer will always be full

  4. #4
    Addicted Member
    Join Date
    Nov 2011
    Posts
    188

    Re: VBnet serial port byte retrieval

    Not sure if I have fully got it but of the top of my head I made a couple of very minor adjustments to your existing code in the hope you can retrieve your response 100%. The success of this depends on some timing issues but looking at what you have go ahead and give it a try.

    Sometimes it's a good idea to direct your received data to a text box to verify you are getting what you expect.


    Code:
      ' Define Arrays
            Dim ArrayBuffer As Byte() = New Byte(150) {}
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Open Serial Port
            SerialPort1.Open()
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Clear Buffer
            SerialPort1.DiscardInBuffer()
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Send Frame
            SerialPort1.Write(SendFrame, 0, SendFrame.Length)
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' n Chars of Bus into Buffer
            Dim x As Integer = 0
            'Dim BufLen As Integer = ArrayBuffer.Length - 1
    
            SerialPort1.ReadTimeout = 100
    
            Do 
    
                Try
    
                    ArrayBuffer(x) = SerialPort1.ReadByte
                    x += 1
    
                Catch ex As Exception
    
                    x = 0
                    Exit Do
    
                End Try
    
            Loop
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Close Serial Port
            SerialPort1.Close()

  5. #5

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    Re: VBnet serial port byte retrieval

    Thanks heaps for that, it didn't help with the accuracy but it did improve the speed of the function (y) from 2-4 seconds for a read down to just under 1 second


    Quote Originally Posted by Mc_VB View Post
    Not sure if I have fully got it but of the top of my head I made a couple of very minor adjustments to your existing code in the hope you can retrieve your response 100%. The success of this depends on some timing issues but looking at what you have go ahead and give it a try.

    Sometimes it's a good idea to direct your received data to a text box to verify you are getting what you expect.


    Code:
      ' Define Arrays
            Dim ArrayBuffer As Byte() = New Byte(150) {}
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Open Serial Port
            SerialPort1.Open()
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Clear Buffer
            SerialPort1.DiscardInBuffer()
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Send Frame
            SerialPort1.Write(SendFrame, 0, SendFrame.Length)
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' n Chars of Bus into Buffer
            Dim x As Integer = 0
            'Dim BufLen As Integer = ArrayBuffer.Length - 1
    
            SerialPort1.ReadTimeout = 100
    
            Do 
    
                Try
    
                    ArrayBuffer(x) = SerialPort1.ReadByte
                    x += 1
    
                Catch ex As Exception
    
                    x = 0
                    Exit Do
    
                End Try
    
            Loop
    
            '-----------------------------------------------------------------------------------------------------------------------
            ' Close Serial Port
            SerialPort1.Close()

  6. #6

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    Re: VBnet serial port byte retrieval

    ok so I have it sending the arraybuffer to a text box, the bytes are out of order, but I also watched it with realterm to a separate machine with its own controller, the bus is sending it in the right order but the serial function is ordering it wrong .... confusing

  7. #7
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    4,651

    Re: VBnet serial port byte retrieval

    Since the transmit and receive is using the same line, you need to ensure you're sending your command during a quiet time on the bus.

    I'm thinking I wouldn't continually open and close the serial port.
    I would create a background thread, open the serial port, then enter a loop and start monitoring the chatter.
    You would be looking for the frames, and in particular identifying the heartbeat frame.
    I believe the chatter should be scheduled so you would see a pattern.

    If a request is generated by user interaction from a GUI, then probably the request should be queued using a concurrent queue so that the background thread could send the request on a non-interfering basis with the regular chatter.
    When a heartbeat frame is expected, the background thread could check the queue and if a command is waiting, right after the heartbeat frame you might want to send a suspend chatter command, then send your command, and collect your response.
    You could then either let the chatter suspension time out or send a command to resume chatter.

    Another option, might be that since the biggest gap in chatter should be after the heartbeat frame, you would just send your request after the heartbeat frame and just filter the response from the chatter.

    If the background thread was continually collecting frames from the serial port, and either decoding them or discarding them, you should stay in sync with the serial stream and be able to inject your requests and process the response reliably since you shouldn't end up starting in the middle of a frame and have to count on your search for the command byte to hopefully sync you to the response.

    I don't have experience with trying to interface with an ECU, but that would be the approach I would try if I did.

  8. #8

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    Re: VBnet serial port byte retrieval

    there's a bit of food for thought there .. its everything that's transmitted over the bus, not just the ecu (that's a whole different story J1850VPW + Interface Module to translate to 8192)

    but I am logging the data bus separately when I test the function (different system with a different adapter) the bus is supplying the data in the correct order, that is whats confusing me atm


    Quote Originally Posted by passel View Post
    Since the transmit and receive is using the same line, you need to ensure you're sending your command during a quiet time on the bus.

    I'm thinking I wouldn't continually open and close the serial port.
    I would create a background thread, open the serial port, then enter a loop and start monitoring the chatter.
    You would be looking for the frames, and in particular identifying the heartbeat frame.
    I believe the chatter should be scheduled so you would see a pattern.

    If a request is generated by user interaction from a GUI, then probably the request should be queued using a concurrent queue so that the background thread could send the request on a non-interfering basis with the regular chatter.
    When a heartbeat frame is expected, the background thread could check the queue and if a command is waiting, right after the heartbeat frame you might want to send a suspend chatter command, then send your command, and collect your response.
    You could then either let the chatter suspension time out or send a command to resume chatter.

    Another option, might be that since the biggest gap in chatter should be after the heartbeat frame, you would just send your request after the heartbeat frame and just filter the response from the chatter.

    If the background thread was continually collecting frames from the serial port, and either decoding them or discarding them, you should stay in sync with the serial stream and be able to inject your requests and process the response reliably since you shouldn't end up starting in the middle of a frame and have to count on your search for the command byte to hopefully sync you to the response.

    I don't have experience with trying to interface with an ECU, but that would be the approach I would try if I did.

  9. #9
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    4,651

    Re: VBnet serial port byte retrieval

    If you're looking at raw byte ordered values, I'm not sure why they would be different.
    If the multiple bytes are being converted into numbers for display, then I could see where that could be an issue. I believe the processors used in a lot of the automotive computers were Motorola based, and the values could be BigEndian, i.e. the two bytes 02 03 could be a two byte integer value of 515 (2 * 256 + 3). But a LittleEndian processor, such as an Intel processor, the lower byte comes first, so the 02 03 value would be (2 + 3 * 256) = 770.

    I don't know if there would be any reason for the adapter to be swapping bytes.
    Anyway, not something I deal with so can't really help.

    I came across this link earlier, where the person was using VS2010 and VB.net to listen to the bus. I didn't read through the whole thread. Don't know if there would be anything for you to glean from the thread.

  10. #10
    Addicted Member
    Join Date
    Nov 2011
    Posts
    188

    Re: VBnet serial port byte retrieval

    Can you post an example of what Realterm displays with a comparison of what your app displays.

    I think when the receive function is finally working you will be able to see an even better improvement in speed.


    EDIT Out of interest I Googled the device info you post, does the following link relate to your project? https://www.mictronics.de/projects/j1850-vpw-interface/
    Last edited by Mc_VB; Feb 27th, 2018 at 10:52 AM.

  11. #11

    Thread Starter
    New Member
    Join Date
    Feb 2018
    Posts
    6

    Re: VBnet serial port byte retrieval

    hopefully if the rain eases up I can get out and take a good snapshot of the data...

    that is similar but not quite it... I'm trying to build a diagnostic program for 4 models of Holden Commodore (Sold in the US as Pontiac G4 I believe) the body modules use 8192 serial bus to communicate (so does the ecu for the V6) but the LS1 equipped vehicles use an ECU that's uses J1850VPW and a Powertrain Interface Module to translate , at the moment I'm just looking to talk to things like the Instrument Cluster, Body Control Module, SRS System, Radio, I have most of the modules for each written and when I get a good read from my serial function.. it works well


    Quote Originally Posted by Mc_VB View Post
    Can you post an example of what Realterm displays with a comparison of what your app displays.

    I think when the receive function is finally working you will be able to see an even better improvement in speed.


    EDIT Out of interest I Googled the device info you post, does the following link relate to your project? https://www.mictronics.de/projects/j1850-vpw-interface/

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width