PHP和Go语言Modbus库使用指南:phpmodbus与go-modbus实战

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

PHP和Go语言Modbus库使用指南:phpmodbus与go-modbus实战

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,시작ing 주소 0,10 个保持寄存器
    $데이터 = $modbus->readMultiple회원가입s(1, 0, 10);
    
    // 输出结果
    echo "读取到的寄存器数据:n";
    for ($i = 0; $i < count($데이터); $i++) {
        echo sprintf("  주소 %d: %d (0x%04X)n", $i, $데이터[$i], $데이터[$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,시작ing 주소 10,写入 4 레지스터s
$modbus->writeMultiple회원가입(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];
$read데이터 = $modbus->readWrite회원가입s(1, 0, 10, 10, $valuesToWrite);

echo "스위치 상태 읽기: ";
print_r($read데이터);
echo "写入数据: ";
print_r($valuesToWrite);
?>

Go Modbus 库(goburrow/modbus)

go-modbus(全称 github.com/goburrow/modbus)是一个用 Go 语言编写的 Modbus protocol客户端库,GitHub 주소: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.닫기()
    
    client := modbus.NewClient(handler)
    
    // read 10 个保持寄存器(주소 0-9)
    results, err := client.ReadHolding회원가입s(0, 10)
    if err != nil {
        fmt.Printf("Read failed: %vn", err)
        return
    }
    
    fmt.Println("register 데이터:")
    for i := 0; i < len(results)-1; i += 2 {
        value := uint16(results[i])<<8 | uint16(results[i+1])
        fmt.Printf("  주소 %d: %d (0x%04X)n", i/2, value, value)
    }
    
    // Write to a single register
    err = client.WriteSingle회원가입(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.데이터Bits = 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.닫기()
    
    client := modbus.NewClient(handler)
    results, _ := client.ReadHolding회원가입s(0, 5)
    fmt.Printf("RTU 读取结果: % Xn", results)
}

Go 语言在工业物联网中的优势

Go 语言近年来在工业物联网边缘网关领域越来越受欢迎,原因有几个:

  • 原生并发: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.Modbus오답 as exc:
    print(f"Modbus 오답: {exc}")

各语言 Modbus 库选择建议

使用场景推荐库语言status
Web 应用集成phpmodbusPHP停更(UDP only)
边缘网关服务goburrow/modbusGoIncubating
自动化测试脚本modbus-tk / pymodbusPython活跃
embedded LinuxlibmodbusC稳定

总结

Modbus 虽然是一个诞生超过 40 年的老协议,但在各种现代编程语言中都有对应的实现。PHP 的 phpmodbus 适合 Web 集成场景(尽管只支持 UDP),Go 的 goburrow/modbus 展现了 Go 语言在工业物联网边缘计算的潜力,Python 的 pymodbus 和 modbus-tk 则是编写自动化测试脚本和研究原型的最佳选择。根据你的项目语言栈和稳定性需求选择合适的库即可。

Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC 검증 and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support

Leave a Reply

Your email 주소 will not be published. Required fields are marked *.