找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2571|回复: 1
打印 上一主题 下一主题
收起左侧

VB与松下PLC通信程序学习资料

[复制链接]
跳转到指定楼层
楼主
ID:817370 发表于 2020-9-9 09:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
献给有需要的人

这就是COM口图标。从Private Sub Form_Load()说起,在这个Form_Load()中先检查COM口是否打开。If FP0.PortOpen = True Then FP0.PortOpen = False,这就是若com口是打开的,就先把com口关闭,这样是为了好去调试com口。FP0.CommPort = 1,这个设置com口为1。FP0.Settings = "9600,o,8,1,波特率9600,位数8,停止位1。FP0.InputLen = 0 ,InputLen设为0就是读出缓冲区的所有内容。FP0.OutBufferCount = 0 ,清空发送缓冲区,就是在接收之前清空缓冲区。FP0.InBufferCount = 0,清空接收缓冲区。FP0.PortOpen = True,com口开启。     这就是COM口的通信参数设置。
校验计算程序:
    之前是比较基础的com口参数的设置,这次的校验计算程序是用来进行对传送数据的奇校验或者偶校验,程序上设置的是为偶校验。Function FCS(a$) As String,声明FCS(a$)设置为字符型,在任何模块中都可被调用。b% = 0,设置b%为0。 I% = Len(a$),a$的字符串长度。
    For I = 1 To I%
      b% = b% Xor Asc(Mid(a$, I, 1)),一个FOR循环,根据字符长度开进行循环。Mid(a$, I, 1),把a$的第I位取1个字符。 Asc(Mid(a$, I, 1)),把这个字符转换成Asc码。之后b%与之异或。在松下PLC的通信协议中,在校验中要把每一位的Asc码进行异或求和后生成,所以此程序若有五位,就必须异或五次,把最后的异或求和的数据送入ff$,(ff$ = Hex$(b%)),Hex的作用是把数据转换成16位的数据。
If Len(ff$) = 1 Then
     ff$ = "0" + ff$
