I am building a VB.NET Win Forms app that is reading the serial output of an Arduino and I want the VB.Net app to do something based on what it reads from the Arduino. The problem I am encountering is that even though I can read from the Arduino I can't seem to write it into an if statement.
The Arduino is a simple 3 button schematic. A red, yellow, and green button attached to digital pins 2,3, and 4. When one button is pressed the Arduino outputs the text "Red Button On", "Yellow Button On", or "Green Button On" depending on which button is pressed.
In the VB.Net app I have a label named lblHintRequest. I can load the arduino serial output onto this label. However, once I load the arduino serial output onto this label I can't seem to do anything with it. What I need is an if statement that will read which button is pressed and then do something depending on the button pressed. I have also tried adding a timer that ticks ever 500 ms that would read the label and this still did not work. The vb.net app just keeps skipping over the if statement.
The last thing I can think of trying is to use a textbox instead of a label and maybe that would help? But I really want this to be a label.
Imports System.IO.Ports
Public Class frmRoom
Private Sub frmRoom_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SerialPort1.Open()
End Sub
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
'Searching for data input
Dim ReadCode As String
ReadCode = SerialPort1.ReadLine
'Print the button press
lblHintRequest.Invoke(New MethodInvoker(Sub() lblHintRequest.Text = ReadCode), Nothing)
'This code will not run even though when I invoke the lblhintrequest it shows re button on
If lblHintRequest.Text = "Red Button On" Then
lblHintRequest.ForeColor = Color.Red
End If
'This if statement does not work either
If lblHintRequest.Invoke(New MethodInvoker(Sub() lblHintRequest.Text = ReadCode), Nothing) = "Red Button On" Then
MsgBox("hit")
End If
End Sub
'----------Code below added for solution response on stack overflow ---
Private Sub UpdateHintRequest(code As String)
If lblHintRequest.InvokeRequired Then
lblHintRequest.Invoke(Sub() UpdateHintRequest(code))
--Getting stuff to run here was the solution.
If lblHintRequest.Text = "Red Button On" Then
lblHintRequest.ForeColor = Color.Red
End If
Else
End If
End Sub
End Class
const int RedButton = 2;
const int YellowButton = 3;
const int GreenButton = 4;
const int ledpin = 13;
int buttonstateRed =0;
int buttonstateYellow =0;
int buttonstateGreen =0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(ledpin,OUTPUT);
pinMode(RedButton, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
buttonstateRed = digitalRead(RedButton);
if (buttonstateRed == HIGH){
digitalWrite(ledpin, HIGH);
Serial.println("Red Button On");
}
buttonstateYellow = digitalRead(YellowButton);
if (buttonstateYellow == HIGH){
digitalWrite(ledpin, HIGH);
Serial.println("Yellow Button On");
}
buttonstateGreen = digitalRead(GreenButton);
if (buttonstateGreen == HIGH){
digitalWrite(ledpin, HIGH);
Serial.println("Green Button On");
}
if (buttonstateRed == LOW && buttonstateYellow == LOW && buttonstateGreen == LOW){
digitalWrite(ledpin, LOW);
//Serial.println("No Button Pressed");
}
Serial.flush();
delay(500);
//Serial.println("Hello");
//delay(250);
}
Since you have the value returned by the Arduino in a variable, you can use it in your If
statement:
If ReadCode = "Red Button On" Then
lblHintRequest.ForeColor = Color.Red
End If
Otherwise, to deal with the fact that your code is being invoked from a different thread (SerialPort
's DataReceived
event), you can wrap your entire logic in its own Sub
:
Private Sub UpdateHintRequest(code As String)
If lblHintRequest.InvokeRequired Then
lblHintRequest.Invoke(Sub() UpdateHintRequest(code))
Else
' Print the button press
lblHintRequest.Text = code
If lblHintRequest.Text = "Red Button On" Then
lblHintRequest.ForeColor = Color.Red
End If
If lblHintRequest.Text = "Red Button On" Then
MsgBox("hit")
End If
End If
End Sub
Back to your original code:
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
'Searching for data input
Dim ReadCode As String
ReadCode = SerialPort1.ReadLine
UpdateHintRequest(ReadCode)
End Sub