You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want to be able to read holding registers in "blocks" (i.e a group of registers) and also as single registers. Here's my attempt at doing so:
Slave code on an ESP32 s3
#include <Arduino.h>
#include <ModbusRTU.h>
// Define your application variables
float PV;
float SP;
// Create ModbusRTU object
ModbusRTU mb;
uint16_t cbRead(TRegister* reg, uint16_t val) {
uint16_t address = reg->address.address;
Serial.printf("Address read: %d\n", address);
switch (address) {
case 1:
PV = random(0, 100) / 10.0;
Serial.printf("PV: %.2f\n", PV);
return static_cast<uint16_t>(PV * 10);
case 2:
SP = random(0, 100) / 10.0;
Serial.printf("SP: %.2f\n", SP);
return static_cast<uint16_t>(SP * 10);
case 3:
return static_cast<uint16_t>(random(0,100));
default:
return 0;
}
}
void setup() {
Serial.begin(115200); // Configure the serial port for Modbus communication
Serial2.begin(115200, SERIAL_8N1, 32, 26);
mb.begin(&Serial2, 13);
mb.setBaudrate(115200);
mb.slave(1); // Set Modbus ID to 1
// Add holding registers and set callbacks
mb.addHreg(1, 0xF0F0, 3);
mb.onGetHreg(1, cbRead, 3);
}
void loop() {
mb.task(); // Process Modbus communication
delay(10);
}
Master code on a ESP32 devkit
#include <ModbusRTU.h>
#define SLAVE 1
// Create ModbusRTU object
ModbusRTU mb;
void setup() {
Serial.begin(115200); // Configure the serial port for Modbus communication
Serial2.begin(115200, SERIAL_8N1, 19, 20);
Serial2.setTimeout(200);
mb.begin(&Serial2, 21);
mb.setBaudrate(115200);
mb.master();
}
void loop() {
static uint32_t ts;
if (millis() - ts > 1500) {
ts = millis();
uint16_t res[2];
float PV;
float SP;
// Read PV & SP registers from the slave
if (mb.readHreg(SLAVE, 1, res, 2)) {
PV = res[0] / 10.0;
SP = res[1] / 10.0;
Serial.printf("PV: %.2f\n", PV);
Serial.printf("SP: %.2f\n", SP);
}
else {
Serial.println("Failed to read PV and SP");
}
// Read single register from the slave, address 3
uint16_t var;
if (mb.readHreg(SLAVE, 3, &var, 1)) {
Serial.printf("var: %d\n", var);
}
else {
Serial.println("Failed to read var");
}
}
mb.task(); // Process Modbus communication
delay(10);
}
The result is this:
15:35:29.870 -> PV: 6.80
15:35:29.870 -> SP: 1.10
15:35:29.870 -> Failed to read var
15:35:31.348 -> PV: 0.30
15:35:31.348 -> SP: 4.80
15:35:31.348 -> Failed to read var
15:35:32.858 -> PV: 0.60
15:35:32.858 -> SP: 0.10
If I comment the code related to reading PV and SP, var is succesfully read:
15:33:25.531 -> var: 76
15:33:27.043 -> var: 51
15:33:28.555 -> var: 88
15:33:30.033 -> var: 48
I tried adding a delay between the two but it doesn't work.
The text was updated successfully, but these errors were encountered:
Main point is that mb.readHreg() just sends request and returns. That is query runs async. Response processed bt mb.task(). mb.slave() returns true while request is in-progress.
Simplest way to resolve you problem is to wait the response (or timeout)
// Read PV & SP registers from the slaveif (mb.readHreg(SLAVE, 1, res, 2)) {
while (mb.salve()) { // Wait response receivedyield();
mb.task();
}
PV=res[0] / 10.0;
SP=res[1] / 10.0;
Serial.printf("PV: %.2f\n", PV);
Serial.printf("SP: %.2f\n", SP);
}
else {
Serial.println("Failed to read PV and SP");
}
// Read single register from the slave, address 3uint16_tvar;
if (mb.readHreg(SLAVE, 3, &var, 1)) {
while (mb.salve()) { // Wait response receivedyield();
mb.task();
}
Serial.printf("var: %d\n", var);
}
else {
Serial.println("Failed to read var");
}
I want to be able to read holding registers in "blocks" (i.e a group of registers) and also as single registers. Here's my attempt at doing so:
Slave code on an ESP32 s3
Master code on a ESP32 devkit
The result is this:
15:35:29.870 -> PV: 6.80
15:35:29.870 -> SP: 1.10
15:35:29.870 -> Failed to read var
15:35:31.348 -> PV: 0.30
15:35:31.348 -> SP: 4.80
15:35:31.348 -> Failed to read var
15:35:32.858 -> PV: 0.60
15:35:32.858 -> SP: 0.10
If I comment the code related to reading PV and SP, var is succesfully read:
15:33:25.531 -> var: 76
15:33:27.043 -> var: 51
15:33:28.555 -> var: 88
15:33:30.033 -> var: 48
I tried adding a delay between the two but it doesn't work.
The text was updated successfully, but these errors were encountered: