- Option Explicit
- '
- ' Simple PID Loop Simulator ... for educational use.
- '
- ' By Max Seim, mlseim@mmm.com
- ' Systems Control Technician, 3M Company, Cottage Grove, Minnesota
- '
- Dim invalve As Integer
- Dim outvalve As Integer
- Dim mode As Integer '0=manual, 1=auto
- Dim error As Integer
- Dim stability As Integer '0=stable, 1=unstable
- Dim supply As Integer
- Dim x As Integer
- Dim y As Integer
- Dim gain As Long
- Dim reset As Long
- Dim rate As Long
- Dim output As Integer
- Dim pv As Long
- Dim s1 As Integer
- Dim s2 As Integer
- Dim outgraph(100) As Integer
- Dim pvgraph(100) As Integer
- Dim inputd As Long
- Dim inputdf As Long
- Dim inputlast As Long
- Dim feedback As Long
- Dim dfilter As Long
- Dim sp As Long
- Private Sub Command1_Click() ' Go into MANUAL control
- Shape12.FillStyle = 0
- Shape13.FillStyle = 1
- mode = 0
- HScroll2.Enabled = True
- End Sub
- Private Sub Command2_Click() ' Go into AUTO control
- Shape12.FillStyle = 1
- Shape13.FillStyle = 0
- mode = 1
- HScroll2.Enabled = False
- End Sub
- Private Sub Command3_Click() ' Toggle the Unstable Water Supply
- '
- If stability = 0 Then
- Shape19.FillStyle = 0
- stability = 1
- Exit Sub
- End If
- If stability = 1 Then
- Shape19.FillStyle = 1
- stability = 0
- supply = 2000
- End If
- Label38.Caption = supply
- End Sub
- Private Sub Form_load()
- ' center the form
- Form1.Left = (Screen.Width / 2) - (Form1.Width / 2)
- Form1.Top = (Screen.Height / 2) - (Form1.Height / 2)
- ' Initialize the Sliders and other variables
- VScroll1.Value = 0
- Shape1(1).Top = (3100 - VScroll1.Value) + 1040
- Shape1(1).Height = VScroll1.Value
- Shape1(0).Top = (3100 - pv) + 1030
- Shape1(0).Height = pv
- Label12.Caption = VScroll1.Value
- supply = 2000
- Label38.Caption = supply
- HScroll1.Value = 100
- Label13.Caption = HScroll1.Value
- invalve = (HScroll1.Value * (supply / 100)) / 60
- outvalve = 0
- Label14.Caption = 0
- Text1.Text = pv
- Shape12.FillStyle = 1
- Shape13.FillStyle = 0
- mode = 1
- HScroll2.Enabled = False
- gain = Text2.Text
- reset = Text3.Text
- rate = Text4.Text
- VScroll1.Value = 1500
- Shape1(1).Top = (3100 - VScroll1.Value) + 1040
- Shape1(1).Height = VScroll1.Value
- Label12.Caption = VScroll1.Value
- sp = VScroll1.Value
- Picture1.Cls
- Picture1.ScaleMode = 3
- Picture1.ScaleHeight = 3105
- Picture1.ScaleWidth = 100
- Picture1.AutoRedraw = True
- Picture1.ForeColor = vbCyan
- Picture1.DrawStyle = 0
- Picture1.DrawWidth = 2
- Picture2.Cls
- Picture2.ScaleMode = 3
- Picture2.ScaleHeight = 105
- Picture2.ScaleWidth = 100
- Picture2.AutoRedraw = True
- Picture2.ForeColor = vbRed
- Picture2.DrawStyle = 0
- Picture2.DrawWidth = 2
- End Sub
- Private Sub HScroll1_Change() ' Slider control for INLET VALVE POSITION
- Label13.Caption = HScroll1.Value
- invalve = (HScroll1.Value * (supply / 100)) / 60
- End Sub
- Private Sub HScroll2_Change() ' Slider control for OUTLET VALVE POSITION
- Label14.Caption = HScroll2.Value
- outvalve = (HScroll2.Value * 30) / 60
- End Sub
- Private Sub mnExit_Click() ' Exit program
- Erase outgraph
- Erase pvgraph
- Unload Me
- End Sub
- Private Sub mnInstructions_Click() ' Show instruction form
- instructions.Show
- End Sub
- Private Sub Timer1_Timer()
- On Error Resume Next
- If Text2 < 0 Then
- Text2 = 0
- End If
- If Text2 > 100 Then
- Text2 = 100
- End If
- gain = Val(Text2)
- If Text3 < 0 Then
- Text3 = 0
- End If
- If Text3 > 120 Then
- Text3 = 120
- End If
- reset = Val(Text3)
- If Text4 < 0 Then
- Text4 = 0
- End If
- If Text4 > 120 Then
- Text4 = 120
- End If
- rate = Val(Text4)
- If pv < 3101 Then
- pv = pv + invalve
- End If
- If pv > 0 Then
- pv = pv - outvalve
- End If
- Text1.Text = pv
- error = sp - pv
- Label30.Caption = error
- Label38.Caption = supply
- tank
- If stability = 1 Then
- watersupply
- invalve = (HScroll1.Value * (supply / 100)) / 60
- End If
- If mode = 1 Then
- pidloop
- End If
- ' Graph the PV, Process Variable
- Picture1.Cls
- pvgraph(100) = pv
- For x = 0 To 99
- pvgraph(x) = pvgraph(x + 1)
- Picture1.PSet (x, 3000 - (pvgraph(x)))
- Next x
- ' Display the SP line (yellow)
- Picture1.Line (0, 3000 - sp)-(100, 3000 - sp), vbYellow
- ' Graph the OUTPUT VALVE position
- Picture2.Cls
- outgraph(100) = outvalve
- For x = 0 To 99
- outgraph(x) = outgraph(x + 1)
- Picture2.PSet (x, 100 - (outgraph(x) * 2))
- Next x
- End Sub
- Private Sub VScroll1_Change() ' Slider control for SP (setpoint)
- Shape1(1).Top = (3100 - VScroll1.Value) + 1040
- Shape1(1).Height = VScroll1.Value
- Label12.Caption = VScroll1.Value
- sp = VScroll1.Value
- End Sub
- Private Sub tank() ' Draw the water tank animation
- If HScroll1.Value > 0 Then
- Shape7.FillStyle = 0
- Shape8.FillStyle = 0
- Shape9.FillStyle = 0
- Else: Shape7.FillStyle = 1
- Shape8.FillStyle = 1
- Shape9.FillStyle = 1
- End If
- If pv > -1 Then
- Shape1(0).Top = (3100 - pv) + 1030
- Shape1(0).Height = pv
- End If
- If (pv > 0) Or (HScroll1.Value > 0) Then
- Shape10.FillStyle = 0
- Else: Shape10.FillStyle = 1
- End If
- If (HScroll2.Value > 0) And (pv > 0) Then
- Shape11.FillStyle = 0
- Else: Shape11.FillStyle = 1
- End If
- End Sub
- Private Sub watersupply() ' Create an unstable water supply
- Randomize
- s1 = Int(Rnd(1) * 20 + 1)
- Randomize
- s2 = Int(Rnd(1) * 1000 + 1)
- If s2 < 100 Then
- supply = supply + s1
- End If
- If s2 > 900 Then
- supply = supply - s1
- End If
- If supply < 500 Then
- supply = 500
- End If
- If supply > 2500 Then
- supply = 2500
- End If
- End Sub
- Private Sub pidloop()
- dfilter = 10 ' Filter value to scale down derivative effect.
- inputd = pv + (inputlast - pv) * (rate / 60)
- inputlast = pv
- inputdf = inputdf + (inputd - inputdf) * dfilter / 60
- output = (sp - inputdf) * (gain / 100) + feedback
- If output > 100 Then ' clamp output valve between 0 and 100%
- output = 100
- End If
- If output < 0 Then
- output = 0
- End If
- HScroll2.Value = 100 - output ' Change slider value (AUTO MODE)
- Picture4.Width = HScroll2.Value * 20
- Label14.Caption = HScroll2.Value
- feedback = feedback - (feedback - output) * reset / 60
- End Sub
复制代码 |