PHP 通过 Modbus Tcp 实时获取设备数据
前言:
最近接触了一个关于 PLC 工控的小项目,大概场景是,对方一个茶叶工厂。已经通过各种设备组成了自动化的工控系统。并且也让我的一个朋友做了茶园监控和茶园天气环境等的 web 页面展示,但是还没有工控设备的数据显示。
需求:
工控设备已经连接到了一台作为上机位的电脑上,所以要获取设备数据。需要在同一局域网上,通过 modbus tcp 请求对方已经开放的端口。拿到数据储存到数据库,最后 web 界面只用按时间顺序获取数据库的数据。
因为访问对方电脑需要他们提供授权,所以这里演示就以 modbus 的调试工具,以及后面 PHP 代码请求示例。
工具:
\1. Modbus Slave: 从机端模拟软件,这里测试可以把他作为服务端,PHP 为客户端就是取该机子的数据。
\2. Modbus Poll: 主机仿真器,用于测试和调试 Modbus 从设备,这里测试也只是把他当做客户端使用。
\3. ModScan32: 主机/从机模拟程序 ,以后介绍。
\4. MThings: 一个国产免费软件, 既可以模拟主机设备 又可以模拟从机设备,以后介绍。
以上软件,可以扫描下面二维码,输入“modbus 模拟” 获取地址。
工具操作:
一. Modbus Slave
\1. 创建 TCP/IP 连接。
(1). 点击 connection->connection,弹出参数窗口,可以按下面确认。
(2). 配置函数,点击 setup->slave definition,弹出参数窗口,默认 OK 就可以。
(3). 修改某项数据的值,双击对应的框,弹出后修改 OK 就可以。
\2. 从机参数说明:
(1). ID, 机子的设备标识,是 slave definition 的 slave ID
(2). F, 当前节点的函数码,主机获取代码获取设置数据,需要指定的函数。
\3. 查看发送和接收数据明细。
(1). 点击 display,弹出面板。
\4. 注意
modbus slave 每次连接只能维持 10 分钟,可能是没有激活。
一. Modbus Poll
\1. 通过 Tcp 获取从机上的数据。
(1). 连接,点击 connection->connection, 选择 TCP/IP。
(2). 修改为 slave 机子对应的 IP 地址和端口,点击保存。
(3). 连接成功后,查看读写定义,可以按指定 slave 配置修改。
(4). 连接失败,Mbpoll 面板会提示红色字体。面板文字说明如下。
Tx = 4 表示向主站发送数据帧次数,图中为 4 次; Error = 0 表示通讯错误次数,图中为 0 次; ID = 1 表示模拟的 Modbus 子设备的设备地址,图中地址为 1;F = 03 表示所使用的 Modbus 功能码,图中为 03 功能码; SR = 1000ms 表示扫描周期。红字部分,表示当前的错误状态,“No Connection”表示未连接状态。
(5). 查看读写数据。
PHP 代码演示:
\1. modbus 类库包下载。
composer require adduc/phpmodbus
\2. 编写请求 "03 Read Holding Registers"函数示例代码。
\3. 环境要求。
\4. readMultipleRegisters 说明。
参数 1:unitId, modbus 设备 ID,参考 slave 的 slave ID 参数 2:reference, 地址号,在设备内存中,数据的地址引用,参考 slave 配置的地址参数 3:quantity,线圈,要去设备中读取的数据量,参考 slave 配置的 quantity
\5. 请求异常的几种情况。
(1). socket_connect() failed
slave 的连接停止了,需要重新开启。
(2). Modbus response error code: 2 (ILLEGAL DATA ADDRESS)
从机设备上数据的内容地址不对,可以根据 slave 的 definition 的参数,报错可以查看 ModbusMaster 类的 responseCode 方法。
请求的 quantity 数超过 slave 定义的 quantity 数量也会报内容地址错误,请求只能小于定义的数量。
\6. 关于返回的数组。
如果请求的是 5 个数据,phpmodbus 会返回元素为 10 的数组。如果是 2 个,则返回 4 个元素数组,以此类推。
\7. 关于返回数组与 slave 的数据块地址数据对应的方式。
\8. 获取设备上指定数据块的实际的数据。
(1). 枚举某数据块下索引对应的标识。
(2). 根据返回数组的过滤出有用的索引,并匹配设备数据标识。
实际的数据块索引 = (返回数组的索引-1)/2
前提处于 2 的不能有余数,所以只需要对结果做判断,完整代码如下。
评论