Confundido con el intervalo de tiempo en la reducción del ruido en un sensor

Hola, hace poco planteé un tema donde tenía duda de como implementar una "frecuencia de muestreo", que es a lo que se refiere Luis Llamas en su post, gracias a la ayuda de @anon90500195 y @gonpezzi pude implementarlo en un código para medir temperatura con un sensor, luego que entendí como hacerlo lo hice con un sensor de presión y los datos los envíe a una tarjeta sd.

Esta es la línea según lo que entendí del post de Luis Llamas donde se cambia el intervalo:

medicion = MeasureP(1000,P);

El asunto es que pongo que el intervalo sea de 1000 ms, es decir, 1 segundo y los datos no me los muestra ni en la tarjeta sd ni en el monitor serie cada 1 segundo, sino que cada 2, y esto pasaba tanto con el sensor de presión como con el de temperatura. Imagen de los datos impresos en la tarjeta sd:

ignoren el min "61" porque desde mi computador no pude sincronizar correctamente los minutos, así que en la línea:

  minutos = now.minute();

agregué un +9 (la diferencia del rtc con mi pc) y quedó así :rofl:, pensé que con eso arreglaba el error, son detalles, eso quizás da para otro post. Luego de darme cuenta borré el "+9"

El código completo del RTC, la sd y el sensor de presión con una frecuencia de muestreo de 1000ms es el siguiente:

#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
float medicion;

RTC_PCF8523 RTC;



// Funcion que simula la lectura de un sensor
int analogInPin=A0;
int sensorValue=0;
int outputValue=0;

//int SensorPin=A0
String unit;// variable para la unida de medida de VL53L0X [mm]
String ano;
String dia;
String mes;
String horas;
String minutos;
String segundos;
String FECHA;
String HORA;
String Nombredelarchivo;
String Imprimir;

const int chipSelect=10;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  // instrucciones para RTC
  if (! RTC.isrunning())
  {
    Serial.println("RTC no está activada");
   //Para ajustar la fecha y hora, por primera vez, a la del computador que está usando, debe descomentar la siguiente linea:
    //RTC.adjust(DateTime(__DATE__,__TIME__));
  }
 Serial.print("Iniciando tarjeta SD ...");
 
  if (!SD.begin(chipSelect))
  {
    Serial.println("Error al iniciar");
    //while(1);
  }
  else {
  Serial.println(" SD Iniciada correctamente");
  }
  // fin instruccion RTC
  ///////////////////////////////////////
  
}

void loop() {
  medicion = MeasureP(1000,P); 
  sensorValue=analogRead(analogInPin);
  outputValue=map(medicion,200,400,0,3000); 
  //función map: (valor de entrada, inicio rango de entrada, final rango de entrada, inicio rango de salida, final rango de salida)
  // analogWrite(analogOutPin, outputValue);
  //impresión de los resultados en monitor
  //Serial.print("lec_sens_fr=  ");
  //Serial.print(medicion,1); // imprime float con 1 decimal
  //Serial.print("  lectura_sensor =  ");
  //Serial.print(sensorValue);
  //Serial.print("   Carga=  ");
  //Serial.println(outputValue);
  delay(1000);
   
  DateTime now=RTC.now();
  ano = now.year();
  mes = now.month();
  dia = now.day();
  horas = now.hour();
  minutos = now.minute();
  segundos = now.second();
  FECHA = dia + "/" + mes + "/" + ano + " " ;
  HORA = horas + ":" + minutos + ":" + segundos;
  //////////////////////////////////////////
  Nombredelarchivo = dia + mes + ano + ".txt";
  /////////////////////////////////////////

  
  // instrucciones para impresión en tarjeta SD
  Imprimir= FECHA + HORA + " " + " " + "Sensor: " + medicion + "  Carga: " + outputValue;
  File dataFile= SD.open(Nombredelarchivo,FILE_WRITE);
  //Si el archivo está disponible, escribir en el:
  if (dataFile) {
    dataFile.println(Imprimir);
    dataFile.close();
    Serial.println(Imprimir);
  }
  //Si el archivo no se puede abrir, imprimir mensaje de error:
  else {
    Serial.println("Error al intentar escribir en el archivo");
  }
  delay(500); 
 }

 float P()
{  analogRead(analogInPin);   //Se envía el comando para leer la temperatura
   float P=sensorValue;
   return P;
}

