PHP Modbus 库(phpmodbus)
phpmodbus 是一个用 PHP 実装的 Modbus UDP/TCP 通信库,项目托管在 Google Code Archive:code.google.com/p/phpmodbus(已アーカイブ)。它実装了 Modbus UDP 协议的基本功能,サポート FC03(read holding registers)、FC16(マルチレジスタの書き込み)、FC23(读/マルチレジスタの書き込み)。
尽管 Modbus UDP 在工业现场远不如 Modbus TCP common,但 phpmodbus 在某些特殊的 Web アプリケーションシナリオ。中有独特价值——比如在 PHP 编写的 SCADA 看板网站中直接読み取り Modbus UDP デバイス的データ、或者経由浏览器界面リモートコントロール。 Modbus device。
インストール与基础使用
<?php
// 引入 phpmodbus 库
require_once 'PhpModBus.php';
// 作成 Modbus UDP マスター实例
$modbus = new ModbusUdpMaster('192.168.1.100', 502);
try {
// FC03: 駅から読む。 1,starting address 0,10 レジスタを保持する。
$data = $modbus->readMultipleRegisters(1, 0, 10);
// 出力結果
echo "読み取り到的レジスタのデータ:n";
for ($i = 0; $i < count($data); $i++) {
echo sprintf(" address %d: %d (0x%04X)n", $i, $data[$i], $data[$i]);
}
} catch (Exception $e) {
echo "Modbus 通信エラー: " . $e->getMessage();
}
?>
FC16 複数書き込みレジスタを保持する。
<?php
$modbus = new ModbusUdpMaster('192.168.1.100', 502);
// 要写入的データ
$values = [100, 200, 300, 400];
// FC16: slave 1,starting address 10,写入 4 Registers
$modbus->writeMultipleRegister(1, 10, $values);
echo "写入成功n";
?>
FC23 组合読み書き
<?php
$modbus = new ModbusUdpMaster('192.168.1.100', 502);
// FC23: アドレスを読む。 0-9,同时アドレスを書く。 10-13
$valuesToWrite = [99, 88, 77, 66];
$readData = $modbus->readWriteRegisters(1, 0, 10, 10, $valuesToWrite);
echo "Read switch status: ";
print_r($readData);
echo "写入データ: ";
print_r($valuesToWrite);
?>
Go Modbus 库(goburrow/modbus)
go-modbus(全称 github.com/goburrow/modbus)是一个用 Go 语言编写的 Modbus protocolクライアント側は库,GitHub address:github.com/goburrow/modbus。它被説明为"fault-tolerant, fail-fast"的実装——在设计上注重エラー処理和快速失敗,适合在可靠性和稳定性要求较高的工业エッジゲートウェイ场景で使用する。。
⚠️ 注意:根据 modbus.org 2024 年的最新説明,该库仍处于"incubating"阶段,"do not use in production yet (more testing needed)"。虽然 API 设计优秀,但在生产环境で使用する。前需要充分测试。
インストール
go get github.com/goburrow/modbus
Modbus TCP クライアント側はサンプル
package main
import (
"fmt"
"time"
"github.com/goburrow/modbus"
)
func main() {
// 作成 TCP クライアント側は
handler := modbus.NewTCPClientHandler("192.168.1.100:502")
handler.Timeout = 5 * time.Second
handler.SlaveId = 1
// 建立连接
err := handler.Connect()
if err != nil {
fmt.Printf("接続の失敗: %vn", err)
return
}
defer handler.Close()
client := modbus.NewClient(handler)
// read 10 レジスタを保持する。(address 0-9)
results, err := client.ReadHoldingRegisters(0, 10)
if err != nil {
fmt.Printf("Read failed: %vn", err)
return
}
fmt.Println("register data:")
for i := 0; i < len(results)-1; i += 2 {
value := uint16(results[i])<<8 | uint16(results[i+1])
fmt.Printf(" address %d: %d (0x%04X)n", i/2, value, value)
}
// Write to a single register
err = client.WriteSingleRegister(0, 1234)
if err != nil {
fmt.Printf("写入失敗: %vn", err)
} else {
fmt.Println("写入成功")
}
}
Modbus RTU シリアルポートクライアント側は
package main
import (
"fmt"
"github.com/goburrow/modbus"
)
func main() {
// 作成 RTU クライアント側は(RS-485)
handler := modbus.NewRTUClientHandler("/dev/ttyUSB0")
handler.BaudRate = 9600
handler.DataBits = 8
handler.Parity = "N" // 検証なし。
handler.StopBits = 1
handler.SlaveId = 1
handler.Timeout = 3 * time.Second
err := handler.Connect()
if err != nil {
panic(err)
}
defer handler.Close()
client := modbus.NewClient(handler)
results, _ := client.ReadHoldingRegisters(0, 5)
fmt.Printf("RTU 読み取り结果: % Xn", results)
}
Go 语言在産業用IoT中的优势
Go 语言近年来在産業用IoTエッジゲートウェイ领域越来越受欢迎,原因有几个:
- 原生并发:goroutine 让同时连接数百个 Modbus スレーブ变得简单高效
- 单二进制部署:编译后是一个独立可执行文件,无需运行时依赖(如 JVM、Python 解释器),部署极其简单
- 跨プラットフォーム编译:
GOOS=linux GOARCH=arm64 go build即可交叉编译到 ARM Linux(Raspberry Pi、工控机) - 内存セキュリティ:相比 C 语言,Go 提供的自动垃圾回收和内存セキュリティチェック更适合编写稳定的长时间运行服务
Python Modbus Test Kit(modbus-tk)
Modbus Test Kit(modbus-tk)是一个 Python 実装的 Modbus protocol库,项目在 Google Code Archive。它サポート Modbus RTU 和 Modbus TCP,可以同时编写クライアント側は和サーバー·サーバー。对于 Python 用户来说,另一个更现代的選択是 pymodbus,两者 API 风格不同但功能カバー类似。
#!/usr/bin/env python3
# modbus-tk 基本使用例の例
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_tcp
# 作成 TCP master
master = modbus_tcp.TcpMaster(host="192.168.1.100", port=502)
master.set_timeout(5.0)
# 駅から読む。 1 保持レジスタです。 0-9
try:
values = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 10)
print(f"読み取り结果: {values}")
except modbus_tk.modbus.ModbusError as exc:
print(f"Modbus Error: {exc}")
各语言 Modbus 库選択建议
| 使用シーン | おすすめ库 | 语言 | status |
|---|---|---|---|
| Web 应用集成 | phpmodbus | PHP | 停更(UDP only) |
| エッジゲートウェイ服务 | goburrow/modbus | Go | Incubating |
| 自動化测试脚本 | modbus-tk / pymodbus | Python | 活跃 |
| embedded Linux | libmodbus | C | 稳定 |
总结
Modbus 虽然是一个诞生超过 40 年的老协议,但在各种现代プログラミング语言中都有对应的実装。PHP 的 phpmodbus 适合 Web 集成场景(尽管只サポート UDP),Go 的 goburrow/modbus 展现了 Go 语言在産業用IoT边缘計算的潜力,Python 的 pymodbus 和 modbus-tk 则是编写自動化测试脚本和研究原型的最佳選択。根据你的项目语言栈和稳定性需求選択合适的库即可。
Leave a Reply