You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS2022串口控制Arduino水族箱1-2点时段定时逻辑异常求助

问题

使用VS2022编写VB代码,通过串口连接Arduino Mega控制水族箱。代码多数时段运行正常,但24小时制1:00:00至2:00:00期间,所有定时控制功能异常:本该关闭的灯光、水泵意外开启,夜灯关闭;到2:00:00时功能恢复正常。

已尝试用timeValue、timeNow处理时间判断,问题仍未解决。异常导致鱼类受惊乱窜甚至跳出水面,需解决该问题。

原代码如下:

Public Class VISBAK

    Dim InputData As String = ""
    Dim flasch As Boolean = True

    Public P_Lichtbalk_Linksachter_Aan_Uit As Boolean               'A
    Public P_Lichtbalk_Rechtsvoor_Aan_Uit As Boolean                'B
    Public P_Spot_Links_Aan_Uit As Boolean                          'C
    Public P_Lichtbalk_Rechtsachter_Aan_Uit As Boolean              'D
    Public P_Lichtbalk_Linksvoor_Aan_Uit As Boolean                 'E
    Public P_Klok_Kaamlaag_Aan_Uit As Boolean                       'F
    Public P_Klok_Nachtverlichting_Aan_Uit As Boolean               'G
    Public P_Klok_CO2_Reactor_Aan_Uit As Boolean                    'U
    Public P_Reserve_Klok_Aan_Uit As Boolean                        'W
    Public P_Proc_Verwarming_Aan_Uit As Boolean                     'L
    Public P_Verklikker_Bijvulwater_Aan_Uit As Boolean              'M
    Public P_Proc_Bijvullen_Aan_Uit As Boolean                      'Q
    Public P_Proc_CO2_Dosering_Aan_Uit As Boolean                   'R
    Public P_Klok_Ontluchting_CO2_Aan_Uit As Boolean                'V
    Public P_Klok_Plantenbemesting_Aan_Uit As Boolean               'Z


    Private tb_Klok_Spot_Links As Object


    Public Event DataReceived As IO.Ports.SerialDataReceivedEventHandler


    Private Sub Form1_Load(ByVal sender As System.Object,
                   ByVal e As System.EventArgs) Handles MyBase.Load

        SerialPort1.PortName = "COM4"

        SerialPort1.BaudRate = 9600
        SerialPort1.Parity = IO.Ports.Parity.None
        SerialPort1.DataBits = 8
        SerialPort1.StopBits = IO.Ports.StopBits.One
        SerialPort1.Handshake = IO.Ports.Handshake.None
        SerialPort1.RtsEnable = True

        If Not SerialPort1.IsOpen Then
            SerialPort1.Open()
        End If
        P_Lichtbalk_Linksachter_Aan_Uit = True
        P_Lichtbalk_Rechtsvoor_Aan_Uit = True
        P_Spot_Links_Aan_Uit = True
        P_Lichtbalk_Rechtsachter_Aan_Uit = True
        P_Lichtbalk_Linksvoor_Aan_Uit = True
        P_Klok_Kaamlaag_Aan_Uit = True
        P_Klok_Nachtverlichting_Aan_Uit = True
        P_Proc_Verwarming_Aan_Uit = True
        P_Verklikker_Bijvulwater_Aan_Uit = True
        P_Proc_Bijvullen_Aan_Uit = True
        P_Proc_CO2_Dosering_Aan_Uit = True
        P_Klok_CO2_Reactor_Aan_Uit = True
        P_Klok_Ontluchting_CO2_Aan_Uit = True
        P_Klok_Plantenbemesting_Aan_Uit = True
        P_Reserve_Klok_Aan_Uit = True

    End Sub

    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object,
     ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
      Handles SerialPort1.DataReceived
        Dim inputData = SerialPort1.ReadLine
        Invoke(New Action(Of String)(AddressOf DoUpdate), inputData)
    End Sub

    Private Sub DoUpdate(inputData As String)

        Dim values() As String = inputData.Split(",")
        TextBox3.Text = "450" 'values(0)                  'Geleidbaarheid
        tb_temperatuur.Text = "24.5" 'values(1)            'Temperatuur
        tb_pH.Text = "6.7" 'values(2)                     'Zuurgraad       
        TextBox4.Text = values(3)                  'Bijvullen

    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        Actueletijd.Text = DateTime.Now.ToLongTimeString

        If P_Proc_Bijvullen_Aan_Uit = True Then
            If TextBox4.Text = "1" Then
                SerialPort1.Write("Q")
                Tb_Bijvullen.BackColor = Color.Aqua
                TextBox4.BackColor = Color.Aqua
                tb_OL5.BackColor = Color.Red
            Else
                'TextBox4.Text = "0"
                SerialPort1.Write("q")
                Tb_Bijvullen.BackColor = Color.LightGreen
                TextBox4.BackColor = Color.LightGreen
                tb_OL5.BackColor = Color.LightGreen
            End If
        End If

        If P_Proc_Verwarming_Aan_Uit = True Then
            If tb_temperatuur.Text <= "23.5" And tb_temperatuur.Text <= "24.0" Then

                SerialPort1.Write("L")
                Tb_Verwarming.BackColor = Color.Aqua
                tb_OL1.BackColor = Color.Red
            Else
                SerialPort1.Write("l")
                Tb_Verwarming.BackColor = Color.LightGreen
                tb_OL1.BackColor = Color.LightGreen
            End If
        End If

        If P_Verklikker_Bijvulwater_Aan_Uit = True Then
            If tb_temperatuur.Text >= "0" And tb_temperatuur.Text <= "40" Then
                SerialPort1.Write("M")
                Tb_Verklikker_Bijvulwater.BackColor = Color.Aqua
                tb_OL3.BackColor = Color.Red
            Else
                SerialPort1.Write("m")
                Tb_Verklikker_Bijvulwater.BackColor = Color.LightGreen
                tb_OL3.BackColor = Color.LightGreen
            End If
        End If

        If P_Proc_CO2_Dosering_Aan_Uit = True Then
            If tb_pH.Text >= "6.6" And tb_pH.Text >= "6.4" Then
                SerialPort1.Write("R")
                Tb_CO2_Dosering.BackColor = Color.Aqua
                tb_B1.BackColor = Color.Red
            Else
                SerialPort1.Write("r")
                Tb_CO2_Dosering.BackColor = Color.LightGreen
                tb_B1.BackColor = Color.LightGreen
            End If
        End If

        If P_Lichtbalk_Linksachter_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "15:30" And DateTime.Now.ToShortTimeString <= "21:00" Then
                SerialPort1.Write("A")
                Btn_Klok_A.BackColor = Color.Yellow
                Tb_Lichtbalk_Linksachter.BackColor = Color.Yellow
                tb_B3.BackColor = Color.Red
            Else
                SerialPort1.Write("a")
                Tb_Lichtbalk_Linksachter.BackColor = Color.LightBlue
                Btn_Klok_A.BackColor = Color.Yellow
                tb_B3.BackColor = Color.LightGreen
            End If
        End If

        If P_Lichtbalk_Rechtsvoor_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "13:30" And DateTime.Now.ToShortTimeString <= "23:00" Then
                SerialPort1.Write("B")
                Btn_Klok_B.BackColor = Color.Yellow
                Tb_Lichtbalk_Rechtsvoor.BackColor = Color.Yellow
                tb_B7.BackColor = Color.Red
            Else
                SerialPort1.Write("b")
                Tb_Lichtbalk_Rechtsvoor.BackColor = Color.LightBlue
                Btn_Klok_B.BackColor = Color.Yellow
                tb_B7.BackColor = Color.LightGreen
            End If
        End If

        If P_Spot_Links_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "00:00" And DateTime.Now.ToShortTimeString <= "23:59" Then
                SerialPort1.Write("C")
                Btn_Klok_C.BackColor = Color.Yellow
                Tb_Spot_Links.BackColor = Color.Yellow
                tb_B4.BackColor = Color.Red
            Else
                SerialPort1.Write("c")
                Tb_Spot_Links.BackColor = Color.LightBlue
                Btn_Klok_C.BackColor = Color.Yellow
                tb_B4.BackColor = Color.LightGreen
            End If
        End If

        If P_Lichtbalk_Rechtsachter_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "15:45" And DateTime.Now.ToShortTimeString <= "21:30" Then
                SerialPort1.Write("D")
                Btn_Klok_D.BackColor = Color.Yellow
                Tb_Lichtbalk_Rechtsachter.BackColor = Color.Yellow
                tb_B8.BackColor = Color.Red
            Else
                SerialPort1.Write("d")
                Tb_Lichtbalk_Rechtsachter.BackColor = Color.LightBlue
                Btn_Klok_D.BackColor = Color.Yellow
                tb_B8.BackColor = Color.LightGreen
            End If
        End If

        If P_Lichtbalk_Linksvoor_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "13:00" And DateTime.Now.ToShortTimeString <= "22:30" Then
                SerialPort1.Write("E")
                Btn_Klok_E.BackColor = Color.Yellow
                Tb_Lichtbalk_Linksvoor.BackColor = Color.Yellow
                tb_B5.BackColor = Color.Red
            Else
                SerialPort1.Write("e")
                Tb_Lichtbalk_Linksvoor.BackColor = Color.LightBlue
                Btn_Klok_E.BackColor = Color.Yellow
                tb_B5.BackColor = Color.LightGreen
            End If
        End If

        If P_Klok_Kaamlaag_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "12:30" And DateTime.Now.ToShortTimeString <= "20:30" Then
                SerialPort1.Write("F")
                Btn_Klok_F.BackColor = Color.Yellow
                Tb_Kaamlaag.BackColor = Color.Yellow
                tb_B9.BackColor = Color.Red
            Else
                SerialPort1.Write("f")
                Tb_Kaamlaag.BackColor = Color.LightBlue
                Btn_Klok_F.BackColor = Color.Yellow
                tb_B9.BackColor = Color.LightGreen
            End If
        End If

        If P_Klok_Nachtverlichting_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "13:00" And DateTime.Now.ToShortTimeString <= "22:00" Then
                SerialPort1.Write("g")
                Btn_Klok_G.BackColor = Color.Yellow
                Tb_Nachtverlichting.BackColor = Color.LightBlue
                tb_B6.BackColor = Color.LightGreen
            Else
                SerialPort1.Write("G")
                Tb_Nachtverlichting.BackColor = Color.Yellow
                Btn_Klok_G.BackColor = Color.Yellow
                tb_B6.BackColor = Color.Red
            End If
        End If

        If P_Klok_CO2_Reactor_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "10:15" And DateTime.Now.ToShortTimeString <= "20:30" Then
                SerialPort1.Write("U")
                Btn_Klok_U.BackColor = Color.Yellow
                Tb_CO2_Reactorpomp.BackColor = Color.Yellow
                tb_OL6.BackColor = Color.Red
            Else
                SerialPort1.Write("u")
                Tb_CO2_Reactorpomp.BackColor = Color.LightBlue
                Btn_Klok_U.BackColor = Color.Yellow
                tb_OL6.BackColor = Color.LightGreen
            End If
        End If

        If P_Klok_Plantenbemesting_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "14:00" And DateTime.Now.ToShortTimeString <= "14:05" Then
                SerialPort1.Write("Z")
                Btn_Klok_Z.BackColor = Color.Yellow
                Tb_Plantenbemesting.BackColor = Color.Yellow
                tb_L2.BackColor = Color.Red
            Else
                SerialPort1.Write("z")
                Tb_Plantenbemesting.BackColor = Color.LightBlue
                Btn_Klok_Z.BackColor = Color.Yellow
                tb_L2.BackColor = Color.LightGreen
            End If
        End If

        If P_Klok_Ontluchting_CO2_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString >= "20:30:" And DateTime.Now.ToShortTimeString <= "20:31" Then
                SerialPort1.Write("V")
                Btn_Klok_V.BackColor = Color.Yellow
                Tb_Ontluchting_CO2.BackColor = Color.Yellow
                tb_O2.BackColor = Color.Red
            Else
                SerialPort1.Write("v")
                Tb_Ontluchting_CO2.BackColor = Color.LightBlue
                Btn_Klok_V.BackColor = Color.Yellow
                tb_O2.BackColor = Color.LightGreen
            End If
        End If


        If P_Reserve_Klok_Aan_Uit = True Then
            If DateTime.Now.ToShortTimeString <= "00:00" And DateTime.Now.ToShortTimeString >= "00:00" Then
                SerialPort1.Write("W")
                Btn_Klok_W.BackColor = Color.Yellow
                Tb_Reserve_Klok.BackColor = Color.Yellow
                tb_R5.BackColor = Color.Red
            Else
                SerialPort1.Write("w")
                Tb_Reserve_Klok.BackColor = Color.LightBlue
                Btn_Klok_W.BackColor = Color.Yellow
                tb_R5.BackColor = Color.LightGreen
            End If
        End If

    End Sub
