Modbus RTU: function codes y registros para PLC/SCADA

Equipo Yubox
Equipo Yubox
3 de July, 2026
IoT Industria Guías
Modbus RTU: function codes y registros para PLC/SCADA

Ya tiene el bus RS485 tendido y terminado: par trenzado, 120 Ω en las puntas, referencia común. El cableado funciona. Y sin embargo el sensor sigue sin aparecer en el SCADA, o el PLC lee un número que no tiene sentido. Ahí es donde termina la electricidad y empieza el verdadero desafío de Modbus RTU: la capa de aplicación. Direcciones de registro, function codes, orden de bytes y mapeo de variables —lo que decide si esos bits que ya viajan bien por el cable se convierten en un dato útil o en basura con forma de número.

Este artículo asume que el bus físico ya está resuelto y se enfoca en lo que viene después: cómo hablar Modbus a nivel de protocolo, cómo mapear los registros de un dispositivo real y cómo esa información llega, de forma ordenada, a un PLC o a un sistema SCADA.

El modelo de datos: cuatro tipos de registro, no uno

Modbus organiza la memoria del esclavo en cuatro tablas independientes. Confundirlas es el error más común al integrar un dispositivo nuevo:

Tipo Tamaño Acceso Uso típico Dirección clásica
Coils 1 bit Lectura/escritura Salidas digitales: encender un relé, un contactor, una bomba 0xxxx
Discrete inputs 1 bit Solo lectura Entradas digitales: fin de carrera, botón de paro, estado de un breaker 1xxxx
Input registers 16 bits Solo lectura Mediciones analógicas: temperatura, presión, corriente de un sensor 3xxxx
Holding registers 16 bits Lectura/escritura Configuración y proceso: setpoints, parámetros, consignas 4xxxx

La notación “4xxxx” es herencia de los PLC Modicon originales, donde el primer dígito indicaba la tabla y los cuatro siguientes la dirección dentro de ella (offset 1-based). La mayoría del software moderno ya trabaja con direcciones 0-based puras (0 a 65535) y el número de tabla lo indica el function code, no un prefijo. Ese desfase de “uno” entre la dirección del manual (40001) y la que hay que pedir por protocolo (0) es, en la práctica, la causa número uno de “el registro no responde” en una integración nueva.

Function codes: el verbo de cada operación

El function code le dice al esclavo qué tabla tocar y qué operación hacer. Los que aparecen en el 90% de las integraciones de campo:

  • 01 – Read Coils: lee el estado de una o varias salidas digitales.
  • 02 – Read Discrete Inputs: lee entradas digitales de solo lectura.
  • 03 – Read Holding Registers: lee registros de configuración/proceso. El más usado para leer sensores que exponen sus datos como holding registers (aunque formalmente sean de solo medición).
  • 04 – Read Input Registers: lee mediciones analógicas de solo lectura.
  • 05 – Write Single Coil: escribe una salida digital (on/off).
  • 06 – Write Single Register: escribe un holding register (por ejemplo, un setpoint).
  • 15 – Write Multiple Coils: escribe varias salidas digitales en un solo mensaje.
  • 16 – Write Multiple Registers: escribe varios holding registers consecutivos en un solo mensaje (útil para configurar de una vez velocidad, dirección o umbrales de un dispositivo).

Un maestro Modbus RTU típico arma la trama con: dirección del esclavo, function code, dirección inicial, cantidad de registros y un CRC de 16 bits al final. Si el esclavo detecta un error, no ignora el mensaje: responde con el mismo function code pero con el bit más significativo activado (por ejemplo, 0x83 en vez de 0x03) y un código de excepción —dirección ilegal, valor ilegal, dispositivo ocupado— que es la primera pista para diagnosticar una integración que “no jala”.

Mapear un dispositivo real: el registro no dice lo que es

Aquí está el punto que los tutoriales genéricos casi nunca explican bien: un holding register es solo un número de 16 bits sin unidad ni significado propio. El significado lo define exclusivamente la hoja de mapeo (register map) del fabricante. Tomemos un caso típico de campo: un sensor de temperatura y humedad Modbus RTU para invernadero o cuarto de bombas.

Dirección  Registro                  Tipo        Escala   Nota
0x0000     Temperatura               INT16 con signo   /10   -400 = -40.0 °C
0x0001     Humedad relativa          UINT16            /10    650 = 65.0 %
0x0002-03  Contador de energía       UINT32 (2 regs)   /100   ABCD (big-endian)

