Reading two or more sensors via RS485

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.