Abstraction layer over libmodbus, for Modbus RTU/TCP communication.
The following types and ranges are used by the Modbus protocol:
Code | Range | Type | Function |
---|---|---|---|
0x | 00001 – 09999 | coil | dm_modbus_read_bits() |
1x | 10001 – 19999 | discrete input | dm_modbus_read_input_bits() |
3x | 30001 – 39999 | input register | dm_modbus_read_input_registers() |
4x | 40001 – 49999 | holding register | dm_modbus_read_registers() |
You may want to use the functions dm_to_signed()
and
dm_to_unsigned()
available in module dm_c
to convert unsigned to
signed integers and vice versa.
Use Modbus function code 0x03
to read holding registers from a Modbus
RTU connection:
integer :: i, rc, s
integer(kind=u2) :: data(2)
type(modbus_rtu_type) :: modbus
! Create Modbus RTU context and connect to device 10.
rc = dm_modbus_create(modbus = modbus, &
path = '/dev/ttyUSB0', &
baud_rate = TTY_B19200, &
byte_size = TTY_BYTE_SIZE8, &
parity = TTY_PARITY_EVEN, &
stop_bits = TTY_STOP_BITS1)
rc = dm_modbus_connect(modbus)
rc = dm_modbus_set_slave(modbus, slave=10)
! Read and output two registers.
rc = dm_modbus_read_registers(modbus, address=50, data=data)
do i = 1, size(data)
s = dm_to_signed(data(i))
print '("data(", i0, ") = ", i0, " (0x", z0, ")")', i, s, s
end do
! Print the two registers as real in ABCD byte order.
print '(f12.8)', dm_modbus_get_float_abcd(data)
! Disconnect and clean-up.
call dm_modbus_close(modbus)
call dm_modbus_destroy(modbus)
In production, add additional error handling of the return codes.
Generic function to create Modbus RTU or TCP context.
Creates a new Modbus RTU context.
The function returns the following error codes:
E_INVALID
if a given argument is invalid.E_MODBUS
if no Modbus context could be created.Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_rtu_type), | intent(out) | :: | modbus |
Modbus RTU type. |
||
character(len=*), | intent(in) | :: | path |
Device path. |
||
integer, | intent(in) | :: | baud_rate |
Baud rate enumerator ( |
||
integer, | intent(in) | :: | byte_size |
Byte size enumerator ( |
||
integer, | intent(in) | :: | parity |
Parity enumerator ( |
||
integer, | intent(in) | :: | stop_bits |
Stop bits enumerator ( |
Creates a new Modbus TCP context.
The function returns the following error codes:
E_INVALID
if the given arguments are invalid.E_MODBUS
if no Modbus context could be created.Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_tcp_type), | intent(out) | :: | modbus |
Modbus TCP type. |
||
character(len=*), | intent(in) | :: | address |
IPv4 address. |
||
integer, | intent(in) | :: | port |
Port number. |
Opaque Modbus RTU/TCP context type.
Opaque Modbus RTU context type.
Opaque Modbus TCP context type.
Connects to Modbus RTU/TCP device.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
Creates a new Modbus RTU context.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_rtu_type), | intent(out) | :: | modbus |
Modbus RTU type. |
||
character(len=*), | intent(in) | :: | path |
Device path. |
||
integer, | intent(in) | :: | baud_rate |
Baud rate enumerator ( |
||
integer, | intent(in) | :: | byte_size |
Byte size enumerator ( |
||
integer, | intent(in) | :: | parity |
Parity enumerator ( |
||
integer, | intent(in) | :: | stop_bits |
Stop bits enumerator ( |
Creates a new Modbus TCP context.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_tcp_type), | intent(out) | :: | modbus |
Modbus TCP type. |
||
character(len=*), | intent(in) | :: | address |
IPv4 address. |
||
integer, | intent(in) | :: | port |
Port number. |
Returns error message from libmodbus.
Flushes non-transmitted data.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
Returns real value from two registers of given byte order in argument
value
. The argument byte order must be one of the following:
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(inout) | :: | data(2) |
Registers to convert. |
||
integer, | intent(in) | :: | order |
Byte order. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Returns real value from two registers in ABCD byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(inout) | :: | data(2) |
Registers to convert. |
Returns real value from two registers in BADC byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(inout) | :: | data(2) |
Registers to convert. |
Returns real value from two registers in CDAB byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(inout) | :: | data(2) |
Registers to convert. |
Returns real value from two registers in DCBA byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(inout) | :: | data(2) |
Registers to convert. |
Returns high byte from 2-byte integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(in) | :: | data |
Register data. |
Returns 4-byte integer from two 2-byte registers.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(in) | :: | data(2) |
Register data. |
Returns 8-byte integer from four 2-byte registers.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(in) | :: | data(4) |
Register data. |
Returns low byte from 2-byte integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=u2), | intent(in) | :: | data |
Register data. |
Gets the current Modbus RTU serial mode (RS-232 or RS-485).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_rtu_type), | intent(inout) | :: | modbus |
Modbus RTU type. |
||
integer, | intent(out) | :: | mode |
Modbus RTU mode ( |
Gets current slave number in the Modbus context.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(out) | :: | slave |
Device id. |
Reads many input bits from address
. The size of argument data
determines the number of bits to read, unless optional argument
n
is passed. The function uses the Modbus function code 0x01
(read coil status).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=u1), | intent(inout) | :: | data(:) |
Bits. |
||
integer, | intent(inout), | optional | :: | n |
Number of registers to read on input, number of registers read on output. |
Reads 4-byte real from input or holding register, depending on the
address, and returns result in value
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
real(kind=4), | intent(out) | :: | value |
Value read from register. |
||
integer, | intent(in) | :: | order |
Byte order. |
Reads many input bits from address
. The size of argument data
determines the number of bits to read, unless optional argument
n
is passed. The function uses the Modbus function code 0x02
(read input status).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=u1), | intent(inout) | :: | data(:) |
Bits. |
||
integer, | intent(inout), | optional | :: | n |
Number of registers to read on input, number of registers read on output. |
Reads many registers from address
. The size of argument data
determines the number of registers to read, unless optional argument
n
is passed. The function uses the Modbus function code 0x04
(read input registers).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=u2), | intent(inout) | :: | data(:) |
Register values (unsigned). |
||
integer, | intent(inout), | optional | :: | n |
Number of registers to read on input, number of registers read on output. |
Reads 2-byte signed integer from input or holding register, depending
on the address, and returns result in value
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=i2), | intent(out) | :: | value |
Value read from register. |
Reads 4-byte signed integer from input or holding register, depending
on the address, and returns result in value
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=i4), | intent(out) | :: | value |
Value read from register. |
Reads many registers from address
. The size of argument data
determines the number of registers to read, unless optional argument
n
is passed. The function uses the Modbus function code 0x03
(read holding registers).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=u2), | intent(inout) | :: | data(:) |
Register values (unsigned). |
||
integer, | intent(inout), | optional | :: | n |
Number of registers to read on input, number of registers read on output. |
Reads 2-byte unsigned integer from input or holding register,
depending on the address, and returns result in value
. Stores the
2-byte unsigned value in a 4-byte signed integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=i4), | intent(out) | :: | value |
Value read from register. |
Reads 4-byte unsigned integer from input or holding register,
depending on the address, and returns result in value
. Stores the
4-byte unsigned value in a 8-byte signed integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to read from. |
||
integer(kind=i8), | intent(out) | :: | value |
Value read from register. |
Sets debug flag of the Modbus context. Returns E_MODBUS
on error.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
logical, | intent(in) | :: | debug |
Enable debug mode. |
Sets the Modbus RTU serial mode to RS-232 or RS-485. This API function is only supported on Linux kernels 2.6.28 onwards.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(modbus_rtu_type), | intent(inout) | :: | modbus |
Modbus RTU type. |
||
integer, | intent(in) | :: | mode |
Modbus RTU mode ( |
Sets slave number in the Modbus context.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | slave |
Device id. |
Returns libmodbus version as allocatable string.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
logical, | intent(in), | optional | :: | name |
Add prefix |
Version string.
Writes 2-byte signed integer to address
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=i2), | intent(in) | :: | value |
Value to write. |
Writes 4-byte signed integer to address
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=i4), | intent(in) | :: | value |
Value to write. |
Writes register to address
. The function uses the Modbus function
code 0x06
(preset single register).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=u2), | intent(in) | :: | data |
Register value (unsigned). |
Writes many registers to address
. The size of argument data
determines the number of registers to write, unless optional
argument n
is passed. The function uses the Modbus function code
0x10
(preset multiple registers).
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=u2), | intent(inout) | :: | data(:) |
Register values (unsigned). |
||
integer, | intent(inout), | optional | :: | n |
Number of registers to write on input, number of registers written on output. |
Writes 2-byte unsigned integer to address
. The unsigned value must
be passed in a 4-byte signed integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=i4), | intent(in) | :: | value |
Value to write. |
Writes 4-byte unsigned integer to address
. The unsigned value must
be passed in a 8-byte signed integer.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
integer, | intent(in) | :: | address |
Address to write to. |
||
integer(kind=i8), | intent(in) | :: | value |
Value to write. |
Closes the Modbus RTU/TCP connection.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCPtype. |
Destroys the Modbus RTU/TCP context.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
Sets 4-byte integer to two 2-byte registers.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=i4), | intent(in) | :: | value |
Value to convert. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Returned register data. |
Sets 8-byte integer to four 2-byte registers.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=i8), | intent(in) | :: | value |
Value to convert. |
||
integer(kind=u2), | intent(out) | :: | data(4) |
Returned register data. |
Sets real value to registers of given byte order. The argument
order
must be one of the following:
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real, | intent(in) | :: | value |
Real value to set. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Registers to write to. |
||
integer, | intent(in) | :: | order |
Byte order. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Returns real value to registers in ABCD byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real, | intent(in) | :: | value |
Real value to set. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Registers to write to. |
Returns real value to registers in BADC byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real, | intent(in) | :: | value |
Real value to set. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Registers to write to. |
Sets real value to registers in CDAB byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real, | intent(in) | :: | value |
Real value to set. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Registers to write to. |
Sets real value to registers in DCBA byte order.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real, | intent(in) | :: | value |
Real value to set. |
||
integer(kind=u2), | intent(out) | :: | data(2) |
Registers to write to. |