前言:

最近接触了一个对于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?>