golang + snap7 对西门子plc进行读写

最近手上有一个工控项目,不想使用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. 
AddressStringInPLC 的 IP(V4) 地址
ex. “192.168.1.12”
RackStringInPLC 机架,默认为0
SlotStringInPLC 节点(见下文)

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

参考资料:http://snap7.sourceforge.net/sharp7.html

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 {
    }

}
如果喜欢记得点赞
原文地址:https://www.cnblogs.com/smallidea/p/15646085.html