目录
一、前言
二、开发前说明
三、效果图
四、安装PHP扩展
五、安装phpModbus类库
六、通信逻辑
七、完整实例
一、前言
使用PHP语言与硬件设备通信交互,并向COM串口发送和接收数据。
前面写了三篇关于PHP与RS235和USB端口通信的文章,可以作为参考,本文介绍PHP怎么使用RS485串口的Modbus-Rut协议与硬件通信。
【PHP】PHP通过串口与硬件通讯,向硬件设备发送数据并接收硬件返回的数据_php串口通信-CSDN博客
【PHP】PHP实现与硬件串口交互,接收硬件发送的实时数据(上)_php 怎么进行串口通讯-CSDN博客
【PHP】PHP实现与硬件串口交互,向硬件设备发送指令数据(下)_c语言esp32,php怎么发送硬件信息-CSDN博客
二、开发前说明
需求:PHP通过COM串口与天平通信,PHP能够向天平发送指令,并接收天平返回的响应信息。
硬件设备:天平。
串口:RS485。
串口传输协议:Modbus-Rut。
指令集:由天平供应商提供。
开发语言:PHP7.4.3。
框架:ThinkPHP5。
三、效果图
四、安装PHP扩展
下载并安装dio扩展,下载地址PECL :: Package :: dio,注意要与使用的PHP版本保持一致,下载后将php_dio.dll文件拷贝到/Extensions/php/php7.4.3nts/ext/目录下,再打开php.ini,删除掉“extension=dio”前面的分号,如果没有则直接添加即可,最后重启Apache
五、安装phpModbus类库
使用composer安装modbus,注意安装前提是PHP ≥ 7.4.0,dio ≥ 0.2.0
由于modbus协议支持TCP/UDP和RTU两种,由于本项目使用的是COM串口,所以使用的是RTU协议,所以需要安装支持Modbus RTUd 类库
composer require fawno/modbus
安装完成之后,会在vendor文件夹里生成fawno/modubs文件夹,表示安装成功。
六、通信逻辑
dio扩展和modbus类库安装完成后,通信的前提就完成了。
由于Modbus RTU协议发送和接收的是十六进制的数据,所以可以根据自己需要对发送和接收的数据进行转码,转成十进制,方便使用。
业务逻辑
① 引用modbus类库
② 实例化
③ 打开COM串口
④ 发送指令
⑤ 接收响应结果
⑥ 对返回的结果进行解析,解析成需要的格式
⑦ 关闭串口
七、完整实例
- 我这里发送的指令是”01 03 00 00 00 02 C4 0B“,使用chr()函数转成十六进制
- 延迟100ms接收响应
- 将返回的结果转换成十六进制格式
- 对返回的结果进行解析,解析成需要的格式,我这里需要的是重量(浮点数)
<?php
namespace app\home\controller;
use think\Controller;
use think\Db;use Fawno\PhpSerial\Config\BaudRates;
use Fawno\PhpSerial\Config\StopBits;
use Fawno\PhpSerial\Config\Parity;
use Fawno\PhpSerial\Config\DataBits;
use Fawno\PhpSerial\SerialConfig;
use Fawno\PhpSerial\SerialDio;
use Fawno\Modbus\ModbusDDS238;
use Fawno\Modbus\ModbusRTU;class Tianpingapi extends Controller
{public function putCommond(){set_time_limit(0);$ret = []; // 返回数组$response = '初始化';include "../vendor/fawno/modbus/autoload.php";$com='COM4'; $baud = '9600'; $data='8'; $stop = '1';try {// 指令 获取当前重量// $commond = "01 03 00 00 00 02 C4 0B";$commond = chr(0x01) . chr(0x03) . chr(0x00) . chr(0x00) . chr(0x00) . chr(0x02) . chr(0xC4) . chr(0x0B);$dds238 = new ModbusDDS238($com);$dds = $dds238->open();if ($dds) {TLog("打开串口:".$com."成功");}else{TLog("打开串口:".$com."失败");TLog(">>>> end <<<<");TLog("\r\n");}// 读取串口数据TLog(">>>> 天平模块 <<<<");TLog(">>>> start <<<<");// 延迟100msusleep(100000);// 发送指令$dds->send($commond);// 接收设备的响应$response = $dds238->read();if (!empty($response)) {// 转成十六进制,并且字母小写$hex = strtolower(bin2hex($response));TLog("读取串口".$com."的响应结果成功:十六进制【".$hex."】");// 响应结果处理,返回重量$wei = $this->responseParse($hex);$log = "接收:".$hex."。重量:".$wei. "\r\n";// 响应结果解析成功TLog($log);$ret['code'] = '200';$ret['data'] = $wei;}else{TLog("读取串口".$com."的响应结果失败"."\r\n");$ret['code'] = '110';$ret['data'] = 99999;}TLog(">>>> end <<<<");TLog("\r\n"."-------------------------------------");// 关闭串口$dds238->close();} catch (Exception $e) {$ret['code'] = '110';$ret['message'] = $e->getMessage();}return $ret;}}