Leer datos de sensor cada 30 seg. y actuar si el delta es superior a x

Hola a todos.

Encima de la ducha tengo un extractor de humedad con un arduino nano, un DHT11 y un relé.
El código es el siguiente:

int sensor = 11; // PIN donde va conectado el sensor de temperatura y humedad DHT11
int rele = 12; // PIN donde va conectado el rele
int ON = LOW; // Variable para activar el rele (HIGH = apagado / LOW = encendido) ?Hago algo mal?
int OFF = HIGH; // Variable para desactivar el rele
int LEDOK = 6; // LED verde - todo OK // Eliminado para poder conectar el display
int LEDERR = 7; // LED rojo - ERROR // Eliminado para poder conectar el display
int hmax = 70; // Humedad maxima a la que se activa el extractor
int tol = 3 ; // Rango de seguridad para evitar que se encienda de manera intermitente el ventilador
int dh = 10 ;
int h1 = 0; //
int h2; //
int estado = OFF;

#include <DHT.h> // Carga la libreria del sensor
#define DHTPIN sensor //Define el pin 4 para el sensor
#define DHTTYPE DHT11   // Define el tipo de sensor a DHT 11 

DHT dht(DHTPIN, DHTTYPE);
//Create an instance of the object.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // Activamos el monitor serie a 9600 bauds // Desactivado - da problemas con el display
  pinMode(rele, OUTPUT); // Activamos el PIN rele como salida para el rele
  //pinMode(sensor, OUTPUT); // Activamos el PIN sensor como salida para el sensor

  dht.begin(); // Iniciamos el sensor de humedad

}

void loop() {
  // Aqui se leen los datos del sensor y se envian por el monitor de serie

  int h = dht.readHumidity();
  int t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h) || h == 0 && t == 0) {
    Serial.println("Failed to read from DHT");
    digitalWrite(LEDERR, HIGH); // Eliminado para poder conectar el display
  } else {
    digitalWrite(LEDOK, HIGH); // Eliminado para poder conectar el display
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
    Serial.print("Estado: ");
    Serial.print(estado);
    Serial.println(" // ");
    delay(2000);

  }
  // Empieza la parte del rele que controla el ventilador
  if (h > hmax) {
    estado = ON;
    digitalWrite(rele, estado);

  }
  if (h < hmax - tol) {
    estado = OFF;
    digitalWrite(rele, estado);
  }
}

Lleva funcionando desde el verano, pero claro, cuando me interesa que funcione es en estas fechas.
El problema es que han llegado las nieblas y el frío, y la humedad es alta afuera. En casa pongo poco la calefacción (15º), por lo que la humedad es alta también dentro.

Así que creo que debo cambiar el código de mi arduino y hacerlo de la siguiente forma:

-Medir la humedad estática
-Medir humedad cada 30" y si el delta h es superior a 2 ó 3 puntos poner en marcha el ventilador hasta que ésta baje de nuevo a la humedad estática.

¿Consejos?

Gracias.
Un saludo.
Raúl

¿A que te refieres con "humedad estática"?

Bueeeno, con la termodinámica hemos topado...

Yo tampoco sé lo que es humedad "estática"...

He supuesto que lo que no quieres que se te empañe es el cristal de la ventana y no el espejo de dentro del baño.
Esto es sin duda un problema de psicrometría. Te paso una web donde hay ejemplos (que recuerdos) http://www6.uniovi.es/usr/fblanco/Problemas.PSICROMETRIA.2008.2009.ppt.pdf
(video recomendable de ver) ¿Por qué se me empañan las gafas? - YouTube
Pienso que en vez de usar tablas termodinámicas, deberás de usar algún tipo de aproximación analítica...Pero como poco deberías de tener conocimiento de la temperatura exterior también.

En caso de que solo sea para elementos internos, como el espejo del baño u otros cristales dentro de la estancia.
Aquí sería más sencillo, simplemente deberías de medir Humedad Relativa y Temperatura (como ya haces) aplicar la fórmula del punto de rocío (Hay aproximaciones sencillas) y activar el relé (extractor) cuando tengas unos cuantos grados de diferencia entre la temperatura del baño y la del rocío.