Tres decisiones del fabricante que hay que respetar al decodificar, o el dato sale mal aunque la comunicación esté perfecta:

  • Signo. Un INT16 de -40.0 °C se transmite como el complemento a dos de 400 (0xFE70), no como “400 con un bit de signo aparte”. Si el decoder lo trata como UINT16, una temperatura bajo cero aparece como un número absurdo cercano a 65.000.
  • Escala. Casi ningún fabricante transmite decimales directos: multiplica por 10 o por 100 para evitar el punto flotante en registros de 16 bits. Sin dividir por el factor correcto, 65.0% de humedad llega como “650”.
  • Orden de bytes en valores de 32 bits. Cuando un dato ocupa dos registros (por ejemplo, un contador de energía o un caudal), existen cuatro variantes de orden —ABCD, BADC, CDAB, DCBA— y no hay forma de adivinarlo: si el valor sale en cero, negativo o con un exponente absurdo (típico de leer un float con el orden de palabra invertido), el primer sospechoso es el word swap. Se corrige comparando la lectura cruda contra un valor conocido en el display del equipo.

Esta lógica de mapeo es exactamente la misma que ya se explicó para decodificar payloads LoRaWAN: un flujo de bytes solo se convierte en dato con un decoder que conozca tipo, signo, escala y orden. La diferencia es que en Modbus ese “decoder” vive en la lógica del maestro que hace el polling, no en un Network Server.

De Modbus RTU a un PLC o a un SCADA

Con el mapa de registros resuelto, queda la pregunta de integración: ¿cómo entra ese dato al sistema de control de la planta?

PLC como maestro Modbus. La mayoría de los PLC industriales (Siemens, Allen-Bradley, Delta, Unitronics, entre otros) incluyen un bloque o instrucción de comunicación Modbus RTU maestro. El programador configura, por cada esclavo: dirección, function code, registro inicial, cantidad y a qué área de memoria interna del PLC mapear el resultado. El PLC hace polling —pregunta y espera respuesta— en un ciclo periódico, típicamente cada 200 ms a varios segundos según cuántos esclavos tenga el bus y qué tan rápido necesite reaccionar la lógica de control.

Gateway Modbus RTU → Modbus TCP. Cuando el sistema de supervisión (SCADA, historian, plataforma en la nube) está en la red de datos y no puede colgarse físicamente de un bus RS485, se usa un gateway que actúa de esclavo hacia el maestro RTU original y de maestro (o servidor) hacia el lado TCP/IP. Modbus TCP es, en esencia, la misma trama de aplicación —mismos function codes, mismos registros— encapsulada en Ethernet, sin el CRC (lo cubre el propio TCP) y con un identificador de transacción en vez de silencios de bus para separar mensajes.

El watchdog y el timeout, no opcionales. Un maestro Modbus real —PLC, SCADA o un nodo IoT— debe definir qué hacer si un esclavo no responde: cuántos reintentos, con qué timeout, y qué valor reportar mientras tanto (¿la última lectura válida? ¿un flag de “sin comunicación”?). Sin esa lógica, un solo sensor caído en un bus de veinte puede colgar el ciclo de polling completo y hacer que el PLC parezca “trabado” cuando en realidad solo está esperando una respuesta que nunca llega.

Cuando el “SCADA” es la nube. No toda integración necesita un PLC de por medio. La tarjeta Yubox Industrial actúa directamente como maestro Modbus RTU con RS485 aislado ópticamente: recorre las direcciones del bus, aplica el mapeo de cada esclavo y sube el paquete consolidado por LoRaWAN hasta un gateway y de ahí a la plataforma en la nube. Para plantas o sitios remotos donde instalar un SCADA local no se justifica —una estación de bombeo, un cuarto de tableros en una camaronera, una subestación menor— ese camino reemplaza al PLC/SCADA tradicional con la misma disciplina de protocolo, pero sin el cableado Ethernet ni el servidor en sitio.

Errores de integración más comunes

  • Parámetros de puerto distintos entre maestro y esclavo. Baud rate, paridad y bits de parada deben coincidir exactamente; una diferencia no da error legible, simplemente no hay respuesta.
  • Confundir la dirección “de manual” con la dirección “de protocolo”. El desfase 1-based vs 0-based ya mencionado.
  • Usar el function code de la tabla equivocada. Pedir con 03 (holding) un dato que el fabricante expone como input register (04) devuelve una excepción, no el valor.
  • Ignorar el orden de bytes en valores de 32 bits. Sin verificarlo contra un valor conocido, un contador o un caudal puede leerse consistentemente mal durante meses sin que nadie lo note, porque el número “se ve” plausible.
  • Direcciones duplicadas en el mismo bus, heredado de la instalación física pero que solo se manifiesta como corrupción intermitente a nivel de protocolo.

Conclusión

RS485 resuelve cómo viajan los bits; Modbus RTU resuelve qué significan. Integrar un sensor o un actuador de verdad —a un PLC, a un SCADA o a una plataforma en la nube vía LoRaWAN— exige dominar los cuatro tipos de registro, elegir el function code correcto, y sobre todo, respetar al pie de la letra el mapa de registros del fabricante: signo, escala y orden de bytes. Ahí es donde se decide si el dato que llega a la pantalla es confiable o solo parece serlo.

¿Necesita integrar sensores o equipos Modbus RTU a un sistema de supervisión, con o sin PLC en sitio? Hablemos y revisamos el mapa de registros y la arquitectura de comunicación de su planta.