Reading serial Byte data at 115200 Baud

Dear all

Thank you for this possibility to ask you and apologize me if this question is not relevant ..

I'm new in VB 2005

I have small project to CODE application to log serial data from uPC with 32 Bit message / 4 Byte. Speed is 115200 Baud

for evaluation I did universal logger where I can choose type of data

  • ASCII
  • BYTE
  • BINARY

Program at 4800Baus with GPS mouse work well, but problem is with my target 115200 Baud,... on this speed I can recieve and log to file ASCII - strings ... please have a look to code, I try to change input read buffer but without sucsess

....

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

L_TIME.Text = TimeString

If RS232.IsOpen Then

ReadingPort()

If CHB_CLEAR.Checked And TextBox1.Lines.Length > 20 Then TextBox1.Text = ""

L_PortStatus.ForeColor = Color.Green

L_PortStatus.Text = RS232.PortName & " is open, with " & RS232.BaudRate & " BaudRate"

Else

L_PortStatus.ForeColor = Color.Red

L_PortStatus.Text = RS232.PortName & " is NOT open, with " & RS232.BaudRate & " BaudRate"

End If

End Sub

.....

Sub ReadingPort()

Dim i As Integer = 0

Dim MyBinaryDATA As String

Dim MyHexDATA As String

Dim MYByteDATA As Integer

Dim m As Long

Const maxpower = 8

TEMP_DATA = ""

Do While RS232.BytesToRead <> 0

'-------------------------------------------------------------------------

If RB_ASCII.Checked Then

TEMP_DATA += RS232.ReadExisting

End If

'-------------------------------------------------------------------------

If RB_HEX.Checked Then

MyHexDATA = Conversion.Hex(RS232.ReadByte)

l += 1

TEMP_DATA += " " & MyHexDATA

If l Mod 8 = 0 Then TEMP_DATA = TEMP_DATA & vbCrLf

End If

'-------------------------------------------------------------------------

If RB_BINARY.Checked Then

MyBinaryDATA = ""

MYByteDATA = RS232.ReadByte

For m = maxpower - 1 To 0 Step -1

If MYByteDATA And (2 ^ m) Then ' Use the logical "AND" operator.

MyBinaryDATA = MyBinaryDATA + "1"

Else

MyBinaryDATA = MyBinaryDATA + "0"

End If

Next

TEMP_DATA += " " & MyBinaryDATA

k += 1

If k Mod 4 = 0 Then TEMP_DATA += vbCrLf

End If

'-------------------------------------------------------------------------

'i += 1

'L_WHILE.Text = "While: " & i

' to see how mutch is program looping

'-------------------------------------------------------------------------

Loop

TextBox1.Text += TEMP_DATA

If CHB_SAVEDATA.Checked Then Logging()

End Sub

...

I thing that this was heart of program

Can you help me where I miss

Thank you very mutch




Answer this question

