使用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
相关产品推荐
相关产品推荐

