1. Introducción
MB2HAL es un componente HAL en tiempo no-real genérico para comunicarse con uno o más dispositivos Modbus. Hasta ahora, hay dos opciones para comunicarse con un dispositivo Modbus:
-
Una opción es crear un componente HAL como un controlador, ver VFD Modbus.
-
Otra opción es usar Classic Ladder, el cual tiene Modbus interconstruido, ver ClassicLadder.
-
Ahora hay una tercera opción que consiste en un controlador "genérico" configurado por archivo de texto, y es llamada MB2HAL.
¿Por qué MB2HAL? Considera usar MB2HAL si:
-
Tienes que escribir un controlador nuevo y no sabes nada de programación.
-
Necesitas usar Classic Ladder "solo" para manejar las conexiones de Modbus.
-
Debes encontrar y configurar las transacciones Modbus por primera vez. MB2HAL tiene niveles de depuración que facilitan la depuración de protocolo de bajo nivel.
-
Tienes que conectar más de un dispositivo. MB2HAL es muy eficiente administrando múltiples dispositivos, transacciones y enlaces. Actualmente monitoreo dos controladores de ejes usando un puerto Rs232, un controlador VFD usando otro puerto Rs232 y una E/S remota usando TCP/IP.
-
Quieres un protocolo para conectar tu Arduino con HAL. Ver el archivo de ejemplo de configuración incluido, diagrama y librería para Arduino en Modbus.
2. Utilización
-
Crear un archivo de configuración del ejemplo de abajo
-
Asignar el nombre del componente (opcional)
Asignar
HAL_MODULE_NAME=mimodulo(predeterminadoHAL_MODULE_NAME=mb2hal) -
Carga el componente HAL de tiempo no-real modbus
-
-
Nombre de componente predeterminado:
loadusr -W mb2hal config=config_file.ini -
Nombre de componente personalizado:
loadusr -Wn mimodulo mb2hal config=config_file.ini
3. Opciones
3.1. Sección Init
[MB2HAL_INIT]
| Valor | Tipo | Requerido | Descripción |
|---|---|---|---|
|
Entero |
No |
Nivel de depuración de init y parseo del archivo INI. |
|
Cadena |
No |
Número de versión en el formato N.N[NN]. Predeterminado a 1.0. |
|
Cadena |
No |
Nombre del módulo (componente) HAL. Predeterminado a "mb2hal". |
|
Flotante |
No |
Inserta un retardo de "FLOTANTE segundos" entre
transacciones con el fin de no tener mucho que registrar y facilitar la depuración.
Útil cuando se usa |
|
Entero |
Sí |
El número total de transacciones Modbus. No hay máximo. |
3.2. Secciones de transacción
Se requiere una sección de transacción por transacción, comenzando con [TRANSACTION_00] y contando hacia arriba secuencialmente. Si hay un enlace nuevo (sin transacción) debes proporcionar los parámetros REQUERIDOS la 1era vez. Advertencia: Cualquier parámetro OPCIONAL no especificado es copiado de la transacción previa.
| Valor | Tipo | Requerido | Descripción |
|---|---|---|---|
|
Cadena |
Sí |
Debes especificar un enlace "serial" o "tcp" para la primera transacción. Transacciones posteriores usarán el enlace de la transacción anterior si no se especifica. |
|
Dirección IP |
Si |
La dirección IP del dispositivo Modbus esclavo. Ignorada si |
|
Entero |
No |
El puerto del dispositivo Modbus esclavo. Predeterminado a 502. Ignorado si |
|
Cadena |
Si |
El puerto serie. Por ejemplo "/dev/ttyS0". Ignorado si |
|
Entero |
Si |
La velocidad en baudios. Ignorado si |
|
Entero |
Si |
Bits de datos. Uno de 5, 6, 7 u 8. Ignorado si |
|
Cadena |
Si |
Paridad de datos. Uno de: even, odd o none. Ignorado si |
|
Entero |
Si |
Bits de parada. Uno de 1, 2. Ignorado si |
|
Entero |
Si |
Retardo de puerto serial entre transacciones de solo esta sección. En ms. Predeterminado a 0. Ignorado si |
|
Entero |
Sí |
Número de esclavo Modbus. |
|
Entero |
Sí |
La dirección del primer elemento. |
|
Entero |
A menos que se especifique |
El número de elementos.
Es un error especificar ambos |
|
Lista |
A menos que `NELEMENTS`este especificado |
Una lista de nombres de elementos. Estos nombres se usarán para los nombres de pines, p. ej. mb2hal.plcin.cycle_start. |
|
Cadena |
Sí |
Código de la función de transacción de Modbus (ver especificaciones): • fnct_01_read_coils |
|
Entero |
No |
Tiempo de expiración de respuesta para esta transacción. En ms. Predeterminado a 500 ms. Esto es cuánto esperar al 1er byte antes de mandar un error. |
|
Entero |
No |
Tiempo de expiración de byte para esta transacción. En ms. Predeterminado a 500 ms. Esto es cuánto esperar de un byte a otro antes de mandar un error. |
|
Cadena |
No |
En lugar de dar un número de transacción usar un nombre. Ejemplo: |
|
Flotante |
No |
Velocidad máxima de actualización en Hz. Predeterminado a 0.0 (0.0 = en cuanto este disponible = infinito).
NOTA: Esta es la tasa máxima y la tasa real puede ser menor. Si se quiere calcular en ms usar (1000 / ms_requeridos).
Ejemplo: 100 ms = |
|
Cadena |
No |
Nivel de depuración para solo esta transacción. Ver el parámetro |
3.3. Códigos de error
Al depurar transacciones nota que el valor devuelto "ret[]" corresponde a:
Excepciones de protocolo 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).
Programa o conexión:
-
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. Archivo de configuración de ejemplo
Clic aquí para descargar.
#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. Pines
|
Note
|
Yellow = Nuevo en MB2HAL 1.1 (LinuxCNC 2.9) Para usar estas nuevas características debes asignar m = Valor de Ejemplo:
|
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 necesita ser 1 o PIN_NAMES debe contener solo un nombre.
5.6. fnct_06_write_single_register
-
mb2hal.m.n.float float in
-
mb2hal.m.n.int s32 in
NELEMENTS necesita ser 1 o PIN_NAMES debe contener solo un nombre. Ambos valores de pines están sumados y limitados a 65535 (UINT16_MAX). Usar uno y dejar el otro abierto (leer como 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
Ambos valores de pines son sumados y limitados a 65535 (UINT16_MAX). Usar uno y dejar el otro abierto (leer como 0).