LinuxCNC Documentation

1. Вступ

MB2HAL — це універсальний компонент HAL, що не працює в реальному часі, для зв’язку з одним або кількома пристроями Modbus. Наразі існує два варіанти зв’язку з пристроєм Modbus:

  1. Один із варіантів — створити компонент HAL як драйвер, див. VFD Modbus.

  2. Іншим варіантом є використання Classic Ladder з вбудованим Modbus, див. ClassicLadder.

  3. Тепер є третій варіант, який складається з "загального" драйвера, налаштованого текстовим файлом, він називається MB2HAL.

Чому варто обрати MB2HAL? Розгляньте можливість використання MB2HAL, якщо:

  • Вам потрібно написати новий драйвер, і ви нічого не знаєте про програмування.

  • Для керування з’єднаннями Modbus потрібно використовувати "лише" Classic Ladder.

  • Вам потрібно виявити та налаштувати перші транзакції Modbus. MB2HAL має рівні налагодження для полегшення низькорівневого налагодження протоколу.

  • У вас є більше одного пристрою для підключення. MB2HAL дуже ефективно управляє декількома пристроями, транзакціями та посиланнями. В даний час я контролюю два двоосьові драйвери за допомогою порту Rs232, драйвер VFD за допомогою іншого порту Rs232 та віддалений ввід/вивід за допомогою TCP/IP.

  • Вам потрібен протокол для підключення вашого Arduino до HAL. Перегляньте доданий зразок файлу конфігурації, ескізу та бібліотеки для Arduino Modbus.

2. Safety Considerations

Modbus (RTU or TCP) is not suitable as the only run-enable path for a spindle or drive. A Modbus slave such as a VFD holds the last value written to its control registers indefinitely. If LinuxCNC exits, crashes, or the serial link drops while the spindle is running, no stop command is ever sent and the spindle keeps running. MB2HAL is a non-realtime userspace component and performs no cleanup on exit, so this applies even to a clean shutdown. Writing a stop command from shutdown.hal only covers the clean-exit case and is not a safety measure.

The standard practice is to layer the control:

  1. Wire the enable in hardware. The VFD enable or STO (Safe Torque Off) inputs belong in the machine estop chain, independent of any communication bus. This is the only layer that qualifies as safety. Many VFDs offer dual redundant estop inputs for use with safety relays. With this layer in place, run and stop over Modbus is accepted practice; the remaining layers decide what happens when the communication fails.

  2. Arrange a stop on communication loss. Most VFDs provide a Modbus timeout parameter with a fault or coast-to-stop action; set it to a few hundred milliseconds, so a crash or dropped link stops polling and the VFD stops the motor. Alternatively detect the loss in HAL: the mb2hal.__m__.num_errors pin counts failed transactions (0 means the last transaction succeeded), and feeding it into a machine-off or estop chain stops the machine when the link dies. HAL-side detection avoids VFD-specific parameterization and needs no rework when the VFD is replaced, but coverage of a PC crash then rests on the output hardware watchdog, for example the Mesa hostmot2 watchdog or a parallel-port charge pump.

  3. Optionally split the command sources. Configure run command from terminals and frequency reference from Modbus, drive the VFD run terminal from motion.spindle-on or motion.machine-is-on through a relay or digital output, and let Modbus carry only speed reference, direction and status. This also avoids the read-modify-write problem when a single control register multiplexes run, stop and other commands.

These considerations apply to every Modbus control path (MB2HAL, hm2_modbus, ClassicLadder or a custom driver), not only to MB2HAL.

3. Застосування

  1. Створіть конфігураційний файл з наведеного нижче прикладу

    1. Встановити назву компонента (необов’язково)

      Отримати HAL_MODULE_NAME=mymodule (за замовчуванням HAL_MODULE_NAME=mb2hal)

    2. Завантажити компонент Modbus HAL, що не працює в режимі реального часу

  2. Назва компонента за замовчуванням: loadusr -W mb2hal config=config_file.ini

  3. Назва користувацького компонента: loadusr -Wn mymodule mb2hal config=config_file.ini

4. Опції

4.1. Розділ ініціалізації

[MB2HAL_INIT]

Значення Тип Обов’язково Опис

INIT_DEBUG

Ціле число

Ні

