You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用simonvetter/modbus库读取寄存器时请求超时求助

Modbus读取寄存器超时问题求助

首次使用Modbus,采用github.com/simonvetter/modbus库,能够与设备建立连接,但读取寄存器的请求始终超时。

测试代码(RTU over TCP模式)

package main

import (
    "fmt"
    "os"
    "time"
    "github.com/simonvetter/modbus"
)

func main() {
    client, err := modbus.NewClient(&modbus.ClientConfiguration{
        URL:      "rtuovertcp://192.168.50.60:502",
        Speed:    19200,
        Parity:   modbus.PARITY_NONE,
        DataBits: 8,
        StopBits: 1,
        Timeout:  1 * time.Second,
    })
    if err != nil {
        fmt.Println("Error creating Modbus client:", err)
        return
    }

    // 尝试过设置和不设置该值
    client.SetUnitId(100)

    err = client.Open()
    for err != nil {
        fmt.Println("faild to open", err)
        os.Exit(1)
    }
    defer client.Close()

    var addr uint16
    var reg16 uint16

    // 尝试过多个不同地址,也试过modbus.INPUT_REGISTER
    addr = 100
    reg16, err = client.ReadRegister(addr, modbus.HOLDING_REGISTER)
    if err != nil {
        fmt.Println("ReadRegister:", err) // 错误信息为"request timed out"
        os.Exit(1)
    }

    fmt.Printf("address: %v", addr)
    fmt.Printf("   value: %v", reg16)          // 无符号整数
    fmt.Printf("   value: %v", int16(reg16))   // 有符号整数
    fmt.Printf("   value: %v", float32(reg16)) // 浮点数
}

现象说明

  • 设备界面显示已建立连接,且有数据接收(RX>0),但无数据发送(TX==0)
  • Wireshark抓包显示发送的RTU帧为8字节:01 03 00 64 00 01 c5 d5

设备配置信息

设备配置的关键参数:

  • 从站地址(Slave ID):100
  • 波特率:19200
  • 校验位:无
  • 数据位:8
  • 停止位:1
  • Modbus TCP端口:502

补充测试(Modbus TCP模式)

改用纯TCP模式后问题依旧,调整后的客户端初始化代码:

client, err := modbus.NewClient(&modbus.ClientConfiguration{
    URL:     "tcp://192.168.50.60:502",
    Timeout: 1 * time.Second,
})

对应的Wireshark抓包显示,发送的TCP请求帧中单元标识符(Unit ID)为01,与设备配置的Slave ID 100不匹配。

可能的问题原因

  • 单元标识符不匹配:
    不管是RTU over TCP还是纯TCP模式,抓包显示请求的Unit ID都是01,但设备的Slave ID是100。Modbus设备仅会响应与自身Slave ID一致的请求,这是导致无响应超时的核心原因。需确认client.SetUnitId(100)是否在两种模式下都被正确应用,部分库在纯TCP模式下默认Unit ID为01,需显式设置。
  • 寄存器地址偏移:
    部分Modbus设备使用基于1的地址编号,而ReadRegister方法的参数是基于0的地址。如果设备文档中的寄存器地址是基于1的,你传入的100实际对应设备的101号寄存器,若该寄存器不存在,设备可能不返回响应。
  • 寄存器类型不匹配:
    需确认设备中地址100对应的寄存器类型是保持寄存器还是输入寄存器,若请求类型与实际类型不符,设备可能返回异常或无响应。
  • 超时时间过短:
    当前设置的1秒超时可能不足以让设备完成响应,可尝试将超时调整为3秒后测试。

内容的提问来源于stack exchange,提问作者jpx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:07:46