Problema con sensor de temperatura Dht11

buenas, quería saber si podrían ayudarme con lo que creo yo es un fallo con el sensor dht1 o una mala lectura, el problema esta en las lecturas que recibo del sensor, lecturas así: 2.30, 1.30, 2.20. Y no es realmente la temperatura que debería marcar.
Me gustaría subir el código, pero no me deja.


// infinite Xpro
#include <LiquidCrystal_I2C.h> // Librería para control de LCD I2C
#include <DHT.h>             // Librería para el sensor DHT
#include <DHT_U.h>           // Librería adicional para el sensor DHT (utilizada por DHT.h)

// Configuración de la pantalla LCD I2C: dirección (0x27), 16 columnas, 2 filas
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Definición de un carácter personalizado para el símbolo de grado (°)
byte degree_symbol[8] =
{
  0b00111,
  0b00101,
  0b00111,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

// Pines y variables para el sensor DHT
#define Type DHT11      // Define el tipo de sensor DHT que estás usando (DHT11 o DHT22)
int dhtPin = 4;         // Pin digital donde está conectado el sensor DHT
DHT dht(dhtPin, Type); // Crea un objeto DHT

int humidity;           // Variable para almacenar la humedad
float tempC;            // Variable para almacenar la temperatura en Celsius
float tempF;            // Variable para almacenar la temperatura en Fahrenheit (no usada en la visualización actual)

// Variables para la lectura de la señal personalizada
int gate = 11;                   // Pin digital para la señal personalizada
volatile unsigned long duration = 0; // Almacena la duración de los pulsos
unsigned char i[5];              // Array para almacenar bytes decodificados
unsigned int j[40];              // Array para almacenar los bits individuales (para depuración)
unsigned char value = 0;         // Valor del bit (0 o 1)
unsigned answer = 0;             // Suma de los primeros 4 bytes decodificados para verificación
int z = 0;                       // Contador de bits

void setup()
{
  Serial.begin(9600); // Inicia la comunicación serial a 9600 baudios (¡Debe coincidir con Python!)
  dht.begin();        // Inicia el sensor DHT

  lcd.init();         // Inicializa la pantalla LCD
  lcd.backlight();    // Enciende la luz de fondo de la LCD

  // Crea el carácter personalizado para el símbolo de grado en la posición 1
  lcd.createChar(1, degree_symbol);

  // Muestra texto estático inicial en la LCD
  lcd.setCursor(0, 0);
  lcd.print("Temp = ");
  lcd.setCursor(0, 1);
  lcd.print("Humedad = ");

  // Realiza una lectura inicial del DHT y actualiza la LCD
  updateDHTDisplay();
}

void loop()
{
  // --- Lógica para la lectura del sensor DHT y envío a Python ---
  updateDHTDisplay(); // Lee DHT y actualiza la LCD con Temp y Humedad
  // Envía la temperatura Celsius al puerto serial para que el script de Python la lea
  Serial.println(tempC);

  // --- Lógica para la lectura de la señal personalizada (ahora integrada en el loop principal) ---
  // Configura el pin GATE como salida, lo pone en LOW, espera, luego en HIGH
  pinMode(gate, OUTPUT);
  digitalWrite(gate, LOW);
  delay(20);
  digitalWrite(gate, HIGH);

  // Cambia el pin GATE a entrada con pull-up interno para leer la señal
  pinMode(gate, INPUT_PULLUP);

  // Lee la duración de un pulso LOW en el pin GATE (puede bloquear si no hay señal)
  duration = pulseIn(gate, LOW);

  // Si la duración está dentro de un rango esperado (señal de inicio)
  if (duration <= 84 && duration >= 72)
  {
    // Reinicia el contador de bits y el array 'i' para la nueva lectura de la señal
    z = 0;
    i[0] = i[1] = i[2] = i[3] = i[4] = 0;

    // Bucle para leer los 40 bits de la señal
    // Se limita a 40 iteraciones para evitar un bucle infinito si la señal es corrupta
    for (int bitCount = 0; bitCount < 40; bitCount++)
    {
      duration = pulseIn(gate, HIGH); // Lee la duración de un pulso HIGH (puede bloquear)

      // Decodifica el bit basado en la duración del pulso
      if (duration <= 26 && duration >= 20)
      {
        value = 0; // Pulso corto = 0
      }
      else if (duration <= 74 && duration >= 65)
      {
        value = 1; // Pulso largo = 1
      }
      else
      {
        // Si la duración no coincide con 0 o 1, la señal es inválida o termina prematuramente
        // Salir del bucle de bits y manejar como error de checksum
        z = 40; // Forzar salida y fallo de checksum
        break;
      }

      // Almacena el bit decodificado en el array 'i' (bytes) y 'j' (bits individuales)
      i[z / 8] |= value << (7 - (z % 8)); // Almacena el bit en el byte correcto y posición
      j[z] = value;                      // Almacena el bit individual (para depuración si se necesita)
      z++;                               // Incrementa el contador de bits
    }

    // Si se leyeron los 40 bits
    if (z == 40) {
      // Calcula la suma de los primeros 4 bytes
      answer = i[0] + i[1] + i[2] + i[3];

      // Si la suma de los primeros 4 bytes es igual al quinto byte (checksum) y no es cero
      if (answer == i[4] && answer != 0)
      {
        // Muestra el valor de i[2] en la posición de temperatura (señal personalizada)
        lcd.setCursor(7, 0); // Después de "Temp = "
        lcd.print(i[2]);
        lcd.print("   "); // Limpia dígitos anteriores si el número es más corto

        // Muestra el valor de i[0] en la posición de humedad (señal personalizada)
        lcd.setCursor(11, 1); // Después de "Humidity = " y los dígitos de humedad del DHT
        lcd.print(i[0]);
        lcd.print("   "); // Limpia dígitos anteriores
      } else {
        // Si el checksum falla, indicar error en la lectura de la señal
        lcd.setCursor(7, 0);
        lcd.print("Err "); // Indicar error en la lectura de la señal
        lcd.setCursor(11, 1);
        lcd.print("Err ");
      }
    } else {
      // Si no se leyeron 40 bits (señal incompleta o corrupta)
      lcd.setCursor(7, 0);
      lcd.print("Inv "); // Indicar señal inválida
      lcd.setCursor(11, 1);
      lcd.print("Inv ");
    }
  } else {
    // Si la señal de inicio no es válida, limpiar los campos de la señal personalizada
    lcd.setCursor(7, 0);
    lcd.print("--- "); // Limpiar si no hay señal
    lcd.setCursor(11, 1);
    lcd.print("--- ");
  }

  // Pequeño retraso para evitar sobrecargar el puerto serial y para la estabilidad general del loop
  delay(70);
}

// Función para actualizar la visualización de temperatura y humedad
void updateDHTDisplay() {
  humidity = dht.readHumidity();    // Lee la humedad
  tempC = dht.readTemperature()*12;    // Lee la temperatura en Celsius

  // Verifica si las lecturas fallaron
  if (isnan(humidity) || isnan(tempC)) {
    Serial.println(F("¡Error al leer del sensor DHT!"));
    lcd.setCursor(7, 0);
    lcd.print("ERROR!"); // Muestra error en la LCD
    lcd.setCursor(10, 1);
    lcd.print("ERROR!");
    tempC = 0.0; // Establece un valor por defecto o de error para tempC si la lectura falla
  } else {
    // Si las lecturas son exitosas, las muestra en la LCD
    lcd.setCursor(7, 0); // Después de "Temp = "
    lcd.print(tempC, 1); // Muestra la temperatura con un decimal
    lcd.write(1);        // Muestra el símbolo de grado
    lcd.print("C   ");   // Muestra 'C' y espacios para borrar dígitos anteriores

    lcd.setCursor(10, 1); // Después de "Humidity = "
    lcd.print(humidity);
    lcd.print("%   ");    // Muestra '%' y espacios para borrar dígitos anteriores
  }
}

Muestre su diagrama de cableado con todos los pines etiquetados y la fuente de alimentación. Además, muestre el código que está usando pegado dentro de un bloque de código.

1 Like

He trasladado su tema de una categoría de idioma inglés del foro a la categoría International > Español @juandm.

En adelante por favor usar la categoría apropiada a la lengua en que queráis publicar. Esto es importante para el uso responsable del foro, y esta explicado aquí la guía "How to get the best out of this forum".
Este guía contiene mucha información útil. Por favor leer.

De antemano, muchas gracias por cooperar.

asi esta bien?

Si.


Tu código funciona. Verifique su cableado.

A disculpa compa, pero en el lector de temperatura hay un ×12
tempC = dht.readTemperature()*12;

Ese código parece demasiado complicado. Este boceto puede probar el DHT11 solo sin volver a cablear. ¿Ves cómo se lee "c" sin ningún cálculo?

#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
}