Рівень налагодження ініціалізації та розбору INI-файлів.
0 = беззвучно
1 = повідомлення про помилки (за замовчуванням)
2 = повідомлення про підтвердження OK
3 = повідомлення про налагодження
4 = максимальна кількість повідомлень про налагодження (лише в транзакціях)

ВЕРСІЯ

Рядок

Ні

Номер версії у форматі N.N[NN]. За замовчуванням — 1.0.

HAL_MODULE_NAME

Рядок

Ні

Назва модуля (компонента) HAL. За замовчуванням — «mb2hal».

SLOWDOWN

Float

Ні

Вставте затримку «FLOAT секунд» між транзакціями, щоб уникнути великої кількості записів у журналі та полегшити налагодження. Корисно при використанні DEBUG=3 (НЕ INIT_DEBUG=3). Це впливає на ВСІ транзакції. Для нормальної роботи використовуйте «0.0».

TOTAL_TRANSACTIONS

Ціле число

Так

Загальна кількість транзакцій Modbus. Максимальної кількості немає..

4.2. Розділи транзакцій

Для кожної транзакції необхідний один розділ транзакції, починаючи з [TRANSACTION_00] і послідовно збільшуючи номер. Якщо є нове посилання (не транзакція), ви повинні вказати ОБОВ’ЯЗКОВІ параметри вперше. Попередження: будь-які НЕОБОВ’ЯЗКОВІ параметри, які не вказані, копіюються з попередньої транзакції.

Значення Тип Обов’язково Опис

LINK_TYPE

Рядок

Так

Ви повинні вказати посилання "serial" або "tcp" для першої транзакції. Якщо не вказано посилання попередньої транзакції, наступні транзакції використовуватимуть його.

TCP_IP

IP-адреса

Якщо LINK_TYPE=tcp

IP-адреса веденого пристрою Modbus. Ігнорується, якщо LINK_TYPE=serial.

TCP_PORT

Ціле число

Ні

TCP-порт веденого пристрою Modbus. За замовчуванням 502. Ігнорується, якщо LINK_TYPE=serial.

SERIAL_PORT

Рядок

Якщо LINK_TYPE=serial

Послідовний порт. Наприклад, "/dev/ttyS0". Ігнорується, якщо LINK_TYPE=tcp.

SERIAL_BAUD

Ціле число

Якщо LINK_TYPE=serial

Швидкість передачі даних. Ігнорується, якщо LINK_TYPE=tcp.

SERIAL_BITS

Ціле число

Якщо LINK_TYPE=serial

Біти даних. Один з 5, 6, 7, 8. Ігнорується, якщо LINK_TYPE=tcp.

SERIAL_PARITY

Рядок

Якщо LINK_TYPE=serial

Парність даних. Одне з: парне, непарне, жодного. Ігнорується, якщо LINK_TYPE=tcp.

SERIAL_STOP

Ціле число

Якщо LINK_TYPE=serial

Стоп-біти. Один з 1, 2. Ігнорується, якщо LINK_TYPE=tcp.

SERIAL_DELAY_MS

Ціле число

Якщо LINK_TYPE=serial

Затримка послідовного порту між транзакціями лише цього розділу. У мс. За замовчуванням 0. Ігнорується, якщо LINK_TYPE=tcp.

MB_SLAVE_ID

Ціле число

Так

Номер веденого пристрою Modbus.

FIRST_ELEMENT

Ціле число

Так

Адреса першого елемента.

NELEMENTS

Ціле число

Якщо не вказано PIN_NAMES

Кількість елементів. Вказувати одночасно NELEMENTS та PIN_NAMES є помилкою. Назви контактів будуть послідовними номерами, наприклад, mb2hal.plcin.01.

PIN_NAMES

Список

Якщо не вказано NELEMENTS

Список імен елементів. Ці імена будуть використовуватися для імен контактів, наприклад mb2hal.plcin.cycle_start.
ПРИМІТКА: У списку не повинно бути пробілів. Приклад: PIN_NAMES=cycle_start,stop,feed_hold

MB_TX_CODE

Рядок

Так

Код функції транзакції Modbus (див. посилання: специфікації):

• fnct_01_read_coils
• fnct_02_read_discrete_inputs
• fnct_03_read_holding_registers
• fnct_04_read_input_registers
• fnct_05_write_single_coil
• fnct_06_write_single_register
• fnct_15_write_multiple_coils
• fnct_16_write_multiple_registers

