php实现modbus
PHP 实现 Modbus 通信
Modbus 是一种工业通信协议,常用于设备间的数据交换。PHP 可以通过 TCP/IP 或串口(RTU)与 Modbus 设备通信。
Modbus TCP/IP 实现
使用 PHP 的 socket 函数与 Modbus TCP 设备通信:
$host = '192.168.1.1'; // Modbus 设备 IP
$port = 502; // Modbus 默认端口
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $host, $port);
// 构建 Modbus 请求帧 (读取保持寄存器)
$transactionId = 1;
$unitId = 1;
$functionCode = 3; // 读取保持寄存器
$startAddress = 0;
$quantity = 2;
$data = pack('nnnn', $transactionId, 0, 6, $unitId);
$data .= pack('Cnn', $functionCode, $startAddress, $quantity);
socket_write($socket, $data, strlen($data));
$response = socket_read($socket, 1024);
socket_close($socket);
// 解析响应
if ($response) {
$data = unpack('ntransactionId/nprotocolId/nlength/CunitId/CfunctionCode/CbyteCount', $response);
$values = unpack('n*', substr($response, 9));
print_r($values);
}
Modbus RTU (串口) 实现
对于串口通信,需要使用 PHP 扩展或外部工具:
- 安装
php-serial扩展或使用exec()调用外部程序 - 通过串口发送 Modbus RTU 帧
// 使用 php-serial 示例
require_once 'PhpSerial.php';
$serial = new PhpSerial;
$serial->deviceSet('/dev/ttyUSB0');
$serial->confBaudRate(9600);
$serial->confParity('none');
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->deviceOpen();
// 构建 RTU 帧 (读取输入寄存器)
$unitId = 1;
$functionCode = 4;
$startAddress = 0;
$quantity = 2;
$data = pack('Cnn', $unitId, $functionCode, $startAddress, $quantity);
$crc = crc16($data);
$frame = $data . pack('v', $crc);
$serial->sendMessage($frame);
$response = $serial->readPort();
$serial->deviceClose();
// CRC16 计算函数
function crc16($data) {
$crc = 0xFFFF;
for ($i = 0; $i < strlen($data); $i++) {
$crc ^= ord($data[$i]);
for ($j = 0; $j < 8; $j++) {
if ($crc & 0x0001) {
$crc = ($crc >> 1) ^ 0xA001;
} else {
$crc >>= 1;
}
}
}
return $crc;
}
使用第三方库
推荐使用成熟的 PHP Modbus 库简化开发:
-
Adduc/PhpModbus:
require 'vendor/autoload.php'; use Adduc\PhpModbus\ModbusMaster; $modbus = new ModbusMaster('192.168.1.1', 'TCP'); $values = $modbus->readMultipleRegisters(1, 0, 2); -
Elephant418/Modbus:
use Elephant418\Modbus\ModbusMaster; $client = new ModbusMaster('tcp://192.168.1.1:502'); $response = $client->readHoldingRegisters(1, 0, 2);
注意事项
- Modbus TCP 需要确保网络连通性和端口开放
- Modbus RTU 需正确配置串口参数(波特率、校验位等)
- 工业环境中考虑添加错误处理和重试机制
- 大数据量读取时分批请求,避免超时







