calcIrms sampling rate slower than expected

Thanks, @Robert.Wall! What you said makes a lot of sense. I followed the suggestions and now the sample rate (considering only the for loop in calcIrms()) is around 5.5 kHz, similar to what you measured in Sampling rate of emonLib.

Here’s the new test code src.ino:

#include "EmonLib.h"                   // Include Emon Library
#include <Wire.h>

EnergyMonitor emon1;                   // Create an instance

unsigned long t_start, t1, t2, t_out, n_avg = 0;
double t1_avg, t2_avg, t_out_avg, t_in_avg = 0;
int n_inner_loop = 1000;

void setup()
{
  Serial.begin(9600);

  emon1.current(1, 111.1);             // Current: input pin, calibration.
  t_start = millis();
}

void loop()
{
  t_out += millis() - t_start;

  t_start = millis();
  double Irms1 = emon1.calcIrms(100);  // Calculate Irms only
  t1 += millis() - t_start;

  t_start = millis();
  double Irms2 = emon1.calcIrms(100 + n_inner_loop);  // Calculate Irms only
  t2 += millis() - t_start;

  n_avg++;
  if (n_avg == 100) {
    t1_avg = (double)t1 / n_avg ;
    t2_avg = (double)t2 / n_avg ;
    t_out_avg = (double)t_out / n_avg ;
    t_in_avg = (t2_avg - t1_avg) / (double)n_inner_loop;

    Serial.print("n_inner_loop\t\t");
    Serial.println(n_inner_loop);
    Serial.print("100 loops (ms)\t\t");
    Serial.println(t1_avg);
    Serial.print("1100 loops (ms)\t\t");
    Serial.println(t2_avg);
    Serial.print("out side loop (ms)\t");
    Serial.println(t_out_avg);
    Serial.print("total (ms)\t\t");
    Serial.println(t1_avg + t2_avg + t_out_avg);
    Serial.print("1 inner loop (ms)\t");
    Serial.println(t_in_avg);
    Serial.print("sample rate\t\t");
    Serial.println(1.0/(t_in_avg * 1e-3));
    Serial.println();
    t1 = 0;
    t2 = 0;
    t_out = 0;
    n_avg = 0;
  }
  t_start = millis();
}

Test output:

n_inner_loop            1000
100 loops (ms)          20.21
1100 loops (ms)         199.91
out side loop (ms)      0.00
total (ms)              220.12
1 inner loop (ms)       0.18
sample rate             5564.83

For completeness, I also checked why I got 400 Hz with the previous code. It’s because when Number_of_Samples = 1, the codes outside the loop takes almost 93% of the time of calcIrms(). When I made calcIrms to take only 1 and 2 samples (with proper n_avg), i.e., these two lines

  double Irms1 = emon1.calcIrms(1);  // Calculate Irms only
  double Irms2 = emon1.calcIrms(2);  // Calculate Irms only

the test output becomes:

n_inner_loop            1
1 loops (ms)            2.47
2 loops (ms)            2.65
out side loop (ms)      0.00
total (ms)              5.12
1 inner loop (ms)       0.18
sample rate             5452.56

The sample rate computed from the previous codes would be 5452 * 0.18 / 2.47 =~ 400 (Hz)