这条程序就是检测最后异或求和的数据有几位,等于1的话就是一位,而最后的校验码应该是两位,所以需要ff$ = "0" + ff$。最后FCS = ff$,这就是最后的一步,是所有模块都可以进行调用。
首先我们要在通用声明模块中进行声明:Dim 操作类型 As Integer,将操作类型定义为整数。
Dim Sendata As String,将Sendata定义为字符串。
Sendata = "#RDD0000100001",根据通信协议发送数据(%起始码、01为PLC站号、RD为读取寄存器指令,D0000100001,数据代码D,起始数据编码00001,结束数据编码00001)。
FP0.RThreshold = 13,接收到13个字节数据就立即触发OnComm()事。
Sendata = Sendata + FCS(Sendata) + vbCr,意思是Sendata = #RDD0000100001+调用校验码程序的结果+vbCr(vbCr是回车的意思,回到本行的开头,意思不是特别懂)。
操作类型 = 1,这个后面再说。
FP0.InBufferCount = 0,在发送数据之前清空接收缓冲区。
FP0.OutBufferCount = 0,在发送数据之前清空发送缓冲区。
FP0.Output = Sendata,向PLC发送数据。
Dim Sendata As String ,定义Sendata为字符串。
Dim Devdat1 As String,定义Devdat1为字符串。
If CDbl(Val(Text2.Text)) > 32767 Then: MsgBox ("数值超限!"): Exit Sub,CDbl为把数值转换为双精度浮点数据类型。Val是将字符串数据类型转换为数值型数据类型。32767(2的15开方)是不允许输入的数据超过16位。
Devdat1 = Right("00000000" + Hex(Val(Text2.Text)), 4),Hex就是使数值返回16进制数值。("00000000" + Hex(Val(Text2.Text)),凑成16位数。Right去后面的4位。
Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2),数据的写入格式为先低位后高位。
Devdat1 = Devdat1
FP0.RThreshold = 9,接收9位字符数就触发OnComm()事。
Sendata = "#WDD0000100001" + Devdat1,发送数据的地址+要写入的数据。
操作类型 = 2
FP0.InBufferCount = 0 '清空接收缓冲区
FP0.OutBufferCount = 0 '清空发送缓冲区
FP0.Output = Sendata + FCS(Sendata) + vbCr。
Dim Sendata As String
FP0.RThreshold = 9
Sendata = "#WCSR00011,WCS单触点写入。R0001指令代码+触点编号。1最后的1是触点ON。
操作类型 = 3
FP0.InBufferCount = 0 '清空接收缓冲区
FP0.OutBufferCount = 0 '清空发送缓冲区
FP0.Output = Sendata + FCS(Sendata) + vbCr
Dim Sendata As String
FP0.RThreshold = 9
Sendata = "#WCSR00010",跟第五章一样,只是最后以为是0,0是状态OFF。
操作类型 = 4
FP0.InBufferCount = 0 '清空接收缓冲区
FP0.OutBufferCount = 0 '清空发送缓冲区
FP0.Output = Sendata + FCS(Sendata) + vbCr
Dim Sendata As String
FP0.RThreshold = 10
Sendata = "#RCP1R0001"RCP为读取多触点状态,之后的1为触点编号。R0001为触点代码编号。
操作类型 = 5
FP0.InBufferCount = 0 '清空接收缓冲区
FP0.OutBufferCount = 0 '清空发送缓冲区
FP0.Output = Sendata + FCS(Sendata) + vbCr
COM主程序:
Private Sub FP0_OnComm(),当接收到一定数目的FP0.RThreshold=X,就会触发此COM。
Dim getData As String '
Dim station1
Dim station2
Dim M1data As Integer
If FP0.CommEvent = comEvReceive Then,CommEvent 是判断 MSComm控件的当前状态。 comEvReceive 是收到 Rthreshold 个字符。
getData = FP0.Input ,读取接收缓冲内容。
Select Case 操作类型,选择操作类型。
Case 1,如果是读取DT1.
getData = Mid(getData, 7, 4),读取第7位(包括第七位)的四位,这四位就是触点的数据。
station1 = Right(getData, 2) ,因为之前的四位数据是先低后高,所以这边先取高位。
station2 = Left(getData, 2),取低位。
getData = station1 + station2 ,先高后低。
getData = Val("&H" + getData),十六进制转换为十进制。
Text1.Text = CStr(getData), 显示在Text1里。
Case 2 ,如果是写DT1。
If Mid(getData, 4, 1) = "$" Then                             getDate前面定义就是FP0.input,当接受PLC                         Label1.Caption = "写入成功"                                 发出的数据的第四位为$时,就说明了数据发送
                  Else                                                      成功,否则就是失败的。这里的程序就是就是这样的。
                     Label1.Caption = "写入失败"
                  End If
Case 3 '如果是置位R1
                  If Mid(getData, 4, 1) = "$" Then
                     Label2.Caption = "置位成功"
                  Else
                     Label2.Caption = "置位失败"
                  End If
Case 4 '如果是复位R1
                  If Mid(getData, 4, 1) = "$" Then
                     Label2.Caption = "复位成功"
                  Else
                     Label2.Caption = "复位失败"
                  End If
             Case 5 '如果是读取R1的状态
                  If Mid(getData, 7, 1) = 1 Then
                     Label3.Caption = "ON"
                  Else
                     Label3.Caption = "OFF"
                  End If
      End Select