float MeasureP(int msInterval, float(*funct)())
{
   float sum=0;
   long startTime = millis();
   int samplesNumber = 0;

   while (millis() - startTime < msInterval)
   {
      samplesNumber++;
      sum += P();
   }
   return sum / samplesNumber;
}

Cual es el error? O yo estoy interpretando incorrectamente el post de Luis Llamas?

Saludos.

esta funcion parece rara...

1 Like

Si tienes algo que toma intervalos de 1000 mseg

medicion = MeasureP(1000,P); 

para que pones un delay(1000) luego? tu solo has generado un retardo inútil.
Quita ese delay() y jamás uses delay cuando tengas millis() trabajando para controlar tiempos.

1 Like

Aparte de todo lo dicho anteriormente es este y en el otro hilo, ¿poque llamas a la funcion:

float MeasureP(int msInterval, float(*funct)()) {

con dos parametros?. si solo usas el primero, siendo el segundo una llamada a leer la temperatura que no veo el motivo de hacerla.
Veo mas logico definir esa funcion de esta forma :

float MeasureP(int msInterval) {

y su llamada demto del loop de esta forma:

medicion = MeasureP(1000); 

Ademas estoy de acuerdo con @J-M-L . La funcion correcta para leer la temperatura ¿no era la anterior?:

float temp()
{  sensors.requestTemperatures();   //Se envía el comando para leer la temperatura
   float temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
   return temp;
}

Saludos.

1 Like

Porque asi lo habrá copiado y pegado del ejemplo de Luis Llamas.

1 Like

Si, me la inventé haciendo la analogía con esta parte del codigo de un sensor de temperatura que si funcionó:

float temp()
{  sensors.requestTemperatures();   //Se envía el comando para leer la temperatura
   float temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
   return temp;
}

El código si funciona en cuanto al muestreo en un intervalo de tiempo, la cuestión es que no existe coherencia entre el intervalo que yo impongo y el que es entregado por el script, por ejemplo, pongo 5000ms y me lanza los resultados en aprox 4 segundos, cuando deberían ser 5.

Saludos!

… Buen intento pero...

1 Like

Porque así estaba escrito en el codigo de Luis Llamas, copiado y pegado de su web (que puse el link en el inicio del post):

Ademas estoy de acuerdo con @J-M-L . La funcion correcta para leer la temperatura ¿no era la anterior?:

Si, esa parte de codigo que muestras es correcto, funcionó para el sensor de temperatura, pero ahora lo implementé en un sensor de presión industrial de dos cables y como en el caso del sensor de presión no funciona un

 sensors.requestPressure()

lo cambié por

{  analogRead(analogInPin);   //Se envía el comando para leer la temperatura

Funciona, pero también reconozco que es raro, estoy intentando imitar otro codigo y puede que me equivoqué, el sensor muestra resultados coherentes, pero tengo ese problemilla del intervalo como conté en las respuestas anteriores.

Saludos!

Gracias, tienes toda la razón, lo voy a corregir ahora y para el futuro!

Si ya lei su publicacion y sigo pensando lo mismo que te dije antes.
Yo tu loop y funciones las veo mas coherentes de la siguiente manera:

void loop() {
  medicion = MeasureP(1000);  
  outputValue = map(medicion, 200, 400, 0, 3000);
  etc...
  etc...
}

float P() { 
  float P = analogRead(analogInPin);   //Se lee el sensor
  return P;
}

float MeasureP(int msInterval){
  float sum = 0;
  long startTime = millis();
  int samplesNumber = 0;

  while (millis() - startTime < msInterval){
    samplesNumber++;
    sum += P();
  }
  return sum / samplesNumber;
}
1 Like