MB_RESPONSE_TIMEOUT_MS

Ціле число

Ні

Тайм-аут відповіді для цієї транзакції. У мс. За замовчуванням 500 мс. Це час очікування першого байта перед виникненням помилки.

MB_BYTE_TIMEOUT_MS

Ціле число

Ні

Тайм-аут байта для цієї транзакції. У мс. За замовчуванням 500 мс. Це час очікування від байта до байта, перш ніж виникне помилка.

HAL_TX_NAME

Рядок

Ні

Замість номера транзакції використовуйте ім’я. Приклад: mb2hal.00.01 може стати mb2hal.plcin.01. Ім’я не повинно перевищувати 28 символів. ПРИМІТКА: при використанні імен будьте обережні, щоб не створити дві транзакції з однаковим ім’ям.

MAX_UPDATE_RATE

Float

Ні

Максимальна частота оновлення в Гц. За замовчуванням встановлено значення 0,0 (0,0 = як тільки з’явиться можливість = нескінченно). ПРИМІТКА: Це максимальна частота, фактична частота може бути нижчою. Якщо ви хочете обчислити її в мс, використовуйте (1000 / required_ms). Приклад: 100 мс = MAX_UPDATE_RATE=10.0, оскільки 1000,0 мс / 100,0 мс = 10,0 Гц.

НАЛАГОДЖЕННЯ

Рядок

Ні

Рівень налагодження лише для цієї транзакції. Див. параметр INIT_DEBUG вище.

4.3. Коди помилок

Під час налагодження транзакцій зверніть увагу, що повернене значення "ret[]" відповідає:

Винятки протоколу Modbus:

  • 0x01 - ILLEGAL_FUNCTION - the FUNCTION code received in the query is not allowed or invalid.

  • 0x02 - ILLEGAL_DATA_ADDRESS - the DATA ADDRESS received in the query is not an allowable address for the slave or is invalid.

  • 0x03 - ILLEGAL_DATA_VALUE - a VALUE contained in the data query field is not an allowable value or is invalid.

  • 0x04 - SLAVE_DEVICE_FAILURE - SLAVE (or MASTER) device unrecoverable FAILURE while attempting to perform the requested action.

  • 0x04 - SERVER_FAILURE - (see above).

  • 0x05 - ACKNOWLEDGE - This response is returned to PREVENT A TIMEOUT in the master. A long duration of time is required to process the request in the slave.

  • 0x06 - SLAVE_DEVICE_BUSY - The slave (or server) is BUSY. Retransmit the request later.

  • 0x06 - SERVER_BUSY - (see above).

  • 0x07 - NEGATIVE_ACKNOWLEDGE - Unsuccessful programming request using function code 13 or 14.

  • 0x08 - MEMORY_PARITY_ERROR - SLAVE parity error in MEMORY.

  • 0x0A (-10) - GATEWAY_PROBLEM_PATH - Gateway path(s) not available.

  • 0x0B (-11) - GATEWAY_PROBLEM_TARGET - The target device failed to respond (generated by master, not slave).

Програма або з’єднання:

  • 0x0C (-12) - COMM_TIME_OUT

  • 0x0D (-13) - PORT_SOCKET_FAILURE

  • 0x0E (-14) - SELECT_FAILURE

  • 0x0F (-15) - TOO_MANY_DATAS

  • 0x10 (-16) - INVALID_CRC

  • 0x11 (-17) - INVALID_EXCEPTION_CODE

5. Приклад конфігураційного файлу

Натисніть тут для завантаження.

#This .INI file is also the HELP, MANUAL and HOW-TO file for mb2hal.

#Load the Modbus HAL userspace module as the examples below,
#change to match your own HAL_MODULE_NAME and INI file name
#Using HAL_MODULE_NAME=mb2hal or nothing (default): loadusr -W mb2hal config=config_file.ini
#Using HAL_MODULE_NAME=mymodule: loadusr -Wn mymodule mb2hal config=config_file.ini

# ++++++++++++++++++++++++
# Common section
# ++++++++++++++++++++++++
[MB2HAL_INIT]

#OPTIONAL: Debug level of init and INI file parsing.
# 0 = silent.
# 1 = error messages (default).
# 2 = OK confirmation messages.
# 3 = debugging messages.
# 4 = maximum debugging messages (only in transactions).
INIT_DEBUG=3