以上。
从第九章开始就是真正意义上的自动监控程序的学习:
Dim 非实时监控通讯 As Boolean,对非实时监控通信定义为布尔。
Dim 何种非实时监控通讯 As String,何种非实时监控通信定义为字符串。
Dim 实时监控通讯 As Boolean ,实时监控通讯定义为布尔。
Dim j As Integer ,j定义为整型。
Dim Sendata As String ,Sendata定义为字符串。
Dim yuanji As String ,yuanji定义为字符串。
Dim zhuang As String ,zhuang定义为字符串。
Dim devdat As String ,devdat定义为字符串。
Dim setad As String ,setad定义为字符串。
Dim caoxian As Boolean ,caoxian定义为布尔。
Dim awe1 As Integer ,awe1定义为整型。
Dim errT As Boolean ,errT定义为布尔。
在通用声明里对这些变量进行声明。
Private Sub Combo2_Click() ,通讯超时的选择
Timer2.Interval = (Combo2.ListIndex + 1) * 1000 ,检测时间为s,而计时器的单位为ms,所以要乘以1000。ListIndex为项目的索引值,第一个ListIndex等于0,所以必须+ 1。
End Sub
Private Sub Combo1_Click() ,通讯口的选择。
errT = True ,通讯口错误。
Call CommSet ,调用通讯口设置过程。
End Sub
对COM口参数进行设置:
Private Sub CommSet()
    On Error GoTo err1 ,On Error是个错误处理程序,On Error GoTo err1语句就是启动错误处理程序从指定的err1开始。
    If fp0.PortOpen = True Then fp0.PortOpen = False ,如果通讯口已打开,则先关闭通讯口。开始通讯口设置工作。
    fp0.CommPort = Combo1.ListIndex + 1 ,索引值+1就是所选的COM。
    fp0.Settings = "9600,o,8,1"
    fp0.InputLen = 0
    fp0.OutBufferCount = 0
    fp0.InBufferCount = 0
    fp0.PortOpen = True ,打开通讯口。
    errT = False ,不存在错误。
    Exit Sub
err1:
  MsgBox Err.Description ,错误提示。
End Sub
Private Sub Command9_Click()
  setad = UCase(Text3.Text) ,UCase的作用是将小写字母转换为大写字母,Text3.Text为输入的文本。
  setad = Right("0000" + CStr(setad), 4) ,CStr(setad)的作用是将setad转换为字符串型,Right就是去数据右边的4位。
  If setad = "" Then ,""为VB的空字符。
     MsgBox ("请输入元件地址!")
     Text3.SetFocus ,Text3置为焦点。
     Exit Sub
  End If
  非实时监控通讯 = True ,为真。
  何种非实时监控通讯 = "查询"
  Select Case zhuang ,zhuang为置/复位,位状态查询元件标志。
         Case "X" ,zhuang为X。
              Sendata = "#RCP1X" + setad ,%为指令指定的,01为站号,RCP为读取多触点状态,1为触点数目(n=1-8),X为触点代码,setad就是触点编号。下面也是一样的道理。
         Case "Y" ,zhuang为Y。
              Sendata = "#RCP1Y" + setad
         Case "R" ,zhuang为R。
              Sendata = "#RCP1R" + setad
  End Select
End Sub
Private Sub Command8_Click()
  setad = UCase(Text3.Text)
  setad = Right("0000" + CStr(setad), 4)
  If setad = "" Then
     MsgBox ("请输入元件地址!")
     Text3.SetFocus
     Exit Sub
  End If
  非实时监控通讯 = True
  何种非实时监控通讯 = "置位"
  Select Case zhuang
         Case "X"
              Sendata = "#WCSX" + setad + "1" ,WCS为写入单触点状态,setad为触点编号,"1"为触点数据,状态为ON。
         Case "Y"
              Sendata = "#WCSY" + setad + "1"
         Case "R"
              Sendata = "#WCSR" + setad + "1"
  End Select
End Sub
Private Sub Command7_Click()
  setad = UCase(Text3.Text)
  setad = Right("0000" + CStr(setad), 4)
  If setad = "" Then
     MsgBox ("请输入元件地址!")
     Text3.SetFocus
     Exit Sub
  End If
  非实时监控通讯 = True
  何种非实时监控通讯 = "置位"
  Select Case zhuang
         Case "X"
              Sendata = "#WCSX" + setad + "0"
         Case "Y"
              Sendata = "#WCSY" + setad + "0"
         Case "R"
              Sendata = "#WCSR" + setad + "0"
  End Select
