Many readings at once using Modbus RTU and too long data reading period

I need to write code that will allow me to read data from an ORNO energy meter using Modbus RTU. I read the data using a MAX485 converter. To read I use a ready-made library from Github (@CSchoch LINK). Unfortunately, I ran into a problem when writing the code, as it takes about 4 seconds to read all the data. Instead, I need to get a few of some values read every 1 second, while the rest every 1 minute. On the other hand, I care very much about reading a few variables in up to 1 second (the time needed to read these few data is 300ms).
Can perhaps someone inspire me with an idea on how to solve this? Or can help me write small code that will allow me to do this? I was also thinking about using the millis() function, which would check before each value is read whether the time of 1000ms has passed since reading the few required values (which it needs to read every 1 second). If the time has passed - the data I need to have every 1 second is refreshed, and then in the remaining time the rest of the values are refreshed.

The code I use to read the data using Modbus:

  float value;
  // Voltage
  Serial.println("Voltage");
  value = EnergyMeter.getVoltageL1();
  Serial.print("L1: ");
  Serial.print(value);
  value = EnergyMeter.getVoltageL2();
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getVoltageL3();
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" V");

  value = EnergyMeter.getFrequency();
  Serial.print("Freq: ");
  Serial.print(value);
  Serial.println(" Hz");

  //Current
  Serial.println("Current");
  value = EnergyMeter.getCurrentL1();
  Serial.print("L1: ");
  Serial.print(value);
  value = EnergyMeter.getCurrentL2();
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getCurrentL3();
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" A");

  //Active Power
  value = EnergyMeter.getActivePowerTotal() * 1000;
  Serial.print("Bezug: ");
  Serial.print(value, 0);
  Serial.println("W");
  
  Serial.println("ActivePower");
  Serial.print("Total ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL1() * 1000;
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL2() * 1000;
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL3() * 1000;
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" W");

  //Reactive Power
  Serial.println("Reactive Power");
  value = EnergyMeter.getReactivePowerTotal() * 1000;
  Serial.print("Total: ");
  Serial.print(value);
  value = EnergyMeter.getReactivePowerL1() * 1000;
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getReactivePowerL2() * 1000;
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getReactivePowerL3() * 1000;
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" var");

  //Apparent Power
  Serial.println("Apparent Power");
  value = EnergyMeter.getApparentPowerTotal() * 1000;
  Serial.print("Total: ");
  Serial.print(value);
  value = EnergyMeter.getApparentPowerL1() * 1000;
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getApparentPowerL2() * 1000;
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getApparentPowerL3() * 1000;
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" VA");

  //Power Factor
  Serial.println("Power Factor");
  value = EnergyMeter.getPowerFactorTotal();
  Serial.print("Total: ");
  Serial.print(value);
  value = EnergyMeter.getPowerFactorL1();
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getPowerFactorL2();
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getPowerFactorL3();
  Serial.print(" L3: ");
  Serial.println(value);

  //Counter
  value = EnergyMeter.getTotalCounterActivePowerTotal();
  Serial.print("Verbrauch: ");
  Serial.print(value);
  Serial.println("kWh ");
  Serial.println("Counter Active Power");
  Serial.print("Total: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerL1();
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerL2();
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerL3();
  Serial.print(" L3: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerT1();
  Serial.print(" T1: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerT2();
  Serial.print(" T2: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerT3();
  Serial.print(" T3: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterActivePowerT4();
  Serial.print(" T4: ");
  Serial.print(value);
  Serial.println(" kWh");

  Serial.println("Counter Reactive Power");
  value = EnergyMeter.getTotalCounterReactivePowerTotal();
  Serial.print("Total: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerL1();
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerL2();
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerL3();
  Serial.print(" L3: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerT1();
  Serial.print(" T1: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerT2();
  Serial.print(" T2: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerT3();
  Serial.print(" T3: ");
  Serial.print(value);
  value = EnergyMeter.getTotalCounterReactivePowerT4();
  Serial.print(" T4: ");
  Serial.print(value);
  Serial.println(" kvarh");

  //Counter Import
  Serial.println("Counter Import Active Power");
  Serial.print("Total: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerTotal());
  Serial.print(" L1: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerL1());
  Serial.print(" L2: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerL2());
  Serial.print(" L3: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerL3());
  Serial.print(" T1: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerT1());
  Serial.print(" T2: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerT2());
  Serial.print(" T3: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerT3());
  Serial.print(" T4: ");
  Serial.print(EnergyMeter.getImportCounterActivePowerT4());
  Serial.println(" kWh");

  Serial.println("Counter Import Reactive Power");
  Serial.print("Total: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerTotal());
  Serial.print(" L1: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerL1());
  Serial.print(" L2: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerL2());
  Serial.print(" L3: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerL3());
  Serial.print(" T1: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerT1());
  Serial.print(" T2: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerT2());
  Serial.print(" T3: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerT3());
  Serial.print(" T4: ");
  Serial.print(EnergyMeter.getImportCounterReactivePowerT4());
  Serial.println(" kvarh");

  //Counter Export
  Serial.println("Counter Export Active Power");
  Serial.print("Total: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerTotal());
  Serial.print(" L1: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerL1());
  Serial.print(" L2: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerL2());
  Serial.print(" L3: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerL3());
  Serial.print(" T1: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerT1());
  Serial.print(" T2: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerT2());
  Serial.print(" T3: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerT3());
  Serial.print(" T4: ");
  Serial.print(EnergyMeter.getExportCounterActivePowerT4());
  Serial.println(" kWh");

  Serial.println("Counter Export Reactive Power");
  Serial.print("Total: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerTotal());
  Serial.print(" L1: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerL1());
  Serial.print(" L2: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerL2());
  Serial.print(" L3: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerL3());
  Serial.print(" T1: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerT1());
  Serial.print(" T2: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerT2());
  Serial.print(" T3: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerT3());
  Serial.print(" T4: ");
  Serial.print(EnergyMeter.getExportCounterReactivePowerT4());
  Serial.println(" kvarh");

Received code (values I need to refresh every 1 minute):

07:33:16.983 -> Voltage
07:33:17.014 -> L1: 236.10 L2: 230.40 L3: 233.70 V
07:33:17.138 -> Freq: 49.97 Hz
07:33:17.138 -> Current
07:33:17.202 -> L1: 0.91 L2: 0.15 L3: 0.47 A
07:33:17.346 -> Bezug: 247W
07:33:17.346 -> ActivePower
07:33:17.346 -> Total 247.00 L1: 122.00 L2: 20.00 L3: 104.00 W
07:33:17.499 -> Reactive Power
07:33:17.549 -> Total: 160.00 L1: 111.00 L2: 22.00 L3: 26.00 var
07:33:17.873 -> Apparent Power
07:33:17.921 -> Total: 303.00 L1: 165.00 L2: 30.00 L3: 107.00 VA
07:33:18.059 -> Power Factor
07:33:18.106 -> Total: 0.92 L1: 0.74 L2: 0.67 L3: 0.97
07:33:18.309 -> Verbrauch: 14964.40kWh 
07:33:18.309 -> Counter Active Power
07:33:18.309 -> Total: 14964.40 L1: 5291.86 L2: 2039.56 L3: 7632.98 T1: 8086.17 T2: 6878.23 kWh
07:33:18.653 -> Counter Reactive Power
07:33:18.872 -> Total: 3586.24 L1: 1706.11 L2: 1072.27 L3: 807.86 T1: 2217.42 T2: 1368.82  kvarh
07:33:19.213 -> Counter Import Active Power
07:33:19.213 -> Total: 14964.05 L1: 5291.86 L2: 2039.21 L3: 7632.98 T1: 8085.82 T2: 6878.23 kWh
07:33:19.588 -> Counter Import Reactive Power
07:33:19.588 -> Total: 398.32 L1: 36.83 L2: 186.74 L3: 174.75 T1: 236.86 T2: 161.46 kvarh
07:33:20.173 -> Counter Export Active Power
07:33:20.173 -> Total: 0.35 L1: 0.00 L2: 0.35 L3: 0.00 T1: 0.35 T2: 0.00 kWh
07:33:20.538 -> Counter Export Reactive Power
07:33:20.538 -> Total: 3187.92 L1: 1669.28 L2: 885.53 L3: 633.11 T1: 1980.56 T2: 1207.36 kvarh

The values I need to refresh every 1 second:

07:33:17.346 -> Bezug: 247W
07:33:17.346 -> ActivePower
07:33:17.346 -> Total 247.00 L1: 122.00 L2: 20.00 L3: 104.00 W

The code that is responsible for reading the required values every 1 second:

  //Active Power
  value = EnergyMeter.getActivePowerTotal() * 1000;
  Serial.print("Bezug: ");
  Serial.print(value, 0);
  Serial.println("W");
  
  Serial.println("ActivePower");
  Serial.print("Total ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL1() * 1000;
  Serial.print(" L1: ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL2() * 1000;
  Serial.print(" L2: ");
  Serial.print(value);
  value = EnergyMeter.getActivePowerL3() * 1000;
  Serial.print(" L3: ");
  Serial.print(value);
  Serial.println(" W");

Hello

The main problem with your code is that it does many small requests to the slave. You could make it much faster by reading multiple registers at once, so using much less, but bigger requests

The ModBusMaster library allows to read up to 64 bytes of data (and more if you increase the value of ku8MaxBufferSize) from a starting register address.

For example, instead of doing 3 requests, each reading 2 bytes from the slave :

getVoltageL1
getVoltageL2
getVoltageL3

You would do only one request to read 6 bytes starting at VoltageL1 register.

You could read all the registers that you need with a few big requests and it would probably be like 10x faster.

Ok I understand you but I would prefer to use this library. Do you have maybe any ideas how to solve this?

Look at the BlinkWithoutDelay example to learn how to do timers using the millis function

Did, you find a solution?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.