How to improve analog reading

August 13, 2019 by
How to improve analog reading
Boot & Work Corp. S.L., Quesada Dani Salvans

Introduction

In this post we are going to see a comparison between the common way to develop an analog reading of the inputs of our device and an improved way in certain points and their own examples:

Common way

Usually, when we need to execute an analog reading of the inputs of our device, we declare the pins as inputs and make the readings following a structure such as the next example (made to test analog inputs in a M-Duino 21+):


/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

void setup() {
  Serial.begin(9600L);
  Serial.print("common analogRead test example");
  
  pinMode(I0_7, INPUT);
  pinMode(I0_8, INPUT);
  pinMode(I0_9, INPUT);
  pinMode(I0_10, INPUT);
  pinMode(I0_11, INPUT);
  pinMode(I0_12, INPUT);
}

void loop() {
  uint16_t i0_7 = analogRead(I0_7);
  uint16_t i0_8 = analogRead(I0_8);
  uint16_t i0_9 = analogRead(I0_9);
  uint16_t i0_10 = analogRead(I0_10);
  uint16_t i0_11 = analogRead(I0_11);
  uint16_t i0_12 = analogRead(I0_12);

  Serial.print ("I0_7: "); Serial.print(i0_7, DEC); Serial.print(" ");
  Serial.print ("I0_8: "); Serial.print(i0_8, DEC); Serial.print(" ");
  Serial.print ("I0_9: "); Serial.print(i0_9, DEC); Serial.print(" ");
  Serial.print ("I0_10: "); Serial.print(i0_10, DEC); Serial.print(" ");
  Serial.print ("I0_11: "); Serial.print(i0_11, DEC); Serial.print(" ");
  Serial.print ("I0_12: "); Serial.print(i0_12, DEC); Serial.print(" ");

  Serial.println();
  Serial.flush();
  delay(200);
}


Improved way

The Filter library includes a module called "Filter.h" that allows smooth analog inputs, a really useful function when the signal is unstable.

#include <Filter.h>

The definition of the analog filter requires a number of samples and a sample period. In this example, the time is 2 ms and the number of samples is 10.

AnalogFilter<10, 2> aFilter;

The update function returns the filtered value according to the passed input value as an argument.

int input = analogRead(I0_0);
int filteredInput = aFilter.update(input);

Now, we can see a complete example as the previous one (made to test analog inputs in an M-Duino 21+):

/*
   Copyright (c) 2018 Boot&Work Corp., S.L. All rights reserved

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <Filter.h>

AnalogFilter<10,2> aFilter;

void setup() {
  Serial.begin(9600L);
  Serial.print("improved analogRead test example");
  
  pinMode(I0_7, INPUT);
  pinMode(I0_8, INPUT);
  pinMode(I0_9, INPUT);
  pinMode(I0_10, INPUT);
  pinMode(I0_11, INPUT);
  pinMode(I0_12, INPUT);
}

void loop() {
  uint16_t I0_7 = analogRead(I0_7);
  uint16_t I0_8 = analogRead(I0_8);
  uint16_t I0_9 = analogRead(I0_9);
  uint16_t I0_10 = analogRead(I0_10);
  uint16_t I0_11 = analogRead(I0_11);
  uint16_t I0_12 = analogRead(I0_12);

  uint16_t filtered_I0_7 = aFilter.update(I0_7);
  uint16_t filtered_I0_8 = aFilter.update(I0_8);
  uint16_t filtered_I0_9 = aFilter.update(I0_9);
  uint16_t filtered_I0_10 = aFilter.update(I0_10);
  uint16_t filtered_I0_11 = aFilter.update(I0_11);
  uint16_t filtered_I0_12 = aFilter.update(I0_12);

  Serial.print("I0_7: "); Serial.print(filtered_I0_7, DEC); Serial.print(" ");
  Serial.print("I0_8: "); Serial.print(filtered_I0_8, DEC); Serial.print(" ");
  Serial.print("I0_9: "); Serial.print(filtered_I0_9, DEC); Serial.print(" ");
  Serial.print("I0_10: "); Serial.print(filtered_I0_10, DEC); Serial.print(" ");
  Serial.print("I0_11: "); Serial.print(filtered_I0_11, DEC); Serial.print(" ");
  Serial.print("I0_12: "); Serial.print(filtered_I0_12, DEC); Serial.print(" ");

  Serial.println();
  Serial.flush();
  delay(200);
}


In both examples, if we open the Serial Monitor (configuring the BaudRate to 9600 as the code), we will see the same but the second one is going to be better in the case of unstable signals. We will see the analogRead of the device inputs (printed in decimal), repeatedly in the loop every 200 ms. In the second example, using the filter, this is going to make an analogRead of 10 samples every 2 ms (depending on which values we previously set) and show an average value, repeatedly in the loop every 200 ms.


If you want to check out more information about Filter.h library, you can click on the link below:

Filter GitHub repository

​Search in our Blog

How to improve analog reading
Boot & Work Corp. S.L., Quesada Dani Salvans August 13, 2019

Looking for your ideal Programmable Logic Controller?

Take a look at this product comparison with other industrial controllers Arduino-based. 

We are comparing inputs, outputs, communications and other features with the ones of the relevant brands.


Industrial PLC comparison >>>