Tuesday, October 18, 2016

Arduino - ESP8266 Digital Smoothing Filter for Analog Readings

Hello everyone,

In this tutorial i will show you how can read more stable , more accurate and more smooth analog values with arduino or esp8266. Our methods are same for both of them.


Method 1: AveragingMethod.

We will smooth the values by using below equation (Eq. 1)



Eq. 1   





Where ;
Y : Output of filter
X : Signal

What we are doing now ?
X [k] is the signal value and X[k-1] is the old signal value.
When you use that notation,  you can decrease noise effect or unwanted instantenious effects.

Arduino Code :
 
#define SensorPin A0

int nowValue = 0;
int pastValue = 0;
int filteredValue = 0;
void setup() {
  Serial.begin(115200);

}

void loop() {
 
  pastValue = nowValue;
  nowValue = analogRead(SensorPin);
  filteredValue = (pastValue + nowValue) / 2;
  Serial.print("Now Value = ");
  Serial.print(nowValue);
  Serial.print(" Filtered Value = ");
  Serial.println(filteredValue);

  delay(500);

}

 

Method 2 : More sampling ...

This method assumes that if we samples more, we can eliminate analog reading noise. I write a function hat is very common for analog readings. My function samples 30 times and it takes ~31ms. If your signal is at high frequency. You can change delay with delayMicroseconds. You can use 10uS with your project.


int AnalogRead(volatile int AnalogPin) {
  unsigned int RawData = 0;
  for(int = 0; i < 30; i++) {
    RawData = analogRead(AnalogPin);
    delay(1);
  }
  RawData = RawData / 30;
  return RawData;
}


Complete Arduino Code : with method 1.

#define SensorPin A0

int nowValue = 0;
int pastValue = 0;
int filteredValue = 0;
void setup() {
  Serial.begin(115200);

}

void loop() {
 
  pastValue = nowValue;
  nowValue = AnalogRead(SensorPin);
  filteredValue = (pastValue + nowValue) / 2;
  Serial.print("Now Value = ");
  Serial.print(nowValue);
  Serial.print(" Filtered Value = ");
  Serial.println(filteredValue);

  delay(500);

}

int AnalogRead(volatile int AnalogPin) {
  unsigned int RawData = 0;
  for(int = 0; i < 30; i++) {
    RawData = analogRead(AnalogPin);
    delay(1);
  }
  RawData = RawData / 30;
  return RawData;
}

 


Now you have a smoothing filter. If you say my signal has too much noise , You can continue with method 3.

Method 3 : Method 1 with more sample

In this part, we have a signal array where its size is k and filter outpur is average of signal array each value. Also, i use special AnalogRead function.

#define SensorPin A0

int nowValue = 0;
int pastValue = 0;
int filteredValue = 0;

const int ArraySize = 10;
int SignalArray[ArraySize];
void setup() {
  Serial.begin(115200);

}

void loop() {

  //Shifting Array
  for(int i = 0; i < ArraySize - 1; i++) {
    SignalArray[i] = SignalArray[i+1];
  }
 
  SignalArray[ArraySize - 1] = AnalogRead(SensorPin);

  //Average
  unsigned int ArraySum = 0;

  for(int i = 0; i < ArraySize; i++) {
    ArraySum = AnalogRead(SensorPin);
  }

  filteredValue = ArraySum / ArraySize;
  filteredValue = (pastValue + nowValue) / 2;

 
  Serial.print("Now Value = ");
  Serial.print(SignalArray[ArraySize - 1]);
  Serial.print(" Filtered Value = ");
  Serial.println(filteredValue);

  delay(500);

}

int AnalogRead(volatile int AnalogPin) {
  unsigned int RawData = 0;
  for(int i = 0; i < 30; i++) {
    RawData = analogRead(AnalogPin);
    delay(1);
  }
  RawData = RawData / 30;
  return RawData;
}

 



Complete Project Code : Download

No comments:

Post a Comment

ESP8266 SoftwareSerial Library & Level Shifter for ESP8266 - Arduino

Hello everyone, I have found a very usefull software library for esp8266. Library works well with Arduino IDE. In this tutorial, I will s...