Abstraction layer over libmodbus, for Modbus RTU/TCP communication.
The following types and ranges are used by the Modbus protocol:
| Code | Range | Type | Functions |
|---|---|---|---|
| 0x01 | 00001 – 09999 | coil | dm_modbus_read_bit(), dm_modbus_read_bits() |
| 0x02 | 10001 – 19999 | discrete input | dm_modbus_read_input_bits() |
| 0x04 | 30001 – 39999 | input register | dm_modbus_read_input_registers() |
| 0x03 | 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=30050, 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 single input bit from address. 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=i4), | intent(out) | :: | value |
Bit read. |
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 read. |
||
| 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. If the address is not in
input register or holding register range, it is interpreted as a
holding register address.
| 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=r4), | 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. If the address is not
in input register or holding register range, it is interpreted as a
holding register address.
| 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. If the address is not
in input register or holding register range, it is interpreted as a
holding register address.
| 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. If the address is
not in input register or holding register range, it is interpreted
as a holding register address.
| 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. If the address is
not in input register or holding register range, it is interpreted
as a holding register address.
| 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 bit value to address using Modbus function code
0x05(force single coil).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(modbus_type), | intent(inout) | :: | modbus |
Modbus RTU/TCP type. |
||
| integer, | intent(in) | :: | address |
Address to write to. |
||
| integer, | intent(in) | :: | value |
Value to write (0 or 1). |
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. |
Writes 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. |
Writes 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. |
Writes 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. |
Writes 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. |
Writes 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. |
Writes 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. |
Writes 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. |