I have no clue how you try to calculate average without a for loop ...
But, you are storing a float value into an integer value.
In Uno an int is only 16 bits, where the first bit holds the sign. It is very likely that it will overflow... you will also loose precision.
Calc of average:
int sum=0;
for (int i=0; i<10; i++) {
sum=sum+val[i];
}
int average = sum/10;
i tried testing the code on my laptop. i modified the code to use know values and simply the computation in order to verify the averaging and get the following
Hi
Thanks for supporting, your code giving me error
++++++++++++++++++++++++++++
In file included from C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish.h:72:0,
from C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/Arduino.h:30,
from sketch\filter_average.ino.cpp:1:
C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/usb_serial.h:96:22: error: 'Serial' has a previous declaration as 'USBSerial Serial'
extern USBSerial Serial;
^
C:\Users\Galinka\Documents\Arduino\filter_average\filter_average.ino: In member function 'double EnergyMonitor::calcIrms(int)':
filter_average:11:46: error: no matching function for call to 'random()'
double calcIrms (int x) { return random () * 100. / RAND_MAX; }
^
C:\Users\Galinka\Documents\Arduino\filter_average\filter_average.ino:11:46: note: candidates are:
In file included from C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish.h:63:0,
from C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/Arduino.h:30,
from sketch\filter_average.ino.cpp:1:
C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish_math.h:50:6: note: long int random(long int)
long random(long max);
^
C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish_math.h:50:6: note: candidate expects 1 argument, 0 provided
C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish_math.h:59:6: note: long int random(long int, long int)
long random(long min, long max);
^
C:\Users\Galinka\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple/wirish_math.h:59:6: note: candidate expects 2 arguments, 0 provided
exit status 1
conflicting declaration 'Serial_s Serial'
+++++++++++++++++++++++++++++++++++++
here is the code to which I want to add average
and this is the program which I am trying to use for that
const int numReadings = 10;
int readings[numReadings];
int readIndex = 0;
int total = 0;
int average = 0;
int inputPin = PA0;
void setup() {
Serial.begin(115200);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
total = total - readings[readIndex];
readings[readIndex] = analogRead(inputPin);
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings) {
readIndex = 0;
}
average = total / numReadings;
Serial.println(average);
}
The first column is Ux, average of it is a third column, so average should be 790 instead of -1090 and for Uy ( the second column ) average should be 835 instead of 0
//https://github.com/openenergymonitor/EmonLib/blob/master/examples/current_only/current_only.ino
#include "EmonLib.h"
EnergyMonitor emon1Ux;
EnergyMonitor emon1Uy;
float xn1;
float yn1;
float xn1b;
float yn1b;
//////////////
int i;
int sum = 0;
int val[i] = yn;
////////////
void setup()
{
Serial.begin(115200);
emon1Ux.current(PA0, 1000); // Ux green // Current: input pin, calibration.
emon1Uy.current(PA1, 1000); //Uy brawn
////////
for (int i = 0; i < 10; i++) {
sum = sum + val[i];
//////////////////
}
/*
pinMode(PA8, PWM);
pinMode(PA9, PWM);
TIMER1_BASE->CCER = (1 << 4) | (1 << 0); //cc1e/cc2e enable
TIMER1_BASE->CCMR1 = (1 << 13) | (1 << 12) | (1 << 5) | (1 << 4); //toogle mode
TIMER1_BASE->PSC = 0;
//TIMER1_BASE->ARR=2879;
TIMER1_BASE->ARR = 1181 * 2; // 15.2kHz
TIMER1_BASE->CCR1 = 0 ;
//TIMER1_BASE->CCR2=1439 ;//
TIMER1_BASE->CCR2 = 1181 ;
TIMER1_BASE->CR1 = 1;
*/
}
void loop()
{
double Ux = emon1Ux.calcIrms(1480); // Calculate Irms only
double Uy = emon1Uy.calcIrms(1480);
///////////////////////
float xn = Ux;
float xnb = Uy;
// compute filtered signal
float yn = 0.969 * yn1 + 0.0155 * xn + 0.0155 * xn1 ;
float ynb = 0.969 * yn1b + 0.0155 * xnb + 0.0155 * xn1b ;
// store the previous vale
xn1 = xn;
yn1 = yn ;
xn1b = xnb;
yn1b = ynb ;
int average = sum / 10;
Serial.print(" average = ");
Serial.print(average); //Ux after filter
Serial.print(" ynv = ");
Serial.print(yn); //Ux after filter
Serial.print(" ynb = ");
Serial.print(ynb); //Uy after filter
Serial.println();
}
but I have a error
average_sum:13:13: error: array bound is not an integer constant before ']' token
float val[i] = yn;
^
C:\Users\Galinka\Documents\Arduino\average_sum\average_sum.ino: In function 'void setup()':
average_sum:23:17: error: 'val' was not declared in this scope
sum = sum + val[i];
^
exit status 1
array bound is not an integer constant before ']' token
I had no clue what was going on there...
So, maybe forget my suggestions, or throw away this more complicated filter and replace it with my suggestions...
Both at the same time seems not a good idea...
That's because the filter doesn't remove it nicely. It might attenuate it a little bit, but it is a poor filter for the job. You'll have to understand the characteristics of the noise you're dealing with and design the filter based on that knowledge.
The moving average “smoothing” you're trying to add is just another filter with a specific frequency response:
It's a simple first-order IIR filter, with a cut-off frequency of 5 Hz and a sampling rate of 1 kHz (or a normalized frequency of 0.01 half-cycles/sample).
You need to decide if this order is high enough and if the cut-off frequency is appropriate for your application. There is no magic one-size-fits-all low-pass filter.
At the very least, you should make sure that your sampling rate is constant, e.g. by using a timer using micros().