End Sub
Private Sub Form_Unload(Cancel As Integer)
End ,End就是退出。
End Sub
Private Sub Option8_Click()
zhuang = "X"
End Sub
Private Sub Option10_Click()
zhuang = "R"
End Sub
Private Sub Command1_Click()
     非实时监控通讯 = True
     Sendata = "#RMR" ,Sendata为发送数据命令,RM为遥控命令,R为PROG到RUN模式。
     何种非实时监控通讯 = "运行"
End Sub
Private Sub Command2_Click()
     非实时监控通讯 = True
     Sendata = "#RMP" ,P为RUN到PROG模式。
     何种非实时监控通讯 = "运行"
End Sub
校验计算程序是用来进行对传送数据的奇校验或者偶校验,程序上设置的是为偶校验。
Function FCS(a$) As String 声明FCS(a$)设置为字符型,在任何模块中都可被调用。
  b% = 0
I% = Len(a$)  ,a$的字符串长度。
  For I = 1 To I% ,一个FOR循环,根据字符长度开进行循环。
      b% = b% Xor Asc(Mid(a$, I, 1)) ,Mid(a$, I, 1),把a$的第I位取1个字符。 Asc(Mid(a$, I, 1)),把这个字符转换成Asc码。之后b%与之异或。
  Next
  ff$ = Hex$(b%)  ,Hex的功能是转换为十六进制数值。
  If Len(ff$) = 1 Then
     ff$ = "0" + ff$
  End If
  FCS = ff$
End Function
Private Sub Command5_Click(index As Integer) ,读或者写。
Dim Devadd As String, Devadd1 As String ,Devadd是输入地址的16位数据,Devadd1是32位。
Dim Devdat1 As String
Dim station1
Dim station2
Dim station3
Dim station4
Dim station5
Dim station6
Dim setad As String, setad1 As String ,setad为输入地址。
非实时监控通讯 = True ,需要非实时监控通讯状态。
setad = Text1.Text ,读取输入的地址。
If setad = "" Then ,如果地址为空则提示。
MsgBox ("请输入元件地址!") ,提示这个。
Text1.SetFocus ,text1控件取得焦点。
Exit Sub ,退出此事件。
End If
Devadd = Right("00000" + CStr(Val(setad)), 5) ,因为其实数据编码是五位,所以寄存器地址为后五位。
Devadd1 = Right("00000" + CStr(Val(Text1.Text) + 1), 5) ,是32位数据的时候需要两个寄存器,分为高十六位和低十六位,其中高十六位在的寄存器地址是低十六位的寄存器地址的+1,所以CStr(Val(Text1.Text) + 1。
If index = 0 Then '如果是点击的是读按钮,index是command5中的数组标识,index = 0就是读取。
何种非实时监控通讯 = "读"
If Option3.Value = True Then ,如果是16位读。
Sendata = "#RDD" + Devadd + Devadd ,读取十六位数据。
Else
Sendata = "#RDD" + Devadd + Devadd1   ,读三十二位数据。
End If
Else ,如果是点击的是写按钮。
何种非实时监控通讯 = "写"
If Option3.Value = True Then
devdat = "#WDD" + Devadd + Devadd ,写入十六位数据。
Else
devdat = "#WDD" + Devadd + Devadd1 ,写入三十二位数据。
End If
If Option1.Value Then ,十进制方式。
If Option4.Value = True Then ,三十二位写入。
If CDbl(Val(Text2.Text)) > 2147483648# Then: MsgBox ("数值超限!"): Exit Sub ,CDbl为转换为双精度浮点型数据。若数值大于2147483648,则数值超限。Text2.Text为写入数值,数值为16进制四位数值,如00A3H。
Devdat1 = Right(("00000000" + Hex(Val(Text2.Text))), 8)
station1 = Right(Devdat1, 4) ,取数据的右四位。
           station2 = Left(Devdat1, 4) ,取数据的左四位。
           station3 = Right(station1, 2) ,右四位数据的右二位。
           station4 = Left(station1, 2) ,右四位数据的左二位。
           station1 = station3 + station4  ,数据的原始格式是左高右低,而PLC读出和写入的数据的格式是左低右高。
           station5 = Right(station2, 2) ,左四位数据的右二位。
           station6 = Left(station2, 2)  ,左四位数据的左二位。
           station2 = station5 + station6
           Devdat1 = station1 + station2
           Sendata = devdat + Devdat1 ,devadd就是DTn,而devadd1就是DTn+1,devdat =起始码+目标站号+#+指令名称+DTn+DTn(DTn+DTn+1),Devdar1是要写入的数据。
            Else  ,单字节写入。
           If CDbl(Val(Text2.Text)) > 32767 Then: MsgBox ("数值超限"): Exit Sub
           Devdat1 = Right("00000000" + Hex(Val(Text2.Text)), 4)         
           Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2)
           Sendata = devdat + Devdat1        
           End If
        If Option4.Value = True Then
           If Val("&H" + Text2.Text) > 2147483648# Then: MsgBox ("数值超限"): Exit Sub ,&H为转换为十进制。例如:&H61=97。
           Devdat1 = Right("00000000" + Text2.Text, 8)
           station1 = Right(Devdat1, 4)
           station2 = Left(Devdat1, 4)
           station3 = Right(station1, 2)
           station4 = Left(station1, 2)
           station1 = station3 + station4
           station5 = Right(station2, 2)
           station6 = Left(station2, 2)
           station2 = station5 + station6
           Devdat1 = station1 + station2
           Sendata = devdat + Devdat1
        Else
           If Val("&H" + Text2.Text) > 32767 Then: MsgBox ("êy?μ3??T£?"): Exit Sub
           Devdat1 = Right("00000000" + Text2.Text, 4)
           Devdat1 = Right(Devdat1, 2) + Left(Devdat1, 2)
           Sendata = devdat + Devdat1
        End If
     End If
  End If
