最近手上有一个工控项目,不想使用C#、Java这种高级语言,转而想选择了golang这种脚本语言,主要考虑:
- golang发布的都是二进制文件,体积小部署方便,运行效率也高,不需要经过中间的运行时
- 都是基于snap7的,不深度的使用问题不大,C#、Java的封装肯定会更加成熟一些
- 工控领域是个“烂泥坑”,二进制可以有效的预防各种偷窃行为
- 垮平台,windows、linux 都可以部署,对于后期独立服务器非常灵活
以下均使用golang snap7 开源库
https://github.com/robinson/gos7
1. 连接
const (
tcpDevice = "192.168.0.1"
rack = 0
slot = 1
)
// TCPClient
handler := gos7.NewTCPClientHandler(tcpDevice, rack, slot)
参数
Type | Dir. | ||
---|---|---|---|
Address | String | In | PLC 的 IP(V4) 地址 ex. “192.168.1.12” |
Rack | String | In | PLC 机架,默认为0 |
Slot | String | In | PLC 节点(见下文) |
Rack && Slot
In addition to the IP Address, that we all understand, there are two other parameters that index the unit : Rack (0..7) and Slot (1..31) that you find into the hardware configuration of your project, for a physical component, or into the Station Configuration manager for WinAC.
在博图软件中,查看 设备组态,如下图所示分别代表了rack 和 slot
2. 读写
新建一个DB100用于测试,测试一个数据的写入和读取,开始位置为0,因为是float类型,所以size为4(4*8位)
func main() {
const (
tcpDevice = "192.168.0.1"
rack = 0
slot = 1
)
// TCPClient
fmt.Printf("connect to %v", tcpDevice)
fmt.Println()
handler := gos7.NewTCPClientHandler(tcpDevice, rack, slot)
handler.Timeout = 200 * time.Second
handler.IdleTimeout = 200 * time.Second
handler.Logger = log.New(os.Stdout, "tcp: ", log.LstdFlags)
// 创建连接,可以基于这个新建多个会话(client)
err := handler.Connect()
common.CheckError(err)
defer handler.Close()
// 初始化连接
client := gos7.NewClient(handler)
address := 100
start := 0
size := 4
buffer := make([]byte, 255)
value := float32(3) // 写入的数据
// 向DB中写入数据
var helper gos7.Helper
helper.SetValueAt(buffer, 0, value)
err = client.AGWriteDB(address, start, size, buffer)
common.CheckError(err)
fmt.Printf("write to db%v start:%v size:%v value:%v", address, start, size, value)
fmt.Println()
// 从DB中读取数据
buf := make([]byte, 255)
err = client.AGReadDB(address, start, size, buf)
common.CheckError(err)
var s7 gos7.Helper
var result float32 // 结果
s7.GetValueAt(buf, 0, &result)
fmt.Printf("read value:%v from db%v start:%v size:%v ", result, address, start, size)
fmt.Println()
for {
}
}