Results 1 to 8 of 8

Thread: [RESOLVED] Serial Port Read Index Out Of Range Exception

  1. #1

    Thread Starter
    Hyperactive Member pourkascheff's Avatar
    Join Date
    Apr 2020
    Location
    LocalHost
    Posts
    384

    Resolved [RESOLVED] Serial Port Read Index Out Of Range Exception

    Well, Hello. It's me again.
    Consider a half-duplex modbus RTU serial communication between two devices which we want to only listen. A repeater.
    Without any CRC/Checksum complexity, I stuck at the beginning. What is the best approach to do such thing?

    Here's the code so far but making 2 bytes to an integer applies for first 8 bytes and then an exception will occur for line #30 which is comparing it is a HoldingRegister or not (Correct received package). I mean using Try/Catch will do the matter for first 8 bytes and continues the loop. I need the whole data. Any clues is precious. Thanks in advanced.
    vb.net Code:
    1. Public Class Form1
    2.  
    3.     Private Buffer As Byte()    'I'M NOT SURE IT IS THE BEST WAY TO DECLARE A BYTE ARRAY WITH UNKNOWN/CHANGABLE LENGTH OR NOT
    4.    
    5.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6.         Control.CheckForIllegalCrossThreadCalls = False 'FOR ERRORS FROM NOWHERE(?)
    7.         Try
    8.             If SerialPort1.IsOpen = False Then
    9.             SerialPort1.Open()
    10.             End If
    11.         Catch ex As Exception
    12.             MsgBox(ex.Message, MsgBoxStyle.Critical)
    13.             Application.Exit()
    14.         End Try
    15.     End Sub
    16.  
    17.     Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    18.         If BackgroundWorker1.IsBusy = False Then
    19.             BackgroundWorker1.RunWorkerAsync()  'IT'S GOING TO BE A VERY CROWDY CODE. LET THE BACKGROUNDWORKER DO THE LOOP THING FOR ME
    20.         End If
    21.     End Sub
    22.    
    23.     Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    24.         Dim byteCount = SerialPort1.BytesToRead 'GET INPUT BUFFER SIZE
    25.         If SerialPort1.BytesToRead > 8 Then 'IGNORE BLANK AND NOT REQUEST COMMANDS (GET ONLY ANSWERS FROM SLAVES. REQUEST COMMANDS ARE 8 BYTES)
    26.             buffer = New Byte(byteCount) {}     'EXTEND VARIABLE/ARRAY AS IT IS
    27.             SerialPort1.Read(Buffer, 0, byteCount)  'READ SERIAL PORT FUNCTION
    28.             Dim UserControl as UserControl() = {UserControl1, UserControl2, UserControl3, UserControl4, UserControl5, UserControl6, UserControl7, UserControl8, UserControl9, UserControl10, UserControl11, UserControl12, UserControl13, UserControl14}    'THERE ARE 14 USERCONTROLS WHICH SORTING VALUES IN THEM IS REQUIRED
    29.            
    30.             If Buffer(1) = 3 And Buffer(2) = 192 Then 'CORRECT PACKET(S) INCOMING
    31.            
    32.                 If Buffer(0) = 2 Then   'FIRST PARAMETER              
    33.                     For i = 0 To 29 Step 2  'ARRANGING/ASSIGNING VALUES IN THEIR PLACES FOR 14 USERCONTROLS
    34.                     UserControl(i/2).TextBox1.Text = (Val(Buffer(i+3)*256) + Val(Buffer(i+4))   'COMBINE 2 BYTES => INTEGER
    35.                     Next               
    36.                 End If
    37.                
    38.                 'If Buffer(0) = 3 Then  'SECOND PARAMETR
    39.                 ''SAME AS ABOVE
    40.                 'End If
    41.                 '.
    42.                 '.
    43.                 '.
    44.                 'If Buffer(0) = n Then  'LAST PARAMETR
    45.                 ''SAME AS ABOVE
    46.                 'End If
    47.             End If
    48.     'POSSIBLE 'BUFFER' DISPOSE/CLEAR CODE GOES HERE WHICH I DON'T KNOW HOW TO DO IT
    49.         End If
    50.     End Sub
    51. End Class

    Exception full message:
    IndexOutOfRangeException was unhandled by user code: Index was outside the bounds of the array.
    Last edited by pourkascheff; Jun 10th, 2022 at 03:43 AM.

  2. #2
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    846

    Re: Serial Port Read Index Out Of Range Exception

    check for the value of bytecount and SerialPort1.BytesToRead

    by the way, you don't need bytecount, you can replace it everywhere by
    SerialPort1.BytesToRead,

    check buffer after line 27, you may read nothing
    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)

  3. #3

    Thread Starter
    Hyperactive Member pourkascheff's Avatar
    Join Date
    Apr 2020
    Location
    LocalHost
    Posts
    384

    Re: Serial Port Read Index Out Of Range Exception

    Quote Originally Posted by Delaney View Post
    check for the value of bytecount and SerialPort1.BytesToRead
    Hum, Is it possible that my stream broken or delayed a few milliseconds?

    Quote Originally Posted by Delaney View Post
    by the way, you don't need bytecount, you can replace it everywhere by SerialPort1.BytesToRead,
    I remember I used all as SerialPort1.BytesToRead once and it didn't work. That's why, but when you say so, I will follow. I remember you sir from lots of SerialPort threads. Merci beaucoup

    Quote Originally Posted by Delaney View Post
    check buffer after line 27, you may read nothing
    Is there any debugging tool included in Visual Studio? I believe I saw a list of parameters/variables below the screen. Buffer length was 2. Bingo, You might be exact on faultfinding. I'm going to check it.
    You already read the whole code? Could it be something else?

    I used SerialPort1_ReceivedData event. How can I switchover on something that waits to get like 300 bytes then take action? Legendary timers came to my head at the beginning why? because input buffer may be fully received and raw data ready to be processed. (Relax, my read data cycle is too slow)

    Or how about increasing BytesToRead condition on equal and greater than an acceptable value like If SerialPort1.BytesToRead > 300 Then in line #23?
    Last edited by pourkascheff; Jun 10th, 2022 at 08:13 AM.

  4. #4
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Serial Port Read Index Out Of Range Exception

    See this post and also the link contained in it.

    https://www.vbforums.com/showthread....=1#post5569657
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  5. #5
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    846

    Re: Serial Port Read Index Out Of Range Exception

    Is there any debugging tool included in Visual Studio?
    there are 3 ways:
    1 - you include some messagebox with the variable to check it
    2 - you click on the grey column on the left of the column with line number (must be a line with code), a red dot will appear and it will put a stop in you code when you run it and you will be able to check the values of the variable
    3 - put the keyword "stop" in you code. it does the same than the red dot.
    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)

  6. #6

    Thread Starter
    Hyperactive Member pourkascheff's Avatar
    Join Date
    Apr 2020
    Location
    LocalHost
    Posts
    384

    Re: Serial Port Read Index Out Of Range Exception

    Quote Originally Posted by dbasnett View Post
    See this post and also the link contained in it.
    It is a bit complicated sir. But one of its advantages is "Dim readBuf(TheSP.BytesToRead - 1) As Byte".

    Exception now occurs here:
    Name:  serial port exception.jpg
