Ir al contenido

Lectura y escritura por Modbus RTU y Modbus TCP

Modbus es el protocolo que la mayoría del software SCADA y HMI espera encontrar en un PLC. En esta lección la estación de bombeo publica su estado y el nivel del depósito en un mapa de registros que cualquier cliente Modbus puede leer, y acepta una orden de marcha. Usarás la librería oficial Modbus de Industrial Shields, que convierte el PLC en maestro o esclavo Modbus sobre RS485/RS232 (RTU) o Ethernet (TCP).

Qué aprenderás

  • Distinguir Modbus RTU de Modbus TCP y elegir uno para un proyecto.
  • Diseñar un mapa de registros pequeño antes de escribir código.
  • Ejecutar un esclavo Modbus TCP con la librería de Industrial Shields y probarlo desde tu PC.

Necesitas: un M-Duino con Ethernet configurado como en el curso de fundamentos, la librería instalada y un PC en la misma red.

Instalar la librería

  1. Descarga la librería arduino-Modbus de GitHub como archivo ZIP.
  2. En el Arduino IDE, usa Sketch > Include Library > Add .ZIP Library y selecciona el archivo.
  3. Los ejemplos aparecen en File > Examples > Modbus.

RTU sobre RS485, TCP sobre Ethernet

Modbus RTU funciona sobre RS485: un maestro sondea a varios esclavos, cada uno con su propia dirección. Modbus TCP funciona sobre Ethernet, por defecto en el puerto 502. El modelo de registros es el mismo en ambos, así que lo que diseñes aquí vale para cualquiera.

Diseña primero el mapa de registros

Antes de escribir código, decide qué verá el SCADA. Un mapa escrito evita el problema de integración más frecuente: que ambas partes no coincidan en el significado de cada registro.

Holding registerSignificadoSentido
0Estado (0 IDLE, 1 RUNNING, 2 FAULT)PLC a SCADA
1Nivel del depósito, cuenta analógica en brutoPLC a SCADA
2Orden de marcha (1 = marcha)SCADA a PLC

Un detalle que causa muchos errores de índice: la dirección de registro que usa la librería suele ser el número de registro menos 1. El holding register número 40009 tiene la dirección 8.

Un esclavo Modbus TCP en el PLC

Asocias un array a los holding registers, llamas a update() en cada pasada de loop() y lees o escribes el array en tu propia lógica. Arranca Ethernet antes que el objeto Modbus.

#include <Ethernet.h>
#include <ModbusTCPSlave.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // usa la MAC de tu PLC
IPAddress ip(192, 168, 1, 50);

#define NUM_HOLDING_REGISTERS 3
uint16_t holdingRegisters[NUM_HOLDING_REGISTERS];

ModbusTCPSlave slave(502);

void setup() {
  Ethernet.begin(mac, ip);
  slave.setHoldingRegisters(holdingRegisters, NUM_HOLDING_REGISTERS);
  slave.begin();
}

void loop() {
  // publica datos del PLC
  holdingRegisters[0] = currentState;        // de la lección 1
  holdingRegisters[1] = analogRead(I0_6);

  slave.update();

  // lee lo que escribió el SCADA
  if (holdingRegisters[2] == 1) {
    // petición de marcha: tu máquina de estados decide qué hacer con ella
  }
}

La librería no bloquea, así que encaja con la máquina de estados y la temporización con millis() de las lecciones anteriores.

Pruébalo desde tu PC

Usa cualquier cliente Modbus, por ejemplo una herramienta gratuita como mbpoll o Modbus Poll. Conéctate a la dirección del PLC en el puerto 502 y lee los holding registers 0 a 2. Deberías ver cambiar el estado y el nivel al accionar las entradas.

Si falla: comprueba primero el ping, después el puerto y después que las direcciones coinciden con el mapa, recordando la regla del menos 1.

Y sobre RS485 (RTU)

El mapa de registros y los arrays son idénticos. Lo que cambia es el transporte: inicializas el puerto serie y el objeto Modbus, y velocidad, paridad y bits de parada deben coincidir en todos los dispositivos del bus, como en el curso de fundamentos. Para RS485, arranca el puerto en half duplex, que funciona tanto en Ardbox como en M-Duino (en un M-Duino el interruptor debe coincidir). Los ejemplos de la librería en File > Examples > Modbus muestran la inicialización RTU exacta para tu puerto.

#include <RS485.h>
#include <ModbusRTUMaster.h>

ModbusRTUMaster master(RS485);

void setup() {
  RS485.begin(9600, HALFDUPLEX, SERIAL_8E1);
  master.begin(9600);
}

Ten en cuenta que pasas la velocidad al begin() del maestro, porque define los timeouts internos de Modbus.

Elegir RTU o TCP

Si el SCADA y el PLC ya están en el mismo bus RS485 con otros dispositivos de campo, RTU mantiene una red consistente. Si el PLC ya tiene Ethernet y el SCADA habla TCP, Modbus TCP evita una segunda red física para una sola integración.

Para profundizar

Siguiente lección: conservar los datos de la estación de bombeo tras un corte de alimentación. Haz primero el cuestionario de abajo.

Calificación
0 0

No hay comentarios por ahora.

para ser el primero en comentar.