Je je je, perdón. Igual no me he explicado bien. No es tan complejo.

Quiero que, cuando me duche, se ponga en marcha el extractor. Lo controlo con un DHT11.

Hasta ahora, tiene un tope, que es el 70%. Cuando lo supera se pone en marcha y no para hasta que no baja a 67%.

Ahora mismo, dado que la calefacción no trabaja mucho y la humedad exterior es alta, el extractor se pondría en marcha y no pararía.
Ésta mañana tenía un 75% en la habitación junto al baño y un 85% en el baño. Como mucho la humedad hubiera bajado al 75%, por tanto no hubiera parado el ventilador.

Visto esto, creo que lo suyo sería ir haciendo mediciones a intervalos y mientras la humedad sea estable, registrar ese valor hmax. Lo que accionará el relé que controla el ventilador será cuando el delta entre h1 y h2 sea superior a 2-3 % en un intervalo de 30 segundos.

¿Qué opináis?

Tu programa debería tener un apartado en el que ingreses los parámetros de control de forma manual. Creo que eso sería lo más simple. Asi podrás ajustar el control ante eventos como el que identificaste. Una vez que las condiciones regresen a las "normales", ingresas los parámetros habituales de control.

La aproximacón compleja implica que el programa almacene, digamos unas 10 o 15 lecturas, de tal forma que pueda comparar el valor actual con los ya adquiridos y haga de forma automática los ajustes en base a ese delta 2-3%

PD: por cierto ¿que placa arduino estás usando?

Hola!

Lo que había pensado es un valor h1 y otro h2. Mientras la diferencia cada 30 seg no sea mayor de 2%, almacena h2 en hmax.
Cuando lo sea, no registrar hmax y actuar el ventilador hasta que h2 vuelva a ser hmax.

Pero estoy un poco perdido. Esta tarde le daré una vuelta.
Un saludo

Creo que ya lo entendí.

El problema como te dijo TFTLCDCyg es que "h1" y "h2" no son valores que puedas cambiar a tu antojo si los programas, por lo que si no tienes una entrada manual no los podrás variar.

int sensor = 11; // PIN donde va conectado el sensor de temperatura y humedad DHT11
int rele = 12; // PIN donde va conectado el rele
int hmax = 98; // Humedad maxima a la que se activa el extractor
float delta = 3.00;
float h1; //
float h2; //
int estado = 0;
int tiempo = 500; //0,5 segundos
float hmin; //Almacenamos el valor que queremos que deje de funcionar el extractor

#include <DHT.h> // Carga la libreria del sensor
#define DHTPIN sensor //Define el pin 4 para el sensor
#define DHTTYPE DHT11   // Define el tipo de sensor a DHT 11 

DHT dht(DHTPIN, DHTTYPE);
//Create an instance of the object.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // Activamos el monitor serie a 9600 bauds // Desactivado - da problemas con el display
  pinMode(rele, OUTPUT); // Activamos el PIN rele como salida para el rele
  //pinMode(sensor, OUTPUT); // Activamos el PIN sensor como salida para el sensor

  dht.begin(); // Iniciamos el sensor de humedad
  
  //Leemos inicialmente
  float h1 = dht.readHumidity();
  delay(tiempo);
}

void loop() {
 
  float h2 = dht.readHumidity();
  float t = dht.readTemperature();
  /* Si superamos el delta o si es mayor que hmax (98% por ejemplo) que se 
   *  active
   */
  if (h2 >= h1+delta || h2 >= hmax) {
    digitalWrite(rele, LOW); //Encendemos
    estado=1;
  }
  /* Que se quede encendido hasta que humedad sea la medida anteriormente */
  while(estado==1){
    hmin=h1;
    delay(tiempo);
    float h2 = dht.readHumidity();
    if(h2<=hmin){
      estado=0;
      digitalWrite(rele, HIGH); //Apagamos
    }
    
  }
  
  delay(500); //tiempo que quieras entre medidas
  
  h1=h2; //Almacenamos h2 en h1 para la siguiente iteración
  
  }

