VB与PLC通信

VB与AB的PLC之间通讯
AB系列的PLC一般都有专用的驱动程序用于实现PLC和计算机之间的通讯,如RSLINX就是专门用于做这项工作的,但使用RSLINX也具有一定的局限性,这里提供一个使用VB编程实现PLC和计算机之间的通讯程序,使用的协议是DF1,可以支持Micrologix、SLC500等系列的PLC。使用的代码如下:
Option Explicit
Dim tns%, comunicating
Private Sub Command1_Click()
ReDim tb%(10)
Dim st
If ReadTable(0, tb%()) Then
For st = 0 To 9 '显示结果
Text1.SelText = Str(tb%(st)) + Chr(32)
Next st
Text1.SelText = Chr(13) + Chr(10)
End If
End Sub

Private Sub Command2_Click()
ReDim tm%(5)
tm%(0) = Rnd * 32768
tm%(1) = Rnd * 32768
tm%(2) = Rnd * 32768
tm%(3) = Rnd * 32768
tm%(4) = Rnd * 32768
If Not WriteTable(4, tm%()) Then Text1.SelText = "写入错误!!"
End Sub

Private Sub Exit_Click()
Unload Me
End
End Sub

Private Sub Form_Load()
Comm1.PortOpen = True
End Sub

Private Sub Form_Unload(Cancel As Integer)
Comm1.PortOpen = False
End Sub


Private Sub CalcCRC(mes$)
Dim byt%, res&
'对消息进行crc校验,然后将结果添加到消息的结尾。
byt% = 3
Do
res& = res& Xor Asc(Mid(mes$, byt%, 1))
rotate res&
If Asc(Mid(mes$, byt%, 1)) = 16 Then
mes$ = Left$(mes$, byt%) + Chr(16) + Right$(mes$, Len(mes$) - byt%)
byt% = byt% + 1
End If
byt% = byt% + 1
Loop While (byt% <= Len(mes$) - 2)
res& = res& Xor 3
rotate res&
mes$ = mes$ + Chr(res& Mod 256) + Chr(Int(res& / 256))
End Sub

Function ReadTable(start, n%())
Dim st, com$
'从PLC CIF数据表中读取数据, Micrologix=N7 SLC500=N9
If comunicating Then Exit Function
comunicating = True
https://www.360docs.net/doc/0618304958.html,m1.InputLen = 0 '清缓冲区
com$ = https://www.360docs.net/doc/0618304958.html,m1.Input
'构建消息
com$ = Chr(16) + Chr(2) + Chr(0) + Chr(0)
com$ = com$ + Chr(1) + Chr(0) + Chr(tns%) + Chr(0)
com$ = com$ + Chr(start) + Chr(0) + Chr(UBound(n%) * 2)
com$ = com$ + Chr(16) + Chr(3)
'进行crc计算并附加到结尾。
CalcCRC com$
tns% = tns% + 1
If tns% = 256 Then tns% = 0
'发送命令
https://www.360docs.net/doc/0618304958.html,m1.Output = com$
'等待确认
st = Timer
Do
DoEvents
Loop While st + 3 > Timer And https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 2
'从缓冲中移除确认
https://www.360docs.net/doc/0618304958.html,m1.InputLen = 2
com$ = https://www.360docs.net/doc/0618304958.html,m1.Input
If com$ <> Chr(16) + Chr(6) Then
comunicating = False
Exit Function
End If
st = Timer '等待应答
Do
DoEvents
Loop While st + 3 > Timer And https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 12 + (UBound(n%)
* 2)

'超时则退出
If https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 12 + (UBound(n%) * 2) Then
comunicating = False
Exit Function
End If
'发送确认
https://www.360docs.net/doc/0618304958.html,m1.Output = Chr(16) + Chr(6)
'得到应答
https://www.360docs.net/doc/0618304958.html,m1.InputLen = 0
com$ = https://www.360docs.net/doc/0618304958.html,m1.Input
st = 3
Do
If Mid(com$, st, 1) = Chr(16) Then
com$ = Left(com$, st) + Right(com$, Len(com$) - 1 - st)
End If
st = st + 1
Loop While st < Len(com$) - 4
'保存结果
For st = 0 To UBound(n%) - 1
n%(st) = 256 * Asc(Mid(com$, 2 * st + 10, 1)) + Asc(Mid(com$, 2 * st + 9,
1))
Next st
ReadTable = True
comunicating = False
End Function

