Vrms readings by using analogRead function

Hello folks,
I am using arduino Nano, for my projects that is reading out the analog value attached to some of the analog (input) pins, and based on that to calculate the Voltage rms value.

I have seen some approaches like ( emonlib, ZMPT101B etc.) but as it is not so complicated I decided to go with ''do it by myself''.

Here is the thing:

Schematic topology: Voltage transofrmer (230V/6V) > full wave rectifier (greatz) > voltage divider that (R1=470K;R2=5K) >arduino nano analog input pin A7 (or any).

Here are the code lines:

========================================================================


int pin = A1;
int Voltage = 0;

double V_square = 0;
double accum  = 0;
unsigned long avg = 0;
double  V_rms =0;
unsigned int  period = 20000;  
unsigned long t_start = micros();
unsigned long counts = 0;

void setup() {
  
  Serial.begin(115200); 
      while (micros() - t_start < period){
            Voltage = (analogRead(pin));
           //Serial.println(Voltage);
            V_square = Voltage*Voltage;
           accum  += V_square;
           counts++;
          //Serial.println(Voltage);
   }      //Serial.println(accum);
   avg=accum /counts;
   V_rms=sqrt(avg)/1023*5;  
   Serial.println( V_rms);
}

void loop() {     
   delay(1000);         
}

========================================================================

I just want the measurements to be performed for 1 perdiod of 50Hz sine wave, that's why the perdiod is like 20 000;

Nevertheless, the code is being compiled and some printings pop out on the serial monitor, they look far away from what I expected to see; The results is close to 0.29 or something ...

I realized also that when nothing is being attached to analog pin, arduino still reads out some valies in the range of 145-250; which my be OK since it is floating pin.

Any ideas what the root cause could be, looking at the code above?

Thanks!

Yes you are just taking a lot of samples and averaging them. This will not work.

To get an RMS value you have to find the maximum and minimum value you can read, then assuming it is a sin wave subtract the maximum from the minimum and multiply by 0.707.

in the statement

V_square = Voltage*Voltage;

if Voltage is a 16bit int (range −32,768 to 32,767) the expression Voltage*Voltage could result in overflow - try making it long int or a float
you can check the result of your code by measuring the voltage from the transformer using a multimeter
for more details see Root Mean Square: Formula and Calculation

Rms is some kind of average, so it should work. For a sin the rms is 0.707 of max. But a wave may also be square (pwm) or triangular. So your assumption of sin shape may be wrong.
A square or triangular waveform will not get through a transformer unchanged. It will loose the flats... so a transformer is not the best way to measure rms voltage.

You already have some Serial debug prints in the while loop that are commented out. You didn't mention what results from those.

Come on. RMS is undefined for non-sinusoidal waveforms. What you are talking about, is a misapplication of the calculation that could also happen with a DVM or any measurement.

Of course it is defined. But in that case you can't use the 1/√2 trick, because that's the specific result of applying the general formula to a sinusoidal signal.
Cheap multimeters assume that all AC voltages are sinusoidal, true RMS meters can deal with other shapes as well.

Oh, yeah... since it's used for audio signals for example. However we're measuring line voltage here, it's a sine.

But the OP said this

So my assumption about the wave shape is perfectly valid.

The problem is while it is "some" sort of avrage it is NOT that sort of avrage so it will not work.

I seem to remember from basic classes on electricity that the RMS value of an AC voltage was equivalent to a DC voltage of the same value in terms of power output when applied to a resistive load.

Why is avg an integer? Make it a double as well. (Same for Voltage as mentioned by horace earlier.)

This is my opinion that the DC level of a sampled rectified signal is approximately proportional to the Vrms of the line voltage. This idea helps to make low cost Volt Meter by introducing appropriate calibration factor.

Then the OP can put a 100uF/25V filter capacitor (Fig-1) after the full wave rectified signal.
vur
Figure-1:

Put a voltage divider across the capacitor (Fig-1); where, the GND-side of the divider contain a potentiometer.

Adjust the potentiometer to get about 3.3V DC at the cross point of the divider and feed it at A1-pin of the UNO. Why is 3.3V? There is a 3.3V point on the UNO, which can be easily used as a test signal.

After that the OP can use the following codes to display 230 V on the Serial Monitor.

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

void loop()
{
  float vrms = (5 * analogRead(A1)) / 1023 * 69.69; // 69.69 = 230/3.3
  Serial.println((byte)vrms);
  delay(1000);
}

Output:

229
229
229
1 Like

Correct. Or, mathematically:
image
Where 'T' is the signal's period.

But, the DC (average) voltage of a sine wave signal is zero; whereas, RMS is not! Your formula calculates the RMS value.

Error sources:
your transformer reduces the 230V to 6V and then you run it through a full bridge rectifier. If you're using standard silicon diodes, you are immediately reducing the voltage by 1.2V (20% error). What tolerance are your resistors? 5%? 1%? Measure them to be sure they're are close enough to work. 1% resistors are usually pretty tight but I've seen 5% ones all over the place.

Also, I would recommend taking all your samples in a buffer and then doing the math outside the loop. This ensures that you are getting enough samples to properly represent your signal: Nyquist is 2x, real life is 10x.

Oh, and measure that "6V" coming out of the transformer to be sure it really is 6V so you know what to expect.

All those errors could be minimized to acceptable level by introducing "Calibration Factor."

Of course it does. That's the topic of this thread!!!

1 Like

I never said that they can't. The point is they have to be measured and accounted for somehow. You can't jump to a solution until you know what the problem is.

1 Like

Yes, and why? There is no need, and it's probably the biggest source of error.

Presumably to "fold" the negative half of the AC cycle "up" so that it's positive and can be measured by the ADC. Per the RMS Formula, the result is unchanged.