Sondear esclavos Modbus RTU con timeouts y valores de 32 bits
Un maestro Modbus RTU en un PLC ESP32 abre la puerta a todo lo que cuelga del bus RS-485: analizadores de energía, variadores, controladores de máquina. Este ejemplo envuelve toda la transacción en una función genérica — peticionModbusFC3(slave, address, count, timeout) — que devuelve un vector de registros, o vacío en caso de fallo, más utilidades para combinar pares de registros en valores de 32 bits. Sale directamente de un despliegue real de monitorización de máquinas textiles.
Una función genérica para todas las lecturas
En lugar de dispersar la gestión de peticiones y respuestas por todo el firmware, una única función envía la lectura FC3, espera la respuesta dentro de un bucle acotado y devuelve un std::vector de registros. Un vector vacío significa error o timeout — quien llama comprueba el tamaño y sigue adelante. Añadir un dispositivo nuevo al sondeo se convierte en una línea, no en una nueva máquina de estados.
Los timeouts evitan que el bus se adueñe de tu loop
Un esclavo desenchufado o apagado es la vida normal de un bus de fábrica, no una excepción. La espera de respuesta está limitada a un timeout configurable (200 ms aquí), así que el peor caso es una pausa corta y acotada en lugar de un nodo de monitorización congelado. La función retorna con la primera respuesta completa — buena o de error — y el resto del firmware, contador de pulsos incluido, sigue funcionando intacto.
Dos registros, un valor de 32 bits
Los registros Modbus tienen 16 bits, pero los valores que de verdad merece la pena registrar — totalizadores, contadores de energía, producción acumulada — casi siempre son de 32. regsToU32() desplaza la palabra alta a la izquierda y hace OR con la baja; regsToS32() reinterpreta el mismo patrón de bits como complemento a dos para magnitudes con signo, como el flujo de potencia. El orden de palabra varía entre fabricantes, y algunos envían primero la palabra baja, así que las utilidades mantienen la suposición big-endian explícita en un solo sitio y trivial de invertir por dispositivo.
Un fragmento de la implementación
Tal cual del ejemplo desplegado en el ESP32 PLC — cópialo libremente:
El ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.
Preguntas frecuentes
¿Cuántos esclavos puedo poner en un bus RS-485?
Modbus RTU permite hasta 247 direcciones, y 32 dispositivos por segmento sin repetidores es el límite práctico de RS-485. Sondéalos secuencialmente con la misma función, un ID de esclavo cada vez.
Mis valores de 32 bits salen mal — ¿por qué?
Casi siempre es el orden de palabra. Algunos fabricantes envían primero la palabra baja. Intercambia los argumentos de regsToU32() o añade una variante little-endian; los bytes dentro de cada registro los define Modbus y rara vez son el problema.
¿Puede el mismo PLC publicar también estos datos por MQTT?
Sí — ese es el montaje de producción. El sondeo Modbus rellena un documento JSON que el módulo MQTT publica y el módulo SD almacena offline, de modo que los datos de los analizadores reciben el mismo tratamiento offline-first que las entradas de máquina.