vb.netif-statementarduinoserial-portcomm

VB.NET If statement based on Arduino Serial Output


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.

VB.NET Code

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

Arduino Code

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);
}

Solution

  • 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