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)