Documentation
¶
Overview ¶
libmodbusgo golang binding for libmodbus
libmodbus functions convert ¶
| C | GO | comment | | ---------------------------------- | ------------------------------- | ------- | | modbus_close() | Modbus.Close() | | | modbus_connect() | Modbus.Connect() | | | modbus_disable_quirks() | Modbus.DisableQuirks() | | | modbus_enable_quirks() | Modbus.EnableQuirks() | | | modbus_flush() | Modbus.Flush() | | | modbus_free() | Modbus.Free() | | | modbus_get_byte_from_bits() | ModbusGetByteFromBits() | | | modbus_get_byte_timeout() | Modbus.GetByteTimeout() | | | modbus_get_float() | ModbusGetFloat() | | | modbus_get_float_abcd() | ModbusGetFloatAbcd() | | | modbus_get_float_badc() | ModbusGetFloatBadc() | | | modbus_get_float_cdab() | ModbusGetFloatCdab() | | | modbus_get_float_dcba() | ModbusGetFloatDcba() | | | modbus_get_header_length() | Modbus.GetHeaderLength() | | | modbus_get_indication_timeout() | Modbus.GetIndicationTimeout() | | | modbus_get_response_timeout() | Modbus.GetResponseTimeout() | | | modbus_get_slave() | Modbus.GetSlave() | | | modbus_get_socket() | Modbus.GetSocket() | | | modbus_mapping_free() | ModbusMapping.Free() | | | modbus_mapping_new() | ModbusMapping.New() | | | modbus_mapping_new_start_address() | ModbusMapping.NewStartAddress() | | | modbus_mask_write_register() | Modbus.MaskWriteRegister() | | | modbus_new_rtu() | ModbusNewRtu() | | | modbus_new_tcp() | ModbusNewTcp() | | | modbus_new_tcp_pi() | ModbusNewTcpPi() | | | modbus_read_bits() | Modbus.ReadBits() | | | modbus_read_input_bits() | Modbus.ReadInputBits() | | | modbus_read_input_registers() | Modbus.ReadInputRegisters() | | | modbus_read_registers() | Modbus.ReadRegisters() | | | modbus_receive() | Modbus.Receive() | | | modbus_receive_confirmation() | Modbus.ReceiveConfirmation() | | | modbus_reply() | Modbus.Reply() | | | modbus_reply_exception() | Modbus.ReplyException() | | | modbus_report_slave_id() | Modbus.ReportSlaveId() | | | modbus_rtu_get_rts() | Modbus.RtuGetRts() | | | modbus_rtu_get_rts_delay() | Modbus.RtuGetRtsDelay() | | | modbus_rtu_get_serial_mode() | Modbus.RtuGetSerialMode() | | | modbus_rtu_set_custom_rts() | Modbus.RtuSetCustomRts() | | | modbus_rtu_set_rts() | Modbus.RtuSetRts() | | | modbus_rtu_set_rts_delay() | Modbus.RtuSetRtsDelay() | | | modbus_rtu_set_serial_mode() | Modbus.RtuSetSerialMode() | | | modbus_send_raw_request() | Modbus.SendRawRequest() | | | modbus_set_bits_from_byte() | ModbusSetBitsFromByte() | | | modbus_set_bits_from_bytes() | ModbusSetBitsFromBytes() | | | modbus_set_byte_timeout() | Modbus.SetByteTimeout() | | | modbus_set_debug() | Modbus.SetDebug() | | | modbus_set_error_recovery() | Modbus.SetErrorRecovery() | | | modbus_set_float() | ModbusSetFloat() | | | modbus_set_float_abcd() | ModbusSetFloatAbcd() | | | modbus_set_float_badc() | ModbusSetFloatBadc() | | | modbus_set_float_cdab() | ModbusSetFloatCdab() | | | modbus_set_float_dcba() | ModbusSetFloatDcba() | | | modbus_set_indication_timeout() | Modbus.SetIndicationTimeout() | | | modbus_set_response_timeout() | Modbus.SetResponseTimeout() | | | modbus_set_slave() | Modbus.SetSlave() | | | modbus_set_socket() | Modbus.SetSocket() | | | modbus_strerror() | ModbusStrError() | | | modbus_tcp_accept() | Modbus.TcpAccept() | | | modbus_tcp_listen() | Modbus.TcpListen() | | | modbus_tcp_pi_accept() | Modbus.TcpPiAccept() | | | modbus_tcp_pi_listen() | Modbus.TcpPiListen() | | | modbus_write_and_read_registers() | Modbus.WriteAndReadRegisters() | | | modbus_write_bit() | Modbus.WriteBit() | | | modbus_write_bits() | Modbus.WriteBits() | | | modbus_write_register() | Modbus.WriteRegister() | | | modbus_write_registers() | Modbus.WriteRegisters() | |
cgo, C, go type convert ¶
|C Language Type | CGO Type |Go Language Type| SDK | |---------------------- | ------------- | -------------- | -------------- | |char | C.char | byte | | |singed char | C.schar | int8 | | |unsigned char | C.uchar | uint8 | BYTE | |short | C.short | int16 | | |unsigned short | C.ushort | uint16 | WORD,USHORT | |int | C.int | int32 | BOOL,LONG | |unsigned int | C.uint | uint32 | DWORD,UINT | |long | C.long | int32 | | |unsigned long | C.ulong | uint32 | | |long long int | C.longlong | int64 | | |unsigned long long int | C.ulonglong | uint64 | | |float | C.float | float32 | | |double | C.double | float64 | | |size_t | C.size_t | uint | | |void* | unsafe.Pointer| unsafe.Pointer | LPVOID.HANDLE |
cgo, C, go string convert ¶
func C.CString(string) *C.char
Go string to C string. The C string is allocated in the C heap using malloc. It is the caller's responsibility to arrange for it to be freed, such as by calling C.free (be sure to include stdlib.h if C.free is needed).
func C.CBytes([]byte) unsafe.Pointer
Go []byte slice to C array. The C array is allocated in the C heap using malloc. It is the caller's responsibility to arrange for it to be freed, such as by calling C.free (be sure to include stdlib.h if C.free is needed).
func C.GoString(*C.char) string
C string to Go string
func C.GoStringN(*C.char, C.int) string
C data with explicit length to Go string
func C.GoBytes(unsafe.Pointer, C.int) []byte
C data with explicit length to Go []byte
C header -> CGO header ¶
delete __stdcall
delete CALLBACK
enum XXX{}; -> type enum _XXX {}XXX;
delete function with init parameters, pUser = NULL
struct must have tag name
Index ¶
- Constants
- Variables
- func ModbusGetByteFromBits(src []byte, index int, nb uint) byte
- func ModbusGetFloat(src []uint16) float32
- func ModbusGetFloatAbcd(src []uint16) float32
- func ModbusGetFloatBadc(src []uint16) float32
- func ModbusGetFloatCdab(src []uint16) float32
- func ModbusGetFloatDcba(src []uint16) float32
- func ModbusGetHighByte[T int16 | uint16 | int32 | uint32 | int64 | uint64](data T) byte
- func ModbusGetInt16FromInt8(tab []int8) int16
- func ModbusGetInt32FromInt16(tab []int16) int32
- func ModbusGetInt64FromInt16(tab []int16) int64
- func ModbusGetLowByte[T int16 | uint16 | int32 | uint32 | int64 | uint64](data T) byte
- func ModbusSetBitsFromByte(dest []byte, index int, value byte)
- func ModbusSetBitsFromBytes(dest []byte, index int, nb uint, tab []byte)
- func ModbusSetFloat(f float32, dest []uint16)
- func ModbusSetFloatAbcd(f float32, dest []uint16)
- func ModbusSetFloatBadc(f float32, dest []uint16)
- func ModbusSetFloatCdab(f float32, dest []uint16)
- func ModbusSetFloatDcba(f float32, dest []uint16)
- func ModbusSetInt16ToInt8(value int16) []int8
- func ModbusSetInt32ToInt16(value int32) []int16
- func ModbusSetInt64ToInt16(value int64) []int16
- func ModbusStrError() error
- func ModbusVersionCheck(major uint, minor uint, micro uint) bool
- type Error
- type ErrorCode
- type Modbus
- func (x *Modbus) Close()
- func (x *Modbus) Connect() (err error)
- func (x *Modbus) DisableQuirks(quirksMask ModbusQuirks) (err error)
- func (x *Modbus) EnableQuirks(quirksMask ModbusQuirks) (err error)
- func (x *Modbus) Flush() (err error)
- func (x *Modbus) Free()
- func (x *Modbus) GetByteTimeout() (timeout time.Duration, err error)
- func (x *Modbus) GetHeaderLength() (length int)
- func (x *Modbus) GetIndicationTimeout() (timeout time.Duration, err error)
- func (x *Modbus) GetResponseTimeout() (timeout time.Duration, err error)
- func (x *Modbus) GetSlave() (slave int, err error)
- func (x *Modbus) GetSocket() (s int, err error)
- func (x *Modbus) MaskWriteRegister(addr int, andMask uint16, orMask uint16) (err error)
- func (x *Modbus) ReadBits(addr int, nb int) (out []byte, err error)
- func (x *Modbus) ReadInputBits(addr int, nb int) (out []byte, err error)
- func (x *Modbus) ReadInputRegisters(addr int, nb int) (out []uint16, err error)
- func (x *Modbus) ReadRegisters(addr int, nb int) (out []uint16, err error)
- func (x *Modbus) Receive() (req []byte, err error)
- func (x *Modbus) ReceiveConfirmation() (rsp []byte, err error)
- func (x *Modbus) Reply(req []byte, mm *ModbusMapping) (err error)
- func (x *Modbus) ReplyException(req []byte, ecode uint) (err error)
- func (x *Modbus) ReportSlaveId() (dest *ReportSlaveId, err error)
- func (x *Modbus) RtuGetRts() (mode int, err error)
- func (x *Modbus) RtuGetRtsDelay() (us time.Duration, err error)
- func (x *Modbus) RtuGetSerialMode() (mode int, err error)
- func (x *Modbus) RtuReceive() (req []byte, err error)
- func (x *Modbus) RtuReceiveConfirmation() (rsp []byte, err error)
- func (x *Modbus) RtuSetCustomRts(cb SetRtsCallback) (err error)
- func (x *Modbus) RtuSetRts(mode int) (err error)
- func (x *Modbus) RtuSetRtsDelay(us time.Duration) (err error)
- func (x *Modbus) RtuSetSerialMode(mode int) (err error)
- func (x *Modbus) SendRawRequest(raw []byte) (err error)
- func (x *Modbus) SendRawRequestTid(raw []byte, tid int) (err error)
- func (x *Modbus) SetByteTimeout(timeout time.Duration) (err error)
- func (x *Modbus) SetDebug(flag bool) (err error)
- func (x *Modbus) SetErrorRecovery(errorRecovery ModbusErrorRecoveryMode) (err error)
- func (x *Modbus) SetIndicationTimeout(timeout time.Duration) (err error)
- func (x *Modbus) SetResponseTimeout(timeout time.Duration) (err error)
- func (x *Modbus) SetSlave(slave int) (err error)
- func (x *Modbus) SetSocket(s int) (err error)
- func (x *Modbus) TcpAccept() (socket int, err error)
- func (x *Modbus) TcpListen(nb int) (socket int, err error)
- func (x *Modbus) TcpPiAccept() (err error)
- func (x *Modbus) TcpPiListen(nb int) (socket int, err error)
- func (x *Modbus) TcpReceive() (req []byte, err error)
- func (x *Modbus) TcpReceiveConfirmation() (rsp []byte, err error)
- func (x *Modbus) TcpSocket() int
- func (x *Modbus) WriteAndReadRegisters(writeAddr int, src []uint16, readAddr int, readNb int) (dest []uint16, err error)
- func (x *Modbus) WriteBit(addr int, status byte) (err error)
- func (x *Modbus) WriteBits(addr int, data []byte) (err error)
- func (x *Modbus) WriteRegister(addr int, value uint16) (err error)
- func (x *Modbus) WriteRegisters(addr int, data []uint16) (err error)
- type ModbusErrorRecoveryMode
- type ModbusException
- type ModbusMapping
- func (mm *ModbusMapping) Free()
- func (mm *ModbusMapping) GetTabBits(addr int) byte
- func (mm *ModbusMapping) GetTabInputBits(addr int) byte
- func (mm *ModbusMapping) GetTabInputRegisters(addr int) uint16
- func (mm *ModbusMapping) GetTabRegisters(addr int) uint16
- func (mm *ModbusMapping) MarshalBinary() (buff []byte, err error)
- func (mm *ModbusMapping) NbBits() int
- func (mm *ModbusMapping) NbInputBits() int
- func (mm *ModbusMapping) NbInputRegisters() int
- func (mm *ModbusMapping) NbRegisters() int
- func (mm *ModbusMapping) SetTabBits(addr int, v byte)
- func (mm *ModbusMapping) SetTabInputBits(addr int, v byte)
- func (mm *ModbusMapping) SetTabInputRegisters(addr int, v uint16)
- func (mm *ModbusMapping) SetTabRegisters(addr int, v uint16)
- func (mm *ModbusMapping) StartBits() int
- func (mm *ModbusMapping) StartInputBits() int
- func (mm *ModbusMapping) StartInputRegisters() int
- func (mm *ModbusMapping) StartRegisters() int
- func (mm *ModbusMapping) TabBits() iter.Seq2[int, byte]
- func (mm *ModbusMapping) TabInputBits() iter.Seq2[int, byte]
- func (mm *ModbusMapping) TabInputRegisters() iter.Seq2[int, uint16]
- func (mm *ModbusMapping) TabRegisters() iter.Seq2[int, uint16]
- func (mm *ModbusMapping) UnmarshalBinary(data []byte) (err error)
- type ModbusQuirks
- type ReportSlaveId
- type SetRtsCallback
Examples ¶
- Modbus.Close
- Modbus.Connect
- Modbus.DisableQuirks
- Modbus.EnableQuirks
- Modbus.Free
- Modbus.GetByteTimeout
- Modbus.GetIndicationTimeout
- Modbus.GetResponseTimeout
- Modbus.ReadRegisters
- Modbus.ReceiveConfirmation
- Modbus.ReportSlaveId
- Modbus.RtuSetRts
- Modbus.RtuSetSerialMode
- Modbus.SendRawRequest
- Modbus.SetErrorRecovery
- Modbus.SetResponseTimeout
- Modbus.SetSlave
- Modbus.SetSocket
- Modbus.TcpAccept
- Modbus.TcpListen
- Modbus.TcpPiAccept
- Modbus.TcpPiListen
- ModbusMapping.Free
- ModbusMappingNew
- ModbusMappingNewStartAddress
- ModbusNewRtu
- ModbusNewTcp
- ModbusNewTcpPi
Constants ¶
const ( MODBUS_FC_READ_COILS = C.MODBUS_FC_READ_COILS MODBUS_FC_READ_DISCRETE_INPUTS = C.MODBUS_FC_READ_DISCRETE_INPUTS MODBUS_FC_READ_HOLDING_REGISTERS = C.MODBUS_FC_READ_HOLDING_REGISTERS MODBUS_FC_READ_INPUT_REGISTERS = C.MODBUS_FC_READ_INPUT_REGISTERS MODBUS_FC_WRITE_SINGLE_COIL = C.MODBUS_FC_WRITE_SINGLE_COIL MODBUS_FC_WRITE_SINGLE_REGISTER = C.MODBUS_FC_WRITE_SINGLE_REGISTER MODBUS_FC_READ_EXCEPTION_STATUS = C.MODBUS_FC_READ_EXCEPTION_STATUS MODBUS_FC_WRITE_MULTIPLE_COILS = C.MODBUS_FC_WRITE_MULTIPLE_COILS MODBUS_FC_WRITE_MULTIPLE_REGISTERS = C.MODBUS_FC_WRITE_MULTIPLE_REGISTERS MODBUS_FC_REPORT_SLAVE_ID = C.MODBUS_FC_REPORT_SLAVE_ID MODBUS_FC_MASK_WRITE_REGISTER = C.MODBUS_FC_MASK_WRITE_REGISTER MODBUS_FC_WRITE_AND_READ_REGISTERS = C.MODBUS_FC_WRITE_AND_READ_REGISTERS )
Modbus function codes
const ( MODBUS_MAX_READ_BITS = C.MODBUS_MAX_READ_BITS MODBUS_MAX_WRITE_BITS = C.MODBUS_MAX_WRITE_BITS )
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12) Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0) (chapter 6 section 11 page 29) Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
const ( MODBUS_MAX_READ_REGISTERS = C.MODBUS_MAX_READ_REGISTERS MODBUS_MAX_WRITE_REGISTERS = C.MODBUS_MAX_WRITE_REGISTERS MODBUS_MAX_WR_WRITE_REGISTERS = C.MODBUS_MAX_WR_WRITE_REGISTERS MODBUS_MAX_WR_READ_REGISTERS = C.MODBUS_MAX_WR_READ_REGISTERS )
Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15) Quantity of Registers to read (2 bytes): 1 to 125 (0x7D) (chapter 6 section 12 page 31) Quantity of Registers to write (2 bytes) 1 to 123 (0x7B) (chapter 6 section 17 page 38) Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
const ( MODBUS_RTU_RS232 = C.MODBUS_RTU_RS232 MODBUS_RTU_RS485 = C.MODBUS_RTU_RS485 )
const ( MODBUS_RTU_RTS_NONE = C.MODBUS_RTU_RTS_NONE MODBUS_RTU_RTS_UP = C.MODBUS_RTU_RTS_UP MODBUS_RTU_RTS_DOWN = C.MODBUS_RTU_RTS_DOWN )
const ( MODBUS_TCP_DEFAULT_PORT = C.MODBUS_TCP_DEFAULT_PORT MODBUS_TCP_SLAVE = C.MODBUS_TCP_SLAVE )
const ( LIBMODBUS_VERSION_MAJOR = C.LIBMODBUS_VERSION_MAJOR // The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) LIBMODBUS_VERSION_MINOR = C.LIBMODBUS_VERSION_MINOR // The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) LIBMODBUS_VERSION_MICRO = C.LIBMODBUS_VERSION_MICRO // The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) LIBMODBUS_VERSION_STRING = C.LIBMODBUS_VERSION_STRING // The full version, in string form (suited for string concatenation) LIBMODBUS_VERSION_HEX = C.LIBMODBUS_VERSION_HEX // Numerically encoded version, eg. v1.2.3 is 0x010203 )
const (
MODBUS_BROADCAST_ADDRESS = C.MODBUS_BROADCAST_ADDRESS
)
const MODBUS_ENOBASE = C.MODBUS_ENOBASE
MODBUS_ENOBASE Random number to avoid errno conflicts
const MODBUS_MAX_ADU_LENGTH = C.MODBUS_MAX_ADU_LENGTH
MODBUS_MAX_ADU_LENGTH
Consequently:
- RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256 bytes.
- TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.
so the maximum of both backend in 260 bytes. This size can used to allocate an array of bytes to store responses and it will be compatible with the two backends.
const MODBUS_MAX_PDU_LENGTH = C.MODBUS_MAX_PDU_LENGTH
MODBUS_MAX_PDU_LENGTH The size of the MODBUS PDU is limited by the size constraint inherited from the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256 bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server address (1 byte) - CRC (2 bytes) = 253 bytes.
const ( // MODBUS_RTU_MAX_ADU_LENGTH Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 // RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes MODBUS_RTU_MAX_ADU_LENGTH = C.MODBUS_RTU_MAX_ADU_LENGTH )
const ( // MODBUS_TCP_MAX_ADU_LENGTH Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 // TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes MODBUS_TCP_MAX_ADU_LENGTH = C.MODBUS_TCP_MAX_ADU_LENGTH )
Variables ¶
var ( LibmodbusVersionMajor = C.libmodbus_version_major LibmodbusVersionMinor = C.libmodbus_version_minor LibmodbusVersionMicro = C.libmodbus_version_micro )
Functions ¶
func ModbusGetByteFromBits ¶
ModbusGetByteFromBits modbus_get_byte_from_bits - get the value from many bits
The modbus_get_byte_from_bits() function shall extract a value from many bits. All nb_bits bits from src at position index will be read as a single value. To obtain a full byte, set nb_bits to 8.
func ModbusGetFloat ¶
ModbusGetFloat modbus_get_float - get a float value from 2 registers
The modbus_get_float() function shall get a float from 4 bytes in Modbus format (DCBA byte order). The src array must be a pointer on two 16 bits values, for example, if the first word is set to 0x4465 and the second to 0x229a, the float value will be 916.540649.
func ModbusGetFloatAbcd ¶
ModbusGetFloatAbcd modbus_get_float_abcd - get a float value from 2 registers in ABCD byte order
The modbus_get_float_abcd() function shall get a float from 4 bytes in usual Modbus format. The src array must be a pointer on two 16 bits values, for example, if the first word is set to 0x0020 and the second to 0xF147, the float value will be read as 123456.0.
func ModbusGetFloatBadc ¶
ModbusGetFloatBadc modbus_get_float_badc - get a float value from 2 registers in BADC byte order
The modbus_get_float_badc() function shall get a float from 4 bytes with swapped bytes (BADC instead of ABCD). The src array must be a pointer on two 16 bits values, for example, if the first word is set to 0x2000 and the second to 0x47F1, the float value will be read as 123456.0.
func ModbusGetFloatCdab ¶
ModbusGetFloatCdab modbus_get_float_cdab - get a float value from 2 registers in CDAB byte order
The modbus_get_float_cdab() function shall get a float from 4 bytes with swapped words (CDAB order instead of ABCD). The src array must be a pointer on two 16 bits values, for example, if the first word is set to F147 and the second to 0x0020, the float value will be read as 123456.0.
func ModbusGetFloatDcba ¶
ModbusGetFloatDcba modbus_get_float_dcba - get a float value from 2 registers in DCBA byte order
The modbus_get_float_dcba() function shall get a float from 4 bytes in inverted Modbus format (DCBA order instead of ABCD). The src array must be a pointer on two 16 bits values, for example, if the first word is set to 0x47F1 and the second to 0x2000, the float value will be read as 123456.0.
func ModbusGetHighByte ¶
func ModbusGetInt16FromInt8 ¶
func ModbusGetInt32FromInt16 ¶
func ModbusGetInt64FromInt16 ¶
func ModbusGetLowByte ¶
func ModbusSetBitsFromByte ¶
ModbusSetBitsFromByte modbus_set_bits_from_byte - set many bits from a single byte value
The modbus_set_bits_from_byte() function shall set many bits from a single byte. All 8 bits from the byte value will be written to dest array starting at index position.
func ModbusSetBitsFromBytes ¶
ModbusSetBitsFromBytes modbus_set_bits_from_bytes - set many bits from an array of bytes
The modbus_set_bits_from_bytes function shall set bits by reading an array of bytes. All the bits of the bytes read from the first position of the array tab_byte are written as bits in the dest array starting at position index.
func ModbusSetFloat ¶
ModbusSetFloat modbus_set_float - set a float value from 2 registers
The modbus_set_float() function shall set a float to 4 bytes in Modbus format (ABCD). The dest array must be pointer on two 16 bits values to be able to store the full result of the conversion.
func ModbusSetFloatAbcd ¶
ModbusSetFloatAbcd modbus_set_float_abcd - set a float value in 2 registers using ABCD byte order
The modbus_set_float_abcd() function shall set a float to 4 bytes in usual Modbus format. The dest array must be pointer on two 16 bits values to be able to store the full result of the conversion.
func ModbusSetFloatBadc ¶
ModbusSetFloatBadc modbus_set_float_badc - set a float value in 2 registers using BADC byte order
The modbus_set_float_badc() function shall set a float to 4 bytes in swapped bytes Modbus format (BADC instead of ABCD). The dest array must be pointer on two 16 bits values to be able to store the full result of the conversion.
func ModbusSetFloatCdab ¶
ModbusSetFloatCdab modbus_set_float_cdab - set a float value in 2 registers using CDAB byte order
The modbus_set_float_cdab() function shall set a float to 4 bytes in swapped words Modbus format (CDAB order instead of ABCD). The dest array must be pointer on two 16 bits values to be able to store the full result of the conversion.
func ModbusSetFloatDcba ¶
ModbusSetFloatDcba modbus_set_float_dcba - set a float value in 2 registers using DCBA byte order
The modbus_set_float_dcba() function shall set a float to 4 bytes in inverted Modbus format (DCBA order). The dest array must be pointer on two 16 bits values to be able to store the full result of the conversion.
func ModbusSetInt16ToInt8 ¶
func ModbusSetInt32ToInt16 ¶
func ModbusSetInt64ToInt16 ¶
func ModbusStrError ¶
func ModbusStrError() error
ModbusStrError modbus_strerror - return the error message
The modbus_strerror() function shall return a pointer to an error message string corresponding to the error number specified by the errnum argument. As libmodbus defines additional error numbers over and above those defined by the operating system, applications should use modbus_strerror() in preference to the standard strerror() function.
Types ¶
type ErrorCode ¶
type ErrorCode int
const ( EMBXILFUN ErrorCode = C.EMBXILFUN EMBXILADD ErrorCode = C.EMBXILADD EMBXILVAL ErrorCode = C.EMBXILVAL EMBXSFAIL ErrorCode = C.EMBXSFAIL EMBXACK ErrorCode = C.EMBXACK EMBXSBUSY ErrorCode = C.EMBXSBUSY EMBXNACK ErrorCode = C.EMBXNACK EMBXMEMPAR ErrorCode = C.EMBXMEMPAR EMBXGPATH ErrorCode = C.EMBXGPATH EMBXGTAR ErrorCode = C.EMBXGTAR )
type Modbus ¶
type Modbus struct {
// contains filtered or unexported fields
}
func ModbusNewRtu ¶
modbus_new_rtu modbus_new_rtu - create a libmodbus context for RTU
The modbus_new_rtu() function shall allocate and initialize a modbus_t structure to communicate in RTU mode on a serial line.
The device argument specifies the name of the serial port handled by the OS, eg. "/dev/ttyS0" or "/dev/ttyUSB0". On Windows, it's necessary to prepend COM name with "\.\" for COM number greater than 9, eg. "\\.\COM10". See http:// msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx for details
The baud argument specifies the baud rate of the communication, eg. 9600, 19200, 57600, 115200, etc.
The parity argument can have one of the following values:
- N for none
- E for even
- O for odd
The data_bits argument specifies the number of bits of data, the allowed values are 5, 6, 7 and 8.
The stop_bits argument specifies the bits of stop, the allowed values are 1 and 2.
Once the modbus_t structure is initialized, you can connect to the serial bus with modbus_connect.
In RTU, your program can act as server or client:
server is called slave in Modbus terminology, your program will expose data to the network by processing and answering the requests of one of several clients. It up to you to define the slave ID of your service with modbus_set_slave, this ID should be used by the client to communicate with your program.
client is called master in Modbus terminology, your program will send requests to servers to read or write data from them. Before issuing the requests, you should define the slave ID of the remote device with modbus_set_slave. The slave ID is not an argument of the read/write functions because it's very frequent to talk with only one server so you can set it once and for all. The slave ID it not used in TCP communications so this way the API is common to both.
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.SetSlave(1) if err != nil { fmt.Println(err) return } out, err := ctx.ReadRegisters(0, 2) if err != nil { fmt.Println(err) return } fmt.Println(out)
func ModbusNewTcp ¶
ModbusNewTcp modbus_new_tcp - create a libmodbus context for TCP/IPv4
The modbus_new_tcp() function shall allocate and initialize a modbus_t structure to communicate with a Modbus TCP IPv4 server.
The ip argument specifies the IP address of the server to which the client wants to establish a connection. A NULL value can be used to listen any addresses in server mode.
The port argument is the TCP port to use. Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one (502). It's convenient to use a port number greater than or equal to 1024 because it's not necessary to have administrator privileges.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func ModbusNewTcpPi ¶
ModbusNewTcpPi modbus_new_tcp_pi - create a libmodbus context for TCP Protocol Independent
The modbus_new_tcp_pi() function shall allocate and initialize a modbus_t structure to communicate with a Modbus TCP IPv4 or IPv6 server.
The node argument specifies the host name or IP address of the host to connect to, eg. "192.168.0.5" , "::1" or "server.com". A NULL value can be used to listen any addresses in server mode.
The service argument is the service name/port number to connect to. To use the default Modbus port, you can provide an NULL value or the string "502". On many Unix systems, it's convenient to use a port number greater than or equal to 1024 because it's not necessary to have administrator privileges.
v3.1.8 handles NULL value for service (no EINVAL error).
Example ¶
ctx := ModbusNewTcpPi("::1", "1502") if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func (*Modbus) Close ¶
func (x *Modbus) Close()
Close modbus_close - close a Modbus connection
The modbus_close() function shall close the connection established with the backend set in the context.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func (*Modbus) Connect ¶
Connect modbus_connect - establish a Modbus connection
The modbus_connect() function shall establish a connection to a Modbus server, a network or a bus using the context information of libmodbus context given in argument.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func (*Modbus) DisableQuirks ¶
func (x *Modbus) DisableQuirks(quirksMask ModbusQuirks) (err error)
DisableQuirks modbus_disable_quirks - disable a list of quirks according to a mask
The function shall disable the quirks according to the provided mask. It's useful to revert changes applied by a previous call to modbus_enable_quirks
To reset all quirks, you can use the specific value MODBUS_QUIRK_ALL.
modbus_enable_quirks(ctx, MODBUS_QUIRK_MAX_SLAVE | MODBUS_QUIRK_REPLY_TO_BROADCAST); ... // Reset all quirks modbus_disable_quirks(ctx, MODBUS_QUIRK_ALL);
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.DisableQuirks(MODBUS_QUIRK_ALL) if err != nil { fmt.Println(err) return }
func (*Modbus) EnableQuirks ¶
func (x *Modbus) EnableQuirks(quirksMask ModbusQuirks) (err error)
EnableQuirks modbus_enable_quirks - enable a list of quirks according to a mask
The function is only useful when you are confronted with equipment which does not respect the protocol, which behaves strangely or when you wish to move away from the standard.
In that case, you can enable a specific quirk to workaround the issue, libmodbus offers the following flags:
- MODBUS_QUIRK_MAX_SLAVE allows slave adresses between 247 and 255.
- MODBUS_QUIRK_REPLY_TO_BROADCAST force a reply to a broacast request when the device is a slave in RTU mode (should be enabled on the slave device).
You can combine the flags by using the bitwise OR operator.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.EnableQuirks(MODBUS_QUIRK_MAX_SLAVE | MODBUS_QUIRK_REPLY_TO_BROADCAST) if err != nil { fmt.Println(err) return }
func (*Modbus) Flush ¶
Flush modbus_flush - flush non-transmitted data
The modbus_flush() function shall discard data received but not read to the socket or file descriptor associated to the context 'ctx'.
func (*Modbus) Free ¶
func (x *Modbus) Free()
Free modbus_free - free a libmodbus context
The modbus_free() function shall free an allocated modbus_t structure.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func (*Modbus) GetByteTimeout ¶
GetByteTimeout modbus_get_byte_timeout - get timeout between bytes
The modbus_get_byte_timeout() function shall store the timeout interval between two consecutive bytes of the same message in the to_sec and to_usec arguments.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() timeout, err := ctx.GetByteTimeout() if err != nil { fmt.Println(err) return } fmt.Println(timeout)
func (*Modbus) GetHeaderLength ¶
GetHeaderLength modbus_get_header_length - retrieve the current header length
The modbus_get_header_length() function shall retrieve the current header length from the backend. This function is convenient to manipulate a message and so it's limited to low-level operations.
func (*Modbus) GetIndicationTimeout ¶
GetIndicationTimeout modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server).
The modbus_get_indication_timeout() function shall store the timeout interval used to wait for an indication in the to_sec and to_usec arguments. Indication is the term used by the Modbus protocol to designate a request received by the server.
The default value is zero, it means the server will wait forever.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() timeout, err := ctx.GetIndicationTimeout() if err != nil { fmt.Println(err) return } fmt.Println(timeout)
func (*Modbus) GetResponseTimeout ¶
GetResponseTimeout modbus_get_response_timeout - get timeout for response
The modbus_get_response_timeout() function shall return the timeout interval used to wait for a response in the to_sec and to_usec arguments.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() timeout, err := ctx.GetResponseTimeout() if err != nil { fmt.Println(err) return } fmt.Println(timeout)
func (*Modbus) GetSlave ¶
GetSlave modbus_get_slave - get slave number in the context
The modbus_get_slave() function shall get the slave number in the libmodbus context.
func (*Modbus) GetSocket ¶
GetSocket modbus_get_socket - get the current socket of the context
The modbus_get_socket() function shall return the current socket or file descriptor of the libmodbus context.
func (*Modbus) MaskWriteRegister ¶
MaskWriteRegister modbus_mask_write_register - mask a single register
The modbus_mask_write_register() function shall modify the value of the holding register at the address 'addr' of the remote device using the algorithm:
new value = (current value AND 'and') OR ('or' AND (NOT 'and'))
The function uses the Modbus function code 0x16 (mask single register).
func (*Modbus) ReadBits ¶
ReadBits modbus_read_bits - read many bits
The modbus_read_bits() function shall read the status of the nb bits (coils) to the address addr of the remote device. The result of reading is stored in dest array as unsigned bytes (8 bits) set to TRUE or FALSE.
You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint8_t)).
The function uses the Modbus function code 0x01 (read coil status).
func (*Modbus) ReadInputBits ¶
ReadInputBits modbus_read_input_bits - read many input bits
The modbus_read_input_bits() function shall read the content of the nb input bits to the address addr of the remote device. The result of reading is stored in dest array as unsigned bytes (8 bits) set to TRUE or FALSE.
You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint8_t)).
The function uses the Modbus function code 0x02 (read input status).
func (*Modbus) ReadInputRegisters ¶
ReadInputRegisters modbus_read_input_registers - read many input registers
The modbus_read_input_registers() function shall read the content of the nb input registers to address addr of the remote device. The result of the reading is stored in dest array as word values (16 bits).
You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint16_t)).
The function uses the Modbus function code 0x04 (read input registers). The holding registers and input registers have different historical meaning, but nowadays it's more common to use holding registers only.
func (*Modbus) ReadRegisters ¶
ReadRegisters modbus_read_registers - read many registers
The modbus_read_registers() function shall read the content of the nb holding registers to the address addr of the remote device. The result of reading is stored in dest array as word values (16 bits).
You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint16_t)).
The function uses the Modbus function code 0x03 (read holding registers).
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.SetSlave(1) if err != nil { fmt.Println(err) return } out, err := ctx.ReadRegisters(0, 2) if err != nil { fmt.Println(err) return } fmt.Println(out)
func (*Modbus) Receive ¶
Receive modbus_receive - receive an indication request
The modbus_receive() function shall receive an indication request from the socket of the context ctx. This function is used by a Modbus slave/server to receive and analyze indication request sent by the masters/clients.
If you need to use another socket or file descriptor than the one defined in the context ctx, see the function modbus_set_socket.
func (*Modbus) ReceiveConfirmation ¶
ReceiveConfirmation modbus_receive_confirmation - receive a confirmation request
The modbus_receive_confirmation() function shall receive a request via the socket of the context ctx. This function must be used for debugging purposes because the received response isn't checked against the initial request. This function can be used to receive request not handled by the library.
The maximum size of the response depends on the used backend, in RTU the rsp array must be MODBUS_RTU_MAX_ADU_LENGTH bytes and in TCP it must be MODBUS_TCP_MAX_ADU_LENGTH bytes. If you want to write code compatible with both, you can use the constant MODBUS_MAX_ADU_LENGTH (maximum value of all libmodbus backends). Take care to allocate enough memory to store responses to avoid crashes of your server.
Example ¶
var ctx *Modbus // just for test rsp, err := ctx.ReceiveConfirmation() if err != nil { fmt.Println(err) return } fmt.Println(rsp)
func (*Modbus) Reply ¶
func (x *Modbus) Reply(req []byte, mm *ModbusMapping) (err error)
Reply modbus_reply - send a response to the received request
The modbus_reply() function shall send a response to received request. The request req given in argument is analyzed, a response is then built and sent by using the information of the modbus context ctx.
If the request indicates to read or write a value the operation will done in the modbus mapping mb_mapping according to the type of the manipulated data.
If an error occurs, an exception response will be sent.
This function is designed for Modbus servers.
func (*Modbus) ReplyException ¶
ReplyException modbus_reply_exception - send an exception response
The modbus_reply_exception() function shall send an exception response based on the 'exception_code' in argument.
The libmodbus provides the following exception codes:
- MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1)
- MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2)
- MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3)
- MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4)
- MODBUS_EXCEPTION_ACKNOWLEDGE (5)
- MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6)
- MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7)
- MODBUS_EXCEPTION_MEMORY_PARITY (8)
- MODBUS_EXCEPTION_NOT_DEFINED (9)
- MODBUS_EXCEPTION_GATEWAY_PATH (10)
- MODBUS_EXCEPTION_GATEWAY_TARGET (11)
The initial request req is required to build a valid response.
func (*Modbus) ReportSlaveId ¶
func (x *Modbus) ReportSlaveId() (dest *ReportSlaveId, err error)
ReportSlaveId modbus_report_slave_id - returns a description of the controller
The modbus_report_slave_id() function shall send a request to the controller to obtain a description of the controller.
The response stored in dest contains:
- the slave ID, this unique ID is in reality not unique at all so it's not possible to depend on it to know how the information are packed in the response.
- the run indicator status (0x00 = OFF, 0xFF = ON)
- additional data specific to each controller. For example, libmodbus returns the version of the library as a string.
The function writes at most max_dest bytes from the response to dest so you must ensure that dest is large enough.
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() report, err := ctx.ReportSlaveId() if err != nil { fmt.Println(err) return } fmt.Println(report.SlaveId) fmt.Println(report.RunIndicatorStatus)
func (*Modbus) RtuGetRts ¶
RtuGetRts modbus_rtu_get_rts - get the current RTS mode in RTU
The modbus_rtu_get_rts() function shall get the current Request To Send mode of the libmodbus context ctx. The possible returned values are:
- MODBUS_RTU_RTS_NONE
- MODBUS_RTU_RTS_UP
- MODBUS_RTU_RTS_DOWN
This function can only be used with a context using a RTU backend.
func (*Modbus) RtuGetRtsDelay ¶
RtuGetRtsDelay modbus_rtu_get_rts_delay - get the current RTS delay in RTU
The modbus_rtu_get_rts_delay() function shall get the current Request To Send delay period of the libmodbus context 'ctx'.
This function can only be used with a context using a RTU backend.
func (*Modbus) RtuGetSerialMode ¶
RtuGetSerialMode modbus_rtu_get_serial_mode - get the current serial mode
The modbus_rtu_get_serial_mode() function shall return the serial mode currently used by the libmodbus context:
MODBUS_RTU_RS232, the serial line is set for RS-232 communication. RS-232 (Recommended Standard 232) is the traditional name for a series of standards for serial binary single-ended data and control signals connecting between a DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating Equipment). It is commonly used in computer serial ports
MODBUS_RTU_RS485, the serial line is set for RS-485 communication. EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the electrical characteristics of drivers and receivers for use in balanced digital multipoint systems. This standard is widely used for communications in industrial automation because it can be used effectively over long distances and in electrically noisy environments. This function is only available on Linux kernels 2.6.28 onwards and can only be used with a context using a RTU backend.
func (*Modbus) RtuReceive ¶ added in v0.1.1
RtuReceive modbus_receive - receive an indication request
The modbus_receive() function shall receive an indication request from the socket of the context ctx. This function is used by a Modbus slave/server to receive and analyze indication request sent by the masters/clients.
If you need to use another socket or file descriptor than the one defined in the context ctx, see the function modbus_set_socket.
func (*Modbus) RtuReceiveConfirmation ¶ added in v0.1.1
RtuReceiveConfirmation modbus_receive_confirmation - receive a confirmation request
The modbus_receive_confirmation() function shall receive a request via the socket of the context ctx. This function must be used for debugging purposes because the received response isn't checked against the initial request. This function can be used to receive request not handled by the library.
The maximum size of the response depends on the used backend, in RTU the rsp array must be MODBUS_RTU_MAX_ADU_LENGTH bytes and in TCP it must be MODBUS_TCP_MAX_ADU_LENGTH bytes. If you want to write code compatible with both, you can use the constant MODBUS_MAX_ADU_LENGTH (maximum value of all libmodbus backends). Take care to allocate enough memory to store responses to avoid crashes of your server.
func (*Modbus) RtuSetCustomRts ¶
func (x *Modbus) RtuSetCustomRts(cb SetRtsCallback) (err error)
RtuSetCustomRts modbus_rtu_set_custom_rts - set a function to be used for custom RTS implementation
The modbus_rtu_set_custom_rts() function shall set a custom function to be called when the RTS pin is to be set before and after a transmission. By default this is set to an internal function that toggles the RTS pin using an ioctl call.
Note that this function adheres to the RTS mode, the values MODBUS_RTU_RTS_UP or MODBUS_RTU_RTS_DOWN must be used for the function to be called.
This function can only be used with a context using a RTU backend.
func (*Modbus) RtuSetRts ¶
RtuSetRts modbus_rtu_set_rts - set the RTS mode in RTU
The modbus_rtu_set_rts() function shall set the Request To Send mode to communicate on a RS-485 serial bus. By default, the mode is set to MODBUS_RTU_RTS_NONE and no signal is issued before writing data on the wire.
To enable the RTS mode, the values MODBUS_RTU_RTS_UP or MODBUS_RTU_RTS_DOWN must be used, these modes enable the RTS mode and set the polarity at the same time. When MODBUS_RTU_RTS_UP is used, an ioctl call is made with RTS flag enabled then data is written on the bus after a delay of 1 ms, then another ioctl call is made with the RTS flag disabled and again a delay of 1 ms occurs. The MODBUS_RTU_RTS_DOWN mode applies the same procedure but with an inverted RTS flag.
This function can only be used with a context using a RTU backend.
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() ctx.SetSlave(1) ctx.RtuSetSerialMode(MODBUS_RTU_RS485) ctx.RtuSetRts(MODBUS_RTU_RTS_UP) err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() report, err := ctx.ReportSlaveId() if err != nil { fmt.Println(err) return } fmt.Println(report.SlaveId) fmt.Println(report.RunIndicatorStatus)
func (*Modbus) RtuSetRtsDelay ¶
RtuSetRtsDelay modbus_rtu_set_rts_delay - set the RTS delay in RTU
The modbus_rtu_set_rts_delay() function shall set the Request To Send delay period of the libmodbus context 'ctx'.
This function can only be used with a context using a RTU backend.
func (*Modbus) RtuSetSerialMode ¶
RtuSetSerialMode modbus_rtu_set_serial_mode - set the serial mode
The modbus_rtu_set_serial_mode() function shall set the selected serial mode:
MODBUS_RTU_RS232, the serial line is set for RS-232 communication. RS-232 (Recommended Standard 232) is the traditional name for a series of standards for serial binary single-ended data and control signals connecting between a DTE (Data Terminal Equipment) and a DCE (Data Circuit-terminating Equipment). It is commonly used in computer serial ports.
MODBUS_RTU_RS485, the serial line is set for RS-485 communication. EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the electrical characteristics of drivers and receivers for use in balanced digital multipoint systems. This standard is widely used for communications in industrial automation because it can be used effectively over long distances and in electrically noisy environments.
This function is only supported on Linux kernels 2.6.28 onwards.
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() ctx.SetSlave(1) ctx.RtuSetSerialMode(MODBUS_RTU_RS485) ctx.RtuSetRts(MODBUS_RTU_RTS_UP) err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() report, err := ctx.ReportSlaveId() if err != nil { fmt.Println(err) return } fmt.Println(report.SlaveId) fmt.Println(report.RunIndicatorStatus)
func (*Modbus) SendRawRequest ¶
SendRawRequest modbus_send_raw_request - send a raw request
The modbus_send_raw_request() function shall send a request via the socket of the context ctx. This function must be used for debugging purposes because you have to take care to make a valid request by hand. The function only adds to the message, the header or CRC of the selected backend, so raw_req must start and contain at least a slave/unit identifier and a function code. This function can be used to send request not handled by the library.
The public header of libmodbus provides a list of supported Modbus functions codes, prefixed by MODBUS_FC_ (eg. MODBUS_FC_READ_HOLDING_REGISTERS), to help build of raw requests.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() req := []byte{0xFF, MODBUS_FC_READ_HOLDING_REGISTERS, 0x00, 0x01, 0x0, 0x05} err = ctx.SendRawRequest(req) if err != nil { fmt.Println(err) return } rsp, err := ctx.ReceiveConfirmation() if err != nil { fmt.Println(err) return } fmt.Println(rsp)
func (*Modbus) SendRawRequestTid ¶
func (*Modbus) SetByteTimeout ¶
SetByteTimeout modbus_set_byte_timeout - set timeout between bytes
The modbus_set_byte_timeout() function shall set the timeout interval between two consecutive bytes of the same message. The timeout is an upper bound on the amount of time elapsed before select() returns, if the time elapsed is longer than the defined timeout, an ETIMEDOUT error will be raised by the function waiting for a response.
The value of to_usec argument must be in the range 0 to 999999.
If both to_sec and to_usec are zero, this timeout will not be used at all. In this case, modbus_set_response_timeout() governs the entire handling of the response, the full confirmation response must be received before expiration of the response timeout. When a byte timeout is set, the response timeout is only used to wait for until the first byte of the response.
func (*Modbus) SetDebug ¶
SetDebug modbus_set_debug - set debug flag of the context
The modbus_set_debug() function shall set the debug flag of the modbus_t context by using the argument flag. By default, the boolean flag is set to FALSE. When the flag value is set to TRUE, many verbose messages are displayed on stdout and stderr. For example, this flag is useful to display the bytes of the Modbus messages.
func (*Modbus) SetErrorRecovery ¶
func (x *Modbus) SetErrorRecovery(errorRecovery ModbusErrorRecoveryMode) (err error)
SetErrorRecovery modbus_set_error_recovery - set the error recovery mode
The modbus_set_error_recovery() function shall set the error recovery mode to apply when the connection fails or the byte received is not expected. The argument error_recovery may be bitwise-or'ed with zero or more of the following constants.
By default there is no error recovery (MODBUS_ERROR_RECOVERY_NONE) so the application is responsible for controlling the error values returned by libmodbus functions and for handling them if necessary.
When MODBUS_ERROR_RECOVERY_LINK is set, the library will attempt an reconnection after a delay defined by response timeout of the libmodbus context. This mode will try an infinite close/connect loop until success on send call and will just try one time to re-establish the connection on select/read calls (if the connection was down, the values to read are certainly not available any more after reconnection, except for slave/server). This mode will also run flush requests after a delay based on the current response timeout in some situations (eg. timeout of select call). The reconnection attempt can hang for several seconds if the network to the remote target unit is down.
When MODBUS_ERROR_RECOVERY_PROTOCOL is set, a sleep and flush sequence will be used to clean up the ongoing communication, this can occurs when the message length is invalid, the TID is wrong or the received function code is not the expected one. The response timeout delay will be used to sleep.
The modes are mask values and so they are complementary.
It's not recommended to enable error recovery for a Modbus slave/server.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.SetErrorRecovery(MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL) if err != nil { fmt.Println(err) return } err = ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close()
func (*Modbus) SetIndicationTimeout ¶
SetIndicationTimeout modbus_set_indication_timeout - set timeout between indications
The modbus_set_indication_timeout() function shall set the timeout interval used by a server to wait for a request from a client.
The value of to_usec argument must be in the range 0 to 999999.
If both to_sec and to_usec are zero, this timeout will not be used at all. In this case, the server will wait forever.
func (*Modbus) SetResponseTimeout ¶
SetResponseTimeout modbus_set_response_timeout - set timeout for response
The modbus_set_response_timeout() function shall set the timeout interval used to wait for a response. When a byte timeout is set, if elapsed time for the first byte of response is longer than the given timeout, an ETIMEDOUT error will be raised by the function waiting for a response. When byte timeout is disabled, the full confirmation response must be received before expiration of the response timeout.
The value of to_usec argument must be in the range 0 to 999999.
Example ¶
ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.SetResponseTimeout(0) if err != nil { fmt.Println(err) return }
func (*Modbus) SetSlave ¶
SetSlave modbus_set_slave - set slave number in the context
The modbus_set_slave() function shall set the slave number in the libmodbus context.
It is usually only required to set the slave ID in RTU. The meaning of this ID will be different if your program acts as client (master) or server (slave).
As RTU client, modbus_set_slave() sets the ID of the remote device you want to communicate. Be sure to set the slave ID before issuing any Modbus requests on the serial bus. If you communicate with several servers (slaves), you can set the slave ID of the remote device before each request.
As RTU server, the slave ID allows the various clients to reach your service. You should use a free ID, once set, this ID should be known by the clients of the network. According to the protocol, a Modbus device must only accept message holding its slave number or the special broadcast number.
In TCP, the slave number is only required if the message must reach a device on a serial network. Some not compliant devices or software (such as modpoll) uses the slave ID as unit identifier, that's incorrect (cf page 23 of Modbus Messaging Implementation Guide v1.0b) but without the slave value, the faulty remote device or software drops the requests! The special value MODBUS_TCP_SLAVE (0xFF) can be used in TCP mode to restore the default value.
The broadcast address is MODBUS_BROADCAST_ADDRESS. This special value must be use when you want all Modbus devices of the network receive the request.
Example ¶
ctx := ModbusNewRtu("/dev/ttyUSB0", 115200, 'N', 8, 1) if ctx == nil { fmt.Println("Unable to create the libmodbus context") return } defer ctx.Free() err := ctx.Connect() if err != nil { fmt.Println(err) return } defer ctx.Close() err = ctx.SetSlave(1) if err != nil { fmt.Println(err) return } out, err := ctx.ReadRegisters(0, 2) if err != nil { fmt.Println(err) return } fmt.Println(out)
func (*Modbus) SetSocket ¶
SetSocket modbus_set_socket - set socket of the context
The modbus_set_socket() function shall set the socket or file descriptor in the libmodbus context. This function is useful for managing multiple client connections to the same server.
Example ¶
const NB_CONNECTION = 100 ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() ss, err := ctx.TcpListen(NB_CONNECTION) if err != nil { fmt.Println(err) return } var mm *ModbusMapping // TODO: var ms int rs := &unix.FdSet{} rs.Zero() rs.Set(ss) // ... TODO: if rs.IsSet(ms) { ctx.SetSocket(ms) req, err := ctx.Receive() if err == nil { ctx.Reply(req, mm) } }
func (*Modbus) TcpAccept ¶
TcpAccept modbus_tcp_accept - accept a new connection on a TCP Modbus socket (IPv4)
The modbus_tcp_accept() function shall extract the first connection on the queue of pending connections, create a new socket and store it in libmodbus context given in argument. If available, accept4() with SOCK_CLOEXEC will be called instead of accept().
Example ¶
const NB_CONNECTION = 100 ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() _, err := ctx.TcpListen(NB_CONNECTION) if err != nil { fmt.Println(err) return } _, err = ctx.TcpAccept() if err != nil { fmt.Println(err) return }
func (*Modbus) TcpListen ¶
TcpListen modbus_tcp_listen - create and listen a TCP Modbus socket (IPv4)
The modbus_tcp_listen() function shall create a socket and listen to maximum nb_connection incoming connections on the specified IP address. The context ctx must be allocated and initialized with modbus_new_tcp before to set the IP address to listen, if IP address is set to NULL or '0.0.0.0', any addresses will be listen.
Example ¶
const NB_CONNECTION = 100 ctx := ModbusNewTcp("127.0.0.1", 502) if ctx == nil { return } defer ctx.Free() _, err := ctx.TcpListen(NB_CONNECTION) if err != nil { fmt.Println(err) return } _, err = ctx.TcpAccept() if err != nil { fmt.Println(err) return }
func (*Modbus) TcpPiAccept ¶
TcpPiAccept modbus_tcp_pi_accept - accept a new connection on a TCP PI Modbus socket (IPv6)
The modbus_tcp_pi_accept() function shall extract the first connection on the queue of pending connections, create a new socket and store it in libmodbus context given in argument. If available, accept4() with SOCK_CLOEXEC will be called instead of accept().
Example ¶
const NB_CONNECTION = 100 ctx := ModbusNewTcpPi("::0", "502") if ctx == nil { return } defer ctx.Free() _, err := ctx.TcpPiListen(NB_CONNECTION) if err != nil { fmt.Println(err) return } err = ctx.TcpPiAccept() if err != nil { fmt.Println(err) return }
func (*Modbus) TcpPiListen ¶
TcpPiListen modbus_tcp_pi_listen - create and listen a TCP PI Modbus socket (IPv6)
The modbus_tcp_pi_listen() function shall create a socket and listen to maximum nb_connection incoming connections on the specified nodes. The context ctx must be allocated and initialized with modbus_new_tcp_pi before to set the node to listen, if node is set to NULL or '0.0.0.0', any addresses will be listen.
Example ¶
const NB_CONNECTION = 100 ctx := ModbusNewTcpPi("::0", "502") if ctx == nil { return } defer ctx.Free() _, err := ctx.TcpPiListen(NB_CONNECTION) if err != nil { fmt.Println(err) return } err = ctx.TcpPiAccept() if err != nil { fmt.Println(err) return }
func (*Modbus) TcpReceive ¶ added in v0.1.1
TcpReceive modbus_receive - receive an indication request
The modbus_receive() function shall receive an indication request from the socket of the context ctx. This function is used by a Modbus slave/server to receive and analyze indication request sent by the masters/clients.
If you need to use another socket or file descriptor than the one defined in the context ctx, see the function modbus_set_socket.
func (*Modbus) TcpReceiveConfirmation ¶ added in v0.1.1
RtuReceiveConfirmation modbus_receive_confirmation - receive a confirmation request
The modbus_receive_confirmation() function shall receive a request via the socket of the context ctx. This function must be used for debugging purposes because the received response isn't checked against the initial request. This function can be used to receive request not handled by the library.
The maximum size of the response depends on the used backend, in RTU the rsp array must be MODBUS_RTU_MAX_ADU_LENGTH bytes and in TCP it must be MODBUS_TCP_MAX_ADU_LENGTH bytes. If you want to write code compatible with both, you can use the constant MODBUS_MAX_ADU_LENGTH (maximum value of all libmodbus backends). Take care to allocate enough memory to store responses to avoid crashes of your server.
func (*Modbus) WriteAndReadRegisters ¶
func (x *Modbus) WriteAndReadRegisters(writeAddr int, src []uint16, readAddr int, readNb int) (dest []uint16, err error)
WriteAndReadRegisters modbus_write_and_read_registers - write and read many registers in a single transaction
The modbus_write_and_read_registers() function shall write the content of the write_nb holding registers from the array 'src' to the address write_addr of the remote device then shall read the content of the read_nb holding registers to the address read_addr of the remote device. The result of reading is stored in dest array as word values (16 bits).
You must take care to allocate enough memory to store the results in dest (at least nb * sizeof(uint16_t)).
The function uses the Modbus function code 0x17 (write/read registers).
func (*Modbus) WriteBit ¶
WriteBit modbus_write_bit - write a single bit
The modbus_write_bit() function shall write the status of status at the address addr of the remote device. The value must be set to TRUE or FALSE.
The function uses the Modbus function code 0x05 (force single coil).
func (*Modbus) WriteBits ¶
WriteBits modbus_write_bits - write many bits
The modbus_write_bits() function shall write the status of the nb bits (coils) from src at the address addr of the remote device. The src array must contains bytes set to TRUE or FALSE.
The function uses the Modbus function code 0x0F (force multiple coils).
func (*Modbus) WriteRegister ¶
WriteRegister modbus_write_register - write a single register
he modbus_write_register() function shall write the value of value holding registers at the address addr of the remote evice.
he function uses the Modbus function code 0x06 (preset single register).
func (*Modbus) WriteRegisters ¶
WriteRegisters modbus_write_registers - write many registers
The modbus_write_registers() function shall write the content of the nb holding registers from the array src at address addr of the remote device.
The function uses the Modbus function code 0x10 (preset multiple registers).
type ModbusErrorRecoveryMode ¶
type ModbusErrorRecoveryMode byte
const ( MODBUS_ERROR_RECOVERY_NONE ModbusErrorRecoveryMode = C.MODBUS_ERROR_RECOVERY_NONE MODBUS_ERROR_RECOVERY_LINK ModbusErrorRecoveryMode = C.MODBUS_ERROR_RECOVERY_LINK MODBUS_ERROR_RECOVERY_PROTOCOL ModbusErrorRecoveryMode = C.MODBUS_ERROR_RECOVERY_PROTOCOL )
type ModbusException ¶
type ModbusException int
ModbusException Protocol exceptions
const ( MODBUS_EXCEPTION_ILLEGAL_FUNCTION ModbusException = C.MODBUS_EXCEPTION_ILLEGAL_FUNCTION MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS ModbusException = C.MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE ModbusException = C.MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE ModbusException = C.MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE MODBUS_EXCEPTION_ACKNOWLEDGE ModbusException = C.MODBUS_EXCEPTION_ACKNOWLEDGE MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY ModbusException = C.MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE ModbusException = C.MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE MODBUS_EXCEPTION_MEMORY_PARITY ModbusException = C.MODBUS_EXCEPTION_MEMORY_PARITY MODBUS_EXCEPTION_NOT_DEFINED ModbusException = C.MODBUS_EXCEPTION_NOT_DEFINED MODBUS_EXCEPTION_GATEWAY_PATH ModbusException = C.MODBUS_EXCEPTION_GATEWAY_PATH MODBUS_EXCEPTION_GATEWAY_TARGET ModbusException = C.MODBUS_EXCEPTION_GATEWAY_TARGET MODBUS_EXCEPTION_MAX ModbusException = C.MODBUS_EXCEPTION_MAX )
type ModbusMapping ¶
type ModbusMapping struct {
// contains filtered or unexported fields
}
func ModbusMappingNew ¶
func ModbusMappingNew(nbBits int, nbInputBits int, nbRegisters int, nbInputRegisters int) *ModbusMapping
ModbusMappingNew modbus_mapping_new - allocate four arrays of bits and registers
The modbus_mapping_new() function shall allocate four arrays to store bits, input bits, registers and inputs registers. The pointers are stored in modbus_mapping_t structure. All values of the arrays are initialized to zero.
This function is equivalent to a call of the modbus_mapping_new_start_address function with all start addresses to 0.
If it isn't necessary to allocate an array for a specific type of data, you can pass the zero value in argument, the associated pointer will be NULL.
This function is convenient to handle requests in a Modbus server/slave.
Example ¶
BITS_ADDRESS := 0 BITS_NB := 10 INPUT_BITS_ADDRESS := 0 INPUT_BITS_NB := 10 REGISTERS_ADDRESS := 0 REGISTERS_NB := 10 INPUT_REGISTERS_ADDRESS := 0 INPUT_REGISTERS_NB := 10 mm := ModbusMappingNew( BITS_ADDRESS+BITS_NB, INPUT_BITS_ADDRESS+INPUT_BITS_NB, REGISTERS_ADDRESS+REGISTERS_NB, INPUT_REGISTERS_ADDRESS+INPUT_REGISTERS_NB, ) defer mm.Free() fmt.Println(mm.NbBits()) fmt.Println(mm.NbInputBits()) fmt.Println(mm.NbInputRegisters()) fmt.Println(mm.NbRegisters())
Output: 10 10 10 10
func ModbusMappingNewStartAddress ¶
func ModbusMappingNewStartAddress( startBits uint, nbBits uint, startInputBits uint, nbInputBits uint, startRegisters uint, nbRegisters uint, startInputRegisters uint, nbInputRegisters uint, ) *ModbusMapping
ModbusMappingNewStartAddress modbus_mapping_new_start_address - allocate four arrays of bits and registers accessible from their starting addresses
The modbus_mapping_new_start_address() function shall allocate four arrays to store bits, input bits, registers and inputs registers. The pointers are stored in modbus_mapping_t structure. All values of the arrays are initialized to zero.
The different starting addresses make it possible to place the mapping at any address in each address space. This way, you can give access to clients to values stored at high addresses without allocating memory from the address zero, for example to make available registers from 340 to 349, you can use:
mb_mapping = modbus_mapping_new_start_address(0, 0, 0, 0, 340, 10, 0, 0);
The newly created mb_mapping will have the following arrays:
- tab_bits set to NULL
- tab_input_bits set to NULL
- tab_input_registers allocated to store 10 registers (uint16_t)
- tab_registers set to NULL.
The clients can read the first register by using the address 340 in its request. On the server side, you should use the first index of the array to set the value at this client address:
mb_mapping->tab_registers[0] = 42;
If it isn't necessary to allocate an array for a specific type of data, you can pass the zero value in argument, the associated pointer will be NULL.
This function is convenient to handle requests in a Modbus server/slave.
Example ¶
BITS_ADDRESS := 0 BITS_NB := 10 INPUT_BITS_ADDRESS := 0 INPUT_BITS_NB := 10 REGISTERS_ADDRESS := 0 REGISTERS_NB := 10 INPUT_REGISTERS_ADDRESS := 0 INPUT_REGISTERS_NB := 10 mm := ModbusMappingNewStartAddress( uint(BITS_ADDRESS), uint(BITS_NB), uint(INPUT_BITS_ADDRESS), uint(INPUT_BITS_NB), uint(REGISTERS_ADDRESS), uint(REGISTERS_NB), uint(INPUT_REGISTERS_ADDRESS), uint(INPUT_REGISTERS_NB), ) defer mm.Free() fmt.Println(mm.NbBits()) fmt.Println(mm.NbInputBits()) fmt.Println(mm.NbInputRegisters()) fmt.Println(mm.NbRegisters())
Output: 10 10 10 10
func (*ModbusMapping) Free ¶
func (mm *ModbusMapping) Free()
Free modbus_mapping_free - free a modbus_mapping_t structure
The function shall free the four arrays of modbus_mapping_t structure and finally the modbus_mapping_t itself referenced by mb_mapping.
Example ¶
BITS_ADDRESS := 0 BITS_NB := 10 INPUT_BITS_ADDRESS := 0 INPUT_BITS_NB := 10 REGISTERS_ADDRESS := 0 REGISTERS_NB := 10 INPUT_REGISTERS_ADDRESS := 0 INPUT_REGISTERS_NB := 10 mm := ModbusMappingNewStartAddress( uint(BITS_ADDRESS), uint(BITS_NB), uint(INPUT_BITS_ADDRESS), uint(INPUT_BITS_NB), uint(REGISTERS_ADDRESS), uint(REGISTERS_NB), uint(INPUT_REGISTERS_ADDRESS), uint(INPUT_REGISTERS_NB), ) defer mm.Free() fmt.Println(mm.NbBits()) fmt.Println(mm.NbInputBits()) fmt.Println(mm.NbInputRegisters()) fmt.Println(mm.NbRegisters())
Output: 10 10 10 10
func (*ModbusMapping) GetTabBits ¶
func (mm *ModbusMapping) GetTabBits(addr int) byte
func (*ModbusMapping) GetTabInputBits ¶
func (mm *ModbusMapping) GetTabInputBits(addr int) byte
func (*ModbusMapping) GetTabInputRegisters ¶
func (mm *ModbusMapping) GetTabInputRegisters(addr int) uint16
func (*ModbusMapping) GetTabRegisters ¶
func (mm *ModbusMapping) GetTabRegisters(addr int) uint16
func (*ModbusMapping) MarshalBinary ¶ added in v0.1.6
func (mm *ModbusMapping) MarshalBinary() (buff []byte, err error)
func (*ModbusMapping) NbBits ¶
func (mm *ModbusMapping) NbBits() int
func (*ModbusMapping) NbInputBits ¶
func (mm *ModbusMapping) NbInputBits() int
func (*ModbusMapping) NbInputRegisters ¶
func (mm *ModbusMapping) NbInputRegisters() int
func (*ModbusMapping) NbRegisters ¶
func (mm *ModbusMapping) NbRegisters() int
func (*ModbusMapping) SetTabBits ¶
func (mm *ModbusMapping) SetTabBits(addr int, v byte)
func (*ModbusMapping) SetTabInputBits ¶
func (mm *ModbusMapping) SetTabInputBits(addr int, v byte)
func (*ModbusMapping) SetTabInputRegisters ¶
func (mm *ModbusMapping) SetTabInputRegisters(addr int, v uint16)
func (*ModbusMapping) SetTabRegisters ¶
func (mm *ModbusMapping) SetTabRegisters(addr int, v uint16)
func (*ModbusMapping) StartBits ¶
func (mm *ModbusMapping) StartBits() int
func (*ModbusMapping) StartInputBits ¶
func (mm *ModbusMapping) StartInputBits() int
func (*ModbusMapping) StartInputRegisters ¶
func (mm *ModbusMapping) StartInputRegisters() int
func (*ModbusMapping) StartRegisters ¶
func (mm *ModbusMapping) StartRegisters() int
func (*ModbusMapping) TabInputBits ¶
func (mm *ModbusMapping) TabInputBits() iter.Seq2[int, byte]
func (*ModbusMapping) TabInputRegisters ¶
func (mm *ModbusMapping) TabInputRegisters() iter.Seq2[int, uint16]
func (*ModbusMapping) TabRegisters ¶
func (mm *ModbusMapping) TabRegisters() iter.Seq2[int, uint16]
func (*ModbusMapping) UnmarshalBinary ¶ added in v0.1.6
func (mm *ModbusMapping) UnmarshalBinary(data []byte) (err error)
type ModbusQuirks ¶
type ModbusQuirks byte
const ( MODBUS_QUIRK_NONE ModbusQuirks = C.MODBUS_QUIRK_NONE MODBUS_QUIRK_MAX_SLAVE ModbusQuirks = C.MODBUS_QUIRK_MAX_SLAVE MODBUS_QUIRK_REPLY_TO_BROADCAST ModbusQuirks = C.MODBUS_QUIRK_REPLY_TO_BROADCAST MODBUS_QUIRK_ALL ModbusQuirks = C.MODBUS_QUIRK_ALL )
type ReportSlaveId ¶
type SetRtsCallback ¶
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
example
|
|
random-multi-server
command
|
|
random-test-client
command
|
|
random-test-server
command
|