← Mapa de registros Modbus TCP para una planta de biorreactores
Control de biorreactoresM-DuinoModbus TCPComunicación
Mapa de registros Modbus TCP para una planta de biorreactores — ejemplo completo
Disena un mapa de registros Modbus TCP limpio en un PLC M-Duino: coils, holding e input registers para toda una planta de biorreactores. Codigo y layout.
Programa completo y ejecutable para el M-Duino (modbus-register-map.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 — Whole-plant Modbus TCP register map
*
* Device: M-Duino (Industrial Shields, Arduino PLC with Ethernet + RS485)
* Based on: bioreactor control project, ModbusTCPSlaveRTUMaster.ino
*
* This sketch documents and publishes the Modbus TCP map (port 502) that a
* SCADA uses to read from and command the whole bioreactor plant. It does
* not drive the RTU bus (the "Gateway" module does that); its value is to
* act as a live address table, verifiable with any Modbus client.
*
* Coils 0-17 (read/write, function 1/5/15):
* 0..7 : 8 output relays (solenoid valves, auxiliary pumps...)
* 8..15 : 8 pilot lights / status indicators
* 16,17 : counter reset of the 2 flow meters
*
* Holding registers 0-9 (read/write, function 3/6/16):
* 0..3 : analog outputs (0-10 V)
* 4,5 : temperature setpoint of the 2 chillers (x10)
* 6,7 : RPM setpoint of the 2 drives (rpm)
* 8,9 : run command of the 2 chillers
*
* Input registers 0-11 (read only, function 4):
* 0,1 : temperature of the 2 chillers (x10)
* 2,3 : pressure
* 4,5 : pH (x100)
* 6..9 : accumulated liters of the 2 flow meters (32 bits each)
* 10,11 : actual RPM of the 2 drives
*
* Integration: this map is the contract shared by the modules
* "Chiller control", "Drive control" and "Flow meter reading", all
* behind the "Gateway Modbus TCP <-> RTU".
*/
#include
ModbusTCPSlave modbus;
// Memory blocks, sized according to the map above
bool coils[18];
uint16_t holdingRegs[10];
uint16_t inputRegs[12];
// Named indices so the code reads like the map
enum { HR_AO0, HR_AO1, HR_AO2, HR_AO3,
HR_TEMP_SP1, HR_TEMP_SP2,
HR_RPM_SP1, HR_RPM_SP2,
HR_RUN_CH1, HR_RUN_CH2 };
enum { IR_TEMP1, IR_TEMP2, IR_PRES1, IR_PRES2,
IR_PH1, IR_PH2,
IR_LITERS1_H, IR_LITERS1_L, IR_LITERS2_H, IR_LITERS2_L,
IR_RPM1, IR_RPM2 };
void setup() {
Serial.begin(115200);
// Publish the three blocks starting at address 0
modbus.addCoils(0, coils, 18);
modbus.addHoldingRegisters(0, holdingRegs, 10);
modbus.addInputRegisters(0, inputRegs, 12);
modbus.begin(); // listen on port 502
// Consistent initial values (what a SCADA would read on connecting)
holdingRegs[HR_TEMP_SP1] = 185; // 18.5 C x10
holdingRegs[HR_TEMP_SP2] = 185;
holdingRegs[HR_RPM_SP1] = 250; // 250 rpm
holdingRegs[HR_RPM_SP2] = 250;
}
void loop() {
modbus.update(); // keeps the memory image alive over TCP
// Light simulation so a client sees plausible values.
// In the plant these input regs are filled by the gateway from the RTU bus.
static uint32_t t = 0;
if (millis() - t > 1000) {
t = millis();
inputRegs[IR_TEMP1] = holdingRegs[HR_TEMP_SP1]; // follows the setpoint
inputRegs[IR_TEMP2] = holdingRegs[HR_TEMP_SP2];
inputRegs[IR_RPM1] = holdingRegs[HR_RPM_SP1];
inputRegs[IR_RPM2] = holdingRegs[HR_RPM_SP2];
inputRegs[IR_PH1] = 720; // pH 7.20 x100
inputRegs[IR_PH2] = 715;
Serial.print("Temp1="); Serial.print(inputRegs[IR_TEMP1] / 10.0);
Serial.print("C RPM1="); Serial.print(inputRegs[IR_RPM1]);
Serial.print(" pH1="); Serial.println(inputRegs[IR_PH1] / 100.0);
}
}
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales