• «
  • 1
  • 2
  • »
  • Pages: 1/2     Go
dujiang100
我是一只小小鸟
级别: 家园常客
精华主题: 0
发帖数量: 440 个
工控威望: 642 点
下载积分: 1895 分
在线时间: 243(小时)
注册时间: 2011-03-11
最后登录: 2023-03-27
查看dujiang100的 主题 / 回贴
楼主  发表于: 2016-03-23 17:29
   最近在研究VB跟欧姆龙CP1H的通信.了解到可以用串口进行HOSTLINK通信,还可以用以太网进行FANS通信.CP1H没有网口所以不可以用FANS通信吗?串口通信情况下,PLC处于运行时写入不了数据,只有当PLC是监控状态时才能写入.这怎么能达到随时写入的目的呢?
本帖最近评分记录:
  • 下载积分:+1(56071988)
    tkggtdkjpl
    工欲善其事,必先利其器!
    级别: 网络英雄

    精华主题: 1 篇
    发帖数量: 3412 个
    工控威望: 20948 点
    下载积分: 20426 分
    在线时间: 1700(小时)
    注册时间: 2010-01-03
    最后登录: 2024-04-20
    查看tkggtdkjpl的 主题 / 回贴
    1楼  发表于: 2016-03-23 21:29
    将PLC的运行模式改为监控模式就行了!
    本帖最近评分记录:
  • 下载积分:+1(dujiang100) 真诚感谢!
  • 自动化单机,生产线,项目编程调试!
    dujiang100
    我是一只小小鸟
    级别: 家园常客
    精华主题: 0
    发帖数量: 440 个
    工控威望: 642 点
    下载积分: 1895 分
    在线时间: 243(小时)
    注册时间: 2011-03-11
    最后登录: 2023-03-27
    查看dujiang100的 主题 / 回贴
    2楼  发表于: 2016-03-26 09:45
    研究了几天,终于明白,FINS协议也可以通过串口和PLC通信上
    xyzenter
    活在当下,顺其自然
    级别: 略有小成
    精华主题: 0
    发帖数量: 135 个
    工控威望: 266 点
    下载积分: 2080 分
    在线时间: 108(小时)
    注册时间: 2014-04-09
    最后登录: 2021-04-13
    查看xyzenter的 主题 / 回贴
    3楼  发表于: 2016-03-28 15:19
          FINS通讯命令,0401可以让PLC进入运行/监控模式,0402可以让PLC进入停止模式。
          实测用0402让PLC停止后还可以用0101和0102对DM区进行读写。
          另:串口的hostlink模式FINS命令只能上位机控制PLC,PLC无法主动发数据给上位机。通过看w227文件,发现FINS帧格式自由度比较高,理论上来讲可以通过修改帧里面的命令符进行PLC通过串口对上位机发送数据,就好像用以太网发送一样。但是欧姆龙PLC说明书里面并没这方面的介绍。目前来说,PLC通过串口主动发数据给上位机发送数据要用无协议通讯。但是无协议通讯的话上位机无法控制PLC的开关状态。小弟刚学欧姆龙通讯,好多东西还不懂,望论坛各位前辈不吝赐教。
    dujiang100
    我是一只小小鸟
    级别: 家园常客
    精华主题: 0
    发帖数量: 440 个
    工控威望: 642 点
    下载积分: 1895 分
    在线时间: 243(小时)
    注册时间: 2011-03-11
    最后登录: 2023-03-27
    查看dujiang100的 主题 / 回贴
    4楼  发表于: 2016-04-01 10:16
    不用PLC发,上位机不断的读取就可以了.FINS协议是最好的.在运行时可以对PLC进行读,写操作.HOSTLINK在PLC运行时可以读,但要写入必须把PLC改成监控模式,太烦.
    mylinden
    工控闲人
    级别: 探索解密
    精华主题: 0
    发帖数量: 102 个
    工控威望: 196 点
    下载积分: 3026 分
    在线时间: 489(小时)
    注册时间: 2012-12-16
    最后登录: 2024-01-04
    查看mylinden的 主题 / 回贴
    5楼  发表于: 2016-04-03 23:39
    可以用FINS tcp/ip
    zhou5245
    级别: 探索解密
    精华主题: 0
    发帖数量: 54 个
    工控威望: 177 点
    下载积分: 16715 分
    在线时间: 180(小时)
    注册时间: 2012-02-23
    最后登录: 2024-01-02
    查看zhou5245的 主题 / 回贴
    6楼  发表于: 2016-04-06 22:02
    Use for Fins TCP/IP.
    shuangyu
    工控行业呆的越久越迷茫.......懂得多?少?......
    级别: 家园常客
    精华主题: 0
    发帖数量: 343 个
    工控威望: 890 点
    下载积分: 1081 分
    在线时间: 114(小时)
    注册时间: 2009-08-04
    最后登录: 2018-03-10
    查看shuangyu的 主题 / 回贴
    7楼  发表于: 2016-04-13 18:17
    Public Class OmronFins
        Dim WithEvents OmronPLC As New System.IO.Ports.SerialPort
        Dim WithEvents T1 As New Timer
        Dim MLog As New MyFB.RunErrLog


        ''' <summary>
        ''' PLC返回字符
        ''' </summary>
        ''' <remarks></remarks>
        Dim PLCRtString As String

        ''' <summary>
        ''' =True 等待RS返回信息
        ''' </summary>
        ''' <remarks></remarks>
        Dim PLCBusyBit As Boolean = False
        Dim PLCCommd As Integer = 0

        Dim RtValue(19) As String
        Dim RtErrValue(19) As String


        Sub RS232PortSet(ByVal PortNum As Integer)

            Try
                With OmronPLC
                    .BaudRate = 38400
                    .StopBits = 2
                    .DataBits = 7
                    .Parity = IO.Ports.Parity.Even
                    .PortName = "COM" & PortNum
                    .ReceivedBytesThreshold = 1
                End With

                If OmronPLC.IsOpen = False Then
                    OmronPLC.Open()
                End If
            Catch ex As Exception
                MLog.LogErrWrite(ex.ToString)
            End Try



        End Sub

        Sub RS232PortClose()
            If OmronPLC.IsOpen = True Then
                OmronPLC.Close()
            End If
        End Sub

        Sub RS232SendMsg(ByVal SendString As String)
            Dim LenNum As Integer
            LenNum = SendString.Length
            If OmronPLC.IsOpen = True Then
                OmronPLC.Write(SendString)
            Else
                PLCBusyBit = False
            End If

        End Sub



        ''' <summary>
        ''' 20150525
        ''' Fins通讯计算校验码
        ''' </summary>
        ''' <param name="Value">传入需要校验内容</param>
        ''' <returns>返回Fins校验值</returns>
        ''' <remarks></remarks>
        Public Function FinsFcsCheck(ByVal Value As String) As String

            Dim CheckValue As Integer
            Dim CheckHex As String

            For i As Integer = 1 To Value.Length
                CheckValue = Asc(Mid(Value, i, 1)) Xor CheckValue
            Next
            CheckHex = Hex(CheckValue)
            If CheckHex.Length < 2 Then
                CheckHex = "0" & CheckHex
            End If

        
            Return CheckHex


        End Function
        ''' <summary>
        ''' 20150526
        ''' 写单个PLC值函数
        '''
        ''' </summary>
        ''' <param name="AddName"></param>
        ''' <param name="Value"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function SetValue(ByVal AddName As String, ByVal AddNum As Integer, ByVal Value As Integer) As Integer

            Dim AddNumHexLen As Integer '地址16进制长度
            Dim HexAddNum As String     '地址值转到16进制
            Dim HCode As String = "@00FA000000000" '通讯表头
            Dim CommandCode As String = "0102"    '通讯命令代码
            Dim MemoryAreaCode As String          'PLC内存功能码
            Dim BitNum As String = "00"           '位写入需要写数值 0-15;字写如=0
            Dim WriteNum As String = "0001"        '写PLC地址个数;单个写入=0001
            Dim HexValue As String                '写入数值转换为16进制
            Dim FCSString As String               '需要校验的字符串
            Dim FCSValue As String                '命令校验码
            Dim EndCode As String = "*" & vbCr    '结束码
            Dim SenCode As String                 '发送到PLC字符串
            '*************************************************************************
            '修改版本20150526 新建
            '写入数值到D
            '通讯发送命令
            'HCode & CommandCode & MemoryAreaCode  & HEXADDNum & BitNum & WriteNum & Value & FCS & EndCode
            '*************************************************************************


            Try
                If PLCBusyBit = False And OmronPLC.IsOpen Then
                    PLCCommd = 1
                    PLCBusyBit = True
                    '选择写入PLC地址类型
                    Select Case AddName
                        Case "D"
                            MemoryAreaCode = "82"
                        Case Else
                            Return 1000
                            Exit Function
                    End Select


                    '写入地址转换为HEX,计算长度是否=4;长度不够补满
                    HexAddNum = Hex(AddNum)
                    AddNumHexLen = HexAddNum.Length
                    Select Case AddNumHexLen
                        Case 1
                            HexAddNum = "000" & HexAddNum
                        Case 2
                            HexAddNum = "00" & HexAddNum
                        Case 3
                            HexAddNum = "0" & HexAddNum
                        Case 4
                            HexAddNum = HexAddNum
                        Case Else
                            Return 1001
                            Exit Function
                    End Select

                    '写入数值转换位16进制,计算长度=4;长度不够布满
                    HexValue = Hex(Value)
                    Select Case HexValue.Length
                        Case 1
                            HexValue = "000" & HexValue
                        Case 2
                            HexValue = "00" & HexValue
                        Case 3
                            HexValue = "0" & HexValue
                        Case 4
                            HexValue = HexValue
                        Case Else
                            Return 1002
                            Exit Function
                    End Select

                    FCSString = HCode & CommandCode & MemoryAreaCode & HexAddNum & BitNum & WriteNum & HexValue

                    FCSValue = FinsFcsCheck(FCSString)

                    SenCode = FCSString & FCSValue & EndCode
                    RS232SendMsg(SenCode)
                    ' Threading.Thread.Sleep(10)
                    '***************************************************
                    '20150608 返回结果处理

                    Dim StartTick As Integer
                    StartTick = Environment.TickCount
                    Do
                        If (Environment.TickCount - StartTick) > 1500 Then
                            '超时报警
                            PLCBusyBit = False
                            Return 9001
                            Exit Do
                        End If

                        If PLCBusyBit = False Then

                            Exit Do
                        End If
                        Application.DoEvents()
                    Loop

                    If RtErrValue(0) = "1" Then
                        Return 1
                    Else
                        '未知错误报警
                        Return 9002
                    End If
                Else

                    '通讯BUSY
                    Return 9003
                End If
            Catch ex As Exception
                ' MsgBox(ex.Message)
                MLog.LogErrWrite(ex.ToString)
            End Try




        End Function

        Public Function GetValue(ByVal AddName As String, ByVal AddNum As Integer, ByRef RtV As Integer) As Integer

            Dim AddNumHexLen As Integer '地址16进制长度
            Dim HexAddNum As String     '地址值转到16进制
            Dim HCode As String = "@00FA000000000" '通讯表头
            Dim CommandCode As String = "0101"    '通讯命令代码
            Dim MemoryAreaCode As String          'PLC内存功能码
            Dim BitNum As String = "00"           '位读取需要写数值 0-15;字读入=0
            Dim ReadNum As String = "0001"        '读PLC地址个数;单个写入=0001
            'Dim HexValue As String                '写入数值转换为16进制
            Dim FCSString As String               '需要校验的字符串
            Dim FCSValue As String                '命令校验码
            Dim EndCode As String = "*" & vbCr    '结束码
            Dim SenCode As String                 '发送到PLC字符串
            '*************************************************************************
            '修改版本2015703 新建
            '读D数值
            '通讯发送命令
            'HCode & CommandCode & MemoryAreaCode  & HEXADDNum & BitNum & ReadNum  & FCS & EndCode
            '*************************************************************************


            Try
                If PLCBusyBit = False And OmronPLC.IsOpen Then
                    PLCCommd = 1
                    PLCBusyBit = True
                    '选择读PLC地址类型
                    Select Case AddName
                        Case "D"
                            MemoryAreaCode = "82"
                        Case Else
                            Return 1000
                            Exit Function
                    End Select


                    '读地址转换为HEX,计算长度是否=4;长度不够补满
                    HexAddNum = Hex(AddNum)
                    AddNumHexLen = HexAddNum.Length
                    Select Case AddNumHexLen
                        Case 1
                            HexAddNum = "000" & HexAddNum
                        Case 2
                            HexAddNum = "00" & HexAddNum
                        Case 3
                            HexAddNum = "0" & HexAddNum
                        Case 4
                            HexAddNum = HexAddNum
                        Case Else
                            Return 1001
                            Exit Function
                    End Select



                    FCSString = HCode & CommandCode & MemoryAreaCode & HexAddNum & BitNum & ReadNum

                    FCSValue = FinsFcsCheck(FCSString)

                    SenCode = FCSString & FCSValue & EndCode
                    RS232SendMsg(SenCode)
                    ' Threading.Thread.Sleep(10)
                    '***************************************************
                    '20150608 返回结果处理

                    Dim StartTick As Integer
                    StartTick = Environment.TickCount
                    Do
                        If (Environment.TickCount - StartTick) > 1500 Then
                            '超时报警
                            PLCBusyBit = False
                            Return 9001
                            Exit Do
                        End If

                        If PLCBusyBit = False Then

                            Exit Do
                        End If
                        Application.DoEvents()
                    Loop

                    If RtErrValue(0) = "1" Then
                        RtV = Convert.ToInt32(RtValue(0), 16)
                        Return 1
                    Else
                        '未知错误报警
                        Return 9002
                    End If
                Else

                    '通讯BUSY
                    Return 9003
                End If
            Catch ex As Exception
                ' MsgBox(ex.Message)
                MLog.LogErrWrite(ex.ToString)
            End Try




        End Function

        Private Sub OmronPLC_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles OmronPLC.DataReceived
            Threading.Thread.Sleep(100)

            Dim ReadString As String
            If OmronPLC.IsOpen = True Then
                ReadString = OmronPLC.ReadExisting
                Call ReslutCount(ReadString)
            End If


            PLCBusyBit = False

        End Sub

        Sub ReslutCount(ByVal InputS As String)
            Dim FcsRead As String = String.Empty  '返回校验码
            Dim FcsCount As String = String.Empty '计算出校验码
            Dim RtCommand As String = String.Empty '返回命令
            Dim RtMsg As String = String.Empty '返回报警代码
            Dim OKMsg As String = "0000"        '返回正确代码
            Try
                If InputS.Length >= 25 Then
                    If Mid(Microsoft.VisualBasic.Right(InputS, 2), 1, 1) = "*" Then
                        PLCRtString = Mid(InputS, 1, InputS.Length - 4)
                        FcsRead = Mid(InputS, InputS.Length - 3, 2)
                        FcsCount = FinsFcsCheck(PLCRtString)
                        RtCommand = Microsoft.VisualBasic.Mid(PLCRtString, 16, 4)
                    End If

                    If FcsCount = FcsRead Then

                        Select Case RtCommand
                            Case "0101"
                                RtMsg = Microsoft.VisualBasic.Mid(PLCRtString, 20, 4)
                                If RtMsg = OKMsg Then
                                    '=1写入PLC值正常
                                    RtValue(0) = Microsoft.VisualBasic.Mid(PLCRtString, 24, 4)
                                    RtErrValue(0) = "1"
                                    Exit Sub
                                End If

                            Case "0102"
                                RtMsg = Microsoft.VisualBasic.Mid(PLCRtString, 20, 4)
                                If RtMsg = OKMsg Then
                                    '=1写入PLC值正常
                                    RtErrValue(0) = "1"
                                    Exit Sub
                                End If
                            Case Else
                                '不能识别通讯命令
                                RtErrValue(0) = "9002"
                                Exit Sub

                        End Select






                    Else
                        '返回校验码不对报警
                        RtErrValue(0) = "9001"
                    End If




                Else
                    '返回字符串长度不够报警
                    RtErrValue(0) = "9000"

                End If
            Catch ex As Exception
                MLog.LogErrWrite(ex.ToString)
            End Try
          



        End Sub

        Sub ResetErr()
            Try
                If OmronPLC.IsOpen = True Then
                    OmronPLC.Close()
                End If


                If OmronPLC.IsOpen = False Then
                    OmronPLC.Open()
                End If

                PLCBusyBit = False
            Catch ex As Exception
                MLog.LogErrWrite(ex.ToString)
                MsgBox(ex.Message)
            End Try

        End Sub


    End Class
    本帖最近评分记录:
  • 下载积分:+1(吃个鸭梨) 热心助人!
  • 下载积分:+5(dujiang100) 热心助人!
    shuangyu
    工控行业呆的越久越迷茫.......懂得多?少?......
    级别: 家园常客
    精华主题: 0
    发帖数量: 343 个
    工控威望: 890 点
    下载积分: 1081 分
    在线时间: 114(小时)
    注册时间: 2009-08-04
    最后登录: 2018-03-10
    查看shuangyu的 主题 / 回贴
    8楼  发表于: 2016-04-13 18:20
    2015年一个项目写的 工控机 与OMRON CP1H串口通讯, 使用FAINS 能够稳定的读写数据;
    本帖最近评分记录:
  • 下载积分:+1(oahz55) 热心助人!
  • 下载积分:+1(静水磐石) 厉害
    xyzenter
    活在当下,顺其自然
    级别: 略有小成
    精华主题: 0
    发帖数量: 135 个
    工控威望: 266 点
    下载积分: 2080 分
    在线时间: 108(小时)
    注册时间: 2014-04-09
    最后登录: 2021-04-13
    查看xyzenter的 主题 / 回贴
    9楼  发表于: 2016-04-14 11:32
          如果用HostLink通讯,FINS指令,上位机要等待PLC某些步骤准备好,就要上位机监控PLC某位是否是设定值,那就需要不断循环地发读指令,这时候串口一直在工作,上位机程序一直调用串口函数,这样会显得很繁忙,整个程序的资源都被串口收发给占用了,程序经常处在假死状态。这样的程序显然是有很大缺陷的。
          最好的解决办法当然是用中断来代替循环等待。然而,FINS指令无法让PLC主动发送就绪信号,无法提供这个中断。哪位高手有办法解决这个问题?
    shuangyu
    工控行业呆的越久越迷茫.......懂得多?少?......
    级别: 家园常客
    精华主题: 0
    发帖数量: 343 个
    工控威望: 890 点
    下载积分: 1081 分
    在线时间: 114(小时)
    注册时间: 2009-08-04
    最后登录: 2018-03-10
    查看shuangyu的 主题 / 回贴
    10楼  发表于: 2016-04-14 23:20
    线程 批量读取
    dujiang100
    我是一只小小鸟
    级别: 家园常客
    精华主题: 0
    发帖数量: 440 个
    工控威望: 642 点
    下载积分: 1895 分
    在线时间: 243(小时)
    注册时间: 2011-03-11
    最后登录: 2023-03-27
    查看dujiang100的 主题 / 回贴
    11楼  发表于: 2016-04-21 16:47
    然而VB6是单线程的.
    • «
    • 1
    • 2
    • »
    • Pages: 1/2     Go