Reading serial Byte data at 115200 Baud

  • GoodMorningSky

    Thank you Very Mutch

    Yes, I was thinking that is possible to read strings and than make conversion to HEX or BINARY but

    Do you know, why this part is not working correct (too mutch complicated <time consumation> )

    MYByteDATA = RS232.ReadByte

    For m = maxpower - 1 To 0 Step -1

    If MYByteDATA And (2 ^ m) Then ' Use the logical "AND" operator.

    MyBinaryDATA = MyBinaryDATA + "1"

    Else

    MyBinaryDATA = MyBinaryDATA + "0"

    End If

    Next

    Tomorow I will rewrite this code by your recomendation, then I will write status...

    Thank you again

    Victor



  • DW Developer

    Your ReadingPort() code is not correct. If you have the RB_ASCII checkbox checked, you will read *all* the bytes from the serial port. Your ReadByte() calls after that will now block, waiting for another byte to arrive. You can't mix up your ReadExisting and ReadByte calls like this. Use only *one* Read() call and store the returned bytes into a buffer. Decode the text and bytes from that buffer.



  • IGiberson

    There is no problem wth running the standard serial port at that speed.

    The whole point of the windows buffer is to extend the hardware buffer - Carsten, what on earth do you think the windows buffer is for you are wrong to recommend an event driven receiver routine as you have demonstrated quite publicly your inability to understand the threading issues involved, and the steps necessary to solve them.

    You are doubly wrong because you first insist that the [hardware] buffer is indequate and continue to recommend a solution that would make the whole thing worse, if this is the case!



  • kiranshri

    You're fretting a bit too much about your code, modern PCs do this in a few microseconds. If you know for a fact that it is taking too much time:

    Public Shared Function Byte2BinaryString(ByVal value As Byte) As String
    Dim s As New System.Text.StringBuilder(8)
    Dim mask As Byte = &H80
    For ix As Integer = 0 To 7
    If (value And mask) = 0 Then s.Append("0"c) Else s.Append("1"c)
    mask >>= 1
    Next
    Return s.ToString()
    End Function



  • Dylan Beattie

    Victory-sk, Nobugz has the correct answer: use a single read mechanism (I would recommend the 'Read' method as opposed to the 'ReadByte', as you can copy the bytes straight into a byte array.

    Once you have the bytes in the array, you can go ahead and interpret/decode them. Remember, the serial port is just bytes: although it can recieve characters, it can get confusing based on the encoding scheme used with those characters (obviously ASCII is fairly simple to decode). Concentrate on simply acquiring the bytes in the recieve outine, and handling the decoding as a separate issue. It will make it easier to troubleshoot.



  • tr_sreedhar

    SJWhiteley

    Read my post again. I wrote that it ought to work because of the serial port buffer. Without this buffer (or your own buffer) a polled system will never work at this speed - but an event driven system may!

    What is wrong with event driven systems The whole GUI is entirely event driven and the only thing the Main method does is to start the message pump (Application.Run), which is used to handle events.

    "you have demonstrated quite publicly your inability to understand the threading issues involved, and the steps necessary to solve them."

    Please Stephen, when has personal attacks become the style of this forum Remember the very clever words: When you in a discussion becomes angry and upset you are no longer fighting for truth, but for yourself! I understand the threading issues involved and the necessary steps to solve them. I have worked with multitasking and multithreading systems for approximately 30 years, and my program works fine - based on BeginInvoke. However, what I for the moment do not entirely understand is exactly what goes on below the hood. Therefore I asked some question about this in this forum, but nobody - including you - have ever been able to give me a clear answer. Instead you turned the discussion into a discussion about buffers, which I know everything about.

    If you know things so well yourself why don't you answer one of my simple questions like: From which thread is the serial port buffer of SerialPort loaded (input to the buffer) If you don't know the answer, you don't know the threading issues involved yourself!

    "There is no problem with running the standard serial port at that speed."

    Great! What can our friend use this information for Your post is a personal attack on me - nothing else. Our friend has a problem. He has a system that works fine at low speed, but not at high speed, and because an event driven system is faster than a polled one - no matter what you say - what is wrong in suggesting that solution We live in a free world.

    What I am trying to do is to provide workable solution to people, who needs them. When I was in the same situation some time ago, I only got the answer from this forum that it couldn't be done or I needed to write my own drivers. Very helpful indeed for a beginner in VB programming! Therefore I chosed to publish my program including source code and a description, which - unlike the help files - should be very easy to understand for beginners. The program has helped dozens of people getting started and I have received a lot of e-mails with thanks for my help.

     


  • pcompassion

    In your original code above you have declared MyByteDATA as Integer, but RS232.ReadByte returns a byte.

    Besides, I will not recomment you to use string operations like adding two strings - especially if speed is an issue. The problem is that in Visual Basic .Net and C#, all strings are immutable, meaning you cannot change its length or contents once it is defined. Therefore, all string manipulations has to be done by making a new instance of the String class, copying the string and then abandon the previous string. This is a very time consuming procedure, which also leads to a serious fragmentation of the memory. It is better to receive in an array, but since each telegram only contains 4 bytes (plus protocol overhead) it may be a better idea just to collect a full telegram in the serial port receiver and then send this telegram to the display routine for further processing.

    Because each telegram contains more than one byte, you need some kind of protocol to determine the start or the end of the telegram or else the last byte(s) from one telegram may be combined with the first one(s) from the next in case of an error. The easiest way to handle this is to send the value as ASCII, terminate each telegram with e.g. LineFeed and then use ReadLine to collect the entire telegram. Then a single BeginInvoke statement can transmit the telegram to your display routine for further processing. In this case, two lines of code is all you need in the receiver routine.


  • XPSUser

    I presume that you have checked the data integrity with an oscilloscope, so that you are sure that the problem is not coursed by a low pass characteristic of the line or coursed by line reflections.

    The default receive buffer of SerialPort is 4096 bytes, so even though you poll the port by means of a timer it ought to work, but from a hardware point of view you are very close to the limit of Windows. The standard UART 16C550 in the PC has a 16 byte FIFO. This means that it takes 1.4 mS to fill the buffer, but the interrupt latency of Windows is approximately 1 mS!

    I will recommend you to try an event driven receiver routine, which is activated by means of the DataReceived event from the serial port. In the knowledgebase on our homepage you can find such a program. Try to download the .exe file and see if it works (it is a very small exe). If it does, you can download the complete source code and read the very detailed documentation. The URL is: http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm . Note however that there is a small error in the documentation. It is not the thread, which has a queue for subroutines waiting to be executed, but the message pump of the thread. I will correct this error as soon as possible.

    With a 16C950 UART (128 byte FIFO) we have used the program up to 921,6 kbit/s for very short distances and 460.8 kbit/s at approximately 10 m of RS232.

    Good luck

    Innovatic

    Carsten Kanstrup

     

    EDIT Feb. 1st 2007.

    Description now updated and believed to be correct. If not please send an e-mail.

     


  • Reading serial Byte data at 115200 Baud