Modbus Slave
StamPLC驱动库整合了Modbus Slave功能。在整机完成简易的初始化配置后,便能作为从机设备,经由PWR-485接口便捷接入Modbus总线。其他设备也能够非常方便的控制StamPLC的继电器和读取输入信号状态。
案例程序
StamPLC Modbus Slave
#include <Arduino.h>
#include <M5StamPLC.h>
void setup()
{
auto config = M5StamPLC.config();
config.enableModbusSlave = true;
config.modbusBaudRate = 115200;
config.modbusSlaveId = 1;
config.enableCan = true;
M5StamPLC.config(config);
M5StamPLC.begin();
}
void loop()
{
delay(1000);
}
Modbus Master
使用任意 ESP32 主控设备,搭配
Unit RS485
, 实现Modbus Master。然后通过PWR-485接口对 StamPLC 进行控制。
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
RS485Class RS485(Serial2, 32, 26, -1, -1);
uint8_t slave_id = 1;
float parseFloat(uint16_t high, uint16_t low)
{
union {
uint32_t i;
float f;
} value;
value.i = ((uint32_t)high << 16) | low;
return value.f;
}
void setup()
{
Serial.begin(115200);
delay(2000);
if (!ModbusRTUClient.begin(115200, SERIAL_8N1)) {
Serial.println("Failed to start Modbus RTU Client");
while (1);
}
}
void loop()
{
Serial.println("\n--- Reading Modbus Registers ---");
Serial.println("Turning Relays ON:");
for (uint8_t addr = 0; addr < 4; addr++) {
if (ModbusRTUClient.coilWrite(slave_id, addr, 0xFF)) {
Serial.printf("Relay %d ON\n", addr);
} else {
Serial.printf("Failed to turn on Relay %d\n", addr);
}
delay(500);
}
Serial.println("Reading Coils Status:");
for (uint8_t addr = 0; addr < 4; addr++) {
if (ModbusRTUClient.requestFrom(slave_id, COILS, addr, 1)) {
Serial.printf("Relay %d: ", addr);
while (ModbusRTUClient.available()) {
Serial.print(ModbusRTUClient.read(), HEX);
Serial.print(' ');
}
Serial.println();
} else {
Serial.printf("Failed to read Relay %d\n", addr);
}
}
Serial.println("Turning Relays OFF:");
for (uint8_t addr = 0; addr < 4; addr++) {
if (ModbusRTUClient.coilWrite(slave_id, addr, 0x00)) {
Serial.printf("Relay %d OFF\n", addr);
} else {
Serial.printf("Failed to turn off Relay %d\n", addr);
}
delay(500);
}
Serial.println("Reading Coils Status Again:");
for (uint8_t addr = 0; addr < 4; addr++) {
if (ModbusRTUClient.requestFrom(slave_id, COILS, addr, 1)) {
Serial.printf("Relay %d: ", addr);
while (ModbusRTUClient.available()) {
Serial.print(ModbusRTUClient.read(), HEX);
Serial.print(' ');
}
Serial.println();
} else {
Serial.printf("Failed to read Relay %d\n", addr);
}
}
delay(500);
Serial.println("Reading Input Registers:");
uint16_t tempRegisters[2], voltageRegisters[2], currentRegisters[2];
float temperature, busVoltage, shuntCurrent;
if (ModbusRTUClient.requestFrom(slave_id, INPUT_REGISTERS, 8, 2)) {
for (uint8_t i = 0; i < 2; i++) {
tempRegisters[i] = ModbusRTUClient.read();
}
temperature = parseFloat(tempRegisters[0], tempRegisters[1]);
Serial.printf("Temperature: %.2f°C\n", temperature);
} else {
Serial.println("Failed to read Temperature Registers");
}
if (ModbusRTUClient.requestFrom(slave_id, INPUT_REGISTERS, 10, 2)) {
for (uint8_t i = 0; i < 2; i++) {
voltageRegisters[i] = ModbusRTUClient.read();
}
busVoltage = parseFloat(voltageRegisters[0], voltageRegisters[1]);
Serial.printf("Bus Voltage: %.2fV\n", busVoltage);
} else {
Serial.println("Failed to read Bus Voltage Registers");
}
if (ModbusRTUClient.requestFrom(slave_id, INPUT_REGISTERS, 12, 2)) {
for (uint8_t i = 0; i < 2; i++) {
currentRegisters[i] = ModbusRTUClient.read();
}
shuntCurrent = parseFloat(currentRegisters[0], currentRegisters[1]);
Serial.printf("Shunt Current: %.2fA\n", shuntCurrent);
} else {
Serial.println("Failed to read Shunt Current Registers");
}
Serial.printf(">>>>>> Temperature: %.2f°C, Bus Voltage: %.2fV, Shunt Current: %.2fA\n", temperature, busVoltage,
shuntCurrent);
delay(5000);
}
