前言:
最近接触了一个对于 PLC 工控的小我的项目,大略场景是,对方一个茶叶工厂。曾经通过各种设施组成了自动化的工控零碎。并且也让我的一个敌人做了茶园监控和茶园天气环境等的 web 页面展现,然而还没有工控设施的数据显示。
需要:
工控设施曾经连贯到了一台作为上机位的电脑上,所以要获取设施数据。须要在同一局域网上,通过 modbus tcp 申请对方曾经凋谢的端口。拿到数据贮存到数据库,最初 web 界面只用按工夫程序获取数据库的数据。
因为拜访对方电脑须要他们提供受权,所以这里演示就以 modbus 的调试工具,以及前面 PHP 代码申请示例。
工具:
1. Modbus Slave:从机端模仿软件,这里测试能够把他作为服务端,PHP 为客户端就是取该机子的数据。
2. Modbus Poll:主机仿真器,用于测试和调试 Modbus 从设施,这里测试也只是把他当做客户端应用。
3. ModScan32:主机 / 从机模拟程序,当前介绍。
4. MThings:一个国产免费软件,既能够模仿主机设施 又能够模仿从机设备,当前介绍。
工具操作:
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,弹出面板。
留神 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 代码演示:
modbus 类库包下载。
composer require adduc/phpmodbus
编写申请
“03 Read Holding Registers” 函数示例代码。
<?php
/**
* author: bqs
* desc: 申请 modbus 地址
* 公众号:ZERO 开发
*/
require_once 'vendor/adduc/phpmodbus/Phpmodbus/ModbusMaster.php';
// Modbus master UDP
$modbus = new ModbusMaster("127.0.0.1", "TCP");
// Read multiple registers
try {$recData = $modbus->readMultipleRegisters(1, 0, 5);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
var_dump($recData);die;
// Print data in string format
echo PhpType::bytes2string($recData);
?>
环境要求。
1. PHP 的 LAMP 环境曾经搭建结束
2. 能够不必配置虚构域名,间接 localhost 拜访 modubus_tcp_pro.php 文件
3. PHP 版本最好是 5.5,因为 7.0 以上运行会对类的构造函数命名报错
4. PHP5.5 扩大开启了 php_sockets
5. 运行胜利后,返回数据,数组的索引须要计算匹配 modbus slave 的地址名
6. 计算形式:
(索引 -1)/24. readMultipleRegisters 阐明。参数 1:unitId, modbus 设施 ID,参考 slave 的 slave ID 参数 2:reference,地址号,在设施内存中,数据的地址援用,参考 slave 配置的地址参数 3:quantity,线圈,要去设施中读取的数据量,参考 slave 配置的 quantity 5. 申请异样的几种状况。
(1). socket_connect() failedslave 的连贯进行了,须要从新开启。(2). Modbus response error code: 2 (ILLEGAL DATA ADDRESS)
从机设备上数据的内容地址不对,能够依据 slave 的 definition 的参数,报错能够查看 ModbusMaster 类的 responseCode 办法。申请的 quantity 数超过 slave 定义的 quantity 数量也会报内容地址谬误,申请只能小于定义的数量。
7. 对于返回的数组。
如果申请的是 5 个数据,phpmodbus 会返回元素为 10 的数组。如果是 2 个,则返回 4 个元素数组,以此类推。
8. 对于返回数组与 slave 的数据块地址数据对应的形式。
9. 获取设施上指定数据块的理论的数据。
(1). 枚举某数据块下索引对应的标识。
$devicesDataBlock = [
"0" => "weather",
"1" => "water",
"2" => "voice",
"3" => "electric",
"4" => "air"
];
(2). 依据返回数组的过滤出有用的索引,并匹配设施数据标识。理论的数据块索引 = (返回数组的索引 -1)/2 前提处于 2 的不能有余数,所以只须要对后果做判断,残缺代码如下。
<?php
/**
* author: bqs
* desc: 申请 modbus 地址
* 公众号:ZERO 开发
*/
require_once 'vendor/adduc/phpmodbus/Phpmodbus/ModbusMaster.php';
// Modbus master UDP
$modbus = new ModbusMaster("127.0.0.1", "TCP");
// Read multiple registers
try {$recData = $modbus->readMultipleRegisters(1, 0, 5);
}
catch (Exception $e) {
// Print error information if any
echo $modbus;
echo $e;
exit;
}
// 数据库设施的数据形容
$devicesDataBlock = [
"0" => "weather",
"1" => "water",
"2" => "voice",
"3" => "electric",
"4" => "air"
];
$realData = [];
foreach($recData as $key => $value) {$indexs = ($key-1)/2;
if (($key-1)%2 == 0) {$realData[$devicesDataBlock[$indexs]] = $value;
}
}
var_dump($realData);die;
// Print data in string format
echo PhpType::bytes2string($recData);
// 00050000000601030000000A
?>