github.com/simpleiot/simpleiot@v0.18.3/cmd/modbus/main.go (about) 1 // example modbus client application 2 package main 3 4 // eventually, this should become a full fledged client or server test app 5 // perhaps with an interactive shell. 6 7 import ( 8 "flag" 9 "fmt" 10 "log" 11 "os" 12 "strconv" 13 "time" 14 15 "github.com/simpleiot/simpleiot/modbus" 16 "github.com/simpleiot/simpleiot/respreader" 17 "go.bug.st/serial" 18 ) 19 20 func usage() { 21 fmt.Println("Usage: ") 22 flag.PrintDefaults() 23 os.Exit(-1) 24 } 25 26 func main() { 27 log.Println("modbus client") 28 29 flagPort := flag.String("port", "", "serial port") 30 flagBaud := flag.String("baud", "9600", "baud rate") 31 flagCount := flag.Int("count", 1, "number of values to read") 32 flagReadHoldingRegs := flag.Int("readHoldingRegs", -1, "address to read") 33 flagAddress := flag.Int("address", 1, "device address") 34 flagFormatInt16 := flag.Bool("int16", false, "Interpret result as 16-bit signed integer") 35 flagFormatUInt16 := flag.Bool("uint16", false, "Interpret result as 16-bit unsigned integer") 36 flagFormatInt32 := flag.Bool("int32", false, "Interpret result as 32-bit signed integer") 37 flagFormatUInt32 := flag.Bool("uint32", false, "Interpret result as 32-bit unsigned integer") 38 flagFormatFloat32 := flag.Bool("float32", false, "Interpret result as 32-bit floating point") 39 flagScale := flag.Float64("scale", 1, "Scale data by some factor") 40 41 flag.Parse() 42 43 if *flagPort == "" { 44 usage() 45 } 46 47 baud, err := strconv.Atoi(*flagBaud) 48 49 if err != nil { 50 log.Println("Baud rate error:", err) 51 os.Exit(-1) 52 } 53 54 mode := &serial.Mode{ 55 BaudRate: baud, 56 } 57 58 port, err := serial.Open(*flagPort, mode) 59 if err != nil { 60 log.Fatal(err) 61 } 62 63 portRR := respreader.NewReadWriteCloser(port, time.Second*1, time.Millisecond*30) 64 transport := modbus.NewRTU(portRR) 65 client := modbus.NewClient(transport, 1) 66 67 if *flagFormatInt32 || *flagFormatUInt32 || *flagFormatFloat32 { 68 *flagCount = *flagCount * 2 69 } 70 71 if *flagReadHoldingRegs > 0 { 72 log.Printf("Reading holding reg adr: 0x%x, cnt: %v\n", 73 *flagReadHoldingRegs, *flagCount) 74 75 regs, err := client.ReadHoldingRegs(byte(*flagAddress), 76 uint16(*flagReadHoldingRegs), 77 uint16(*flagCount)) 78 79 if err != nil { 80 log.Println("Error reading holding regs:", err) 81 os.Exit(-1) 82 } 83 84 if len(regs) != *flagCount { 85 log.Printf("Error, expected %v regs, got %v\n", 86 *flagCount, len(regs)) 87 os.Exit(-1) 88 } 89 90 if *flagFormatInt16 { 91 values := modbus.RegsToInt16(regs) 92 for i, v := range values { 93 log.Printf("Value %v: %v\n", i, float64(v)*(*flagScale)) 94 } 95 } else if *flagFormatUInt16 { 96 for i, r := range regs { 97 log.Printf("Value %v: %v\n", i, float64(r)*(*flagScale)) 98 } 99 } else if *flagFormatInt32 { 100 values := modbus.RegsToInt32(regs) 101 for i, v := range values { 102 log.Printf("Value %v: %v\n", i, float64(v)*(*flagScale)) 103 } 104 } else if *flagFormatUInt32 { 105 values := modbus.RegsToUint32(regs) 106 for i, v := range values { 107 log.Printf("Value %v: %v\n", i, float64(v)*(*flagScale)) 108 } 109 } else if *flagFormatFloat32 { 110 values := modbus.RegsToFloat32(regs) 111 for i, v := range values { 112 log.Printf("Value %v: %v\n", i, float64(v)*(*flagScale)) 113 } 114 } else { 115 for i, r := range regs { 116 log.Printf("Reg result %v: 0x%x\n", i, r) 117 } 118 } 119 } 120 }