1. Вступ
MB2HAL — це універсальний компонент HAL, що не працює в реальному часі, для зв’язку з одним або кількома пристроями Modbus. Наразі існує два варіанти зв’язку з пристроєм Modbus:
-
Один із варіантів — створити компонент HAL як драйвер, див. VFD Modbus.
-
Іншим варіантом є використання Classic Ladder з вбудованим Modbus, див. ClassicLadder.
-
Тепер є третій варіант, який складається з "загального" драйвера, налаштованого текстовим файлом, він називається MB2HAL.
Чому варто обрати MB2HAL? Розгляньте можливість використання MB2HAL, якщо:
-
Вам потрібно написати новий драйвер, і ви нічого не знаєте про програмування.
-
Для керування з’єднаннями Modbus потрібно використовувати "лише" Classic Ladder.
-
Вам потрібно виявити та налаштувати перші транзакції Modbus. MB2HAL має рівні налагодження для полегшення низькорівневого налагодження протоколу.
-
У вас є більше одного пристрою для підключення. MB2HAL дуже ефективно управляє декількома пристроями, транзакціями та посиланнями. В даний час я контролюю два двоосьові драйвери за допомогою порту Rs232, драйвер VFD за допомогою іншого порту Rs232 та віддалений ввід/вивід за допомогою TCP/IP.
-
Вам потрібен протокол для підключення вашого Arduino до HAL. Перегляньте доданий зразок файлу конфігурації, ескізу та бібліотеки для Arduino Modbus.
2. Застосування
-
Створіть конфігураційний файл з наведеного нижче прикладу
-
Встановити назву компонента (необов’язково)
Отримати
HAL_MODULE_NAME=mymodule(за замовчуваннямHAL_MODULE_NAME=mb2hal) -
Завантажити компонент Modbus HAL, що не працює в режимі реального часу
-
-
Назва компонента за замовчуванням:
loadusr -W mb2hal config=config_file.ini -
Назва користувацького компонента:
loadusr -Wn mymodule mb2hal config=config_file.ini
3. Опції
3.1. Розділ ініціалізації
[MB2HAL_INIT]
| Значення | Тип | Обов’язково | Опис |
|---|---|---|---|
|
Ціле число |
Ні |
Рівень налагодження ініціалізації та розбору INI-файлів. |
|
Рядок |
Ні |
Номер версії у форматі N.N[NN]. За замовчуванням — 1.0. |
|
Рядок |
Ні |
Назва модуля (компонента) HAL. За замовчуванням — «mb2hal». |
|
Float |
Ні |
Вставте затримку «FLOAT секунд» між
транзакціями, щоб уникнути великої кількості записів у журналі та полегшити налагодження.
Корисно при використанні |
|
Ціле число |
Так |
Загальна кількість транзакцій Modbus. Максимальної кількості немає.. |
3.2. Розділи транзакцій
Для кожної транзакції необхідний один розділ транзакції, починаючи з [TRANSACTION_00] і послідовно збільшуючи номер. Якщо є нове посилання (не транзакція), ви повинні вказати ОБОВ’ЯЗКОВІ параметри вперше. Попередження: будь-які НЕОБОВ’ЯЗКОВІ параметри, які не вказані, копіюються з попередньої транзакції.
| Значення | Тип | Обов’язково | Опис |
|---|---|---|---|
|
Рядок |
Так |
Ви повинні вказати посилання "serial" або "tcp" для першої транзакції. Якщо не вказано посилання попередньої транзакції, наступні транзакції використовуватимуть його. |
|
IP-адреса |
Якщо |
IP-адреса веденого пристрою Modbus. Ігнорується, якщо |
|
Ціле число |
Ні |
TCP-порт веденого пристрою Modbus. За замовчуванням 502. Ігнорується, якщо |
|
Рядок |
Якщо |
Послідовний порт. Наприклад, "/dev/ttyS0". Ігнорується, якщо |
|
Ціле число |
Якщо |
Швидкість передачі даних. Ігнорується, якщо |
|
Ціле число |
Якщо |
Біти даних. Один з 5, 6, 7, 8. Ігнорується, якщо |
|
Рядок |
Якщо |
Парність даних. Одне з: парне, непарне, жодного. Ігнорується, якщо |
|
Ціле число |
Якщо |
Стоп-біти. Один з 1, 2. Ігнорується, якщо |
|
Ціле число |
Якщо |
Затримка послідовного порту між транзакціями лише цього розділу. У мс. За замовчуванням 0. Ігнорується, якщо |
|
Ціле число |
Так |
Номер веденого пристрою Modbus. |
|
Ціле число |
Так |
Адреса першого елемента. |
|
Ціле число |
Якщо не вказано |
Кількість елементів.
Вказувати одночасно |
|
Список |
Якщо не вказано |
Список імен елементів. Ці імена будуть використовуватися для імен контактів, наприклад mb2hal.plcin.cycle_start. |
|
Рядок |
Так |
Код функції транзакції Modbus (див. посилання: специфікації): • fnct_01_read_coils |
|
Ціле число |
Ні |
Тайм-аут відповіді для цієї транзакції. У мс. За замовчуванням 500 мс. Це час очікування першого байта перед виникненням помилки. |
|
Ціле число |
Ні |
Тайм-аут байта для цієї транзакції. У мс. За замовчуванням 500 мс. Це час очікування від байта до байта, перш ніж виникне помилка. |
|
Рядок |
Ні |
Замість номера транзакції використовуйте ім’я. Приклад: |
|
Float |
Ні |
Максимальна частота оновлення в Гц. За замовчуванням встановлено значення 0,0 (0,0 = як тільки з’явиться можливість = нескінченно).
ПРИМІТКА: Це максимальна частота, фактична частота може бути нижчою. Якщо ви хочете обчислити її в мс, використовуйте (1000 / required_ms).
Приклад: 100 мс = |
|
Рядок |
Ні |
Рівень налагодження лише для цієї транзакції. Див. параметр |
3.3. Коди помилок
Під час налагодження транзакцій зверніть увагу, що повернене значення "ret[]" відповідає:
Винятки протоколу Modbus:
-
0x01 - ILLEGAL_FUNCTION - код FUNCTION, отриманий у запиті, є недозволеним або недійсним.
-
0x02 - ILLEGAL_DATA_ADDRESS - адреса даних, отримана в запиті, не є допустимою адресою для ведомого пристрою або є недійсною.
-
0x03 - ILLEGAL_DATA_VALUE - значення, що міститься в полі запиту даних, не є допустимим або недійсним.
-
0x04 - SLAVE_DEVICE_FAILURE - ЗБІЙ ПІДЛЕЖЕНОГО (або ГОЛОВНОГО) пристрою, що неможливо відновити, під час спроби виконання запитуваної дії.
-
0x04 - SERVER_FAILURE - (див. вище).
-
0x05 - ПІДТВЕРДЖЕННЯ - Ця відповідь повертається для ЗАПОБІГАННЯ ЧАСУ ОЧИЩЕННЯ (PREVENT A TIMEOUT) у головному пристрої. Для обробки запиту у веденому пристрої потрібен тривалий час.
-
0x06 - SLAVE_DEVICE_BUSY - Ведений пристрій (або сервер) ЗАЙНЯТИЙ. Повторіть запит пізніше.
-
0x06 - SERVER_BUSY - (див. вище).
-
0x07 - NEGATIVE_ACKNOWLEDGE - Невдалий запит на програмування з використанням коду функції 13 або 14.
-
0x08 - MEMORY_PARITY_ERROR - Помилка парності SLAVE в ПАМ’ЯТІ.
-
0x0A (-10) - GATEWAY_PROBLEM_PATH - Шлях(и) шлюзу недоступні.
-
0x0B (-11) - GATEWAY_PROBLEM_TARGET - Цільовий пристрій не відповів (згенеровано головним, а не ведомим пристроєм).
Програма або з’єднання:
-
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
4. Приклад конфігураційного файлу
Натисніть тут для завантаження.
#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
5. Піни
|
Note
|
Жовтий = Нове в MB2HAL 1.1 (LinuxCNC 2.9). Щоб використовувати ці нові функції, потрібно встановити m = Значення Приклад:
|
5.1. fnct_01_read_coils
-
mb2hal.m.n.bit bit out
-
mb2hal.m.n.bit-inv bit out
5.2. fnct_02_read_discrete_inputs
-
mb2hal.m.n.bit bit out
-
mb2hal.m.n.bit-inv bit out
5.3. fnct_03_read_holding_registers
-
mb2hal.m.n.float float out
-
mb2hal.m.n.int s32 out
5.4. fnct_04_read_input_registers
-
mb2hal.m.n.float float out
-
mb2hal.m.n.int s32 out
5.5. fnct_05_write_single_coil
-
mb2hal.m.n.bit bit in
NELEMENTS має бути 1, або PIN_NAMES має містити лише одне ім’я.
5.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).
5.7. fnct_15_write_multiple_coils
-
mb2hal.m.n.bit bit in
5.8. fnct_16_write_multiple_registers
-
mb2hal.m.n.float float in
-
mb2hal.m.n.int s32 in
Обидва значення виводів додаються та обмежені значенням 65535 (UINT16_MAX). Використовуйте один, а інший розімкнутий (зчитується як 0).