Noisy AC voltmeter

Hi
This is a signal on input pin 15 kHz 27 mVpp

and noisy reading of it .

I am using this program to measure AC voltage

//https://github.com/openenergymonitor/EmonLib/blob/master/examples/current_only/current_only.ino
#include "EmonLib.h"
EnergyMonitor emon1;
void setup()
{
  Serial.begin(115200);
  emon1.current(1, 111.1);             // Current: input pin, calibration.
}

void loop()
{
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only

  Serial.print(" irms =  ");
  Serial.println(Irms);               // Irms
}

, the results are very noisy, looking for another program for measuring AC signal.

I hate unlabeled plots. What are the time divisions? What is the sampling rate?

60359 - 60259 = 100

Thank you for refreshing my grade school arithmetic. Please answer the questions.

1 Like

100 = 4 sec

Meaning a sample rate of 100/4S = 25Hz?

How this is related to noise ?

By the Nyquist criterion. You missed it by 2000x.

That is what you would expect to see, sampling a 15kHz signal at 25Hz.

Thanks for pointing that, I overlooked it.

I tried fft

#include "arduinoFFT.h"
 
#define SAMPLES 128             //Must be a power of 2
#define SAMPLING_FREQUENCY 40000 //Hz, must be less than 10000 due to ADC
 
arduinoFFT FFT = arduinoFFT();
 
unsigned int sampling_period_us;
unsigned long microseconds;
 
double vReal[SAMPLES];
double vImag[SAMPLES];
 
void setup() {
    Serial.begin(115200);
 
    sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}
 
void loop() {
   
    /*SAMPLING*/
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
     
        vReal[i] = analogRead(PA2);
        vImag[i] = 0;
     
        while(micros() < (microseconds + sampling_period_us)){
        }
    }
 
    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
 
    /*PRINT RESULTS*/
    //Serial.println(peak);     //Print out what frequency is the most dominant.
 
    for(int i=0; i<(SAMPLES/2); i++)
    {
        /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/
         
        //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
        Serial.print(2000);  
        Serial.print(" ");
        Serial.println(vReal[49], 1);    //View only this line in serial plotter to visualize the bins
    }
 
    delay(100);  //Repeat the process every second OR:
    //while(1);       //Run code once
}

results are not so good (red line)

You need at least 30000 samples per second to read a 15kHz signal. Did you fix that?

I didn't mention it before, but 25mV is a weak signal for the Arduino ADC input. Did you amplify it first?

Please, we need more details in order to give an intelligent answer.

#define SAMPLING_FREQUENCY 40000

I want to measure voltage before and after amplifier

Okay, you should post the waveform again, so we can see the converted data before the FFT.

My guess is, the hardware ADC is not supported by the library at that rate. It's just a setting, I could:

#define SAMPLING_FREQUENCY 400000000

and it wouldn't work just because I plugged in a big number

What amplifier? I'm not omniscient.

that is stm32f103

Hurrah. Are you sure the library supports that sampling rate? Please post the captured waveform. It would give us all a warm fuzzy feeling to see the sine wave. Did you read this:

#define SAMPLING_FREQUENCY 40000 //Hz, must be less than 10000 due to ADC

This is VLF receiver, signal from antenna is 25mV, that signal is amplified by 100x using op amp.

That is for Arduino stm32 is much faster

Please post a schematic. It would be a great idea for you to read the rest of the posting guide, too.