我来帮你分析一下goburrow/modbus库的TCP连接问题。从你的描述看,可能是连接配置或数据处理的问题。以下是修复后的示例代码:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/goburrow/modbus"
)
func main() {
// 创建TCP客户端处理器
handler := modbus.NewTCPClientHandler("127.0.0.1:502")
// 设置必要的参数
handler.Timeout = 3 * time.Second // 连接超时
handler.SlaveId = 1 // 从站ID,通常为1
// 连接Modbus设备
err := handler.Connect()
if err != nil {
log.Fatalf("连接失败: %v", err)
}
defer handler.Close()
// 创建客户端
client := modbus.NewClient(handler)
// 读取保持寄存器(示例:从地址0开始读取10个寄存器)
address := uint16(0)
quantity := uint16(10)
results, err := client.ReadHoldingRegisters(address, quantity)
if err != nil {
log.Fatalf("读取寄存器失败: %v", err)
}
// 打印原始字节数据
fmt.Printf("读取到的原始数据(字节): %v\n", results)
// 解析数据(假设寄存器存储的是16位整数)
for i := 0; i < len(results); i += 2 {
if i+1 < len(results) {
value := uint16(results[i])<<8 | uint16(results[i+1])
fmt.Printf("寄存器 %d 的值: %d (0x%04X)\n", address+uint16(i/2), value, value)
}
}
}
如果你的Modbus Slave配置了特定的寄存器值,需要确保读取的地址和数量正确。例如,如果Slave在地址40001(对应地址0)存储了数据:
// 读取输入寄存器(功能码04)
results, err := client.ReadInputRegisters(0, 5)
// 读取线圈状态(功能码01)
results, err := client.ReadCoils(0, 8)
// 读取离散输入(功能码02)
results, err := client.ReadDiscreteInputs(0, 8)
调试建议:
- 确保Modbus Slave正在运行并监听502端口
- 使用telnet测试端口连接:
telnet 127.0.0.1 502
- 检查防火墙是否阻止了连接
- 在Modbus Poll中确认可以读取到数据
如果还是无法读取数据,请提供具体的错误信息,我可以进一步帮你排查。