Private Sub rotate(res&)
Dim bitout%, shift%
For shift% = 1 To 8
bitout% = res& Mod 2
res& = Int(res& / 2)
If bitout% Then
res& = res& Xor &H1000A001
res& = res& - &H10000000
End If
Next shift%
End Sub

Function WriteTable(start, n%())
Dim st, com$
'写到 PLC CIF数据表, Micrologix=N7 SLC500=N9
If comunicating Then Exit Function
comunicating = True
https://www.360docs.net/doc/0618304958.html,m1.InputLen = 0
com$ = https://www.360docs.net/doc/0618304958.html,m1.Input
com$ = Chr(16) + Chr(2) + Chr(0) + Chr(0)
com$ = com$ + Chr(8) + Chr(0) + Chr(tns%) + Chr(0)
com$ = com$ + Chr(start) + Chr(0)
For st = 0 To UBound(n%)
com$ = com$ + Chr(n%(st) Mod 256) + Chr(Int(n%(st) / 256))
Next st
com$ = com$ + Chr(16) + Chr(3)
tns% = tns% + 1
If tns% = 256 Then tns% = 0
CalcCRC com$
https://www.360docs.net/doc/0618304958.html,m1.Output = com$
st = Timer
Do
DoEvents
Loop While st + 3 > Timer And https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 2
https://www.360docs.net/doc/0618304958.html,m1.InputLen = 2
com$ = https://www.360docs.net/doc/0618304958.html,m1.Input
If com$ <> Chr(16) + Chr(6) Then
comunicating = False
Exit Function
End If
st = Timer
Do
DoEvents
Loop While st + 3 > Timer And https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 12
https://www.360docs.net/doc/0618304958.html,m1.Output = Chr(16) + Chr(6)
If https://www.360docs.net/doc/0618304958.html,m1.InBufferCount < 12 Then
comunicating = False
Exit Function
End If
https://www.360docs.net/doc/0618304958.html,m1.Output = Chr(16) + Chr(6)
WriteTable = True
comunicating = False
End Function

PID程序的实现

一般而言,使用PLC进行控制的场合是不需要进行PID编程的,目前PLC中都带有PLC的控制模块,只要对有关的参数进行设置就可以很好的工作了,可谓是“傻瓜式”的控制,这也大大降低了对开发者的要求。但在使用工业板卡的场合,遇到需要进行PID控制的工艺时,如果不是采用组态软件进行开发的话,就必须使用高级语言做出PID的控制程序,这里给出一个最简单的PID控制程序,以对大家有所启发,这里使用的是PID的增量控制式。因为程序比较简单,这里不做进一步的解释,

需要说明的是,这个程序虽然简单,但却有着使用性,稍作修改就可以用于工业实际,当然,仍然由进一步修改的余地,比如进行防积分饱和运算、加入滤波处理等等。代码如下:

Option Explicit
Dim EK1 As Single, EK2 As Single
Dim U As Single
Dim Uk As Single, Uk1 As Single, A As Single, B As Single, C As
Single, Ek As Single
Dim Ti As Integer, Td As Integer, Kp As Integer
Dim SP As Single, PV As Single

Private Sub Timer1_Timer()
Ti = Val(Text1) '读取积分时间值
Td = Val(Text2) '读取微分时间值
Kp = Val(Text3) '读取比例值
SP = Val(Text4) '设定值
Text5.Text = Slider1.Value
PV = Val(Text5) '模拟的反馈值
If Ti = 0 Then
A = Kp * (1 + Td)
Else
A = Kp * (1 + 1 / Ti + Td)
End If
B = Kp * (1 + 2 * Td)
C = Kp * Td
Ek = SP - PV

Uk = Uk1 + A * Ek - B * EK1 + C * EK2
If Int(Uk) <= 0 Then Uk = 0 '对输出进行调理,实际使用时灵活掌握。
If Int(Uk) > 1000 Then Uk = 1000
Uk1 = Uk
EK2 = EK1
EK1 = Ek
Text6.Text = Uk '输出显示

End Sub

相关主题
相关文档
最新文档