← 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