Golang使用Modbus通讯

通过golang使用modbus协议通讯,这有利于将控制系统扩展到多个平台,实现跨平台的终端控制。例如Linux、Windows、Unix、手机、平板、浏览器,或许还包括我的语音控制器(语音->文字->指令->控制)。这样也可以进一步的实现远程控制或者实时通过远程方式了解车间情况。

以下是收集到的一些库,将陆续进行测试。

github.com/wilkingj/GoModbusServer github.com/AdamSLevy/modbus git.leaniot.cn/publicLib/go-modbus github.com/goburrow/modbus github.com/knieriem/modbus github.com/minaandrawos/GoModbus github.com/AdvancedClimateSystems/goldfish

作了一下初步测试

    package main
     
    import (
    	"fmt"
    	"github.com/goburrow/modbus"
    )
     
    func main() {
    	handler := modbus.NewTCPClientHandler("localhost:1502")
    	// Connect manually so that multiple requests are handled in one session
    	err := handler.Connect()
    	defer handler.Close()
    	client := modbus.NewClient(handler)
     
    	_, err = client.WriteMultipleRegisters(0, 4, []byte{0, 10, 0, 255, 1, 5, 0, 3})
    	if err != nil {
    		fmt.Printf("%v\n", err)
    	}
     
    	results, err := client.ReadHoldingRegisters(0, 3)
    	if err != nil {
    		fmt.Printf("%v\n", err)
    	}
    	fmt.Printf("results %v\n", results)
    }
    package main
     
    import (
    	"flag"
    	"fmt"
    	"log"
     
    	modbus "github.com/advancedclimatesystems/goldfish"
    )
     
    var SaveValue map[int]int
     
    func handleReadCoils(unitID, start, quantity int) ([]modbus.Value, error) {
    	fmt.Println("ReadCoils")
    	coils := make([]modbus.Value, quantity)
    	for i := 0; i < quantity; i++ {
    		v, err := modbus.NewValue((i + start) % 2)
    		if err != nil {
    			return coils, modbus.SlaveDeviceFailureError
    		}
     
    		coils[i] = v
    	}
     
    	return coils, nil
    }
     
    func handleRegisters(unitID, start, quantity int) ([]modbus.Value, error) {
    	fmt.Println("Registers")
    	registers := make([]modbus.Value, quantity)
    	for i := 0; i < quantity; i++ {
    		registers[i], _ = modbus.NewValue(SaveValue[i])
    	}
     
    	return registers, nil
    }
     
    func handleWriteRegisters(unitID, start int, values []modbus.Value) error {
    	fmt.Println("WriteRegisters")
    	for i, value := range values {
    		fmt.Printf("[%d]: %d\n", i+start, value.Get())
    		SaveValue[i+start] = value.Get()
    	}
     
    	return nil
    }
     
    func handleWriteCoils(unitID, start int, values []modbus.Value) error {
    	fmt.Println("WriteCoils")
    	if start == 1 {
    		return modbus.IllegalAddressError
    	}
    	return nil
    }
     
    func main() {
    	addr := flag.String("addr", ":502", "address to listen on.")
    	flag.Parse()
     
    	SaveValue = make(map[int]int)
    	s, err := modbus.NewServer(*addr)
     
    	if err != nil {
    		log.Fatal(fmt.Sprintf("Failed to start Modbus server: %v", err))
    	}
     
    	s.Handle(modbus.ReadCoils, modbus.NewReadHandler(handleReadCoils))
    	s.Handle(modbus.ReadHoldingRegisters, modbus.NewReadHandler(handleRegisters))
    	s.Handle(modbus.WriteSingleCoil, modbus.NewWriteHandler(handleWriteCoils, modbus.Signed))
    	s.Handle(modbus.WriteSingleRegister, modbus.NewWriteHandler(handleWriteRegisters, modbus.Signed))
    	s.Handle(modbus.WriteMultipleRegisters, modbus.NewWriteHandler(handleWriteRegisters, modbus.Signed))
     
    	s.Listen()
    }

    ```

相关文章