最近手上有一個工控項目,不想使用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 {
}
}

2.1. 對bool類型的數據進行讀寫
dbNumber := 100
address := 10
offsetPosition := 1
dataSize := 1
buffer := make([]byte, 255)
## 讀
err = client.AGReadDB(dbNumber, int(address), dataSize, buffer)
var s7 gos7.Helper
fieldValue := s7.GetBoolAt(buf[0], uint(offsetPosition))
## 寫
fieldNewValue := !fieldValue
var helper gos7.Helper
helper.SetValueAt(buffer, offsetPosition, fieldNewValue)
err := client.AGWriteDB(dbNumber, address, dataSize, buffer)