Views: 845
Size:  40.1 KB

    I only acknowledged that my index=14 (in Buffer(index+4)) exceeds Buffer.Length=16 and causing error but not sure what to do.
    What are my options?

  7. #7
    Fanatic Member Delaney's Avatar
    Join Date
    Nov 2019
    Location
    Paris, France
    Posts
    846

    Re: Serial Port Read Index Out Of Range Exception

    the picture is small, so we can barely see anything.

    you need to think a little bit about what you do : why your index should go over the buffer length? I saw that you coded the upper limit of the index (20 or 29, i can't see well) where you should have a limit linked to the buffer length: for index =0 to buffer.length-4 step 3...
    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)

  8. #8

    Thread Starter
    Hyperactive Member pourkascheff's Avatar
    Join Date
    Apr 2020
    Location
    LocalHost
    Posts
    384

    Re: Serial Port Read Index Out Of Range Exception

    Well, it turned out data stream was broken to pieces based on a port spy app monitored (still not sure why. Maybe timeout/nulldicard/Readbuffersize or other SerialPort control parameters) Mimicking a code in which be looking for an exact combination of bytes and extracting them from a random stream, Rectifies the matter.

    Here the index in outer "for" called 'j' will be followed by another index which represents buffer subset current position:
    vb.net Code:
    1. 'LOOP START
    2. Dim UserControl as UserControl() = {UserControl1, UserControl2, UserControl3, UserControl4, UserControl5, UserControl6, UserControl7, UserControl8, UserControl9, UserControl10, UserControl11, UserControl12, UserControl13, UserControl14}
    3. Dim Buffer(SerialPort1.BytesToRead -1) As Byte
    4. SerialPort1.Read(Buffer, 0, Buffer.Length)
    5. Try
    6.     For j = 0 To Buffer.Length
    7.         If Buffer(j) = 3 And Buffer(j + 1) = 192 Then
    8.         TextBox1.Clear()
    9.             If Buffer(j - 1) = 2 Then
    10.             TextBox1.text = TextBox1.text & "PARAMETER="
    11.                 For i = j + 2 to 29 Step 2
    12.                 TextBox1.text = TextBox1.text & (Buffer(i)*256) + Buffer(i + 1) & ", "
    13.                 UserControl((i - 3)/2).Label1.Text = (Buffer(i)*256) + Buffer(i + 1)
    14.                 Next
    15.             End If
    16.         End If
    17.     Next
    18. Catch ex As Exception
    19. End Try
    20. 'LOOP END

Tags for this Thread

Posting Permissions

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



Click Here to Expand Forum to Full Width