End Class
问题根源

核心问题是用字符串(ToShortTimeString()返回的文本)进行时间比较,而非强类型的时间值对比:

  1. 字符串比较依赖字符ASCII码顺序,而非实际时间逻辑。比如凌晨1点的字符串"01:00"(或12小时制的"1:00 AM")会被错误判定为大于白天的"13:00",导致所有定时判断逻辑反转。
  2. 系统区域设置若为12小时制,ToShortTimeString()返回的格式会和代码中硬编码的24小时制字符串完全不兼容,进一步加剧逻辑混乱。
  3. 代码中还存在其他细节错误:比如温度、pH值用字符串比较而非数值比较,P_Klok_Ontluchting_CO2_Aan_Uit的判断条件里多了一个冒号("20:30:")。
修复方案

彻底抛弃字符串比较时间的方式,改用**DateTime.Now.TimeOfDay(返回TimeSpan类型)和TimeSpan.Parse()创建的固定时间区间**进行强类型比较,同时修正其他细节错误:

具体修改步骤

  1. 统一时间比较逻辑:
    所有定时判断替换为TimeSpan对比模式,示例:

    Dim currentTime As TimeSpan = DateTime.Now.TimeOfDay
    Dim startTime As TimeSpan = TimeSpan.Parse("15:30")
    Dim endTime As TimeSpan = TimeSpan.Parse("21:00")
    If currentTime >= startTime AndAlso currentTime <= endTime Then
        ' 执行开启逻辑
    Else
        ' 执行关闭逻辑
    End If
    

    跨午夜的时间区间(如22:00至次日6:00)需拆分判断:

    If currentTime >= TimeSpan.Parse("22:00") OrElse currentTime <= TimeSpan.Parse("06:00") Then
    
  2. 修正数值比较逻辑:
    温度、pH值的判断改为数值类型对比,避免字符串比较的潜在错误:

    ' 原温度判断
    ' If tb_temperatuur.Text <= "23.5" And tb_temperatuur.Text <= "24.0" Then
    ' 修改为
    If CDbl(tb_temperatuur.Text) >= 23.5 AndAlso CDbl(tb_temperatuur.Text) <= 24.0 Then
    
  3. 修正笔误:
    移除P_Klok_Ontluchting_CO2_Aan_Uit判断条件里多余的冒号,改为TimeSpan.Parse("20:30")。

修改后的核心代码示例

以下是修正后的Timer1_Tick关键逻辑:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Actueletijd.Text = DateTime.Now.ToLongTimeString
    Dim currentTime As TimeSpan = DateTime.Now.TimeOfDay

    ' 补水逻辑(保留原逻辑)
    If P_Proc_Bijvullen_Aan_Uit = True Then
        If TextBox4.Text = "1" Then
            SerialPort1.Write("Q")
            Tb_Bijvullen.BackColor = Color.Aqua
            TextBox4.BackColor = Color.Aqua
            tb_
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:17:32