Filtrado de señal con protothread

Hola, muy buenas.

Hace unos meses acudí al foro con una duda sobre el uso de sensores empleando la librería de Protothread.
https://forum.arduino.cc/index.php?topic=674105.msg4537272#msg4537272

Ahora la duda es poder implementar un “filtro” a la señal del sensor MPXV7002DP.
Este sensor es muy sensible y al tomar las mediciones del diferencial (este sensor se emplea para leer depresión) da valores muy alterados (ej: lecturas de 3,20 mbar a picos de 25mbar e incluso valores de -17mbar durante la toma de 20seg). Los mencionados valores pueden variar puesto que la lectura del vacío se genera a alta velocidad pero no debería de existir alteraciones tan dispares (he tomado lectura con un vacuómetro digital externo y no aparecen estas alteraciones tan dispares).

He probado a implementar el ejemplo de Arduino “Smoothing” para la señal del sensor pero no veo mejora.
O es porque lo he programado mal (muy probable) o porque este filtro no es aplicable a mi proyecto. El hecho de usar la librería Protothread dificulta la programación en este paso (aunque facilita en gran medida la programación de la totalidad del proyecto) puesto que no hay mucha literatura “comprensible” por la red.

Adjunto codigo:

//Librerias
#include <LiquidCrystal.h> //Libreria necesaria para LCDs
#include <pt.h> //Libreria de Protothreads (permite ejecutar varias instrucciones en paralelo)
//Indicamos los pines a utilizar para el LCD
LiquidCrystal lcd(7,8,5,4,3,2);
//Definimos PIN para el contraste del LCD. De esta manera eliminamos el potenciometro
int VO=6;

//Declaramos los Protothreadas
struct pt pt2;  //SensorP2

//función Protothreadas para el SensorP2
void SensorP2Esfuerzo (struct pt *pt){

   static long v = 0;

//Se declara analogica para el sensor P2 y para la conversión de datos de lectura
  const int SensorP2= (A1);
  int SensorP2Val=0;
  float voltajeP2=0;
  float presionP2_mbar=0;
  int i=0;
  static long sum=0;
  static long offset=0;
  
//Declaración para filtro estabilizador de lectura del sensor
  const int numLecturas=100; //Define el número de muestras para realizar un seguimiento.
                            
  float lecturas[numLecturas];
  int indice=0;
  float total=0;
  float promedio=0;

//Inicializa todas las lecturas a 0 del "Array"  
  for (int estaLectura=0; estaLectura < numLecturas; estaLectura++) {
  lecturas[estaLectura]=0; }

 
  PT_BEGIN(pt);

//Calibración inicial del sensor
  for(i=0;i<10;i++){
  SensorP2Val=analogRead(SensorP2)-512;
  sum+=SensorP2Val;}
  offset=sum/10.0;
while(1){
//Filtro
    total=total-lecturas[indice];
    //lecturas[indice]=analogRead(SensorP2);
    lecturas[indice]=(analogRead(SensorP2)-offset);
    total=total+lecturas[indice];
    indice=indice +1;
    if (indice>=numLecturas) {
    indice=0;}
    promedio=total/numLecturas;
  
//Programación para paso de unidades de la lectura del sensor
    SensorP2Val=promedio*100;
    voltajeP2=(SensorP2Val*5.0)/1023.0;      
    presionP2_mbar=voltajeP2-2.5;

//Envio de datos por puerto serie para su estudio
    Serial.print(promedio);
    Serial.print(",");
    Serial.print(voltajeP2);
    Serial.print(",");
    Serial.println(presionP2_mbar,2);
 
//Preparar datos para LCD
    lcd.setCursor(0,1);
    lcd.print("P2:");
    lcd.print(presionP2_mbar*10,2); //Se envia resultado a LCD con resolución de dos decimales
    lcd.print("mbar     ");         
    v = millis();
    PT_WAIT_WHILE(pt,((millis()-v) < 50));                     
  }
  
  PT_END(pt);
}


void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);
  analogWrite(VO,90); 

//Se inician los Protothreads 

  PT_INIT(&pt2);  //SensorP2Esfuerzo
}
void loop()
{              
  SensorP2Esfuerzo(&pt2);
}

No tengo muy claro de que el uso del “promedio” de las lecturas haya sido el correcto.

Gracias de antemano

Un saludo

Porque no haces un código simple sin Protothread tomando numerosas muestras como para ver el comportamiento. Lo primero que te recomendaría es que le apliques una depresión conocida y estable, podrías simplemente tomar una jeringa +- 2Kp son +- 15mmH2O Eso es muy poco y reamente deberías generar una presión fija y estable para asegurarte que el sensor mide bien.

Hola surbyte Probé de tomar mediciones con otro sensor del mismo tipo con un arduino nano separado de la fuente de alimentación del sensor y arduino donde tengo montado el proyecto. Los valores que me daba eran también muy dispares. Por ello pensé que el problema era por falta de filtrado de la señal.

Probaré a hacer lecturas con un programa sin Protothread como me indicas, aunque sigo pensando que estas lecturas tan dispares son debido al efecto de la alta velocidad de generación del vacío y la sensibilidad del sensor

Me pregunto si tienes un osciloscopio como para observar que tal es la señal de salida del sensor y luego decidir un plan de contingencia.

surbyte: Me pregunto si tienes un osciloscopio como para observar que tal es la señal de salida del sensor y luego decidir un plan de contingencia.

Bueno, tengo uno tipo kit de montaje chino (FNIRSI-138 DSO soldada de 2,4 "TFT) pero no me da mucha seguridad los valores que me puede dar.

Hi Una sugerencia es de anadirle un condnsador de por menos 1 ufd electrolitico a la senal de entrada.Esto te va a dar un promedio de la senal y a la vez te filtra la entrada de ruidos.

tauro0221: Hi Una sugerencia es de anadirle un condnsador de por menos 1 ufd electrolitico a la senal de entrada.Esto te va a dar un promedio de la senal y a la vez te filtra la entrada de ruidos.

Hola, Gracias por la sugerencia. Si consiguiera tomar lectura de la frecuencia (alta o baja) que me esta afectando la lectura podría afinar mejor la capacidad del condensador pero probaré a ver que resultados da.

Colocar el capacitor es lo mismo que hacer un filtrado por software. Lo importante es determinar la causa de la perturbación o ruido presente en la salida del sensor de presion. Antes de intentar algo, debes comprender qué ocurre.

Hi, De todas manera aqui posiblemente le pueda ayudar es hacer lo que el fabricate recomienda y es de anadirle dos condensadores uno de 1 ufd y otro de .01 ufd de decoupling a la entrada del vcc y otro de 470pf para filtrar la salida. Esta recomendacion esta en la pagina 3 del datasheet.

Agrego a lo que sugiere @tauro0221 la lectura de la nota de aplicación 1646 que trata de los ruidos y el filtrado.

Saludos

Hi, Yo siempre que uso un modulo siempre le anado un condensador de 10ufd y uno de .1ufd en parallelo a los mas cercano a los pines de Vcc. El de 1.uf elimina las frecuencias altas y el de 10ufd elimina las frecuencias bajas y igual si es una senal analoga de trenzar los cables.