I'm trying to send serial data from Arduino and read it on Visual Basic. When I execute the code sometimes works and sometimes doesn't: throwing exception, System.ArgumentOutOfRangeException: 'Index and length must refer to a location within the string. Can you help me?
I'm new to Visual Basic, thanks.
Imports System.IO
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
Dim TWSL, TWAL, THL, AoAL, WAL, PeL, RoilL, RyL, RydL As Integer
Dim TWS, TWA, TH, AoA, WA, Pe, Roil, Ry, Ryd, TWSResult, TWAResult, THResult, AoAResult, WAResult, PeResult, RoilResult, RyResult, RydResult As String
Dim StrSerialIn, StrSerialInRam As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.CenterToParent()
SerialPort1.PortName = "COM4"
SerialPort1.BaudRate = 9600
SerialPort1.Open()
Timer1.Start()
SerialPort1.Write(TrackBarAWA.Value & Chr(10))
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Try
StrSerialIn = SerialPort1.ReadExisting
Dim TB As New TextBox
TB.Multiline = True
TB.Text = StrSerialIn
If TB.Lines.Count > 0 Then
If TB.Lines(0) = "Failed to read" Then
Timer1.Stop()
SerialPort1.Close()
Return
End If
StrSerialInRam = TB.Lines(0).Substring(0, 2)
If StrSerialInRam = "A" Then
TWS = TB.Lines(0)
TWSL = TWS.Length
Else
TWS = TWS
End If
StrSerialInRam = TB.Lines(1).Substring(0, 3)
If StrSerialInRam = "B" Then
TWA = TB.Lines(1)
TWAL = TWA.Length
Else
TWA = TWA
End If
StrSerialInRam = TB.Lines(2).Substring(0, 3)
If StrSerialInRam = "C" Then
TH = TB.Lines(2)
THL = TH.Length
Else
TH = TH
End If
StrSerialInRam = TB.Lines(3).Substring(0, 2)
If StrSerialInRam = "D" Then
AoA = TB.Lines(3)
AoAL = AoA.Length
Else
AoA = AoA
End If
StrSerialInRam = TB.Lines(4).Substring(0, 1)
If StrSerialInRam = "E" Then
WA = TB.Lines(4)
WAL = WA.Length
Else
WA = WA
End If
StrSerialInRam = TB.Lines(5).Substring(0, 3)
If StrSerialInRam = "F" Then
Pe = TB.Lines(5)
PeL = Pe.Length
Else
Pe = Pe
End If
StrSerialInRam = TB.Lines(6).Substring(0, 3)
If StrSerialInRam = "G" Then
Roil = TB.Lines(6)
RoilL = Roil.Length
Else
Roil = Roil
End If
StrSerialInRam = TB.Lines(7).Substring(0, 3)
If StrSerialInRam = "H" Then
Ry = TB.Lines(7)
RyL = Ry.Length
Else
Ry = Ry
End If
StrSerialInRam = TB.Lines(8).Substring(0, 3)
If StrSerialInRam = "I" Then
Ryd = TB.Lines(8)
RydL = Ryd.Length
Else
Ryd = Ryd
End If
TWSResult = Mid(TWS, 2, TWSL)
TWAResult = Mid(TWA, 2, TWAL)
THResult = Mid(TH, 2, THL)
AoAResult = Mid(AoA, 2, AoAL)
WAResult = Mid(WA, 2, WAL)
PeResult = Mid(Pe, 2, PeL)
RoilResult = Mid(Roil, 2, RoilL)
RyResult = Mid(Ry, 2, RyL)
RydResult = Mid(Ryd, 2, RydL)
TWSvalue.Text = TWSResult
TWAvalue.Text = TWAResult
THvalue.Text = THResult
AoAvalue.Text = AoAResult
WAvalue.Text = WAResult
PeValue.Text = PeResult
RoilValue.Text = RoilResult
RyValue.Text = RyResult
RydValue.Text = RydResult
From what I gather, you are trying to get characters from specific places in specific lines on a text box. Based on the error message you included in your question, I assume the error occurs on a line of code containing the "String. Substring" method. If the string where you are getting the substring from is too short to cover the range you have specified in the substring method, you will get this error. For instance, if you are getting a substring that's 3 characters long from line 2 starting at character 0 and it has less than 3 characters, you will get this error.
See the documentation on the String.Substring method here
I'm trying to validate a postcode from a user input within a form. Using this class, i'm trying to search through every character and check it. Then to call in within the form I have used the latter code.
The problem i'm having is that an error pops up saying
"Conversion from string "True0" to type 'Double' is not valid."
Function VaidatePostCode(ByVal Post As String) As String
For C = 0 To Len(Post) - 1
If Char.IsLetter(Post(C)) & C = 0 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsLetter(Post(C)) & C = 1 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsNumber(Post(C)) & C = 2 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsWhiteSpace(Post(C)) & C = 3 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsNumber(Post(C)) & C = 4 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsLetter(Post(C)) & C = 5 Then
_boolvalid = True
Else
_boolvalid = False
End If
If Char.IsLetter(Post(C)) & C = 6 Then
_boolvalid = True
Else
_boolvalid = False
End If
Next C
Return _boolvalid
End Function
This is the code within the VB.NET form
Private Sub txtPost_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPost.Validated
If myVal.VaidatePostCode(txtPost.Text) = False Then
MsgBox("Please enter correct data format into postcode")
End If
End Sub
To check if the value is a number you can use Integer.TryParse like this:
If Not Integer.TryParse(txtPost.Text, intTemp) Then
MsgBox ...
I have a problem with my blackjack game in vb.net. This code I have will add the player's score perfectly, but when it comes to the dealer's score, it will not. It only takes the second card that the dealer has.
It is called with this:
addScore("p") 'add player's score
addScore("d") 'add dealer's score
And this is "addScore()":
Public Function card(player As String, index As Integer) As Label
Try
If player = "p" Then
Return GroupBox1.Controls.OfType(Of Label).Where(Function(l) l.Name = "YouCard" & index.ToString()).Single()
ElseIf player = "d" Then
Return GroupBox1.Controls.OfType(Of Label).Where(Function(l) l.Name = "DealerCard" & index.ToString()).Single()
End If
Catch
Return Nothing
End Try
End Function
Public Sub addScore(ByVal player As String)
Dim currScore As Integer
Dim result As Integer = 0
'Add Score
For value As Integer = 1 To 7
If card(player, value).Text = "A" AndAlso (currScore + 11) <= 21 Then
result = currScore + 11
ElseIf card(player, value).Text = "A" AndAlso (currScore + 1) <= 22 Then
result = currScore + 1
ElseIf IsNumeric(card(player, value).Text) Then
result = currScore + CInt(card(player, value).Text)
ElseIf card(player, value).Text = "" Then
result = result
Else
result = currScore + 10
End If
If player = "p" Then
YouScore.Text = result
Else
DealerScore.Text = result
End If
Next
End Sub
currScore shouldn't be there. Replace it with result
Public Sub addScore(ByVal player As String)
Dim result As Integer = 0
'Add Score
For value As Integer = 1 To 7
If card(player, value).Text = "A" AndAlso (result + 11) <= 21 Then
result = result + 11
ElseIf card(player, value).Text = "A" AndAlso (result + 1) <= 22 Then
result = result + 1
ElseIf IsNumeric(card(player, value).Text) Then
result = result + CInt(card(player, value).Text)
ElseIf card(player, value).Text = "" Then
result = result
Else
result = result + 10
End If
If player = "p" Then
YouScore.Text = result
Else
DealerScore.Text = result
End If
Next
End Sub
I am creating a program and I need help on how I should go at this I need it to read encoded letters and return the correct letter but any loop that I try I just get System.ArgumentOutOfRangeException and it says that I need to make sure that what I am calling is just as long as what is there.
Private Sub btnDecode_Click(sender As Object, e As EventArgs) Handles btnDecode.Click
Do While ((y / 4) = txtDecoded.Text.Length)
If txtEncoded.Text.Substring(y, 1) = "1" Then
y = y + 1
If txtEncoded.Text.Substring(y, 1) = "0" Then
y = y + 1
If txtEncoded.Text.Substring(y, 1) = "1" Then
y = y + 2
strholder2(z) = "S"
ElseIf txtEncoded.Text.Substring(y, 1) = "0" Then
y = y + 2
strholder2(z) = "s"
End If
Else
If txtEncoded.Text.Substring(y, 1) = "5" Then
y = y + 1
If txtEncoded.Text.Substring(y, 1) = "9" Then
y = y + 2
strholder2(z) = "O"
Else
If txtEncoded.Text.Substring(y, 1) = "8" Then
y = y + 2
strholder2(z) = "o"
End If
End If
End If
End If
End If
Loop
Dim h As Integer
For h = 0 To (z)
strencode2 = strencode2 & strholder2(z)
Next
txtDecoded.Text = strencode2
Label1.Text = y.ToString
End Sub
Now that I took Francis Lord's loop into account I figured out how to get it working so thank you Francis Lord and everyone that gave me feedback..
You'll need to put a condition in your While loop to stop it from incrementing the y past the length of your string. Something like
Do While(y < txtEncode.Text.Lenght)
would do, but I'm not too sure how your code is supposed to work so you might have to adjust the condition to match your logic.
Here's basically what I have:
Public checkprogresstime_p1 As String = ""
Public checkprogresstime_p2 As String = ""
'P1 Progress bar updater
checkprogresstime_p1 = (time_total.Text - time_p1_hour.Value)
If checkprogresstime_p1 >= 60 Then
checkprogresstime_p1 = 60
time_p1_progress.ForeColor = Color.LimeGreen
ElseIf checkprogresstime_p1 <= 0 Then
checkprogresstime_p1 = 1
End If
If time_p1_progress.Value < 60 Then
time_p1_progress.ForeColor = Color.Red
End If
time_p1_progress.Value = checkprogresstime_p1
Here's basically what I need:
Dim cnt As Integer = 1
Do
'P1 Progress bar updater
checkprogresstime_p(cnt) = (time_total.Text - time_p(cnt)_hour.Value)
If checkprogresstime_p(cnt) >= 60 Then
checkprogresstime_p(cnt) = 60
time_p(cnt)_progress.ForeColor = Color.LimeGreen
ElseIf checkprogresstime_p(cnt) <= 0 Then
checkprogresstime_p(cnt) = 1
End If
If time_p(cnt)_progress.Value < 60 Then
time_p(cnt)_progress.ForeColor = Color.Red
End If
time_p(cnt)_progress.Value = checkprogresstime_p(cnt)
Loop While cnt <= 25
I have no idea how to do it... I need it to loop and add +1, 25 times. I basically have it written out 25 times at the moment...
This is the For/Loop with your current request. The cnt variable will increment itself in this type of Loop.
For cnt As Integer = 1 To 25
'P1 Progress bar updater
checkprogresstime_p(cnt) = (time_total.Text - time_p(cnt)_hour.Value)
If checkprogresstime_p(cnt) >= 60 Then
checkprogresstime_p(cnt) = 60
time_p(cnt)_progress.ForeColor = Color.LimeGreen
ElseIf checkprogresstime_p(cnt) <= 0 Then
checkprogresstime_p(cnt) = 1
End If
If time_p(cnt)_progress.Value < 60 Then
time_p(cnt)_progress.ForeColor = Color.Red
End If
time_p(cnt)_progress.Value = checkprogresstime_p(cnt)
Next
I believe what you're wanting to do has more to do with having 25 progress bars on your form where each one is named time_p#_progress where # is the number of the progress bar. That being said, there are two ways to acheive updating your progress bars without having to copy and paste your code 25 times...
1. Use Me.Controls to get a reference to the progress bar
For j = 1 To 25
Dim pbar As ProgressBar = Me.Controls("time_p" & j & "_progress")
Dim ph As NumericUpDown = Me.Controls("time_p" & j & "_hour")
Dim checkprogresstime As Long = (time_total.Text - ph.Value)
If checkprogresstime >= 60 Then
checkprogresstime = 60
pbar.ForeColor = Color.LimeGreen
ElseIf checkprogresstime <= 0 Then
checkprogresstime = 1
End If
If time_p1_progress.Value < 60 Then
pbar.Value = checkprogresstime
End If
pbar.Value = checkprogresstime
Application.DoEvents()
Next
Note: You didn't tell us what type of control time_p1_hour was. I assumed it was a NumericUpDown down control. So, if it's not, you need to replace it the type of control that time_p1_hour is.
2. Dynamically create your controls as a control array
Initizliaze your progress bars in the Form1_Load method (MyBase.Load)
Private pbars(24) As ProgressBar
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For i = LBound(pbars) To UBound(pbars)
pbars(i) = New ProgressBar()
pbars(i).Parent = Me
pbars(i).Top = i * pbars(i).Height
pbars(i).Left = 0
pbars(i).Visible = True
Next
End Sub
Put your code inside of a loop like so
For cnt = 0 To 24
checkprogresstime_p(cnt) = (time_total.Text - time_hour(cnt).Value)
If checkprogresstime_p(cnt) >= 60 Then
checkprogresstime_p(cnt) = 60
time_p_progress(cnt).ForeColor = Color.LimeGreen
ElseIf checkprogresstime_p(cnt) <= 0 Then
checkprogresstime_p(cnt) = 1
End If
If time_p_progress(cnt).Value < 60 Then
time_p_progress(cnt).ForeColor = Color.Red
End If
time_p_progress(cnt).Value = checkprogresstime_p(cnt)
Next