-
Feb 26th, 2018, 06:12 PM
#1
Thread Starter
New Member
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
-
Feb 26th, 2018, 07:44 PM
#2
Addicted Member
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?
-
Feb 26th, 2018, 08:06 PM
#3
Thread Starter
New Member
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
-
Feb 26th, 2018, 08:29 PM
#4
Addicted Member
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()
-
Feb 27th, 2018, 03:34 AM
#5
Thread Starter
New Member
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
Originally Posted by Mc_VB
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()
-
Feb 27th, 2018, 04:14 AM
#6
Thread Starter
New Member
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
-
Feb 27th, 2018, 05:10 AM
#7
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.
-
Feb 27th, 2018, 05:46 AM
#8
Thread Starter
New Member
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
Originally Posted by passel
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.
-
Feb 27th, 2018, 10:17 AM
#9
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.
-
Feb 27th, 2018, 10:36 AM
#10
Addicted Member
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.
-
Feb 27th, 2018, 08:47 PM
#11
Thread Starter
New Member
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
Originally Posted by Mc_VB
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/
-
Oct 10th, 2024, 03:57 PM
#12
New Member
Re: VBnet serial port byte retrieval
I've got the same problem. Did you ever get a solution?
-
Oct 12th, 2024, 12:41 AM
#13
New Member
Re: VBnet serial port byte retrieval
-
Oct 16th, 2024, 05:22 AM
#14
Re: VBnet serial port byte retrieval
the post is from 2018 and the article you gave here is from 2014...
The best friend of any programmer is a search engine
"Don't wish it was easier, wish you were better. Don't wish for less problems, wish for more skills. Don't wish for less challenges, wish for more wisdom" (J. Rohn)
“They did not know it was impossible so they did it” (Mark Twain)
-
Oct 16th, 2024, 12:52 PM
#15
New Member
Re: VBnet serial port byte retrieval
Yes, but still interesting to know. Isn't it?
-
Oct 19th, 2024, 02:22 PM
#16
Hyperactive Member
Re: VBnet serial port byte retrieval
Old materials are always the best, like this one, final SerialPort programming approach for lots of us. Take a look.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|