Repositorie moved to go-cip
A golang based API(Originator) for interfacing with Rockwell Control/CompactLogix PLCs.
NOTE: goplc running in a single go route and never block your process, you need to block it by other way.
node-ethernet-ip project gave me a lot of inspiration.
import (
"github.com/MiguelValentine/goplc"
)
func test(){
//IP Slot Config
plc, _ := NewOriginator("1.1.1.1", 1, nil)
plc.OnConnected = func() {
log.Printf("%+v\n",plc.Controller)
// &{VendorID:1 DeviceType:14 ProductCode:53 Major:32 Minor:11 Status:12400 SerialNumber:1881423856 Version:32.11 Name:Emulator R32.11}
}
_ = plc.Connect()
}
import (
"github.com/MiguelValentine/goplc"
)
func test(){
cfg := DefaultConfig()
//Reconnection Interval default will not automatically reconnect
cfg.ReconnectionInterval = time.Second
//Logger default no log
cfg.Logger = log.New(os.Stdout, "", log.LstdFlags)
//default 0xAF12
cfg.Port = 1111
plc, _ := NewOriginator("1.1.1.1", 1, cfg)
plc.OnConnected = func() {
log.Printf("%+v\n",plc.Controller)
// &{VendorID:1 DeviceType:14 ProductCode:53 Major:32 Minor:11 Status:12400 SerialNumber:1881423856 Version:32.11 Name:Emulator R32.11}
}
_ = plc.Connect()
}
import (
"github.com/MiguelValentine/goplc"
)
func testListAllTags() {
cfg := DefaultConfig()
plc, _ := NewOriginator("1.1.1.1", 1, cfg)
plc.OnConnected = func() {
plc.ListAllTags(0)
// 2020/08/24 17:20:10 Map:Local : (0x1069)
// 2020/08/24 17:20:10 Task:MainTask : (0x1070)
// 2020/08/24 17:20:10 Program:MainProgram : (0x1068)
// 2020/08/24 17:20:10 TESTA : DINT(0xc4)
// 2020/08/24 17:20:10 TESTB : (0xafce)
// 2020/08/24 17:20:10 TESTC : DINT(0xc4)
// 2020/08/24 17:20:10 TESTD : REAL(0xca)
// 2020/08/24 17:20:10 TESTE : (0x8fce)
}
_ = plc.Connect()
}
NOTE: Currently, the Tag
Class only supports Atomic datatypes(SINT, INT, DINT, REAL, BOOL) and String Read(not support string write).support for ARRAY, and UDTs are in the plans and coming soon!
import (
"github.com/MiguelValentine/goplc"
"github.com/MiguelValentine/goplc/tag"
)
func testTag() {
tagA := tag.NewTag("TESTA")
//OnData will be called every time you sync
//Try to use OnChange if not necessary
tagA.OnData = func(value interface{}) {
log.Println(value)
//1237
//1238
}
plc, _ := NewOriginator("1.1.1.1", 1, nil)
plc.OnConnected = func() {
log.Printf("%+v\n", plc.Controller)
plc.ReadTag(tagA).Then(func() {
tagA.SetValue(int32(1238))
plc.WriteTag(tagA).Then(func() {
plc.ReadTag(tagA)
})
})
}
_ = plc.Connect()
}
import (
"github.com/MiguelValentine/goplc"
"github.com/MiguelValentine/goplc/tag"
"github.com/MiguelValentine/goplc/tagGroup"
)
func testTagGroup() {
cfg := DefaultConfig()
tagA := tag.NewTag("TESTA")
tagA.OnChange = func(value interface{}) {
log.Println(value)
}
tagB := tag.NewTag("TESTB")
tagB.OnChange = func(value interface{}) {
log.Println(value)
}
tg := &tagGroup.TagGroup{}
tg.Add(tagA)
tg.Add(tagB)
plc, _ := NewOriginator("1.1.1.1", 1, cfg)
plc.OnConnected = func() {
plc.ReadTagGroup(tg)
}
_ = plc.Connect()
}
import (
"github.com/MiguelValentine/goplc"
"github.com/MiguelValentine/goplc/tag"
"github.com/MiguelValentine/goplc/tagGroup"
)
func testTagGroup() {
cfg := DefaultConfig()
tagA := tag.NewTag("TESTA")
tagA.OnChange = func(value interface{}) {
log.Printf("%s => %f\n", tagA.Name(), value)
}
tagB := tag.NewTag("TESTB")
tagB.OnChange = func(value interface{}) {
log.Printf("%s => %f\n", tagB.Name(), value)
}
tg := &tagGroup.TagGroup{}
tg.Add(tagA)
tg.Add(tagB)
plc, _ := NewOriginator("1.1.1.1", 1, cfg)
plc.OnConnected = func() {
//setTimeInterval
plc.ReadTagGroupInterval(tg, time.Millisecond*50)
}
_ = plc.Connect()
}
This project is licensed under the MIT License - see the LICENCE file for details