Skip to main content
Blog
Blog · LRI AEM-60DC8

Tipos de datos Modbus explicados — coils, discrete inputs, input registers y holding registers

Tipos de datos Modbus en la práctica: coils, discrete inputs, input registers y holding registers, direccionamiento, function codes y trampas reales de campo.

LRI IngenieríaMon May 25 2026 21:00:00 GMT-0300 (Brasilia Standard Time)

El ingeniero lee por primera vez la documentación Modbus de un PLC y encuentra cuatro tablas con nombres parecidos, prefijos de cinco dígitos que comienzan en 0, 1, 3 o 4, y un function code por operación. Luego descubre que la dirección lógica 40001 se convierte en 0x0000 dentro del frame, que el registro más obvio aparece desplazado una posición y que la mitad de los clientes de prueba muestra un valor distinto al de la otra mitad. La confusión es herencia de un protocolo de 1979 que carga en los nombres de sus tipos el mapa de memoria del PLC Modicon 984. Este post separa las cuatro tablas, muestra los function codes que tocan cada una y cierra con las trampas que aparecen en el primer día de campo.

Los 4 tipos de datos Modbus

El modelo de datos original de Modbus tiene cuatro tablas. Cada una define el tipo (bit o palabra de 16 bits), el sentido, el prefijo de dirección lógica y los function codes que operan sobre ella.

Tabla Tipo Acceso Prefijo lógico Function codes
Coils 1 bit Lectura y escritura 0xxxx (00001–09999) 0x01, 0x05, 0x0F
Discrete inputs 1 bit Solo lectura 1xxxx (10001–19999) 0x02
Input registers 16 bits Solo lectura 3xxxx (30001–39999) 0x04
Holding registers 16 bits Lectura y escritura 4xxxx (40001–49999) 0x03, 0x06, 0x10

Coils y discrete inputs viajan empaquetados, ocho por byte. Input y holding registers viajan en palabras de 16 bits big-endian. Intentar escribir en input register devuelve excepción 0x01 (Illegal Function); leer un coil con function code 0x02 también devuelve 0x01.

Coils (0x) — bit de lectura y escritura

Los coils representan salidas digitales individuales. El nombre viene de la bobina de un relé interno: encender y apagar contactos, accionar válvulas solenoides, energizar lámparas, comandar arranques y paradas. En equipos modernos los coils también aparecen como flags de comando: reset de contador, limpieza de alarma, disparo de calibración.

Tres function codes tocan coils:

  • 0x01 Read Coils: lee de 1 a 2000 coils consecutivos; respuesta con ceil(N/8) bytes empaquetados.
  • 0x05 Write Single Coil: escribe un coil. Valor 0xFF00 para encender, 0x0000 para apagar; cualquier otro es ilegal.
  • 0x0F Write Multiple Coils: escribe hasta 1968 coils en una sola transacción.

Trampa frecuente: un coil escrito como 0xFF00 vuelve como bit 1 en la lectura siguiente. Comparar siempre contra la representación de lectura, no contra el valor escrito.

Discrete inputs (1x) — bit solo lectura

Los discrete inputs representan entradas digitales conectadas a sensores binarios. El caso clásico es el contacto seco: final de carrera, sensor inductivo, presostato, termostato, botón de emergencia, contacto auxiliar. En equipos de medición también exponen flags de estado.

Solo un function code opera:

  • 0x02 Read Discrete Inputs: lee de 1 a 2000 entradas consecutivas, con ocho bits empaquetados por byte.

No existe escritura sobre un discrete input. El intento devuelve excepción 0x01 o 0x02. La confusión más común ocurre cuando el mismo equipo expone un estado (sensor) y un comando (actuador) sobre el mismo concepto: el fabricante cuidadoso asigna un discrete input para "alarma activa" y un coil para "limpiar alarma".

Input registers (3x) — palabra solo lectura

Los input registers son palabras de 16 bits solo lectura. El uso original era exponer el valor digitalizado de una entrada analógica (termopar, 4–20 mA, sensor de presión, encoder). En equipos dedicados, alojan magnitudes medidas: tensión, corriente, temperatura, contadores.

  • 0x04 Read Input Registers: lee de 1 a 125 registros. La respuesta lleva 2×N bytes en big-endian.

La separación semántica importa: el input register es el contrato "esto es lo que el equipo mide, no puedes tocarlo". En arquitecturas Secure by Design, mantener magnitudes medidas en una tabla solo lectura simplifica la auditoría. En la práctica, muchos fabricantes consolidan todo en holding registers; el AEM-60DC8 sigue esa línea con 147 holding registers documentados.

Holding registers (4x) — palabra de lectura y escritura

Los holding registers son palabras de 16 bits de lectura y escritura. Es la tabla más usada porque cabe todo: setpoints, límites de alarma, configuración, estado, telemetría, contadores, identificación, calibración.

Tres function codes dominan:

  • 0x03 Read Holding Registers: lee de 1 a 125 registros. La operación más frecuente en supervisorios.
  • 0x06 Write Single Register: escribe una palabra de 16 bits en un único registro.
  • 0x10 Write Multiple Registers: escribe hasta 123 registros en una transacción atómica.

Los function codes secundarios incluyen 0x16 (mask write) y 0x17 (read/write multiple). El contrato de un holding register debe documentar, además de la dirección: unidad, escala, offset, rango válido, valor centinela (0x8000 en int16) y persistencia.

Direccionamiento — origen 0 vs 1, offset Modicon, mapa hex × decimal