#OPTIONAL: Set to 1.1 to enable the new functions:
# - fnct_01_read_coils
# - fnct_05_write_single_coil
# - changed pin names (see https://linuxcnc.org/docs/2.9/html/drivers/mb2hal.html#_pins).
VERSION=1.1

#OPTIONAL: HAL module (component) name. Defaults to "mb2hal".
HAL_MODULE_NAME=mb2hal

#OPTIONAL: Insert a delay of "FLOAT seconds" between transactions in order
#to not to have a lot of logging and facilitate the debugging.
#Useful when using DEBUG=3 (NOT INIT_DEBUG=3)
#It affects ALL transactions.
#Use "0.0" for normal activity.
SLOWDOWN=0.0

#REQUIRED: The number of total Modbus transactions. There is no maximum.
TOTAL_TRANSACTIONS=9

# ++++++++++++++++++++++++
# Transactions
# ++++++++++++++++++++++++
#One transaction section is required per transaction, starting at 00 and counting up sequentially.
#If there is a new link (not transaction), you must provide the REQUIRED parameters 1st time.
#Warning: Any OPTIONAL parameter not specified are copied from the previous transaction.
[TRANSACTION_00]

#REQUIRED: You must specify either a "serial" or "tcp" link for the first transaction.
#Later transaction will use the previous transaction link if not specified.
LINK_TYPE=tcp

#if LINK_TYPE=tcp then REQUIRED (only 1st time): The Modbus slave device ip address.
#if LINK_TYPE=serial then IGNORED
TCP_IP=192.168.2.10

#if LINK_TYPE=tcp then OPTIONAL.
#if LINK_TYPE=serial then IGNORED
#The Modbus slave device tcp port. Defaults to 502.
TCP_PORT=502

#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#The serial port.
SERIAL_PORT=/dev/ttyS0

#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#The baud rate.
SERIAL_BAUD=115200

#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Data bits. One of 5,6,7,8.
SERIAL_BITS=8

#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Data parity. One of: even, odd, none.
SERIAL_PARITY=none

#if LINK_TYPE=serial then REQUIRED (only 1st time).
#if LINK_TYPE=tcp then IGNORED
#Stop bits. One of 1, 2.
SERIAL_STOP=2

#if LINK_TYPE=serial then OPTIONAL:
#if LINK_TYPE=tcp then IGNORED
#Serial port delay between for this transaction only.
#In ms. Defaults to 0.
SERIAL_DELAY_MS=10

#REQUIRED (only 1st time).
#Modbus slave number.
MB_SLAVE_ID=1

#REQUIRED: The first element address (decimal integer).
FIRST_ELEMENT=0

#REQUIRED unless PIN_NAMES is specified: The number of elements.
#It is an error to specify both NELEMENTS and PIN_NAMES
#The pin names will be sequential numbers e.g mb2hal.plcin.01
#NELEMENTS=4

#REQUIRED unless NELEMENTS is specified: A list of element names.
#these names will be used for the pin names, e.g mb2hal.plcin.cycle_start
#NOTE: there must be no white space characters in the list
PIN_NAMES=cycle_start,stop,feed_hold

