65.9K
CodeProject 正在变化。 阅读更多。
Home

Omron PLC 串行接口

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (22投票s)

2011 年 4 月 30 日

CPOL

6分钟阅读

viewsIcon

191684

downloadIcon

22381

超越欧姆龙 OCX OPC 组件,使用用户友好的 .NET 类来连接欧姆龙 PLC 系列

引言

如果您厌倦了使用一些复杂的、非实时且迫使您连接欧姆龙 PLC 系列的 COM/COM+ 组件(就像我一样;D),并对简单易懂、开源、真正的实时 .NET 对象感兴趣,那么您选择对了文章。

本文介绍了一种纯代码实现的主机链路协议,您可以轻松地将其添加到您的项目中,确保可靠安全的 RS232/485 PC-PLC 通信。

背景

面向对象编程和在依赖硬件的实时系统中进行精确实现是我曾经在 DeltaDTB PID 控制器 中完成的。您可以从 这里 参考。

Using the Code

1. 接线

毫无疑问,在阅读了欧姆龙提供的关于主机链路属性的 PDF 文件后,最令人困惑的事情就是物理连接(电缆接线)。首次阅读后,我尝试了一些接线,希望能成功,但尽管我尽了最大努力,也没有成功。最后,经典的 RS232 (2-2, 3-3, 5-5) 才是正确的连接方式(请看下图)。

OmronPLCHostLinkProtocol/Omron-Wiring.PNG

2. 通信协议

2.1 基本定义

  • 主机

    在主机链路通信协议中,主机(请注意,欧姆龙称其 PLC 系列为“计算机”,请勿混淆!)拥有切换优先级。但对于点对点连接(例如,您通过 RS232 物理层直接连接到 PLC),这一点不是很重要。但是,如果您非常在意,根据欧姆龙的定义,“因此,主机和主机链路系统之间的数据传输是在计算机向主机链路系统中的 PC 发送命令时发起的。”(第 3-2 部分,通信协议,第 62 页),运行应用程序的 PC 被假定为主机。

  • 在一次传输中的一组数据称为一个块。

  • 命令块

    从主机发送到主机链路系统的数据块称为命令块。

  • 响应块

    从主机链路系统发送到计算机的块称为响应块。

  • 多路通信与单链路通信

    在多路通信系统中,每个块都以单元号和报头开始,以帧校验和 (FCS) 代码和终止符(* 和 CR)结束。然而,在单链路系统中,每个块仅以报头开始,仅以终止符结束。

  • 终止

    命令块中的终止符使 PC 能够发送响应。响应块中的终止符使主机能够发送下一个命令。

2.2 块格式

下面是一个正式数据块的示意图。一个块通常由一个称为帧的单元组成,但长数据块(超过 131 个字符)必须在传输前分成多个帧。在多路系统中,第一个帧最多可以包含 131 个字符,后续帧最多可以包含 128 个字符。

然而,在单链路系统中,每个帧(包括第一个)最多包含 128 个字符。当多路系统中的块超过 131 个字符,或单链路系统中的块超过 128 个字符时,数据必须分成多个帧。在这种情况下,开始和中间的块以分隔符 (CR) 结束,而不是以终止符 (* CR) 结束。

OmronPLCHostLinkProtocol/Omron-DataBlock.PNG

注意:在此项目中,假定使用的是多路系统,因此,在请求读/写时会自动插入 "@" 和单元号。

2.2.1 多路系统中包含多个帧的块格式

第一个帧(131 个字符或更少)

OmronPLCHostLinkProtocol/Omron-Block-00.PNG

中间帧(128 个字符或更少)

OmronPLCHostLinkProtocol/Omron-Block-01.PNG

最后一个帧(128 个字符或更少)

OmronPLCHostLinkProtocol/Omron-Block-02.PNG

2.3 发送命令

要从计算机(主机)发送包含多个帧的命令块,首先只发送块中的第一个帧。我们必须等到收到 PC 发送回来的分隔符后,主机才能发送下一个帧。

注意:对于任何写入命令,请勿将单个字的数据分成不同的帧。

OmronPLCHostLinkProtocol/Omron-Sending.PNG

最佳使用场景是当您尝试连续写入寄存器中的长数据流时(尽管我不建议这样做)。

...
Do
    Do 
        str_in = str_in & Link.ReadExisting
    Loop While ((str_in.Length < length_predicted) And _
	((DateAndTime.Now.Ticks - tmr_indicator) < lng_length))
    ....
    'Checking FCS code
    'Checking PLC Response code (No Command Error)
    ...    
    'Assume we're waiting for frame(s)
    'The matter that must be checked is the penultimate and the last
    'character received from PLC.
    if mid$(str_in,str_int.length - 1,1)<>"*" then 	'Means some frame(s) 
						'are ready to be received
        'First Process Data 
        'Clear RS232 Input Buffer
        str_out = Link.readExisting
        'str_out = ""
        link.Write(vbCr)'Indicates Host Computer is ready to receive data
        ...
    end if
    ...
Loop While loop_condition
...

2.4 接收命令

要从 PC 接收包含多个帧的响应块,主机必须在收到 PC 发送来的分隔符后,向 PC 发送回车符(分隔符)。这使得 PC 能够发送下一个帧。

OmronPLCHostLinkProtocol/Omron-receiving.PNG

