Thanks!
I converted my code where the body of the loop is this:
double sampleI, lastSampleI;
double lastFilteredI, filteredI;
double sqI,sumI;
unsigned long resultc1;
static double numSamples = (double)NUMBER_OF_SAMPLES;
void calc_irms(uint16_t channel)
{
for (uint16_t n = 0; n < NUMBER_OF_SAMPLES; n++)
{
lastSampleI = sampleI;
sampleI = adc_read(channel);
lastFilteredI = filteredI;
filteredI = 0.996 * (lastFilteredI+sampleI-lastSampleI);
// Root-mean-square method current
// 1) square current values
sqI = filteredI * filteredI;
// 2) sum
sumI += sqI;
}
//Reset accumulators
resultc1 = (unsigned long)sqrt(sumI / numSamples) * 1000.0;
sumI = 0;
}
Where resultc1 is then sent as an unsigned long (hence the * 1000.0) . Then on the receiving end, I use the rest of the original calculation:
private static final double conversionFactor = 1000.0;
private static final double burdenCalibration = (100.0 / 0.05) / 24.0; // Calibration coef for 24ohm burden resistor is 83.33
private static final double supplyVoltage = 3.30;
private static final double ratio = burdenCalibration * (supplyVoltage / 1023.0); // 0-1023 = the 10 bit range.
…
result = ratio * ((double) rawValue / conversionFactor);
This way I avoid using sprintf.
The manual for the meter: http://www.biltema.no/BiltemaDocuments/Manuals/15-287_man.pdf (it’s in nordic languages, but there seems to be no “true rms”, although I can see it has some kind of buffering since the number rises / falls after 1-2 seconds.
The shield is bought from ebay, and it seems OK, it uses SMD components but I have confirmed that it uses 24 ohm. The readings without any current are between 0.0 steadily and an occasional 0.28.
[0000000,0000000,0000000]
versus
[0001000,0001000,0000000]
as raw output from the chip.
When on the lower load from the vacuum cleaner it’s
[0000000,0015000,0000000] 4.0444770283479965
Do you have a link to the better calcIrms?