void loop() {
  delay(2000);

  float h = dht.readHumidity();
  float c = dht.readTemperature();

  if (isnan(h) || isnan(c)) {
    Serial.println(F("DHT read fail."));
    while (1) {} // halt
    // return;
  }

  Serial.print(F("H: "));
  Serial.print(h);
  Serial.print(F("%  T: "));
  Serial.print(c);
  Serial.print(F("°C "));
  Serial.println();
}

Pasa que en ese, esta el de la pantalla y el lector, pero sigue dandome el mismo error

El código en la publicación # 8 usa el DHT y el monitor serie. ¿Mostrar lo que ves con el código de la publicación #8?

Hola @juandm

Has probado poner una resistencia (5k/10 k)entre DATOS y (+) ???.

Es una recomendación usual


asi es como lo tengo cableado fisicamente

Tenés que poner una resistencia pull-up (o sea entre el pin de salida del módulo y 5V) de 5.1KΩ como indica la hoja de datos del DHT11 y lo dijo @ENGRAL.

Mala mía, el módulo ya trae la resistencia. :man_facepalming:

Consigue otro módulo porque parece que ese salió malo.

Agrego:

No se ve bien en la foto o conectaste los 5V en cualquier lado?

Yo veo los 5V (cable azul) conectados a una pista que no es la de alimentación (o sea donde están el gris y el marrón).

No está mal conectar la alimentación en otra pista siempre y cuando todo lo que haya que alimentar se conecte a ese misma pista.

2 Likes

Hola @MaximoEsfuerzo y @juandm

El modulo con PCB es este, y como dice @MaximoEsfuerzo , ya incorpora la resistencia. Comprueba las conexiones.

Prueba resultados en el monitor antes de utilizar el LCD