Creo que tu problema está en que se quede activado hasta que no baje la humedad, ¿no?

Hola. Perdona por la demora, pero no he tenido mucho tiempo estos días y he andado haciendo probatinas.

No conseguí hacerlo funcionar con tu código. Estoy un poco pez en todo esto, pero al final lo he dejado así:

int sensor = 11; // PIN donde va conectado el sensor de temperatura y humedad DHT11
int rele = 12; // PIN donde va conectado el rele
int LEDOK = 6; // LED verde - todo OK
int LEDERR = 7; // LED rojo - ERROR //
int hmax = 70; // Humedad maxima a la que se activa el extractor
int tol = 3 ; // Rango de seguridad para evitar que se encienda de manera intermitente el ventilador
int estado = 0; // Estado del ventilador (1= en marcha ; 0 = parado)
int tiempo = 60000; // en milisegundos, el intervalo entre mediciones
int marcha = 0; // Tiempo en marcha ventilador
int h1 ; // Indice de humedad de referencia previo al aumento repentino
int h2 ; // Indice de humedad actual para contrastar con h1

#include <DHT.h> // Carga la libreria del sensor
#define DHTPIN sensor //Define el pin 4 para el sensor
#define DHTTYPE DHT11   // Define el tipo de sensor a DHT 11 

DHT dht(DHTPIN, DHTTYPE);
//Create an instance of the object.

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // Activamos el monitor serie a 9600 bauds // Desactivado - da problemas con el display
  pinMode(rele, OUTPUT); // Activamos el PIN rele como salida para el rele
  //pinMode(sensor, OUTPUT); // Activamos el PIN sensor como salida para el sensor

  dht.begin(); // Iniciamos el sensor de humedad
  digitalWrite(rele, LOW);
  h1 = dht.readHumidity(); // Lectura inicial para establecer un valor
  h2 = dht.readHumidity() - tol; // Lectura inicial para establecer un valor

}

void loop() {
  // Aqui se leen los datos del sensor y se envian por el monitor de serie

  int h2 = dht.readHumidity(); //
  int t = dht.readTemperature();

  // Revisa que los datos que lee del DHT son correctos y los transmite por el puerto serie
  if (isnan(t) || isnan(h2) || h2 == 0 && t == 0) {
    Serial.println("Failed to read from DHT");
    digitalWrite(LEDERR, HIGH); 
  } else {
    digitalWrite(LEDOK, HIGH); 
    Serial.print(" Estado: ");
    Serial.print(estado);
    Serial.print(" h= ");
    Serial.print(h2);
    Serial.print(" h1= ");
    Serial.print(h1);
    Serial.print(" %\t");
    Serial.print(" t= ");
    Serial.print(t);
    Serial.print(" *C");
    Serial.println(" // ");

  }
  // Empieza la parte del rele que controla el ventilador
  if (h1 + tol < h2) { // Si la humedad actual supera a la humedad de referencia mas la tolerancia, se activa el ventilador
    estado = 1;
    digitalWrite(rele, HIGH);
    while (estado == 1) { // Mientras el ventilador este en marcha, ocurrira esto:
      h2 = dht.readHumidity();
        marcha++;
    Serial.print(" Estado: ");
    Serial.print(estado);
    Serial.print(" h= ");
    Serial.print(h2);
    Serial.print(" h1= ");
    Serial.print(h1);
    Serial.print(" %\t");
    Serial.print(" t= ");
    Serial.print(t);
    Serial.print(" *C");
    Serial.print(" marcha:");
    Serial.print(marcha);
    Serial.println(" // ");
      delay(tiempo);
      if (h2 <= h1 || marcha>20) { //Si se cumple esto, salimos del bucle
        estado = 0;
        marcha=0;
        h1 = h2;
        digitalWrite(rele, LOW);

      }
    }

  }
  else if (h2<h1){ // Si la humedad actual es inferior a la referencia, igualamos la de referencia
  h1=h2;
  }
  delay(tiempo);
}

Gracias! Un saludo