End Sub  
Private Sub Form_Load()
Dim g As Integer
For g = 1 To 10 ,添加通信选择。
     Combo1.AddItem "Com" & Trim$(Str$(g)) ,添加Combo1项目10个。
Next g
For g = 1 To 10
     Combo2.AddItem g  ,添加Combo2项目10个。
Next g
Combo1.ListIndex = 0  ,默认com1口。
Combo2.ListIndex = 0 ,默认通讯超时5秒。
非实时监控通讯 =  False
Option1.Value = True   ,默认选择十进制。
Option3.Value = True   ,默认选择十六位读写方式。
Option10.Value = True  ,默认选择R。
yuanji = "DT" ,默认选择DT。
Timer1.Enabled = True  ,激活定时扫描。
Timer2.Enabled = False  ,通讯超时关闭。
End Sub
Private Sub fp0_OnComm()
Dim GetData As String
Dim k As Integer
Dim asd(3) As Integer
Dim wei(3) As String
Dim gfd As String
Dim xym(15) As String
If fp0.CommEvent = comEvReceive Then ,CommEvent的属性返回的值为comEvReceive时发生了接收事件。
      Timer2.Enabled = False ,PLC有返回数据,定时器关闭。
      Label2.Caption = "通讯正常"
      GetData = fp0.Input ,读取接收区缓冲内容。
      Shape4.BackColor = &HC0& ,通讯状态指示灯为红色。
      If 非实时监控通讯 = True And 实时监控通讯 = False Then ,如果有非实时监控通讯操作并且实时监控通讯处理结束。
      非实时监控通讯 = False ,清楚非实时监控通讯标识。
      Select Case 何种非实时监控通讯
             Case "读"
If Option3.Value = True Then ,16位读。
                        GetData = Mid(GetData, 7, 4)
                        station1 = Right(GetData, 2)
                        station2 = Left(GetData, 2)
                        GetData = station1 + station2
                        If Option2.Value = True Then
                           Text2.Text = CStr(Right(Hex(Val("&H" + GetData)), 4)) ,&H表示括号内为十六进制数据。
                        Else
                           GetData = Val("&H" + GetData)
                           Text2.Text = CStr(GetData)
                        End If
