本学习库所用gomodbus包的原作者已经停止更新,本文所涉及代码仅提供解决思路
https://github.com/things-go/go-modbus/tree/master
也可以在该作者下使用更新的版本:
https://blog.csdn.net/lishuangquan1987/article/details/123441211
go modbus V2版
这里开始是thinkgos
,之前是things-go
1、下载地址
https://github.com/thinkgos/gomodbus
下面使用官方示例进行测试
2、Server代码
生成文件 server.exe
package main
import (
modbus "github.com/thinkgos/gomodbus/v2"
)
func main() {
srv := modbus.NewTCPServer()
srv.LogMode(true)
srv.AddNodes(
modbus.NewNodeRegister(
1,
0, 10, 0, 10,
0, 10, 0, 10),
modbus.NewNodeRegister(
2,
0, 10, 0, 10,
0, 10, 0, 10),
modbus.NewNodeRegister(
3,
0, 10, 0, 10,
0, 10, 0, 10))
err := srv.ListenAndServe(":502")
if err != nil {
panic(err)
}
}
3、Client代码
生成文件 client.exe
package main
import (
"fmt"
"time"
modbus "github.com/thinkgos/gomodbus/v2"
)
func main() {
p := modbus.NewTCPClientProvider("127.0.0.1:502", modbus.WithEnableLogger())
client := modbus.NewClient(p)
err := client.Connect()
if err != nil {
fmt.Println("connect failed, ", err)
return
}
defer client.Close()
fmt.Println("starting")
for {
_, err := client.ReadCoils(1, 0, 10)
if err != nil {
fmt.Println(err.Error())
}
// fmt.Printf("ReadDiscreteInputs %#v\r\n", results)
time.Sleep(time.Second * 2)
}
}
4、操作
单机测试时,先运行 server.exe
,再运行 client.exe
(本示例中如果server.exe
未运行,client.exe
界面将直接关闭)
运行如图:
转载学习
2021.12.04
以下文章为2020年所转载,使用Virtual Serial Port Driver 和 modbus-slave 软件测试及 gomodbus v1版本的代码。原文详见下方链接。
用到的gomodbus包是坛友slzm40编写和共享的,感谢他的无私分享,本帖只是抛砖引玉,将我自己学习的一些经历分享给大家;有关modbus包可以直接向slzm40请教或一起讨论;
1、创建工程,导入modbus包
包地址"github.com/thinkgos/gomodbus";
2、打开虚拟串口
添加一对虚拟串口
3、打开modbus-slave软件
打开modbus-slave从机软件,用来测试从机;
需要注意设置通信地址和读取寄存器的地址和数量;
4、运行代码
查看可用串口,因为虚拟串口选择com1和com2,虚拟中我选择使用/dev/ttyS1
编译运行,会提示串口打开失败,这是因为linux对设备的权限做了限制
获取串口读写、运行等权限
5、测试ok
图5.1
我们已经能正确读取03寄存器的值;其他功能可以自行测试;
package main
import (
"fmt"
modbus "github.com/thinkgos/gomodbus"
"github.com/thinkgos/mb" //原文是"github.com/thinkgos/gomodbus/mb"
"time"
)
func main() {
//调用RTUClientProvider的构造函数,返回结构体指针
p := modbus.NewRTUClientProvider()
p.Address = "/dev/ttyS1"
p.BaudRate = 115200
p.DataBits = 8
p.Parity = "N"
p.StopBits = 1
p.Timeout = 100 * time.Millisecond
client := mb.NewClient(p)
client.LogMode(true)
err := client.Start()
if err != nil {
fmt.Println("start err,", err)
return
}
for {
value, err := client.ReadHoldingRegisters(1, 1, 3)
if err != nil {
fmt.Println("readHoldErr,", err)
} else {
fmt.Printf("%#v\n", value)
}
time.Sleep(time.Second * 3)
}
}