Problemas de medición

Cordial saludos,

tengo el presente codigo:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include <EEPROM.h>

// DHT22 Configuration
#define DHTPIN 18    // Pin donde esta conectador el sensor
#define DHTTYPE DHT22 // Especificacion del sensor DHT22
DHT dht(DHTPIN, DHTTYPE); // Inicializamos el sensor DHT

// OLED configuracion de pantalla
#define SCREEN_WIDTH 128 // OLED pantalla ancho, in pixeles
#define SCREEN_HEIGHT 64 // OLED pantalla alto, en pixeles
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Coeficiente de calibración
float m_temperatura = 1, b_temperatura = 0;
float m_humedadR = 1, b_humedadR = 0;

// EEPROM
int agg_m_temperatura = 0;
int agg_b_temperatura = agg_m_temperatura + sizeof(float);
int agg_m_humedadR = agg_b_temperatura + sizeof(float);
int agg_b_humedadR = agg_m_humedadR + sizeof(float);

// Variables de comunicación serial
String inputLine = "";
bool newDataAvailable = false;

// Calculamos la pendiente m y ordenada al origen b
/*void calcularRegresion (float x[], float y[], int n, float &m, float &b){
  float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0;

  for (int i = 0; i < n; i++){
    sum_x += x[i];
    sum_y += y[i];
    sum_xy += x[i] * y[i];
    sum_x2 += x[i] * x[i];
  }
  // Calculamos la pendiente de (m)
  m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x);
  b = (sum_y - m * sum_x) / n;
}*/

// Guardamos el coeficiente de calibración
void guardarCalibracionEEPROM(){
  EEPROM.put(agg_m_temperatura, m_temperatura);
  EEPROM.put(agg_b_temperatura, b_temperatura);
  EEPROM.put(agg_m_humedadR, m_humedadR);
  EEPROM.put(agg_b_humedadR, b_humedadR);
  EEPROM.commit();
}

// Cargamos los coeficientes de la calibración
void cargarCalibracionEEPROM(){
  EEPROM.get(agg_m_temperatura, m_temperatura);
  EEPROM.get(agg_b_temperatura, b_temperatura);
  EEPROM.get(agg_m_humedadR, m_humedadR);
  EEPROM.get(agg_b_humedadR, b_humedadR);
}

void procesarComando(String cmd){
  cmd.trim();
  Serial.print("Recibido: "); 
  Serial.println(cmd);

  if (cmd.startsWith("MT:")) {
    m_temperatura = cmd.substring(3).toFloat();
    Serial.print("m_temperatura cargado: ");
    Serial.println(m_temperatura, 6);
  }
  else if (cmd.startsWith("BT:")) {
    b_temperatura = cmd.substring(3).toFloat();
    Serial.print("b_temperatura cargado: ");
    Serial.println(b_temperatura, 6);
  }
  else if (cmd.startsWith("MH:")) {
    m_humedadR = cmd.substring(3).toFloat();
    Serial.print("m_humedad cargado: ");
    Serial.println(m_humedadR, 6);
  }
  else if (cmd.startsWith("BH:")) {
    b_humedadR = cmd.substring(3).toFloat();
    Serial.print("b_humedad cargado: ");
    Serial.println(b_humedadR, 6);
  }
  else if (cmd == "GUARDAR") {
    guardarCalibracionEEPROM();
    Serial.println("TODOS los coeficientes fueron guardados en EEPROM.");
  }
  else if (cmd == "RESET") {
    m_temperatura = 1.0; b_temperatura = 0.0;
    m_humedadR = 1.0; b_humedadR = 0.0;
    guardarCalibracionEEPROM();
    Serial.println("Calibración reseteada a valores por defecto.");
  }
  else {
    Serial.println("Comando no reconocido.");
  }
}

void leerSerial() {
  while(Serial.available()){
    char c = Serial.read();
    if (c == '\n' || c == '\r'){
      if(inputLine.length() > 0){
        newDataAvailable = true;
      }
    } else {
      inputLine += c;
    }
  }

    if(newDataAvailable){
      procesarComando(inputLine);
      inputLine = "";
      newDataAvailable = false;
  }
}

void setup() {
  // Inicializamos el monitor serial, preferencia y sensor DHT22
  Serial.begin(115200);
  dht.begin(512);
  delay(2000);
  EEPROM.begin(512);
  
  // Inicializamos la pantalla 
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
  }
 
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);

  //Solo la primera vez que cargues el codigo
  //calcularRegresion(x_temperatura, y_temperatura, m_temperatura, b_temperatura);
  //calcularRegresion(x_humedadR, y_humedadR, m_humedadR, b_humedadR);
  //guardarCalibracionEEPROM();

  // Luego de grabar, se puede comentar las 3 lineas anteriores y descomentar esta
  cargarCalibracionEEPROM();
}