Else '32位读
                           GetData = Mid(GetData, 7, 8) ,读回来的数据的顺序是先低位后高位。
                           station1 = Right(GetData, 4)
                           station2 = Left(GetData, 4)
                           station3 = Right(station1, 2)
                           station4 = Left(station1, 2)
                           station5 = Right(station2, 2)
                           station6 = Left(station2, 2)
                           station1 = station3 + station4
                           station2 = station5 + station6
                           GetData = station1 + station2
                           Dim sdfg As Double
                           sdfg = "&H" + GetData ,字符串+数字=字符串。
                           If Option2.Value = True Then ,如果是以十进制格式读取数据。
                              Text2.Text = Hex(sdfg) ,
                           Else
                              Text2.Text = CStr(sdfg)
                           End If
                      End If
Case "查询"
                     If Mid(GetData, 7, 1) = 1 Then
                        Shape8.BackColor = &HC0&
                     Else
                        Shape8.BackColor = &HE0E0E0
                     End If
End Select
Else
         Select Case j
                Case 0  ,读DT0---DT4。
                     GetData = Mid(GetData, 7, 20) '从GetData变量代表的字符的左侧开始的第七位开始取四个字符赋给GetData
                     Text6 = GetData
                     For k = 0 To 4
                         Text5(k).Text = Val("&H" + Mid(GetData, k * 4 + 3, 2) + Mid(GetData, k * 4 + 1, 2))  'Right的功能是从GetData变量代表的字符的右侧开始取2个字符
                        
                     Next k
                Case 1 '读R0---RF状态
                     GetData = Mid(GetData, 7, 8) '从GetData变量代表的字符的左侧开始的第七位开始取一个字符赋给GetData
                     Text6 = GetData
                     For k = 0 To 7
                         If Mid(GetData, k + 1, 1) = "1" Then
                            Shape3(k).BackColor = &HC0&
                         Else
                            Shape3(k).BackColor = &HE0E0E0
                         End If
                     Next k
Case 2, 3
                     GetData = Mid(GetData, 7, 4) '根据协议,左起第二位开始的八位是需要的数据。取出
                     asd(0) = Val("&H" + Mid(GetData, 1, 2)) '低位寄存器的低八位,并转换为十进制
                     asd(1) = Val("&H" + Mid(GetData, 3, 2)) '低位寄存器的高八位,并转换为十进制
                     For k = 0 To 1
                         wei(k) = dec2bin(asd(k)) '将读取的数据转换成二进制
                     Next k
                     gfd = wei(1) + wei(0)  '将四组的八位二进制合并在一起
                     Text6 = gfd
                     '协议规定返回的PLC是从低位到高位排列,所以先提取出的放在后面
                     '如读D0的双字,那么返回来的顺序是:D0的低八位,D0的高八位,D1的低八位,D1的高八位
                     '如,D0双字节的数=2685674341,它的十六进制=A0142365。那么在读取过程中时PLC返回此数据的顺序为:652314A0
                     For k = 0 To 15
                         xym(k) = Mid(gfd, 16 - k, 1) '读取各位的状态
                         If xym(k) = "1" Then '如果为1,说明相应的位为吸合状态
                            Select Case j
                                   Case 2
                                        Shape1(k).BackColor = &HC0& '如果为读取输入(X)的状态
                                   Case 3
                                        Shape2(k).BackColor = &HC0& '如果为读取输出(Y)的状态
                            End Select
                         Else
                            Select Case j
                                   Case 2
                                        Shape1(k).BackColor = &HE0E0E0 '如果为读取输入(X)的状态
                                   Case 3
                                        Shape2(k).BackColor = &HE0E0E0 '如果为读取输出(Y)的状态
                            End Select
                         End If
                     Next k
