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  }