#REQUIRED: Modbus transaction function code (see www.modbus.org specifications).
#    fnct_01_read_coils               (01 = 0x01) (new in 1.1)
#    fnct_02_read_discrete_inputs     (02 = 0x02)
#    fnct_03_read_holding_registers   (03 = 0x03)
#    fnct_04_read_input_registers     (04 = 0x04)
#    fnct_05_write_single_coil        (05 = 0x05) (new in 1.1)
#    fnct_06_write_single_register    (06 = 0x06)
#    fnct_15_write_multiple_coils     (15 = 0x0F)
#    fnct_16_write_multiple_registers (16 = 0x10)
#
# Created pins:
# fnct_01_read_coils:
# fnct_02_read_discrete_inputs:
#     mb2hal.m.n.bit     (output)
#     mb2hal.m.n.bit-inv (output)
# fnct_03_read_holding_registers:
# fnct_04_read_input_registers:
#     mb2hal.m.n.float   (output)
#     mb2hal.m.n.int     (output)
# fnct_05_write_single_coil:
#     mb2hal.m.n.bit     (input)
#	  NELEMENTS needs to be 1 or PIN_NAMES must contain just one name.
# fnct_06_write_single_register:
#     mb2hal.m.n.float   (input)
#     mb2hal.m.n.int     (input)
#     NELEMENTS needs to be 1 or PIN_NAMES must contain just one name.
#     Both pin values are added and limited to 65535 (UINT16_MAX). Normally use one and let the other open (read as 0).
# fnct_15_write_multiple_coils:
#     mb2hal.m.n.bit     (input)
# fnct_16_write_multiple_registers:
#     mb2hal.m.n.float   (input)
#     mb2hal.m.n.int     (input)
#     Both pin values are added and limited to 65535 (UINT16_MAX). Normally use one and let the other open (read as 0).
#
# m = HAL_TX_NAME or transaction number if not set, n = element number (NELEMENTS) or name from PIN_NAMES
# Example: mb2hal.00.01.<type> (transaction=00, second register=01 (00 is the first one))
#          mb2hal.TxName.01.<type> (HAL_TX_NAME=TxName, second register=01 (00 is the first one))
MB_TX_CODE=fnct_03_read_holding_registers

#OPTIONAL: Response timeout for this transaction. In INTEGER ms. Defaults to 500 ms.
#This is how much to wait for 1st byte before raise an error.
MB_RESPONSE_TIMEOUT_MS=500

#OPTIONAL: Byte timeout for this transaction. In INTEGER ms. Defaults to 500 ms.
#This is how much to wait from byte to byte before raise an error.
MB_BYTE_TIMEOUT_MS=500

#OPTIONAL: Instead of giving the transaction number, use a name.
#Example: mb2hal.00.01 could become mb2hal.plcin.01
#The name must not exceed 28 characters.
#NOTE: when using names be careful that you dont end up with two transactions
#using the same name.
HAL_TX_NAME=remoteIOcfg

#OPTIONAL: Maximum update rate in HZ. Defaults to 0.0 (0.0 = as soon as available = infinite).
#NOTE: This is a maximum rate and the actual rate may be lower.
#If you want to calculate it in ms use (1000 / required_ms).
#Example: 100 ms = MAX_UPDATE_RATE=10.0, because 1000.0 ms / 100.0 ms = 10.0 Hz
MAX_UPDATE_RATE=0.0

#OPTIONAL: Debug level for this transaction only.
#See INIT_DEBUG parameter above.
DEBUG=2

#While DEBUGGING transactions note the returned "ret[]" value correspond to:
#/* Modbus protocol exceptions */
#ILLEGAL_FUNCTION        -0x01 the FUNCTION code received in the query is not allowed or invalid.
#ILLEGAL_DATA_ADDRESS    -0x02 the DATA ADDRESS received in the query is not an allowable address for the slave or is invalid.
#ILLEGAL_DATA_VALUE      -0x03 a VALUE contained in the data query field is not an allowable value or is invalid.
#SLAVE_DEVICE_FAILURE    -0x04 SLAVE (or MASTER) device unrecoverable FAILURE while attempting to perform the requested action.
#SERVER_FAILURE          -0x04 (see above).
#ACKNOWLEDGE             -0x05 This response is returned to PREVENT A TIMEOUT in the master.
#                              A long duration of time is required to process the request in the slave.
#SLAVE_DEVICE_BUSY       -0x06 The slave (or server) is BUSY. Retrasmit the request later.
#SERVER_BUSY             -0x06 (see above).
#NEGATIVE_ACKNOWLEDGE    -0x07 Unsuccessful programming request using function code 13 or 14.
#MEMORY_PARITY_ERROR     -0x08 SLAVE parity error in MEMORY.
#GATEWAY_PROBLEM_PATH    -0x0A (-10) Gateway path(s) not available.
#GATEWAY_PROBLEM_TARGET  -0x0B (-11) The target device failed to respond (generated by master, not slave).
#/* Program or connection */
#COMM_TIME_OUT           -0x0C (-12)
#PORT_SOCKET_FAILURE     -0x0D (-13)
#SELECT_FAILURE          -0x0E (-14)
#TOO_MANY_DATAS          -0x0F (-15)
#INVALID_CRC             -0x10 (-16)
#INVALID_EXCEPTION_CODE  -0x11 (-17)

