【问题标题】:VB.NET If statement based on Arduino Serial Output基于 Arduino 串行输出的 VB.NET If 语句
【发布时间】:2021-06-09 13:42:03
【问题描述】:

我正在构建一个 VB.NET Win Forms 应用程序,该应用程序正在读取 Arduino 的串行输出,我希望 VB.Net 应用程序根据它从 Arduino 读取的内容来做一些事情。我遇到的问题是,即使我可以从 Arduino 读取数据,我似乎也无法将其写入 if 语句。

Arduino 是一个简单的 3 按钮原理图。连接到数字引脚 2、3 和 4 的红色、黄色和绿色按钮。当按下一个按钮时,Arduino 输出文本“红色按钮打开”、“黄色按钮打开”或“绿色按钮打开”,具体取决于哪个按钮按钮被按下。

在 VB.Net 应用程序中,我有一个名为 lblHintRequest 的标签。我可以将 arduino 串行输出加载到这个标签上。但是,一旦我将 arduino 串行输出加载到这个标签上,我似乎无法用它做任何事情。我需要的是一个 if 语句,它将读取按下哪个按钮,然后根据按下的按钮执行某些操作。我还尝试添加一个每 500 毫秒计时的计时器,它会读取标签,但这仍然不起作用。 vb.net 应用程序只是不断跳过 if 语句。

我能想到的最后一件事是使用文本框而不是标签,也许这会有所帮助?但我真的希望这是一个标签。

VB.NET 代码

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 代码

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

【问题讨论】:

  • 对我来说,作为一个 vb.net 假人,并在 c# 中查看所有 .net 示例代码,问题是这种“lambda 函数样式”语法在 VB 中是否正确。如果您创建一个普通的 sub 并提供函数名称怎么办?一个简单的替代方法是忽略 SerialPort1_DataReceived 线程。表单上提到的计时器对象必须读取您的 SerialPort1。无需调用代表。顺便说一句:我猜文本框与标签没有任何区别......
  • 我尝试将读取的行代码放入计时器滴答事件中,它锁定了计时器和代码。

标签: vb.net if-statement arduino serial-port comm


【解决方案1】:

由于您在变量中有 Arduino 返回的值,因此您可以在 If 语句中使用它:

If ReadCode = "Red Button On" Then 
    lblHintRequest.ForeColor = Color.Red
End If

否则,为了处理您的代码是从不同线程调用的事实(SerialPortDataReceived 事件),您可以将整个逻辑包装在自己的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

回到你原来的代码:

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

【讨论】:

  • 我试过这段代码,但它不起作用。当 lbl 更新时,您发布的私人订阅从未被触发。我在第一个 if 语句的开头插入了一个程序中断。我会继续尝试这种方法。
  • 我也只是尝试使用标签文本更改事件,即使它确实触发了文本在技术上仍未更改为“红色按钮打开”,因此跳过了 if 语句。
  • 这段代码应该在你处理DataReceived事件时被调用。我更新了答案以反映这一点。
  • 这行得通,if 语句与我的想法相反,但它很棒。我很感激。我将使用完整的解决方案更新我的答案。我很感激。
猜你喜欢
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
相关资源
最近更新 更多