{"id":17287423,"url":"https://github.com/adamslevy/modbus","last_synced_at":"2025-04-14T11:06:33.530Z","repository":{"id":57487711,"uuid":"100887696","full_name":"AdamSLevy/modbus","owner":"AdamSLevy","description":"A thread safe Modbus Client using idiomatic Go concurrency design patterns.","archived":false,"fork":false,"pushed_at":"2018-08-30T18:25:27.000Z","size":931,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T11:06:28.300Z","etag":null,"topics":["go","golang","modbus","modbus-client","modbus-library","modbus-master","modbus-rtu","modbus-serial","modbus-tcp","thread-safety","threadsafe"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AdamSLevy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-20T20:42:29.000Z","updated_at":"2023-01-14T08:57:20.000Z","dependencies_parsed_at":"2022-08-29T13:31:58.747Z","dependency_job_id":null,"html_url":"https://github.com/AdamSLevy/modbus","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdamSLevy%2Fmodbus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdamSLevy%2Fmodbus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdamSLevy%2Fmodbus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AdamSLevy%2Fmodbus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AdamSLevy","download_url":"https://codeload.github.com/AdamSLevy/modbus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248868768,"owners_count":21174757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","modbus","modbus-client","modbus-library","modbus-master","modbus-rtu","modbus-serial","modbus-tcp","thread-safety","threadsafe"],"created_at":"2024-10-15T10:02:25.973Z","updated_at":"2025-04-14T11:06:33.508Z","avatar_url":"https://github.com/AdamSLevy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Threadsafe Modbus Client Library\n[![GoDoc](https://godoc.org/github.com/AdamSLevy/modbus?status.svg)](https://godoc.org/github.com/AdamSLevy/modbus)\n[![Build Status](https://travis-ci.org/AdamSLevy/modbus.svg?branch=master)](https://travis-ci.org/AdamSLevy/modbus)\n[![Coverage Status](https://coveralls.io/repos/github/AdamSLevy/modbus/badge.svg?branch=master)](https://coveralls.io/github/AdamSLevy/modbus?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/AdamSLevy/modbus)](https://goreportcard.com/report/github.com/AdamSLevy/modbus)\n\nThis Go package implements a Modbus Client (i.e. a master) that can be used\nconcurrently in multiple goroutines.\n\n## Supported Protocols\n- RTU\n- ASCII\n- TCP\n\n## Supported Queries\n- Read Coils\n- Read Discrete Inputs\n- Read Holding Registers\n- Read Input Registers\n- Write Single Coil\n- Write Single Register\n- Write Multiple Coils\n- Write Multiple Registers\n- Mask Write Register\n\n## Example\nInitialize a ConnectionSettings struct. Set the Mode, Host, Timeout, and Baud\nif the Mode is ModeRTU or ModeASCII. When using ModeTCP the Host is the fully\nqualified domain name or ip address and port number. The port number in the\nHost string is required. When using ModeRTU or ModeASCII, the Baud rate is\nrequired and the Host string is the full path to the serial device or the name\nof the COM port if on Windows. For all modes, the Timeout cannot be zero.\n```go\ncsTCP := ConnectionSettings{\n        Mode: ModeTCP,\n        Host: \"192.168.1.121:502\",\n        Timeout: 500 * time.Millisecond,\n}\ncsASCII := ConnectionSettings{\n        Mode: ModeASCII,\n        Host: \"/dev/ttyS1\",\n        Baud: 9600,\n        Timeout: 500 * time.Millisecond,\n}\ncsRTU := ConnectionSettings{\n        Mode: ModeRTU,\n        Host: \"/dev/ttyUSB0\",\n        Baud: 115200,\n        Timeout: 500 * time.Millisecond,\n}\n```\nGetClientHandle returns a ClientHandle object which can be used to concurrently\nsend Query objects to the underlying client. This starts the client with the\ngiven ConnectionSettings if it's not already running. \n```go\nch, err := modbus.GetClientHandle(csTCP)\nif nil != err {\n        fmt.Println(err)\n        return\n}\nq, _ := ReadCoils(0,0,16)\ndata, err := ch.Send(q)\n```\nMultiple ClientHandles can be acquired or the same ClientHandle can be copied\nand reused in multiple goroutines. The ConnectionSettings must match exactly if\na client is already running with the same Host string.\n```go\ncs := csTCP\nch1, err := modbus.GetClientHandle(cs) // Returns another ClientHandle for the same client\nif nil != err {\n        fmt.Println(err)\n        return\n}\ncs.Timeout = 1000\n_, err := modbus.GetClientHandle(cs) // Returns error since the Timeout was changed\nif nil != err {\n        fmt.Println(err)\n        return\n}\n```\nCreate a Query using one of the function code initializers. \n```go\nreadCoils, err := ReadCoils(0, 0, 5) // SlaveID, Address, Quantity\nif nil != err {\n        fmt.Println(err)\n        return\n}\ndata, err := ch.Send(readCoils)\n```\nYou can edit and reuse the Query, say to change the SlaveID.\n```go\nreadCoils.SlaveID = 1\ndata, err := ch.Send(readCoils)\n```\nAlternatively you can manually initialize a Query struct and call IsValid() on\nthe Query to make sure that it is well formed.\n```go\nreadDiscreteInputs := Query{\n        FunctionCode: FunctionReadDiscreteInputs,\n        SlaveID: 1,\n        Address: 3,\n        Quantity: 4,\n}\nwriteMultitpleRegisters := Query{\n        FunctionCode: FunctionWriteMultipleRegisters,\n        Address:      1,\n        Quantity:     2,\n        Values:       []uint16{0x8081, 500},\n}\n\nif valid, err := readDiscreteInputs.IsValid(); !valid {\n        fmt.Println(err)\n        return\n}\nif valid, err := writeMultipleRegisters.IsValid(); !valid {\n        fmt.Println(err)\n        return\n}\n\n```\nWhen you are finished using the ClientHandle, call its Close() method. The\nunderlying client is closed and all associated goroutines will return once all\nopen ClientHandles are closed. Keep in mind that if you are sharing a\nClientHandle between multiple goroutines, and one call Close, that ClientHandle\nwill fail to send any further Queries.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadamslevy%2Fmodbus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadamslevy%2Fmodbus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadamslevy%2Fmodbus/lists"}