Analog read of AC power adapter

Hello all,

I'm trying to make an energy monitor similar to the stuff on openenergymonitor.org (How to build an arduino energy monitor | Archived Forum). It's not working (I get wrong values). I have traced the problem to the following:

One of the things that happens is that the arduino uses one of its analog pins to read in the mains voltage. It does so by transforming the 230 VAC mains to 9 VAC with a standard AC wall wart. It actually outputs about 10.4V unloaded, according to my multimeter.

I then resistively divide this 10.4V AC to 175 mV AC. I then add a 420 mV bias voltage, so that the negative part of the AC period can also be read with the arduino's analog in. (Because of the range of my current sensors, I am using the arduinos internal 1.1V reference as the analog reference). I am actually only using about half the resolution of the AD converter, I may tune this in the future, but it is ok for now.

The problem I am having: When the only input on the arduino is this AC voltage, and I continuously read the pin, and store the value in a histogram, I get something I do not understand. Naïvely, I would expect a centre-weighted distribution of the readings. (Every period, there are twice as many zero crossings as there are positive peaks, for instance. You know what I mean, I hope.)

But what I get is what you see in the attached picture. A more or less flat distribution of the voltage readings in the middle, with large peaks at the sides, supposedly indicating that there are more peaks than zero crossings...?

Below is the code I used to gather this data, and I plotted it with Excel.

Does anyone understand this?

/*
Make a histogram with 512 bins, from analog read data
 */
 
int teller=0;
int values[512]; //Arduino crashes on 1024 bins, so 512 is the next best thing

void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL); // for 1.1V measurements
}

void loop() {
  int sensorValue = floor((analogRead(A4)+1)/2); //divide by two to fit 512 bins
  values[sensorValue]+=1;                        //increase the bin

  teller=teller+1;
  if (teller>5000) {                             //once in a while...
    for(int n=0; n<512;n++) {
      Serial.print(values[n], DEC);              //...output all the bins over the serial port
      Serial.print(" ");
    }
    Serial.println("");
    teller=0;
  } 
}

A sinusoid spends more time near its extremes than it does near the 0 value. Try it yourself: draw a sinusoid then mark N (10-20) regularly-spaced points on it. Now count how many are within 10% of the extreme value. It will be more than 20%!

--
The Ruggeduino: compatible with Arduino UNO, 24V operation, all I/O's fused and protected

And the waveform may be a flattened sinusoid anyway - lots of power supplies connected to the mains only take current at the peaks and thus pull down the peak voltage. If you can collect a sampled waveform (or put a 'scope on the 9Vac supply) it would help answer your concerns...

This for instance is the messy mains I have at home - capacitively coupled by having my foot near mains cables!

Note that all the little ripples are stable, presumably mainly injected into the mains by lots of SMPS's (although my method of measurement is not what I'd call scientific!)

Hey, thanks for your replies.

Hmmm I guess this is one of those things where it would have been better to sleep on it for a night or so. Indeed of course you are right, the derivative of the sinusoid at the peaks is much smaller, and it does spend more time at the extremes.

Unfortunately I have no scope, otherwise I would have surely posted a picture of the reading.

As I've gathered, the reason for the voltage reading is to get a more accurate reading of the power consumption, because the mains voltage is not a perfect sinusoid, at least not with all the loads in the house. So now I can move the investigation of the strange readings to the current (A) sensors.

Thanks guys!