This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Nodemcu y fallos lectura con DHT11
#1
Hola a tod@s, saludos de nuevo.

Os comento, al final me he olvidado de los ESP01, que dan un montón de problemas de estabilidad, al menos es mi experiencia, y por muy poco más me he hecho con un Nodemcu V1.0 y el salto ha sido una auténtica maravilla, unha sencillez absoluta a la hora de cargar el IDE de arduino y una gran estabilidad, puesto que la electrónica que lleva integrada el circuito te elimina un montón de fallos que tenías que suplir al ESP01.
El problema que me ha surgido ahora es que el DHT11 (en breve pondré un DHT22) me hace una lectura de Tª y Humedad intermitente y con un patrón fijo, a thingspeak me envía lecturas intermitentes y claro, no es fiable el sistema puesto que es para hacer un termostato. He colocado en una de las patas un led (como si fuera un relé) para activar una caldera, y cada vez que el DHT11 no lee los datos, el led se apaga, pasan unos segundos y se vuelve a encender, y así en un bucle infinito. No es problema de HW puesto que he probado varios DHT11 y conectados a distintas patillas del Nodemcu, además la patilla de datos del DHT11 lo tengo con una resistencia pullup......
Probablemente sea un fallo de SW, pero no consigo averiguar cual es el fallo, así que os dejo el código a ver si alguien puede iluminar mi camino.....

El código me funciona, leo datos de Tª/Hum y los envío a thingspeak, con una app creada con appinvetor leo los datos de Tª/Hum, estado del relé y la temperatura que seleccionada....

Código:
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ThingSpeak.h> //librería conexión a thingspeak
#include<ESP8266WiFi.h> //librería esp8266
#include <DHT.h> //librería del módulo de temperatura y humedad
#include <Adafruit_Sensor.h>
#define DHTTYPE DHT11



const int releCaldera = 14;
const int DHTpin = 12;
float histeresis = 1;
static unsigned long last_loop;
unsigned long int anteriorRefreshDatos = 0;
float temp= 0;
float humi= 0;
float tempDeseada = 00;
int calderaHabilitada;
int estadoRele = 0;

DHT dht(DHTpin, DHTTYPE);


IPAddress ip(192, 168, 1, 10);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

String apiKey = "XXXXXXXXXXXXXXXXXX";
const char* ssid = "XXXXXXXXXXXXX";
const char* password = "XXXXXXXXXXXXX*";
const char* server = "api.thingspeak.com";
unsigned long myChannelNumber = XXXXXXXXXXXXXXX;
const char * myWriteAPIKey = "XXXXXXXXXXXX";

WiFiClient client;
WiFiServer servidor(80);