El punto donde más integraciones tropiezan no es el function code, es la dirección. Dos convenciones coexisten:

  • Dirección lógica (1-based, con prefijo): la notación Modicon. Primer coil 00001, primer discrete input 10001, primer input register 30001, primer holding register 40001.
  • Dirección de protocolo (0-based, sin prefijo): lo que va dentro del frame. Primer registro de cualquier tabla es 0x0000. Quien distingue la tabla es el function code.
Tabla Dirección lógica Dirección de protocolo Function code
Coils 00001 0x0000 0x01
Coils 00100 0x0063 0x01
Discrete inputs 10001 0x0000 0x02
Input registers 30016 0x000F 0x04
Holding registers 40001 0x0000 0x03
Holding registers 40147 0x0092 0x03

Regla práctica: restar el prefijo, restar uno más y convertir a hex. Algunas herramientas adoptan una tercera convención con prefijo 4 y dirección 0-based, donde 40000 se refiere al mismo registro que 40001 en la notación clásica. En caso de ambigüedad, capturar el frame con analizador serial y leer el byte directamente.

Cómo el AEM-60DC8 organiza sus 147 holding registers

El AEM-60DC8 (Plataforma Industrial de Supervisión DC, firmware v1.03) expone 147 holding registers en 17 bloques funcionales. El recorte de abajo es un ejemplo simplificado con fines didácticos; el mapa autoritativo es el anexo del manual técnico.

Bloque Rango (hex) Registros Sentido Contenido
Tensión CH1–CH8 instantánea 0x0000–0x0007 8 RO efectivo uint16 con escala ×100
Tensión CH1–CH8 promedio 1 s 0x0008–0x000F 8 RO efectivo Ventana móvil de 1 s
Estado por canal 0x0010–0x0017 8 RO efectivo Bitfield: presente, en alarma, calibrado
Límites superiores/inferiores 0x0020–0x002F 16 RW Setpoints por canal
Configuración de canal 0x0040–0x004F 16 RW Habilitación, modo, oversampling
Configuración de comunicación 0x0050–0x0057 8 RW Slave ID, baudrate, paridad, timeout
Contadores de evento 0x0060–0x006F 16 RO efectivo Subida y bajada de alarma
Telemetría forense 0x0070–0x007F 16 RO efectivo Uptime, watchdog resets, CRC errors
Calibración de fábrica 0x0080–0x008F 16 RW (protegido) Ganancia y offset, requiere código
Identificación 0x0090–0x0092 3 RO efectivo Modelo, serial, firmware v1.03

Los holding registers con sentido "RO efectivo" aceptan escritura a nivel de protocolo, pero el firmware rechaza con excepción 0x04 cuando el contenido es resultado de una medida. Publicar un mapa sin indicar sentido efectivo, unidad, escala y persistencia convierte cada integración en negociación.

Errores comunes en la lectura

Cinco trampas explican la mayoría de los reportes de "Modbus que no funciona" en campo:

  1. Off-by-one: leer holding register 40016 escribiendo 0x0010 en lugar de 0x000F. El servidor responde con el valor de 40017. Corregir: restar el prefijo y uno más antes de convertir.

  2. Byte order: Modbus es big-endian dentro del registro de 16 bits — byte alto primero. Implementaciones little-endian leen con los bytes invertidos. Síntoma: 24,00 V aparece como 0,06 V (0x0960 leído como 0x6009).

  3. Word swapping en 32 bits: float, int32 y contadores ocupan dos registros consecutivos. El orden de palabras (high word primero vs low word primero) no está estandarizado. Las cuatro combinaciones (ABCD, CDAB, BADC, DCBA) aparecen en campo. Síntoma: valores pequeños correctos, valores grandes absurdos.

  4. Signed vs unsigned: el protocolo transporta 16 bits crudos, sin indicar signo. -100 llega como 0xFF9C; leído como uint16 vale 65436. Tensiones con referencia flotante pueden ser negativas y exigen interpretación signed.

  5. Cantidad fuera del límite: 0x03 y 0x04 aceptan hasta 125 registros; 0x10 acepta hasta 123. Pedidos mayores devuelven excepción 0x03. Leer 147 registros en una sola solicitud no funciona — dividir en dos lecturas.

Preguntas frecuentes

¿Por qué existen cuatro tablas en lugar de una sola? La separación refleja la memoria del PLC Modicon 984 de los años 80, donde salidas digitales, entradas digitales, entradas analógicas y memoria de configuración ocupaban áreas físicas distintas. La especificación la preservó para dejar explícita la semántica RO vs RW y bit vs palabra.

¿Puedo usar holding registers para todo? Técnicamente sí, y muchos fabricantes consolidan medidas, setpoints y estados en holding registers. La pérdida es semántica: el cliente debe saber por convención cuáles registros son lectura efectiva.

¿Cómo leo un float de 32 bits en Modbus? Leyendo dos holding registers consecutivos y reconstruyendo el float según el orden documentado. El orden más común en equipos modernos es CDAB (low word primero), pero ABCD aparece en equipos europeos.

¿El AEM-60DC8 expone coils o discrete inputs? No. El AEM-60DC8 consolida las 147 variables en holding registers, con soporte para los function codes 0x03 y 0x10. Estado de canal y flags de alarma se exponen como bitfields.

¿Cómo sé si la dirección de la documentación es lógica o de protocolo? Por el número: cinco dígitos comenzando en 0, 1, 3 o 4 es dirección lógica. Hexadecimal o comenzando en 0x0000 es dirección de protocolo. En ambigüedad, capturar el frame y leer el byte directamente.


Contenido relacionado

Más materiales técnicos de LRI sobre temas adyacentes.