其明显的用途是在 Read 方法中,例如,当用户要求读取超过 30 个连续寄存器时。在构建指示用户请求地址和寄存器数量的 string 后,我们进入一个循环等待 PLC 的响应。不要忘记将请求的数量保存在一个变量中。

Dim loop_count As Integer = 0, count_predicted As Integer = 0, 
_As Long = 0, tmr_indicator As Long = 0, 
_As Integer = 0
Dim str_in As String = "", str_in_final As String = "" 
str_in = Link.ReadExisting()
str_in = "" 
Link.Write(str_out)
Do 
    str_in = "" 
    count_predicted = IIf(count > 30, 30, count)
    If loop_count = 0 Then
        If count_predicted = count Then 
            length_predicted = count_predicted * 4 + 11
        Else 
            length_predicted = count_predicted * 4 + 10
        End If 
    Else
        If count_predicted = count Then 
            length_predicted = count_predicted * 4 + 4
        Else 
            length_predicted = count_predicted * 4 + 3
        End If
    End If 
    lng_length = (length_predicted * ByteTime * 1000) + delay_ms
    lng_length *= TimeSpan.TicksPerMillisecond
    tmr_indicator = DateAndTime.Now.Ticks
    
    Do 
        str_in = str_in & Link.ReadExisting
    Loop While ((str_in.Length < length_predicted) And _
	((DateAndTime.Now.Ticks - tmr_indicator) < lng_length))
    
    If ((loop_count > 0) And (str_in.Length < length_predicted)) _
	Then Throw New OmronException("Error in Data line, Data corrupted!")
    
    If loop_count = 0 Then 'Indicates first frame
    
        p_response = Hex2Int(Mid$(str_in, 6, 2))
    
        If Mid$(str_in, str_in.Length, 1) <> vbCr Then _
	Throw New OmronException("Error in Data line, Data corrupted!")
    
        If Not (FCSCode_Get(str_in)) Then Throw New OmronException_
	("Comminucation Error, Please check the line!")If p_response <> _
	Omron_Response_Code.Command_Completed_Normally Then _
	Throw New OmronException(Response(p_response)(0))
        
        If count_predicted = count Then 'One block contains the whole response 
            str_in_final = str_in_final & Mid$(str_in, 8, str_in.Length - 11)
        Else 'It's the first block of a sequence of response blocks 
            str_in_final = str_in_final & Mid$(str_in, 8, str_in.Length - 10)
        End If
    Else
        If count_predicted = count Then 'Indicates last frame 
            str_in_final = str_in_final & Mid$(str_in, 1, str_in.Length - 4)
        Else 'Indicates intermediate frame 
            str_in_final = str_in_final & Mid$(str_in, 1, str_in.Length - 3)
        End If
    End If 
    
    str_in = Link.ReadExisting
    if count_predicted < count then Link.Write(vbCr)
    str_in = "" 
    
    count = IIf(count - 30 > 0, count - 30, 0)
    loop_count += 1

Loop While count > 0 

2.5 数据表示

单元地址、寄存器地址和要读取的寄存器数量必须以十进制格式表示;要读取/写入的寄存器内容必须以十六进制格式表示;布尔值表示为“1”(ASCII 49 十进制)(真)和“0”(ASCII 48 十进制)(假)。

2.6 帧校验和 (FCS) 计算

帧校验和是 8 位数据,转换为两个 ASCII 字符。8 位数据是通过对帧中的每个字符(从第一个字符到该帧文本的最后一个字符)进行异或 (EXCLUSIVE OR) 运算得到的。

OmronPLCHostLinkProtocol/Omron-FCS.PNG

Dim [xor] As Integer = IIf(is_last, 0, 64) '@ascii code 
For I As Integer = 1 To Message.Length - 1
    [xor] = [xor] Xor Convert.ToInt32(Convert.ToChar(Message.Substring(I, 1)))
Next 
Return ([String].Format("{0:X}",[xor]))

上面提到了 FCS 生成器的代码片段。

3. 命令级别

第 60 至 62 页的表格提供了主机链路单元可用的命令和响应、命令级别以及它们适用的模式。命令和响应格式的详细信息可在欧姆龙文档的第 4 部分命令与响应中找到。

使用演示,一步一步

3.1 运行程序

OmronPLCHostLinkProtocol/omron-000.PNG

3.2 检查是否连接了 PLC

OmronPLCHostLinkProtocol/omron-001.PNG

程序未能找到任何 PLC(PLC 无响应)。

OmronPLCHostLinkProtocol/omron-002.PNG

程序找到 PLC(收到响应)。

3.3 读取 PLC 状态和错误

OmronPLCHostLinkProtocol/omron-003.PNG

3.4 从 PLC 读取 30 个顺序寄存器

OmronPLCHostLinkProtocol/omron-004.PNG

致谢

我很感激能感谢 Kamalaldin Farzaneh 教授,他不仅是我的导师,也是我的老师,他让我跌倒了又重新站起来。

历史

  • 创建时间:2011 年 4 月 27 日星期三
  • 首次发布:2011 年 4 月 30 日星期六
  • 更新:2011 年 5 月 3 日星期二
  • 更新:2011 年 7 月 24 日星期日,添加了 Labview 7.0 实现
© . All rights reserved.