LinuxCNC Documentation

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:

  1. Una opción es crear un componente HAL como un controlador, ver VFD Modbus.

  2. Otra opción es usar Classic Ladder, el cual tiene Modbus interconstruido, ver ClassicLadder.

  3. 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

  1. Crear un archivo de configuración del ejemplo de abajo

    1. Asignar el nombre del componente (opcional)

      Asignar HAL_MODULE_NAME=mimodulo (predeterminado HAL_MODULE_NAME=mb2hal)

    2. Carga el componente HAL de tiempo no-real modbus

  2. Nombre de componente predeterminado: loadusr -W mb2hal config=config_file.ini

  3. 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

INIT_DEBUG

Entero

No

Nivel de depuración de init y parseo del archivo INI.
0 = silencioso
1 = mensajes de error (predeterminado)
2 = mensajes de confirmación de OK
3 = mensajes de depuración
4 = máximo de mensajes de depuración (solo en transacciones)

VERSION

Cadena

No

Número de versión en el formato N.N[NN]. Predeterminado a 1.0.

HAL_MODULE_NAME

Cadena

No

Nombre del módulo (componente) HAL. Predeterminado a "mb2hal".

SLOWDOWN

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 DEBUG=3 (NO INIT_DEBUG=3). Afecta TODAS las transacciones. Usar "0.0" para actividad normal.

TOTAL_TRANSACTIONS

Entero

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

LINK_TYPE

Cadena

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.

TCP_IP

Dirección IP

Si LINK_TYPE=tcp

La dirección IP del dispositivo Modbus esclavo. Ignorada si LINK_TYPE=serial.

TCP_PORT

Entero

No

El puerto del dispositivo Modbus esclavo. Predeterminado a 502. Ignorado si LINK_TYPE=serial.

SERIAL_PORT

Cadena

Si LINK_TYPE=serial

El puerto serie. Por ejemplo "/dev/ttyS0". Ignorado si LINK_TYPE=tcp.

SERIAL_BAUD

Entero

Si LINK_TYPE=serial

La velocidad en baudios. Ignorado si LINK_TYPE=tcp.

SERIAL_BITS

Entero

Si LINK_TYPE=serial

Bits de datos. Uno de 5, 6, 7 u 8. Ignorado si LINK_TYPE=tcp.

SERIAL_PARITY

Cadena

Si LINK_TYPE=serial

Paridad de datos. Uno de: even, odd o none. Ignorado si LINK_TYPE=tcp.

SERIAL_STOP

Entero

Si LINK_TYPE=serial

Bits de parada. Uno de 1, 2. Ignorado si LINK_TYPE=tcp.

SERIAL_DELAY_MS

Entero

Si LINK_TYPE=serial

Retardo de puerto serial entre transacciones de solo esta sección. En ms. Predeterminado a 0. Ignorado si LINK_TYPE=tcp.

MB_SLAVE_ID

Entero

Número de esclavo Modbus.

FIRST_ELEMENT

Entero

La dirección del primer elemento.

NELEMENTS

Entero

A menos que se especifique PIN_NAMES

El número de elementos. Es un error especificar ambos NELEMENTS y PIN_NAMES. Los nombres de pines serán números secuenciales, p. ej. mb2hal.plcin.01.

PIN_NAMES

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.
NOTA: No debe haber caracteres de espacio en blanco en la lista. Ejemplo: PIN_NAMES=cycle_start,stop,feed_hold

MB_TX_CODE

Cadena

Código de la función de transacción de Modbus (ver especificaciones):

• 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

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.

MB_BYTE_TIMEOUT_MS

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.

HAL_TX_NAME

Cadena

No

En lugar de dar un número de transacción usar un nombre. Ejemplo: mb2hal.00.01 podría volverse mb2hal.plcin.01. El nombre no debe exceder de 28 caracteres. NOTA: al usar nombres ser cuidadoso de no terminar con dos transacciones usando el mismo nombre.

MAX_UPDATE_RATE

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 = MAX_UPDATE_RATE=10.0, porque 1000.0 ms / 100.0 ms = 10.0 Hz.

DEBUG

Cadena

No

Nivel de depuración para solo esta transacción. Ver el parámetro INIT_DEBUG arriba.

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 VERSION = 1.1.

m = Valor de HAL_TX_NAME si esta configurado o número de transacción
n = Número de elemento (NELEMENTS) o nombre de PIN_NAMES

Ejemplo:

  • mb2hal.00.01.int (TRANSACTION_00, segundo registro)

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

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).