Modbus TCP
Registros y bobinas Modbus sobre TCP/IP, con direccionamiento tipado, control del orden de bytes y una exploración de red acotada.
El controlador Modbus TCP lee y escribe registros y bobinas Modbus sobre TCP/IP: autómatas, medidores, pasarelas y cualquier servidor que hable Modbus/TCP. El direccionamiento es del todo tipado: se elige una clase de registro y un número de registro que empieza en 0, y la aplicación compone la petición del bus; no hay ninguna dirección de texto libre en la que equivocarse.
Dispositivo
| Campo | Significado | Por defecto |
|---|---|---|
| Host o IP | Nombre DNS, dirección IPv4 o IPv6 del servidor o de la pasarela Modbus. | localhost cuando se deja vacío |
| Puerto | Puerto TCP. | 502 (un 0 configurado recae en 502) |
| ID de unidad | El id de unidad (esclavo) Modbus que lleva cada petición: lo que una pasarela usa para encaminar hacia el dispositivo que hay detrás. De 0 a 255. | 1 |
| Intervalo mínimo entre transacciones (ms) | Cadencia de compatibilidad: el silencio mínimo tras completarse una transacción antes de que empiece la siguiente, de 0 a 1000. Cero no añade retardo artificial. | 0 |
| Intervalo de sondeo (ms) | Ritmo de sondeo por defecto para los tags que no lo sustituyen. | 1000 |
El URI base que se muestra en la cabecera del panel es modbus+tcp://host:port/unitID, más ?minimumTransactionIntervalMs=n cuando el intervalo está fijado.
Los dispositivos que comparten host y puerto comparten también una única puerta de transacciones: las peticiones al mismo punto de conexión nunca se solapan, y el intervalo mínimo entre transacciones más grande de entre los dispositivos habilitados de ese punto de conexión marca la cadencia de todos ellos. El panel avisa cuando otro dispositivo eleva el intervalo efectivo por encima del que se ha configurado aquí. El intervalo gobierna solo el tráfico que emite esta aplicación: es una ayuda de compatibilidad para un servidor o una pasarela lentos, no un remedio para las averías de red.
Conectar espera como mucho 5 segundos; una respuesta se espera como mucho 10 segundos; no hay reintentos a nivel de protocolo. El bucle de reintento en segundo plano es el dueño de la reconexión, así que un dispositivo apagado no cuesta más que una lectura de mala calidad.
Direccionamiento del tag
| Campo | Significado | Por defecto |
|---|---|---|
| Clase de registro | Qué entidad Modbus direcciona el tag: HoldingRegister, InputRegister, Coil o DiscreteInput. |
Se deriva del tipo y del acceso: los tags Boolean reciben DiscreteInput (solo lectura) o Coil (con escritura); los demás tipos reciben InputRegister (solo lectura) o HoldingRegister (con escritura). |
| Número de registro (desde 0) | La dirección de protocolo en bruto. Es la dirección que empieza en 0 sobre el bus, no la notación clásica 4xxxx: el registro de retención "40001" es el número de registro 0. El registro viaja por el bus como un número de 16 bits, así que el campo admite de 0 a 65535 y rechaza cualquier cosa más ancha allí donde se escribe. | 0 |
| Cantidad (registros, en blanco = automático) | Cuántos registros de 16 bits ocupa el valor. La casilla se dibuja solo en los tags String: los demás tipos tienen un ancho fijo, así que no hay nada que sustituir. | Por tipo: Boolean 1, Int32 y Float 2, String 4 |
| Byte más significativo primero | Qué byte de cada registro de 16 bits va primero por el bus. Solo en tags numéricos. | encendido (lo que pide la especificación Modbus) |
| Palabra más significativa primero | Qué registro de un valor de dos registros lleva la mitad alta. Solo en tags numéricos. | encendido |
La tarjeta Origen muestra la dirección de bus ya compuesta (por ejemplo 100?quantity=2) como vista previa de solo lectura, así que lo que enseña el panel es exactamente lo que lleva la petición.
Tipos de valor y cantidades
Se ofrecen cuatro tipos de valor, y el ancho de protocolo de cada uno es fijo:
| Tipo de dato | Registros | Forma en el bus |
|---|---|---|
| Boolean | 1 | En una clase de registro: cualquier registro distinto de cero se lee como verdadero, y una escritura envía 1 o 0. En Coil/DiscreteInput: el propio bit. |
| Int32 | 2 | Entero con signo de 32 bits repartido en una pareja de registros. |
| Float | 2 | Precisión simple IEEE 754 repartida en una pareja de registros. |
| String | 1 o más (4 por defecto) | Bytes UTF-8 empaquetados de dos en dos por registro. Una lectura se detiene en el primer byte NUL; una escritura tiene que caber en la cantidad declarada (2 bytes por registro) y se rellena con ceros. |
Un tag String se lee y se escribe en el orden en que el dispositivo guarda los bytes, y una escritura envía siempre UTF-8. Los bytes que no son UTF-8 válido, que es el aspecto que tiene un rango que el dispositivo nunca inicializó o un texto escrito en otra codificación, se leen como el carácter Unicode de sustitución en lugar de fallar: el tag muestra algo visiblemente mal, y todos los demás tags de ese dispositivo siguen leyendo.
La Cantidad se pide solo en los tags String. Los anchos de Boolean, Int32 y Float son fijos, así que la casilla no se dibuja en esos puntos, ni en el panel del tag ni en la rejilla de tags; la sustitución existe para dimensionar los tags String.
Orden de byte y de palabra
Las dos casillas de orden se dibujan en los tags numéricos. Son preguntas independientes: qué byte va delante dentro de cada registro, y qué registro va delante en una pareja. Modbus no define ninguna de las dos para el texto, así que a un tag String no se le ofrecen: sus bytes viajan en el orden en que el dispositivo los guarda. Para el valor 0x01020304, siendo A el byte más significativo, las cuatro disposiciones son:
| Byte más significativo primero | Palabra más significativa primero | Bytes en el bus |
|---|---|---|
| encendido | encendido | AB CD (el valor por defecto de la especificación) |
| encendido | apagado | CD AB (el intercambio de palabras clásico) |
| apagado | encendido | BA DC |
| apagado | apagado | DC BA |
Las lecturas y las escrituras aplican las dos mismas respuestas en el mismo orden, así que una escritura deposita exactamente los bytes que una lectura habría recogido.
Códigos de función
| Clase de registro | Lectura | Escritura |
|---|---|---|
| HoldingRegister | 3 (Read Holding Registers) | 6 (registro único) o 16 (varios registros) |
| InputRegister | 4 (Read Input Registers) | solo lectura; una escritura se rechaza |
| Coil | 1 (Read Coils) | 5 (Force Single Coil, una sola bobina) |
| DiscreteInput | 2 (Read Discrete Inputs) | solo lectura; una escritura se rechaza |
Una escritura devuelve éxito solo cuando la respuesta de protocolo del servidor confirma que la aceptó; el valor en caché avanza únicamente entonces.
Descubrimiento
La exploración es explícita y acotada: la aplicación nunca deduce ni barre la subred local. El formulario del alcance toma:
| Campo | Significado | Por defecto |
|---|---|---|
| Host IPv4 o CIDR | Una dirección (192.168.1.10) o una subred no más ancha que /24 (192.168.1.0/24). Las direcciones de red y de difusión se saltan. |
obligatorio |
| Puerto | El puerto que se va a sondear. | 502 |
| ID de unidad | Valores, listas separadas por comas o rangos ascendentes: 1, 1,5,9, 1, 3, 8-16 (de 0 a 255). |
1 |
| Intervalo mínimo entre transacciones (ms) | Cadencia entre sondeos completados en la misma dirección, de 0 a 1000. | 0 |
Una sola exploración puede enviar como mucho 256 sondeos (direcciones × ID de unidad); un plan mayor se rechaza antes de que se abra ningún zócalo. La única petición que se envía es Read Basic Device Identification (función 43/14): el descubrimiento nunca lee registros ni adivina un mapa de registros. Una respuesta de excepción Modbus del todo válida demuestra que hay una unidad presente sin declarar su identidad; la alcanzabilidad TCP, los tiempos de espera agotados y las tramas mal formadas no lo demuestran. Se exploran hasta cuatro direcciones en paralelo, de forma secuencial dentro de cada una, con tiempos de espera de 750 ms para conectar y para sondear.
Los resultados llevan el punto de conexión completo y un nombre sugerido, montado con el fabricante y el código de producto cuando el dispositivo los informa. Los candidatos tienen cero tags: los registros se configuran después de Añadir. Una unidad que ya está configurada se marca como tal y ofrece Abrir en lugar de crear un duplicado.
Límites que conviene conocer
- Los tipos enteros anchos (Int64, los anchos sin signo) y Double no se ofrecen: el codificador del bus va y vuelve con exactitud solo en los cuatro tipos de arriba.
- Hay una petición pendiente por punto de conexión a la vez; muchos dispositivos detrás de una misma pasarela comparten esa serialización por diseño.
- Las escrituras direccionan una bobina o una tirada de registros a la vez; no hay escritura de varias bobinas.