Cómo mejorar la lectura analógica

13 de agosto de 2019 por
Cómo mejorar la lectura analógica
Boot & Work Corp. S.L., Quesada Dani Salvans

Introducción

En este post vamos a ver una comparación entre el modo normal de llevar a cabo una lectura analógica de las entradas de nuestro dispositivo y un modo mejorado en ciertos puntos y sus correspondientes ejemplos.

Vía común

Normalmente, cuando necesitamos ejecutar una lectura  analógica de las entradas de nuestro dispositivo, declaramos los pins como entradas y hacemos las lecturas siguiendo una estructura parecida a la del siguiente ejemplo (diseñado para probar las entradas analógicas de un 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);
}


Forma mejorada

The Tools40 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;

La función "update" devuelve el valor filtrado acorde el valor que le hemos pasado como entrada como el argumento.

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

Ahora, podemos ver un ejemplo completo como el visto anteriormente a este (diseñado para probar las entradas analógicas de un 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);
}


En ambos ejemplos, si abrimos el Monitor Serie (configurando el BaudRate a 9600 como el código), vamos a observar lo mismo pero el segundo va a ser una mejor opción en el caso de trabajar con señales inestables. Veremos la lectura analógica (analogRead) de las entradas del dispositivo (mostradas en decimal), repetidamente en el "loop" cada 200 ms. En el segundo ejemplo, utilizando el filtro, este va a hacer una lectura analógica (analogRead) de 10 muestras cada 2 ms (dependiendo de los valores que prevaimente hayamos establecido) y va a mostrar una media de los valores, repetidamente en el "loop" cada 200 ms.


Si desea consultar más información sobre la librería Filter.h y Tools40, puede hacer click en el siguiente link:

Filter GitHub repository

Buscar en nuestro blog

Cómo mejorar la lectura analógica
Boot & Work Corp. S.L., Quesada Dani Salvans 13 de agosto de 2019
Compartir

¿Estás buscando tu Controlador Lógico Programable ideal?

Echa un vistazo a esta comparativa de producto de varios controladores industriales basados en Arduino.

Comparamos entradas, salidas, comunicaciones y otras especificaciones con las de los equipos de otras marcas destacadas.


Industrial PLC comparison >>>