[TRANSACTION_01]
MB_TX_CODE=fnct_01_read_coils
FIRST_ELEMENT=1024
NELEMENTS=24
HAL_TX_NAME=remoteIOin
MAX_UPDATE_RATE=0.0
DEBUG=1

[TRANSACTION_02]
MB_TX_CODE=fnct_02_read_discrete_inputs
FIRST_ELEMENT=1280
NELEMENTS=8
HAL_TX_NAME=readStatus
MAX_UPDATE_RATE=0.0

[TRANSACTION_03]
MB_TX_CODE=fnct_05_write_single_coil
FIRST_ELEMENT=100
NELEMENTS=1
HAL_TX_NAME=setEnableout
MAX_UPDATE_RATE=0.0

[TRANSACTION_04]
MB_TX_CODE=fnct_15_write_multiple_coils
FIRST_ELEMENT=150
NELEMENTS=10
HAL_TX_NAME=remoteIOout
MAX_UPDATE_RATE=0.0

[TRANSACTION_05]
LINK_TYPE=serial
SERIAL_PORT=/dev/ttyS0
SERIAL_BAUD=115200
SERIAL_BITS=8
SERIAL_PARITY=none
SERIAL_STOP=2
SERIAL_DELAY_MS=50
MB_SLAVE_ID=1
MB_TX_CODE=fnct_03_read_holding_registers
FIRST_ELEMENT=1
NELEMENTS=2
HAL_TX_NAME=XDrive01
MAX_UPDATE_RATE=0.0
DEBUG=1

[TRANSACTION_06]
MB_TX_CODE=fnct_04_read_input_registers
FIRST_ELEMENT=12
NELEMENTS=3
HAL_TX_NAME=XDrive02
MAX_UPDATE_RATE=10.0
DEBUG=1

[TRANSACTION_07]
MB_TX_CODE=fnct_06_write_single_register
FIRST_ELEMENT=20
NELEMENTS=1
HAL_TX_NAME=XDrive03
MAX_UPDATE_RATE=0.0
DEBUG=1

[TRANSACTION_08]
MB_TX_CODE=fnct_16_write_multiple_registers
FIRST_ELEMENT=55
NELEMENTS=8
HAL_TX_NAME=XDrive04
MAX_UPDATE_RATE=10.0
DEBUG=1

6. Піни

Note

Жовтий = Нове в MB2HAL 1.1 (LinuxCNC 2.9). Щоб використовувати ці нові функції, потрібно встановити VERSION = 1.1.

m = Значення HAL_TX_NAME, якщо встановлено, або номер транзакції
n = Номер елемента (NELEMENTS) або назва з PIN_NAMES

Приклад:

  • mb2hal.00.01.int (TRANSACTION_00, другий регістр)

  • mb2hal.readStatus.01.bit (HAL_TX_NAME=readStatus, first bit)

6.1. fnct_01_read_coils

  • mb2hal.m.n.bit bit out

  • mb2hal.m.n.bit-inv bit out

6.2. fnct_02_read_discrete_inputs

  • mb2hal.m.n.bit bit out

  • mb2hal.m.n.bit-inv bit out

6.3. fnct_03_read_holding_registers

  • mb2hal.m.n.float float out

  • mb2hal.m.n.int s32 out

6.4. fnct_04_read_input_registers

  • mb2hal.m.n.float float out

  • mb2hal.m.n.int s32 out

6.5. fnct_05_write_single_coil

  • mb2hal.m.n.bit bit in

NELEMENTS має бути 1, або PIN_NAMES має містити лише одне ім’я.

6.6. fnct_06_write_single_register

  • mb2hal.m.n.float float in

  • mb2hal.m.n.int s32 in

NELEMENTS має дорівнювати 1, або PIN_NAMES має містити лише одну назву. Обидва значення виводів додаються та обмежені значенням 65535 (UINT16_MAX). Використовуйте одне, а інше розмикайте (читайте як 0).

6.7. fnct_15_write_multiple_coils

  • mb2hal.m.n.bit bit in

6.8. fnct_16_write_multiple_registers

  • mb2hal.m.n.float float in

  • mb2hal.m.n.int s32 in

Обидва значення виводів додаються та обмежені значенням 65535 (UINT16_MAX). Використовуйте один, а інший розімкнутий (зчитується як 0).