Calculating the average of a changing variable.

Hi everyone, i am quite new too programming however need to use it in my current dissertation. I am building a power meter what monitors voltage and current and used the Arduino to calculate the power consumed.

2 ADC inputs on the Arduino are wave forms (0-5v) proportional to the voltage and current wave-forms of the appliance. I have coded up until the point of calculating power.

i now have a defined power value in my code (voltage x current) which is constantly changing due to the voltage and current of the AC appliance always changing. I want to calculate an average of the first 192 power values obtained but finding it difficult. What would be the correct way of going about this? Thank you, my code is shown below.

float A = 426.666667; // Value needed to convert the voltage back to original float x = 0.030304329; // value needed to convert the voltage into current in secondry coil int y = 2000; // value needed to convert into current through the wire float OffsetI = 2.5; // 2.5v offset added in order to meet arduino input range of 0-5v float OffsetV = 0.75; // 0.75v offset on the voltage waveform int inputPin = A0; int inputPin = A1

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

} void loop() { int current; // declaring 'current' int sensorValue0 = analogRead(A0);// read the input on analog pin 0: float voltageI = sensorValue0 * (5.0 / 1023.0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V): current = (voltageI - OffsetI)*x*y; // Convert the voltage back into the initial current flowing through wire

int voltage; // declaring 'voltage' int sensorValue1 = analogRead(A1);// read the input on analog pin 1: float voltageV = sensorValue1 * (5.0 / 1023.0); // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V): voltage = (voltageV - OffsetV)*A; // Convert the voltage back into the mains voltage reading

int power = voltage*current;

}

If you keep the integer values (the value read from analogRead()) instead of the caculated floats you can hold the 192 values (=768 Bytes) in memory. There you can do either a complete average calculation or keep the sum and just delete the value you throw away and add the new value.

First you will need an array of the values. I would suggest storing the V and I values as the ADC count in arrays of unsigned int to save on memory and processing power. The use an index and setup the array as a circular buffer. (store sample at index x, increment x, if x>=192 then x=0)

To calculate the voltage you will need to add the unsigned ints into an unsigned long in order to have enough range for the totals (ADC 0-1024 = unsigned int 0-65535; 192*1024=196k = unsigned long 2.4mil).

To calculate the subsequent sample totals you can either loop through all 192 samples again and add them or get a little fancy. Before storing the sample, subtract the previous sample from the total and then add the new sample to the total, then store the new sample in the array. If you initialize the array to 0 in setup(), this will work without requiring any if...then conditions.

Be warned. Until you have 192 samples, the average will be low (averaging in a lot of 0 samples).

adwsystems: If you initialize the array to 0 in setup(), this will work without requiring any if...then conditions.

If the array is declared as a global (and if it is visible in both setup and loop, it probably will be), there is no need to initialise the array, because it will already be zeroed.

I see no allowance for power factor not equal to 1. Ok if appliance is kitchen range or toaster oven. Not ok for refrigerator, freezer or micro wave oven.

Paul

CtrlAltElite: If the array is declared as a global (and if it is visible in both setup and loop, it probably will be), there is no need to initialise the array, because it will already be zeroed.

Initializing variables has become a habit. Some platforms do this, some don't. I don't remember which one do and which ones don't. I never even checked if the Arduino platform handles this or not.

I am building a power meter what monitors voltage and current and used the Arduino to calculate the power consumed.

The best Arduino resource on this topic is https://learn.openenergymonitor.org/electricity-monitoring/ctac/how-to-build-an-arduino-energy-monitor

Hi everyone, i am quite new too programming however need to use it in my current dissertation.

If energy monitoring is incidental to your dissertation (I assume you are not an Electronics major doing an “electronics project”) consider a [u]Kill-A-Watt[/u].

Otherwise, jremington’s link to the Open Energy Monitor is your best resource.

Or, if you want something “quick and easy”, and you don’t have an inductive load (your power factor is close to 1.0) you can take a couple of shortcuts. Assuming the power is coming from your utility you can assume the voltage is correct & constant* (120 or 240V) so you don’t have to measure it. And since the voltage & current are sine waves, you can measure the peak current and multiply by 0.707 to get the RMS current. You can just sample in a “fast loop” for 20 milliseconds or so, saving the maximum. Then, repeat that as frequently as you wish.

I want to calculate an average of the first 192 power values obtained but finding it difficult.

That’s kind-of meaningless without knowing the sample rate (the timing). When you digitize an analog voltage, you have to sample at a known sample rate. Or in the case of finding the peak, the sample rate is not critical as long as you sample several times per cycle and as long as you sample for the period of at least one half-cycle.

  • You might want to check the line voltage with a multimeter to see if it typically runs high or low in your area.

Check this class, might be useful - https://playground.arduino.cc/Main/Statistics

adwsystems: Initializing variables has become a habit. Some platforms do this, some don't. I don't remember which one do and which ones don't. I never even checked if the Arduino platform handles this or not.

This is not platform-dependant (whatever you mean by this). C and other derived languages like C++ DEMAND that globals are initialized to 0. You CAN rely on that. Any other behaviour would be a serious compiler bug :)

olf2012:
This is not platform-dependant (whatever you mean by this). C and other derived languages like C++ DEMAND that globals are initialized to 0. You CAN rely on that. Any other behaviour would be a serious compiler bug :slight_smile:

Platform as in programming language and/or computer system. I’m not sure of the exact boundaries, which languages, compilers, and/or systems do and which ones don’t.

The C programming class I took in 1994 had an assignment (the second assignment I believe as the first was a Hello World rocket ship blasting off up the screen) specifically to what happens if variables are not initialized. I don’t recall the compiler used, but I do know it was on a the university’s Unix mainframe. There’s not much else I can say, that assignment was proof enough for me that it could not be guaranteed. From then on I have taken the better-safe-than-sorry approach. It isn’t that hard to set the variables to a known value.

adwsystems:
Platform as in programming language and/or computer system.

I really dislike statements like this. The C programming class I took in 1994 had an assignment specifically to what can happen if variables are not initialized. I don’t recall the compiler used, but I do recall it was on a the universities Unix mainframe system. There’s not much else to say, that assignment was proof enough for me that it could not be guaranteed.

A lot of stuff has happened in the intervening quarter century. Some of it, like guaranteed initialisation of global variables, was good. And Linux systems that you can carry around in your shirt pocket.
Some of it, like boy bands, not so good.

If an old fart can add something, I think the non-initializing of variables is a hold-over from the punch card days. Initialized variables meant many more cards were needed in the object deck. Sure, more instructions were necessary, someone may have studied this and made a management decision.

Paul

You don't need an array to calculate an average--all you need is the total and the count. The average will be the total / count.

In fact, in your case, that formula is even easier, since you already know the count is 192. You will need to count how many samples you gather, but each time you gather a sample, add it to the total until you have added 192 of them. Then the average will be that total / 192.

Jimmus: You don't need an array to calculate an average--all you need is the total and the count. The average will be the total / count.

In fact, in your case, that formula is even easier, since you already know the count is 192. You will need to count how many samples you gather, but each time you gather a sample, add it to the total until you have added 192 of them. Then the average will be that total / 192.

If you want to have rounding you might need to add 96 to the total (in case the values are integers)