void loop() {
  leerSerial();  // Escucha comandos por Serial (no se toca)

  static unsigned long lastTime = 0;
  if (millis() - lastTime > 4000) {  // Espera 4 segundos entre lecturas
    lastTime = millis();

    float temperatura = dht.readTemperature();
    float humedad = dht.readHumidity();

    if (isnan(humedad) || isnan(temperatura)) {
      Serial.println(F("Advertencia: Fallo temporal al leer el sensor DHT22."));
      return;  // Saltamos actualización de pantalla esta vez
    }

    float temperatura_calibrada = m_temperatura * temperatura + b_temperatura;
    float humedad_calibrada = m_humedadR * humedad + b_humedadR;

    // Muestra por Serial
    Serial.print("Temperatura calibrada: ");
    Serial.println(temperatura_calibrada, 2);
    Serial.print("Humedad calibrada: ");
    Serial.println(humedad_calibrada, 2);

    // Muestra en pantalla OLED
    display.clearDisplay();

    display.setTextSize(1);
    display.setCursor(0, 7);
    display.print("Temperatura: ");
    display.setTextSize(2);
    display.setCursor(0, 16);
    display.print(temperatura_calibrada, 1);
    display.print(" ");
    display.setTextSize(1);
    display.cp437(true);  // Simbolo °
    display.write(167);
    display.setTextSize(2);
    display.print("C");

    display.setTextSize(1);
    display.setCursor(0, 37);
    display.print("Humedad: ");
    display.setTextSize(2);
    display.setCursor(0, 50);
    display.print(humedad_calibrada, 1);
    display.print(" %");

    display.display();
  }
}

La impresión que me sale es nan para temperatura y humedad. Yo desde una app en java mando el coeficiente porque hago el calculo en la app de java y solo lo mando para guardarlo en el EEPROM y luego poderlo ejecutar, pero ese error no entiendo a que se debe, ensayo un codigo basico normal para lectura de temp y hum y funciona normal.

1 Like
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include <EEPROM.h>

// DHT22 Configuration
#define DHTPIN 18    // Pin donde esta conectador el sensor
#define DHTTYPE DHT22 // Especificacion del sensor DHT22
DHT dht(DHTPIN, DHTTYPE); // Inicializamos el sensor DHT

// OLED configuracion de pantalla
#define SCREEN_WIDTH 128 // OLED pantalla ancho, in pixeles
#define SCREEN_HEIGHT 64 // OLED pantalla alto, en pixeles
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Coeficiente de calibración
float m_temperatura = 1, b_temperatura = 0;
float m_humedadR = 1, b_humedadR = 0;

// EEPROM
int agg_m_temperatura = 0;
int agg_b_temperatura = agg_m_temperatura + sizeof(float);
int agg_m_humedadR = agg_b_temperatura + sizeof(float);
int agg_b_humedadR = agg_m_humedadR + sizeof(float);

// Variables de comunicación serial
String inputLine = "";
bool newDataAvailable = false;

// Calculamos la pendiente m y ordenada al origen b
/*void calcularRegresion (float x[], float y[], int n, float &m, float &b){
  float sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0;

  for (int i = 0; i < n; i++){
    sum_x += x[i];
    sum_y += y[i];
    sum_xy += x[i] * y[i];
    sum_x2 += x[i] * x[i];
  }
  // Calculamos la pendiente de (m)
  m = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x);
  b = (sum_y - m * sum_x) / n;
}*/

// Guardamos el coeficiente de calibración
void guardarCalibracionEEPROM(){
  EEPROM.put(agg_m_temperatura, m_temperatura);
  EEPROM.put(agg_b_temperatura, b_temperatura);
  EEPROM.put(agg_m_humedadR, m_humedadR);
  EEPROM.put(agg_b_humedadR, b_humedadR);
  EEPROM.commit();
}

// Cargamos los coeficientes de la calibración
void cargarCalibracionEEPROM(){
  EEPROM.get(agg_m_temperatura, m_temperatura);
  EEPROM.get(agg_b_temperatura, b_temperatura);
  EEPROM.get(agg_m_humedadR, m_humedadR);
  EEPROM.get(agg_b_humedadR, b_humedadR);
}

void procesarComando(String cmd){
  cmd.trim();
  Serial.print("Recibido: "); 
  Serial.println(cmd);

  if (cmd.startsWith("MT:")) {
    m_temperatura = cmd.substring(3).toFloat();
    Serial.print("m_temperatura cargado: ");
    Serial.println(m_temperatura, 6);
  }
  else if (cmd.startsWith("BT:")) {
    b_temperatura = cmd.substring(3).toFloat();
    Serial.print("b_temperatura cargado: ");
    Serial.println(b_temperatura, 6);
  }
  else if (cmd.startsWith("MH:")) {
    m_humedadR = cmd.substring(3).toFloat();
    Serial.print("m_humedad cargado: ");
    Serial.println(m_humedadR, 6);
  }
  else if (cmd.startsWith("BH:")) {
    b_humedadR = cmd.substring(3).toFloat();
    Serial.print("b_humedad cargado: ");
    Serial.println(b_humedadR, 6);
  }
  else if (cmd == "GUARDAR") {
    guardarCalibracionEEPROM();
    Serial.println("TODOS los coeficientes fueron guardados en EEPROM.");
  }
  else if (cmd == "RESET") {
    m_temperatura = 1.0; b_temperatura = 0.0;
    m_humedadR = 1.0; b_humedadR = 0.0;
    guardarCalibracionEEPROM();
    Serial.println("Calibración reseteada a valores por defecto.");
  }
  else {
    Serial.println("Comando no reconocido.");
  }
}

void leerSerial() {
  while(Serial.available()){
    char c = Serial.read();
    if (c == '\n' || c == '\r'){
      if(inputLine.length() > 0){
        newDataAvailable = true;
      }
    } else {
      inputLine += c;
    }
  }

    if(newDataAvailable){
      procesarComando(inputLine);
      inputLine = "";
      newDataAvailable = false;
  }
}

void setup() {
  // Inicializamos el monitor serial, preferencia y sensor DHT22
  Serial.begin(115200);
  dht.begin(512);
  delay(2000);
  EEPROM.begin(512);
  
  // Inicializamos la pantalla 
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
  }
 
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);

  //Solo la primera vez que cargues el codigo
  //calcularRegresion(x_temperatura, y_temperatura, m_temperatura, b_temperatura);
  //calcularRegresion(x_humedadR, y_humedadR, m_humedadR, b_humedadR);
  //guardarCalibracionEEPROM();

  // Luego de grabar, se puede comentar las 3 lineas anteriores y descomentar esta
  cargarCalibracionEEPROM();
}

void loop() {
  leerSerial();  // Escucha comandos por Serial (no se toca)

  static unsigned long lastTime = 0;
  if (millis() - lastTime > 4000) {  // Espera 4 segundos entre lecturas
    lastTime = millis();

    float temperatura = dht.readTemperature();
    float humedad = dht.readHumidity();

    if (isnan(humedad) || isnan(temperatura)) {
      Serial.println(F("Advertencia: Fallo temporal al leer el sensor DHT22."));
      return;  // Saltamos actualización de pantalla esta vez
    }

    float temperatura_calibrada = m_temperatura * temperatura + b_temperatura;
    float humedad_calibrada = m_humedadR * humedad + b_humedadR;

    // Muestra por Serial
    Serial.print("Temperatura calibrada: ");
    Serial.println(temperatura_calibrada, 2);
    Serial.print("Humedad calibrada: ");
    Serial.println(humedad_calibrada, 2);

    // Muestra en pantalla OLED
    display.clearDisplay();

    display.setTextSize(1);
    display.setCursor(0, 7);
    display.print("Temperatura: ");
    display.setTextSize(2);
    display.setCursor(0, 16);
    display.print(temperatura_calibrada, 1);
    display.print(" ");
    display.setTextSize(1);
    display.cp437(true);  // Simbolo °
    display.write(167);
    display.setTextSize(2);
    display.print("C");

    display.setTextSize(1);
    display.setCursor(0, 37);
    display.print("Humedad: ");
    display.setTextSize(2);
    display.setCursor(0, 50);
    display.print(humedad_calibrada, 1);
    display.print(" %");

    display.display();
  }
}

¿Está seguro de que todo funciona bien? ¿Ha comprobado la correcta recepción de los datos y su almacenamiento en la EEPROM?

(He corregido las etiquetas de código en su primer mensaje.)

No el error ya lo evidencie, y está en el almacenamiento EEPROOM, efectivamente no me está guardando la información cuando la envío, asi sea desde el monitor serial por eso el error.

Hi,
El sensor necesita un delay de 800 a 1000 milisegundo de lectura a lecttura y si no lo haces vaz a sebre escriir el sensor y te manda el error NAN.. Has probado con un ejemplo para ver si el sensor esta bien.