Heroes-David Bowie
El filtrado de datos obtenidos de sensores conectados a una placa Arduino es un proceso crucial para mejorar la precisión y confiabilidad de las mediciones. Los sensores suelen captar ruido y variaciones indeseadas que pueden afectar la calidad de los datos. Implementar técnicas de filtrado ayuda a mitigar estos problemas y obtener lecturas más precisas.
Consiste en promediar un conjunto de valores consecutivos para suavizar las variaciones rápidas. Este método es sencillo y efectivo para eliminar el ruido de alta frecuencia.
Referencia: Arduino Moving Average Filter
// Definición del tamaño del arreglo y variables necesarias
const int numReadings = 10; // Número de lecturas a promediar
int readings[numReadings]; // Arreglo para almacenar las lecturas
int readIndex = 0; // Índice para seguir la posición actual en el arreglo
int total = 0; // Variable para almacenar la suma total de las lecturas
int average = 0; // Variable para almacenar el promedio calculado
void setup() {
// Inicialización del arreglo readings con valores iniciales de 0
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
// Resta la lectura más antigua del total
total = total - readings[readIndex];
// Lee el nuevo valor del sensor y lo guarda en el arreglo en la posición actual
readings[readIndex] = analogRead(A0);
// Suma el nuevo valor al total
total = total + readings[readIndex];
// Avanza al siguiente índice en el arreglo circular
readIndex = readIndex + 1;
// Si se llega al final del arreglo, vuelve al principio (circular)
if (readIndex >= numReadings) {
readIndex = 0;
}
// Calcula el promedio dividiendo la suma total entre el número de lecturas
average = total / numReadings;
// Aquí se utilizaría el valor promedio para realizar alguna acción o proceso adicional
// Ejemplo: enviar el valor promedio por Serial, tomar una decisión basada en el promedio, etc.
}
Es un algoritmo recursivo que proporciona estimaciones óptimas del estado de un sistema dinámico a partir de una serie de mediciones imprecisas. Es ideal para aplicaciones donde se requiere un alto grado de precisión.
Referencia: Kalman Filter Library for Arduino
#include <SimpleKalmanFilter.h> // Incluye la biblioteca del filtro de Kalman
SimpleKalmanFilter kalmanFilter(2, 2, 0.01); // Crea un objeto de filtro de Kalman
void setup() {
// Configuración inicial, no se realiza ninguna configuración en este caso
}
void loop() {
int sensorValue = analogRead(A0); // Lee el valor analógico del sensor conectado a A0
float filteredValue = kalmanFilter.updateEstimate(sensorValue); // Aplica el filtro de Kalman al valor leído
// Utilizar el valor filtrado para realizar acciones adicionales
// Por ejemplo, enviar el valor filtrado por Serial, tomar decisiones basadas en este valor, etc.
}
Selecciona el valor medio de un conjunto de datos, eliminando valores atípicos que puedan distorsionar la lectura. Es útil para datos con picos de ruido.
Referencia: MedianFilter Library
#include <MedianFilter.h> // Incluye la biblioteca del filtro de mediana
MedianFilter medianFilter(5, 0); // Crea un objeto de filtro de mediana con un tamaño de ventana de 5
void setup() {
// Configuración inicial, no se realiza ninguna configuración en este caso
}
void loop() {
int sensorValue = analogRead(A0); // Lee el valor analógico del sensor conectado a A0
int filteredValue = medianFilter.AddValue(sensorValue); // Agrega el valor leído al filtro de mediana
// Utilizar el valor filtrado para realizar acciones adicionales
// Por ejemplo, enviar el valor filtrado por Serial, tomar decisiones basadas en este valor, etc.
}
Asigna más peso a los datos más recientes y menos a los antiguos, proporcionando una respuesta más rápida a los cambios sin sacrificar demasiada suavidad.
Referencia: Exponential Moving Average Filter in Arduino
float alpha = 0.1; // Factor de suavizado, entre 0 y 1
float filteredValue = 0; // Valor filtrado inicializado en 0
void setup() {
// Configuración inicial, no se realiza ninguna configuración en este caso
}
void loop() {
int sensorValue = analogRead(A0); // Lee el valor analógico del sensor conectado a A0
// Aplica el filtro EWMA para suavizar el valor leído
filteredValue = alpha * sensorValue + (1 - alpha) * filteredValue;
// Utilizar el valor filtrado para realizar acciones adicionales
// Por ejemplo, enviar el valor filtrado por Serial, tomar decisiones basadas en este valor, etc.
}
El filtro EWMA es útil cuando se desea una respuesta rápida a cambios en la señal, pero se necesita un cierto nivel de suavizado para reducir el ruido en las mediciones analógicas.
Para implementar estos filtros en un proyecto de Arduino, se utilizan los siguientes componentes:
#include <MovingAverage.h>
const int gasPin = A0; // Pin analógico donde está conectado el sensor de gas
MovingAverage<int> filter(10); // Filtro de media móvil con ventana de 10
void setup() {
Serial.begin(9600); // Inicia la comunicación serial a 9600 baudios para la salida de datos
}
void loop() {
int gasValue = analogRead(gasPin); // Lee el valor analógico del sensor de gas
int filteredValue = filter.add(gasValue); // Aplica el filtro de media móvil al valor leído
Serial.println(filteredValue); // Imprime el valor filtrado por el puerto serial
delay(1000); // Espera 1 segundo antes de la próxima lectura
}
#include <DHT.h>
#include <SimpleKalmanFilter.h>
#define DHTPIN 2 // Pin digital donde está conectado el sensor DHT11
#define DHTTYPE DHT11 // Tipo de sensor DHT (DHT11 en este caso)
DHT dht(DHTPIN, DHTTYPE); // Crear instancia del sensor DHT
SimpleKalmanFilter kalmanFilter(2, 2, 0.01); // Crear filtro de Kalman con parámetros Q, R, A
void setup() {
Serial.begin(9600); // Inicia la comunicación serial a 9600 baudios
dht.begin(); // Inicia el sensor DHT
}
void loop() {
float humidity = dht.readHumidity(); // Lee la humedad desde el sensor DHT
float temperature = dht.readTemperature(); // Lee la temperatura desde el sensor DHT
// Aplica el filtro de Kalman a las lecturas de humedad y temperatura
float filteredHumidity = kalmanFilter.updateEstimate(humidity);
float filteredTemperature = kalmanFilter.updateEstimate(temperature);
// Imprime las lecturas filtradas por el puerto serial
Serial.print("Filtered Humidity: ");
Serial.print(filteredHumidity);
Serial.print(" %\t");
Serial.print("Filtered Temperature: ");
Serial.print(filteredTemperature);
Serial.println(" *C");
delay(2000); // Espera 2 segundos antes de realizar la siguiente lectura
}
#include <MedianFilter.h>
#define echoPin 7 // Pin digital donde está conectado el pin de eco del sensor ultrasónico
#define trigPin 8 // Pin digital donde está conectado el pin de trigger del sensor ultrasónico
MedianFilter filter(5, 0); // Filtro de mediana con ventana de 5 elementos
void setup() {
Serial.begin(9600); // Inicia la comunicación serial a 9600 baudios
pinMode(trigPin, OUTPUT); // Configura el pin de trigger como salida
pinMode(echoPin, INPUT); // Configura el pin de eco como entrada
}
void loop() {
long duration, distance;
// Envía un pulso corto al pin de trigger para iniciar la medición
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Mide la duración del eco recibido y calcula la distancia en centímetros
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1; // Calcula la distancia en centímetros
// Aplica el filtro de mediana a las lecturas de distancia
int filteredDistance = filter.AddValue(distance);
// Imprime la distancia filtrada por el puerto serial
Serial.print("Filtered Distance: ");
Serial.print(filteredDistance);
Serial.println(" cm");
delay(1000); // Espera 1 segundo antes de realizar la siguiente lectura
}
#include <EEPROM.h>
const int ldrPin = A0; // Pin analógico donde está conectado el LDR
float alpha = 0.5; // Factor de suavizado para el filtro EWMA
float filteredValue = 0; // Variable para almacenar el valor filtrado
void setup() {
Serial.begin(9600); // Inicia la comunicación serial a 9600 baudios
}
void loop() {
int ldrValue = analogRead(ldrPin); // Lee el valor analógico del sensor LDR
// Aplica el filtro EWMA para suavizar las lecturas
filteredValue = alpha * ldrValue + (1 - alpha) * filteredValue;
// Imprime el valor filtrado de intensidad de luz por el puerto serial
Serial.print("Filtered Light Intensity: ");
Serial.println(filteredValue);
delay(1000); // Espera 1 segundo antes de realizar la siguiente lectura
}
Implementar estos filtros en proyectos de Arduino ayuda a mejorar significativamente la precisión y fiabilidad de los datos obtenidos de sensores, lo que es crucial para aplicaciones en robótica, monitoreo ambiental, entre muchas otras. Se logra evitar el posible ruido de los datos y el no procesamiento de estos. Con esto es importante también el contexto en el cual se trabaja y para que se quiere lograr, pues si bien al utilizar esto permite que funcione de mejor manera.