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()返回的文本)进行时间比较,而非强类型的时间值对比:
- 字符串比较依赖字符ASCII码顺序,而非实际时间逻辑。比如凌晨1点的字符串
"01:00"(或12小时制的"1:00 AM")会被错误判定为大于白天的"13:00",导致所有定时判断逻辑反转。 - 系统区域设置若为12小时制,
ToShortTimeString()返回的格式会和代码中硬编码的24小时制字符串完全不兼容,进一步加剧逻辑混乱。 - 代码中还存在其他细节错误:比如温度、pH值用字符串比较而非数值比较,
P_Klok_Ontluchting_CO2_Aan_Uit的判断条件里多了一个冒号("20:30:")。
修复方案
彻底抛弃字符串比较时间的方式,改用**DateTime.Now.TimeOfDay(返回TimeSpan类型)和TimeSpan.Parse()创建的固定时间区间**进行强类型比较,同时修正其他细节错误:
具体修改步骤
统一时间比较逻辑:
所有定时判断替换为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修正数值比较逻辑:
温度、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修正笔误:
移除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_
相关产品推荐
相关产品推荐

