Ir al contenido

← Control de RPM de variador por Modbus RTU con M-Duino

Control de biorreactoresM-DuinoModbus RTUControl

Control de RPM de variador por Modbus RTU con M-Duino — ejemplo completo

Gobierna variadores de frecuencia por Modbus RTU con un PLC M-Duino. Escribe marcha y consigna de RPM x100 y lee la velocidad real de dos registros de 16 bits. Codigo completo.

Programa completo y ejecutable para el M-Duino (vfd-rpm-control.ino): incluye cabecera de conexionado, requisitos y notas de integración.

Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales

Vista de solo lectura.

/*
 * COMPLETE EXAMPLE — Variable frequency drive (RPM) control over Modbus RTU
 *
 * Device:  M-Duino (Industrial Shields, Arduino PLC with RS485)
 * Based on: bioreactor control project, ModbusTCPSlaveRTUMaster.ino
 *
 * Bus: Modbus RTU over RS485, 9600 8N1. Two drives at addr 3 and 4
 * that turn the bioreactor stirrers.
 *
 * Drive RTU registers:
 *   0x210D  run/stop                    (1 = run, 0 = stop)
 *   0x0144  RPM setpoint x100           (e.g. 250 rpm -> 25000)
 *   0x2149  actual RPM reading          (2 x 16-bit regs, MSW + LSW)
 *
 * The actual reading combines two 16-bit holding registers into a
 * 32-bit integer: (reg0 << 16) | reg1.
 *
 * Integration: the setpoint is normally set by the SCADA via the
 * "Gateway Modbus TCP <-> RTU" module; here we control one drive directly.
 */

#include 
#include 

ModbusRTUMaster master(RS485);

const uint8_t DRIVE[2] = {3, 4};   // RTU addresses of the two drives

const uint16_t REG_RUN     = 0x210D;
const uint16_t REG_RPM_SP  = 0x0144;  // setpoint x100
const uint16_t REG_RPM_RD  = 0x2149;  // actual reading (2 regs)

void setup() {
  Serial.begin(115200);
  master.begin(9600);
  master.setTimeout(300);

  // Example startup: drive 1 at 250 rpm
  startDrive(DRIVE[0]);
  setRPM(DRIVE[0], 250);
}

void loop() {
  // Periodic actual RPM reading for supervision
  static uint32_t t = 0;
  if (millis() - t > 2000) {
    t = millis();
    uint32_t rpm = checkDrive(DRIVE[0]);
    Serial.print("Actual RPM drive 1: ");
    Serial.println(rpm);
  }
}

// Run the drive
uint8_t startDrive(uint8_t addr) {
  return writeReg(addr, REG_RUN, 1);
}

uint8_t stopDrive(uint8_t addr) {
  return writeReg(addr, REG_RUN, 0);
}

// Setpoint in whole rpm; the drive expects x100
uint8_t setRPM(uint8_t addr, uint16_t rpm) {
  return writeReg(addr, REG_RPM_SP, rpm * 100);
}

// Reads the actual RPM combining two 16-bit registers into a 32-bit one
uint32_t checkDrive(uint8_t addr) {
  if (!master.readHoldingRegisters(addr, REG_RPM_RD, 2)) return 0;
  if (master.isWaitingResponse()) {
    ModbusResponse r = master.available();
    if (r && !r.hasError())
      return (uint32_t)((r.getRegister(0) << 16) | r.getRegister(1));
  }
  return 0;   // no valid response
}

// Generic write with confirmation
uint8_t writeReg(uint8_t addr, uint16_t reg, uint16_t val) {
  if (!master.writeSingleRegister(addr, reg, val)) return 1;
  if (master.isWaitingResponse()) {
    ModbusResponse r = master.available();
    if (r && !r.hasError()) return 0;
  }
  return 1;
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales