modbus

package module
v0.0.0-...-33ef678 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2025 License: BSD-3-Clause Imports: 13 Imported by: 0

README

go modbus Build Status GoDoc

Fault-tolerant, fail-fast implementation of Modbus protocol in Go.

Supported functions

Bit access:

  • Read Discrete Inputs
  • Read Coils
  • Write Single Coil
  • Write Multiple Coils

16-bit access:

  • Read Input Registers
  • Read Holding Registers
  • Write Single Register
  • Write Multiple Registers
  • Read/Write Multiple Registers
  • Mask Write Register
  • Read FIFO Queue
  • Read Device Identification Supported formats

  • TCP
  • Serial (RTU, ASCII)

Usage

Basic usage:

// Modbus TCP
client := modbus.TCPClient("localhost:502")
// Read input register 9
results, err := client.ReadInputRegisters(8, 1)

// Modbus RTU/ASCII
// Default configuration is 19200, 8, 1, even
client = modbus.RTUClient("/dev/ttyS0")
results, err = client.ReadCoils(2, 1)

Advanced usage:

// Modbus TCP
handler := modbus.NewTCPClientHandler("localhost:502")
handler.Timeout = 10 * time.Second
handler.SlaveId = 0xFF
handler.Logger = log.New(os.Stdout, "test: ", log.LstdFlags)
// Connect manually so that multiple requests are handled in one connection session
err := handler.Connect()
defer handler.Close()

client := modbus.NewClient(handler)
results, err := client.ReadDiscreteInputs(15, 2)
results, err = client.WriteMultipleRegisters(1, 2, []byte{0, 3, 0, 4})
results, err = client.WriteMultipleCoils(5, 10, []byte{4, 3})
// Modbus RTU/ASCII
handler := modbus.NewRTUClientHandler("/dev/ttyUSB0")
handler.BaudRate = 115200
handler.DataBits = 8
handler.Parity = "N"
handler.StopBits = 1
handler.SlaveId = 1
handler.Timeout = 5 * time.Second

err := handler.Connect()
defer handler.Close()

client := modbus.NewClient(handler)
results, err := client.ReadDiscreteInputs(15, 2)
// Read device identification
results, err := client.ReadDeviceIdentification(1, 0)

if err == nil {
    objNumber := results[0]

    currStart := byte(1)
    for i := byte(0); i < objNumber; i++ {
        currID := results[currStart]
        currLen := results[currStart+byte(1)]
        currObj := results[currStart+byte(2) : currStart+byte(2)+currLen]
        currStart += byte(2) + currLen
        fmt.Printf("Object ID % x\n Object LEN: % x\nCurr OBJ = %s\n", currID, currLen, currObj)
    }
}

References

Documentation

Overview

Package modbus provides a client for MODBUS TCP and RTU/ASCII.

Index

Constants

