Hi everyone
If I want to add another sensor to the readings, do I need to create a new object?
Is this how it should look?
#include <ModbusMaster.h>
ModbusMaster node1;
ModbusMaster node2;
struct SensorData {
float hum;
float temperature;
};
SensorData data[2];
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, 16, 17);
node1.begin(1, Serial2); // Modbus ID = 1
node2.begin(2, Serial2); // Modbus ID = 2
}
void getData(ModbusMaster &sensor, uint8_t nS, uint8_t id) {
uint8_t result = sensor.readHoldingRegisters(0x0004, 2);
if (result == sensor.ku8MBSuccess) {
data[nS].hum = sensor.getResponseBuffer(0) / 10.0;
data[nS].temperature = sensor.getResponseBuffer(1) / 10.0;
Serial.printf("Sensor ID %d: Sucess\n", id);
}
else {
data[nS].hum = -1.0;
data[nS].temperature = -1.0;
Serial.printf("Sensor ID %d: Error Modbus 0x%02X\n", id, result);
}
}
void loop() {
// It will be a state machine using `millis()`
//node1, data[0],ID = 1)
getData(node1, 0, 1);
delay(200);
// node2,data[1],ID = 2)
getData(node2, 1, 2);
delay(5000);
}
Yes.
However, they don't actually need a separate ModbusMaster object for each slave. Since there is only one RS-485 bus and only one transaction at a time, they can use a single ModbusMaster object and change the slave ID before each request. That makes the code much easier to expand if they eventually have many sensors.
Note: For the code shown, though, yes, a new ModbusMaster object would be required for each additional sensor. It would be worth mentioning that the library also supports using a single object if they expect the number of sensors to grow.
second example
Did I understand correctly?
I’m not sure if I can call it within a loop—for example, updating the data every 10 seconds. node.begin(id, Serial2); ?
#include <ModbusMaster.h>
ModbusMaster node;
struct SensorData {
float hum;
float temperature;
};
SensorData data[2];
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, 16, 17);
node.begin(1, Serial2);
}
void getData(uint8_t nS, uint8_t id) {
node.begin(id, Serial2);
uint8_t result = node.readHoldingRegisters(0x0004, 2);
if (result == node.ku8MBSuccess) {
data[nS].hum = node.getResponseBuffer(0) / 10.0;
data[nS].temperature = node.getResponseBuffer(1) / 10.0;
Serial.printf("Sensor ID %d: Success -> Temp: %.1f°C, Hum: %.1f%%\n", id, data[nS].temperature, data[nS].hum);
}
else {
data[nS].hum = -1.0;
data[nS].temperature = -1.0;
Serial.printf("Sensor ID %d: Error Modbus 0x%02X\n", id, result);
}
}
void loop() {
// data [0], ID Modbus: 1)
getData(0, 1);
delay(200);
// data [1], ID Modbus: 2)
getData(1, 2);
delay(5000);
}
I have seen very little code that does not call from within loop(), I do it all the time.
So, to sum up, can this second example also be used?
It looks OK to me in the loop(). I would split the delay between the reads.