void setup() {
//Relé de la caldera
pinMode(releCaldera, OUTPUT);
digitalWrite(releCaldera, LOW);

//Iniciamos puerto serie
Serial.begin(9600);

delay(5);




//Iniciamos el modulo wifi
WiFi.begin(ssid, password);
Serial.println();
Serial.println();
Serial.print("Connectandose a ");
Serial.println(ssid);
WiFi.begin(ssid, password);

// Static IP Setup Info Here...
WiFi.config(ip, gateway, subnet);
WiFi.mode(WIFI_STA);

while( WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connectado");

ThingSpeak.begin(client);
Serial.println("Cliente thingspeak iniciado");
servidor.begin();
Serial.print("Servidor iniciado, IP: ");
Serial.println(WiFi.localIP());

}

void refreshDatos(){

if (millis() > anteriorRefreshDatos + 20000){
anteriorRefreshDatos = millis();

float temp = dht.readTemperature();
float humi = dht.readHumidity();


    if (calderaHabilitada = 1){
    if (temp + histeresis >= tempDeseada && temp > 0)  digitalWrite(releCaldera, LOW);
   
    else if (temp < tempDeseada && temp > 0) digitalWrite(releCaldera, HIGH);
   
    else digitalWrite(releCaldera, LOW);
        }

           
   
     
Serial.println("Leyendo datos....");
Serial.println();
 
Serial.print("Temperatura deseada: ");
Serial.println(tempDeseada);

Serial.print("Temperatura: ");
Serial.println(temp);
Serial.print("Humedad: ");
Serial.println(humi);

     int estadoRele = digitalRead(releCaldera);
     if (estadoRele == LOW)
       {
       Serial.print("Estado relé caldera: ");  
       Serial.println("LOW");
       } else {
       Serial.print("Estado relé caldera: ");  
       Serial.println("HIGH");
        }


ThingSpeak.setField(1, temp);
ThingSpeak.setField(2, humi);
ThingSpeak.setField(3, estadoRele);
ThingSpeak.setField(4, tempDeseada);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

Serial.println("Enviando datos...");
Serial.println();
}
}

void loop() {
//Lectura del sensor de temperatura
refreshDatos();

//Codigo servidor

WiFiClient clienteDeServidor = servidor.available();
if (!clienteDeServidor) { //Si no se ha conectado nadie, saltamos al inicio del codigo
return;
}
Serial.println("Nuevo cliente conectado");
while(!clienteDeServidor.available()){
//Esperamos hasta que el cliente haya solicitado o enviado datos
delay(1);

//De paso que estamos esperando al cliente... pues comprobamos  si hemos de actualizar la temperatura.
refreshDatos();
}

// Read the first line of the request
String req = clienteDeServidor.readStringUntil('\r');
Serial.println(req);
clienteDeServidor.flush();

// Match the request

   int val;

     if (req.indexOf("/tempDeseada45") != -1){
     tempDeseada = 45;
     val = 1;
     } else if (req.indexOf("/tempDeseada46") != -1){
     tempDeseada = 46;
     val = 1;
     } else if (req.indexOf("/tempDeseada47") != -1){
     tempDeseada = 47;
     val = 1;
     } else if (req.indexOf("/tempDeseada48") != -1){
     tempDeseada = 48;
     val = 1;
     } else if (req.indexOf("/tempDeseada49") != -1){
     tempDeseada = 49;
     val = 1;
     } else if (req.indexOf("/tempDeseada50") != -1){
     tempDeseada = 50;
     val = 1;
     } else if (req.indexOf("/tempDeseada00") != -1){
     tempDeseada = 00;
     val = 0;
     } else {
     Serial.println("peticion invalida");
     clienteDeServidor.stop();
     return;
}

// Ponemos el pin a 0 o a 1, dependiendo de lo recibido
calderaHabilitada = val;
clienteDeServidor.flush();

delay(10);




}
  Responder
#2
Entiendo que lo que pasa es que da fallo de lectura en temp / humi y esos valores se quedan a 0 jodiendolo todo, no?

Primeramente, salvo que necesites que se ejecute tan frecuentemente, en vez de delay(10);, pondría delay(2000); el bucle se ejecutaría cada 2segundos, y el micro respira un poco.

Por otra parte, el tiempo entre lecturas del DHT11 es de 2segundos minimo, dejas pasar 20, no debería haber problema ahí, sin embargo, lo que haría seria tener un bucle hasta que al menos una lectura fuese correcta (algo como esto https://github.com/conejoninja/home_food...#L607-L633 ) basicamente es un loop (while) en el que tomaremoshasta 5 muestras de temperatura diferente y haremos la media. Si alguna temperatura falla, no pasa nada, la siguiente posiblemente si la recoja bien.

podría ser algo tan sencillo como

Código:
float temp = 0;
while(true) {
    temp = dht.readTemperature();
    if(temp!=0) {
        break;
    }
    delay(2000);
}

Aunque depende de tu librería DHT y de lo que readTemperature devuelva si hay un fallo o no (aqui suponemos que si no lo lee devuelve 0).
  Responder
#3
Si no lo lee devuelve un 0, yo he montado un sistema con 12 sensores Dht y es lo que hace... al menos con la libreria que yo he usado. Tambien le consegui bajar la velocidad de lectura de 250ms a 20ms... esas librerias mantienen el arduino tonto 250ms o tiempos similares mientras leen, dependiendo del tipo de sensor, claro... utilizan esperas bloqueantes. Se lo reduje para perder el minimo tiempo y hacia lecturas en cada ciclo de un sensor diferente hasta completar los 12 y vuelta a empezar. Si alguien quiere la libreria modificada que la pida, funciona bien, lleva 1 año funcionamdo el sistema sin fallos.
Creo revordar que lo que use eran Dht22, pero viene a ser lo mismo.

Los 20 segundos los tiene configurados porque los muy majos de Thingspeak solo admiten una transmision de datos cada 15 segundos, si uno le envia con un periodo menor, te ignora completamente. A la tarde le echo yo tambien un ojo.
  Responder
#4
Nada, sigue funcionando igual............el tema es que cada vez que no me lee Tª y Hum el led se me desactiva, y claro, si fuera una relé conectado a una caldera estaría cada dos por tres encendiendo y apagando....

Entre éste problema y que a las horas se desconecta del wifi, los módulos ESP8266 me van a volver loco, jajaja...

Bueno, hoy me voy una semana fuera, así que dejaré todo en standby hasta que regrese, muchísimas gracias por vuestra ayuda...continuaré a mi vuelta, un saludo.
  Responder
#5
Hola buenas y saludos, ya por aquí de nuevo....

Pues el problema lo tengo aún, he probado modificar el HW/SW, cambiar librerías para el DHT22 y nada de nada....el tema es que si le cargo al nodemcu el sketch para que sólo me lea la temperatura y humedad, no me reporta ningún fallo.....pero si le cargo el sketch que estoy usando, para enviar datos a la nube, recibir datos y demás, el DHT22 me falla en la lectura de forma totalmente aleatoria, por lo que creo que será un tema de programación, quizás en cuanto a los "delays" que le he colocado, ya que mis conocimientos de programación son algo limitados (bastante)....

Para salvar el asunto lo que he hecho ha sido sustituir el error "NAN" que me reporta por 21 grados centigrados y de esta forma el relé sigue en HIGH aunque haya un error en la lectura, realmente me vale y funciona, así que el asunto está arreglado a medias, pero me quedo con la mosca de saber el por qué me reporta fallos de lectura con un sketch y con el otro no...


Saludos y gracias por la ayuda...
  Responder
#6
Hola, no se cuando has escrito el post, pero yo tenia el mismo problema, he visto que no has inicializado el sensor.
Usa dht.begin() dentro de setup y debería darte las lecturas correctas.
Un saludo a todos


(12-08-2017, 06:29 AM)jgarridc escribió: Hola a tod@s, saludos de nuevo.

Os comento, al final me he olvidado de los ESP01, que dan un montón de problemas de estabilidad, al menos es mi experiencia, y por muy poco más me he hecho con un Nodemcu V1.0 y el salto ha sido una auténtica maravilla, unha sencillez absoluta a la hora de cargar el IDE de arduino y una gran estabilidad, puesto que la electrónica que lleva integrada el circuito te elimina un montón de fallos que tenías que suplir al ESP01.
El problema que me ha surgido ahora es que el DHT11 (en breve pondré un DHT22) me hace una lectura de Tª y Humedad intermitente y con un patrón fijo, a thingspeak me envía lecturas intermitentes y claro, no es fiable el sistema puesto que es para hacer un termostato. He colocado en una de las patas un led (como si fuera un relé) para activar una caldera, y cada vez que el DHT11 no lee los datos, el led se apaga, pasan unos segundos y se vuelve a encender, y así en un bucle infinito. No es problema de HW puesto que he probado varios DHT11 y conectados a distintas patillas del Nodemcu, además la patilla de datos del DHT11 lo tengo con una resistencia pullup......
Probablemente sea un fallo de SW, pero no consigo averiguar cual es el fallo, así que os dejo el código a ver si alguien puede iluminar mi camino.....

El código me funciona, leo datos de Tª/Hum y los envío a thingspeak, con una app creada con appinvetor leo los datos de Tª/Hum, estado del relé y la temperatura que seleccionada....

Código:
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ThingSpeak.h> //librería conexión a thingspeak
#include<ESP8266WiFi.h> //librería esp8266
#include <DHT.h> //librería del módulo de temperatura y humedad
#include <Adafruit_Sensor.h>
#define DHTTYPE DHT11



const int releCaldera = 14;
const int DHTpin = 12;
float histeresis = 1;
static unsigned long last_loop;
unsigned long int anteriorRefreshDatos = 0;
float temp= 0;
float humi= 0;
float tempDeseada = 00;
int calderaHabilitada;
int estadoRele = 0;

DHT dht(DHTpin, DHTTYPE);


IPAddress ip(192, 168, 1, 10);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

String apiKey = "XXXXXXXXXXXXXXXXXX";
const char* ssid = "XXXXXXXXXXXXX";
const char* password = "XXXXXXXXXXXXX*";
const char* server = "api.thingspeak.com";
unsigned long myChannelNumber = XXXXXXXXXXXXXXX;
const char * myWriteAPIKey = "XXXXXXXXXXXX";

WiFiClient client;
WiFiServer servidor(80);

void setup() {
//Relé de la caldera
pinMode(releCaldera, OUTPUT);
digitalWrite(releCaldera, LOW);

//Iniciamos puerto serie
Serial.begin(9600);

delay(5);




//Iniciamos el modulo wifi
WiFi.begin(ssid, password);
Serial.println();
Serial.println();
Serial.print("Connectandose a ");
Serial.println(ssid);
WiFi.begin(ssid, password);

// Static IP Setup Info Here...
WiFi.config(ip, gateway, subnet);
WiFi.mode(WIFI_STA);

while( WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connectado");

ThingSpeak.begin(client);
Serial.println("Cliente thingspeak iniciado");
servidor.begin();
Serial.print("Servidor iniciado, IP: ");
Serial.println(WiFi.localIP());

}

void refreshDatos(){

if (millis() > anteriorRefreshDatos + 20000){
anteriorRefreshDatos = millis();

float temp = dht.readTemperature();
float humi = dht.readHumidity();


    if (calderaHabilitada = 1){
    if (temp + histeresis >= tempDeseada && temp > 0)  digitalWrite(releCaldera, LOW);
   
    else if (temp < tempDeseada && temp > 0) digitalWrite(releCaldera, HIGH);
   
    else digitalWrite(releCaldera, LOW);
        }

           
   
     
Serial.println("Leyendo datos....");
Serial.println();
 
Serial.print("Temperatura deseada: ");
Serial.println(tempDeseada);

Serial.print("Temperatura: ");
Serial.println(temp);
Serial.print("Humedad: ");
Serial.println(humi);

     int estadoRele = digitalRead(releCaldera);
     if (estadoRele == LOW)
       {
       Serial.print("Estado relé caldera: ");  
       Serial.println("LOW");
       } else {
       Serial.print("Estado relé caldera: ");  
       Serial.println("HIGH");
        }


ThingSpeak.setField(1, temp);
ThingSpeak.setField(2, humi);
ThingSpeak.setField(3, estadoRele);
ThingSpeak.setField(4, tempDeseada);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

Serial.println("Enviando datos...");
Serial.println();
}
}

void loop() {
//Lectura del sensor de temperatura
refreshDatos();

//Codigo servidor

WiFiClient clienteDeServidor = servidor.available();
if (!clienteDeServidor) { //Si no se ha conectado nadie, saltamos al inicio del codigo
return;
}
Serial.println("Nuevo cliente conectado");
while(!clienteDeServidor.available()){
//Esperamos hasta que el cliente haya solicitado o enviado datos
delay(1);

//De paso que estamos esperando al cliente... pues comprobamos  si hemos de actualizar la temperatura.
refreshDatos();
}

// Read the first line of the request
String req = clienteDeServidor.readStringUntil('\r');
Serial.println(req);
clienteDeServidor.flush();

// Match the request

   int val;

     if (req.indexOf("/tempDeseada45") != -1){
     tempDeseada = 45;
     val = 1;
     } else if (req.indexOf("/tempDeseada46") != -1){
     tempDeseada = 46;
     val = 1;
     } else if (req.indexOf("/tempDeseada47") != -1){
     tempDeseada = 47;
     val = 1;
     } else if (req.indexOf("/tempDeseada48") != -1){
     tempDeseada = 48;
     val = 1;
     } else if (req.indexOf("/tempDeseada49") != -1){
     tempDeseada = 49;
     val = 1;
     } else if (req.indexOf("/tempDeseada50") != -1){
     tempDeseada = 50;
     val = 1;
     } else if (req.indexOf("/tempDeseada00") != -1){
     tempDeseada = 00;
     val = 0;
     } else {
     Serial.println("peticion invalida");
     clienteDeServidor.stop();
     return;
}

// Ponemos el pin a 0 o a 1, dependiendo de lo recibido
calderaHabilitada = val;
clienteDeServidor.flush();

delay(10);




}
  Responder
#7
Buenas noches
Estoy revisando tu código y encuentro varias cosas que me llaman la atención, y creo que no están bien, te cuento.
La línea 15 te sobra
En la línea 25 del código pones
Código:
DHT dht(DHTpin, DHTTYPE);
La línea correcta seria
Código:
DHT dht(12, DHT11);
Si utilizas esta línea
Código:
int intervaloMedidas = 1000;
// Hace que solo se lean los valores de los dht11, 1 vez por segundo
Si ya utiliza millis, no uses delay(), son incompatibles y el Arduino se lía y no hace las cosas como debe
 
Como ya te han dicho, no has iniciado el sensor en el
Código:
void setup()
dht.begin();
En el
void loop ()
Hay unas líneas que normalmente se pasan por alto, pero que son muy importantes para saber el estado de los sensores, y comprobar que funcionan bien
Código:
// Comprueba si hay algún fallo de lectura del sensor DHT, (si lo hay inicia de nuevo el programa)
if (isnan(h) || isnan(t)) {
Serial.println ("Fallo de lectura desde el sensor DHT!");
return;
}
Código:
if ( millis() - auxMillis > intervaloMedidas)
// Indica el valor de intervalo entre toma de datos del sensor

Si haces esto, veras como mejoran las lecturas de los sensores

FELICES PASCUAS A TODOS.
  Responder


Posibles temas similares…
Tema Autor Respuestas Vistas Último mensaje
  Frecuencia máxima de lectura de entradas digitales o rebotes? Bear 0 229 26-03-2022, 10:18 AM
Último mensaje: Bear
  CONSULTA ERROR DHT11 Nem0_10 2 1,266 18-11-2020, 09:55 PM
Último mensaje: asesorplaza1
  Lectura nivel combustible con Arduino silth 3 1,493 25-09-2020, 02:03 PM
Último mensaje: silth
  ARDUINO TERMOMETRO DHT11 TM1637 pascual 3 1,692 24-07-2019, 09:47 PM
Último mensaje: Lepes
  Termómetro e Higrómetro con Arduino, DHT11 y LCD 16×2 malopezn 2 2,689 23-11-2015, 10:13 PM
Último mensaje: vcode