Case 4   '读PLC的当前状态
                     GetData = Mid(GetData, 14, 1) '从GetData变量代表的字符的左侧开始的第14位开始取1个字符赋给GetData
                     Text6 = GetData
                     If Val(GetData) Mod 2 = "1" Then
                        Picture1(0).BackColor = &HFF&
                        Picture1(1).BackColor = &H80000005
                     Else
                        Picture1(0).BackColor = &H80000005
                        Picture1(1).BackColor = &HFF&
                     End If
                     j = -1 '计数器清零,开始下一次实时监控循环,下面有一个j=j+1,为了保证清零,所以赋的是-1
           End Select
           j = j + 1 '进行本次循环的下一步通讯
           实时监控通讯 = False '实时监控通讯处理完毕
           Timer1.Enabled = True '打开定时通讯扫描
      End If
End If
End Sub
Private Sub Timer1_Timer() '实时监控
  If errT = True Then '如果通讯口错误
     Label2.Caption = "您的电脑没有此通讯口"
     Exit Sub
  End If
  Shape4.BackColor = &HE0E0E0
  If 非实时监控通讯 = True Then
     Select Case 何种非实时监控通讯
            Case "读"
                 If Option3.Value = True Then '十六进制
                    fp0.RThreshold = 13 '设定产生OnComm事件的接收缓冲区字符数
                 Else
                    fp0.RThreshold = 17 '设定产生OnComm事件的接收缓冲区字符数
                 End If
            Case "查询"
                 fp0.RThreshold = 10 '设定产生OnComm事件的接收缓冲区字符数
            Case "写", "置位", "复位"
                 fp0.RThreshold = 9 '设定产生OnComm事件的接收缓冲区字符数
            Case "运行"
                 fp0.RThreshold = 9 '设定产生OnComm事件的接收缓冲区字符数
     End Select
  Else
     实时监控通讯 = True
     Select Case j '作用:实时监控共需要五次才能完成一个实时监控通讯循环,每次j+1来判断应该发送第几次命令
            Case 0    '读DT0----DT4
                 Sendata = "#RDD0000000004" '根据协议要求发送代码
                 fp0.RThreshold = 29 '设定产生OnComm事件的接收缓冲区字符数
            Case 1    '读R0---RF状态
                 Sendata = "#RCP8R0000R0001R0002R0003R0004R0005R0006R0007"
                 fp0.RThreshold = 17 '设定产生OnComm事件的接收缓冲区字符数
            Case 2    '读输入点状态
                 Sendata = "#RCCX00000000"
                 fp0.RThreshold = 13 '设定产生OnComm事件的接收缓冲区字符数
            Case 3    '读输出点状态
                 Sendata = "#RCCY00000000"
                 fp0.RThreshold = 13 '设定产生OnComm事件的接收缓冲区字符数
            Case 4    '读PLC的当前状态
                 Sendata = "#RT"
                 fp0.RThreshold = 25 '设定产生OnComm事件的接收缓冲区字符数
     End Select
   
  End If
  Sendata = Sendata + FCS(Sendata) + vbCr 'FCS(fs)是调用校验和程序
  fp0.InBufferCount = 0
  fp0.OutBufferCount = 0
  fp0.Output = Sendata

  Timer1.Enabled = False '关闭定时通讯,等待PLC返回数据。fp0_OnComm()事件处理完返回的数据后,再打开定时通讯
  Timer2.Enabled = True '打开与PLC通讯是否正常判断定时器
  l = 0
End Sub
Private Sub Timer2_Timer() '如果发送命令结束后,在设定的通讯超时时间内此定时器仍没有关断
      Label2.Caption = "通讯不正常" '通讯状态指示
     j = 0
     Timer1.Enabled = True '打开定时通讯扫描
End Sub

以上内容word格式下载: VB与松下PLC通信程序学习.docx (83.76 KB, 下载次数: 23)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1006852 发表于 2022-3-7 16:35 | 只看该作者
VB少有人用吗?前一个资料也没有看。这么好的资料没有一个回复的。是不是没有人用上位机联PLC?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表