View Source
const (
	ExceptionCodePDUMaxRequestedQuantity  = 1
	ExceptionCodePDUWrongResponseDataSize = 2
	ExceptionCodePDUWrongResponseAddress  = 3
	ExceptionCodePDUWrongResponseValue    = 4
	ExceptionCodePDUWrongANDMask          = 5
	ExceptionCodePDUWrongORMask           = 6
	ExceptionCodePDUFifoGreater           = 7
	ExceptionCodePDUEmptyResponse         = 8
	ExceptionCodePDUWrongDevIDResponse    = 9
	ExceptionCodePDUWrongValueSet         = 10
)
View Source
const (
	VendorName byte = iota
	ProductCode
	MinorMajorRevision
	VendorUrl
	ProductName
	ModelNumber
	UserApplicationMame
)
View Source
const (
	// Bit access
	FuncCodeReadDiscreteInputs = 2
	FuncCodeReadCoils          = 1
	FuncCodeWriteSingleCoil    = 5
	FuncCodeWriteMultipleCoils = 15

	// 16-bit access
	FuncCodeReadInputRegisters         = 4
	FuncCodeReadHoldingRegisters       = 3
	FuncCodeWriteSingleRegister        = 6
	FuncCodeWriteMultipleRegisters     = 16
	FuncCodeReadWriteMultipleRegisters = 23
	FuncCodeMaskWriteRegister          = 22
	FuncCodeReadFIFOQueue              = 24

	//Device ID
	FuncCodeDevId                = 0x2B
	MEITypeDevId                 = 0x0E
	BasicDeviceIdentification    = 1
	RegularDeviceIdentification  = 2
	ExtendedDeviceIdentification = 3
	SingleDeviceIdentification   = 4

	// Report Slave ID
	FuncCodeReportSlaveId = 0x11
)
View Source
const (
	ExceptionCodeIllegalFunction                    = 1
	ExceptionCodeIllegalDataAddress                 = 2
	ExceptionCodeIllegalDataValue                   = 3
	ExceptionCodeServerDeviceFailure                = 4
	ExceptionCodeAcknowledge                        = 5
	ExceptionCodeServerDeviceBusy                   = 6
	ExceptionCodeMemoryParityError                  = 8
	ExceptionCodeGatewayPathUnavailable             = 10
	ExceptionCodeGatewayTargetDeviceFailedToRespond = 11
)
View Source
const (
	ExceptionCodeWrongTransactionId = 1
	ExceptionCodeWrongProtocolId    = 2
	ExceptionCodeWrongUnitId        = 3
	ExceptionCodeWrongSize          = 4
	ExceptionCodeLengthZero         = 5
	ExceptionCodeLengthMaxSize      = 6
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ASCIIClientHandler

type ASCIIClientHandler struct {
	// contains filtered or unexported fields
}

ASCIIClientHandler implements Packager and Transporter interface.

func NewASCIIClientHandler

func NewASCIIClientHandler(address string) *ASCIIClientHandler

NewASCIIClientHandler allocates and initializes a ASCIIClientHandler.

func (*ASCIIClientHandler) Decode

func (mb *ASCIIClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from ASCII frame and verify LRC.

func (*ASCIIClientHandler) Encode

func (mb *ASCIIClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode encodes PDU in a ASCII frame:

Start           : 1 char
Address         : 2 chars
Function        : 2 chars
Data            : 0 up to 2x252 chars
LRC             : 2 chars
End             : 2 chars

func (*ASCIIClientHandler) Send

func (mb *ASCIIClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

func (*ASCIIClientHandler) Verify

func (mb *ASCIIClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify verifies response length, frame boundary and slave id.

type ASCIIOverTCPClientHandler

type ASCIIOverTCPClientHandler struct {
	// contains filtered or unexported fields
}

ASCIIOverTCPClientHandler implements Packager and Transporter interface.

func NewASCIIOverTCPClientHandler

func NewASCIIOverTCPClientHandler(address string) *ASCIIOverTCPClientHandler

NewASCIIOverTCPClientHandler allocates and initializes a ASCIIOverTCPClientHandler.

func (*ASCIIOverTCPClientHandler) Decode

func (mb *ASCIIOverTCPClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from ASCII frame and verify LRC.

func (*ASCIIOverTCPClientHandler) Encode

func (mb *ASCIIOverTCPClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode encodes PDU in a ASCII frame:

Start           : 1 char
Address         : 2 chars
Function        : 2 chars
Data            : 0 up to 2x252 chars
LRC             : 2 chars
End             : 2 chars

func (*ASCIIOverTCPClientHandler) Send

func (mb *ASCIIOverTCPClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

func (*ASCIIOverTCPClientHandler) Verify

func (mb *ASCIIOverTCPClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify verifies response length, frame boundary and slave id.

type Client

type Client interface {

	// ReadCoils reads from 1 to 2000 contiguous status of coils in a
	// remote device and returns coil status.
	ReadCoils(address, quantity uint16) (results []byte, err error)
	// ReadDiscreteInputs reads from 1 to 2000 contiguous status of
	// discrete inputs in a remote device and returns input status.
	ReadDiscreteInputs(address, quantity uint16) (results []byte, err error)
	// WriteSingleCoil write a single output to either ON or OFF in a
	// remote device and returns output value.
	WriteSingleCoil(address, value uint16) (results []byte, err error)
	// WriteMultipleCoils forces each coil in a sequence of coils to either
	// ON or OFF in a remote device and returns quantity of outputs.
	WriteMultipleCoils(address, quantity uint16, value []byte) (results []byte, err error)

	// ReadInputRegisters reads from 1 to 125 contiguous input registers in
	// a remote device and returns input registers.
	ReadInputRegisters(address, quantity uint16) (results []byte, err error)
	// ReadHoldingRegisters reads the contents of a contiguous block of
	// holding registers in a remote device and returns register value.
	ReadHoldingRegisters(address, quantity uint16) (results []byte, err error)

	// Function code 17: Report Slave ID
	//
	// Returns a description of the type of controller present at the slave address,
	// the current status of the slave RUN indicator, and other information specific
	// to the slave device.
	//
	// Broadcast is not supported. The data contents are specific to each type of controller.
	ReportSlaveId() (results ReportSlaveId, err error)

	// Function code 43: Read Device Identification
	ReadDeviceIdentification(devIdCode byte, objectId byte) (results []byte, err error)
	GetDeviceIdentification(devIdCode byte, objectId byte) (results DeviceIdentification, err error)

	// WriteSingleRegister writes a single holding register in a remote
	// device and returns register value.
	WriteSingleRegister(address, value uint16) (results []byte, err error)
	// WriteMultipleRegisters writes a block of contiguous registers
	// (1 to 123 registers) in a remote device and returns quantity of
	// registers.
	WriteMultipleRegisters(address, quantity uint16, value []byte) (results []byte, err error)
	// ReadWriteMultipleRegisters performs a combination of one read
	// operation and one write operation. It returns read registers value.
	ReadWriteMultipleRegisters(readAddress, readQuantity, writeAddress, writeQuantity uint16, value []byte) (results []byte, err error)
	// MaskWriteRegister modify the contents of a specified holding
	// register using a combination of an AND mask, an OR mask, and the
	// register's current contents. The function returns
	// AND-mask and OR-mask.
	MaskWriteRegister(address, andMask, orMask uint16) (results []byte, err error)
	//ReadFIFOQueue reads the contents of a First-In-First-Out (FIFO) queue
	// of register in a remote device and returns FIFO value register.
	ReadFIFOQueue(address uint16) (results []byte, err error)
}

func ASCIIClient

func ASCIIClient(address string) Client

ASCIIClient creates ASCII client with default handler and given connect string.

func ASCIIOverTCPClient

func ASCIIOverTCPClient(address string) Client

ASCIIOverTCPClient creates ASCII over TCP client with default handler and given connect string.

func NewClient

func NewClient(handler ClientHandler) Client

NewClient creates a new modbus client with given backend handler.

func NewClient2

func NewClient2(packager Packager, transporter Transporter) Client

NewClient2 creates a new modbus client with given backend packager and transporter.

func RTUClient

func RTUClient(address string) Client

RTUClient creates RTU client with default handler and given connect string.

func RTUOverTCPClient

func RTUOverTCPClient(address string) Client

RTUOverTCPClient creates RTU over TCP client with default handler and given connect string.

func TCPClient

func TCPClient(address string) Client

TCPClient creates TCP client with default handler and given connect string.

type ClientHandler

type ClientHandler interface {
	Packager
	Transporter
}

ClientHandler is the interface that groups the Packager and Transporter methods.

type DeviceIdentification

type DeviceIdentification struct {
	VendorName          string
	ProductCode         string
	MinorMajorRevision  string
	VendorUrl           *string
	ProductName         *string
	ModelNumber         *string
	UserApplicationMame *string
}

func ParseDeviceIdentification

func ParseDeviceIdentification(raw []byte) DeviceIdentification

type ModbusError

type ModbusError struct {
	FunctionCode  byte
	ExceptionCode byte
}

ModbusError implements error interface.

func (*ModbusError) Error

func (e *ModbusError) Error() string

Error converts known modbus exception code to error message.

type ModbusPDUError

type ModbusPDUError struct {
	ExceptionCode byte
	Request       interface{}
	Response      interface{}
}

ModbusPDUError implements error interface for PDU data

func (*ModbusPDUError) Error

func (e *ModbusPDUError) Error() string

Error converts known modbus TCP exception code to error message.

type ModbusTCPError

type ModbusTCPError struct {
	ExceptionCode byte
	Request       interface{}
	Response      interface{}
}

ModbusError implements error interface.

func (*ModbusTCPError) Error

func (e *ModbusTCPError) Error() string

Error converts known modbus TCP exception code to error message.

type Packager

type Packager interface {
	Encode(pdu *ProtocolDataUnit) (adu []byte, err error)
	Decode(adu []byte) (pdu *ProtocolDataUnit, err error)
	Verify(aduRequest []byte, aduResponse []byte) (err error)
}

Packager specifies the communication layer.

type ProtocolDataUnit

type ProtocolDataUnit struct {
	FunctionCode byte
	Data         []byte
}

ProtocolDataUnit (PDU) is independent of underlying communication layers.

type ProxyTCPClientHandler

type ProxyTCPClientHandler struct {
	TCPClientHandler
	// contains filtered or unexported fields
}

func NewProxyTCPClientHandler

func NewProxyTCPClientHandler(proxyTargetAddress string, localAddress string) *ProxyTCPClientHandler

func (*ProxyTCPClientHandler) Close

func (h *ProxyTCPClientHandler) Close() error

func (*ProxyTCPClientHandler) Connect

func (h *ProxyTCPClientHandler) Connect() error

func (*ProxyTCPClientHandler) Decode

func (mb *ProxyTCPClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from RTU frame and verify CRC.

func (*ProxyTCPClientHandler) Encode

func (mb *ProxyTCPClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode encodes PDU in a RTU frame:

Slave Address   : 1 byte
Function        : 1 byte
Data            : 0 up to 252 bytes
CRC             : 2 byte

func (*ProxyTCPClientHandler) Send

func (h *ProxyTCPClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

func (*ProxyTCPClientHandler) StartProxy

func (h *ProxyTCPClientHandler) StartProxy() error

func (*ProxyTCPClientHandler) TryDecode

func (mb *ProxyTCPClientHandler) TryDecode(buffer *[]byte, frame *[]byte)

func (*ProxyTCPClientHandler) Verify

func (mb *ProxyTCPClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify verifies response length and slave id.

type RTUClientHandler

type RTUClientHandler struct {
	// contains filtered or unexported fields
}

RTUClientHandler implements Packager and Transporter interface.

func NewRTUClientHandler

func NewRTUClientHandler(address string) *RTUClientHandler

NewRTUClientHandler allocates and initializes a RTUClientHandler.

func (*RTUClientHandler) Decode

func (mb *RTUClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from RTU frame and verify CRC.

func (*RTUClientHandler) Encode

func (mb *RTUClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode encodes PDU in a RTU frame:

Slave Address   : 1 byte
Function        : 1 byte
Data            : 0 up to 252 bytes
CRC             : 2 byte

func (*RTUClientHandler) Send

func (mb *RTUClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

func (*RTUClientHandler) TryDecode

func (mb *RTUClientHandler) TryDecode(buffer *[]byte, frame *[]byte)

func (*RTUClientHandler) Verify

func (mb *RTUClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify verifies response length and slave id.

type RTUOverTCPClientHandler

type RTUOverTCPClientHandler struct {
	// contains filtered or unexported fields
}

RTUOverTCPClientHandler implements Packager and Transporter interface.

func NewRTUOverTCPClientHandler

func NewRTUOverTCPClientHandler(address string) *RTUOverTCPClientHandler

NewRTUOverTCPClientHandler allocates and initializes a RTUOverTCPClientHandler.

func (*RTUOverTCPClientHandler) Decode

func (mb *RTUOverTCPClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from RTU frame and verify CRC.

func (*RTUOverTCPClientHandler) Encode

func (mb *RTUOverTCPClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode encodes PDU in a RTU frame:

Slave Address   : 1 byte
Function        : 1 byte
Data            : 0 up to 252 bytes
CRC             : 2 byte

func (*RTUOverTCPClientHandler) Send

func (mb *RTUOverTCPClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

func (*RTUOverTCPClientHandler) TryDecode

func (mb *RTUOverTCPClientHandler) TryDecode(buffer *[]byte, frame *[]byte)

func (*RTUOverTCPClientHandler) Verify

func (mb *RTUOverTCPClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify verifies response length and slave id.

type ReportSlaveId

type ReportSlaveId struct {
	SlaveId          byte
	RunIndicator     byte
	OtherInformation []byte
}

func ParseReportSlaveId

func ParseReportSlaveId(raw []byte) (ReportSlaveId, error)

type TCPClientHandler

type TCPClientHandler struct {
	// contains filtered or unexported fields
}

TCPClientHandler implements Packager and Transporter interface.

func NewTCPClientHandler

func NewTCPClientHandler(address string) *TCPClientHandler

NewTCPClientHandler allocates a new TCPClientHandler.

func (*TCPClientHandler) Close

func (mb *TCPClientHandler) Close() error

Close closes current connection.

func (*TCPClientHandler) Connect

func (mb *TCPClientHandler) Connect() error

Connect establishes a new connection to the address in Address. Connect and Close are exported so that multiple requests can be done with one session

func (*TCPClientHandler) Decode

func (mb *TCPClientHandler) Decode(adu []byte) (pdu *ProtocolDataUnit, err error)

Decode extracts PDU from TCP frame:

Transaction identifier: 2 bytes
Protocol identifier: 2 bytes
Length: 2 bytes
Unit identifier: 1 byte

func (*TCPClientHandler) Encode

func (mb *TCPClientHandler) Encode(pdu *ProtocolDataUnit) (adu []byte, err error)

Encode adds modbus application protocol header:

Transaction identifier: 2 bytes
Protocol identifier: 2 bytes
Length: 2 bytes
Unit identifier: 1 byte
Function code: 1 byte
Data: n bytes

func (*TCPClientHandler) Send

func (mb *TCPClientHandler) Send(aduRequest []byte) (aduResponse []byte, err error)

Send sends data to server and ensures response length is greater than header length.

func (*TCPClientHandler) Verify

func (mb *TCPClientHandler) Verify(aduRequest []byte, aduResponse []byte) (err error)

Verify confirms transaction, protocol and unit id.

type Transporter

type Transporter interface {
	Send(aduRequest []byte) (aduResponse []byte, err error)
}

Transporter specifies the transport layer.

Directories

Path Synopsis
commw32 command
Port of commw32.c To generate go types: go tool cgo commw32.go
Port of commw32.c To generate go types: go tool cgo commw32.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL