homie-esp8266: DHT22 read failure

Hi all, I’m trying to explore the “world of Homie” but I’ve a strange issue using DHT22 sensor. If I read temperature value during loop function, with interval set to 300 seconds, it’s ok. Instead if I’m trying to read temperature after a received MQTT message, using a settable property and associated handler, it fails always. Here is the sketch I’m using:

#include <Homie.h>
#include <DHT.h>

#define DHTPIN 4     // GPIO4  pin 2  of ESP8266`
#define DHTTYPE DHT22   // DHT 22  (AM2302)`
const int TEMPERATURE_INTERVAL = 300;
unsigned long lastTemperatureSent = 0;

HomieNode temperatureNode("temperature", "temperature");

DHT dht(DHTPIN, DHTTYPE);

void setupHandler() {
  Homie.setNodeProperty(temperatureNode, "unit").send("c");
}

float readTemp(){
    float t = dht.readTemperature();
    if (isnan(t)) {
          Serial.println("Failed to read temperature from DHT sensor!");
          return t;
    }
    Serial.print("Read Temperature: ");
    Serial.print(t);
    Serial.println(" °C");
    return t;
}

void getSendTemp() {
  if (millis() - lastTemperatureSent >= TEMPERATURE_INTERVAL * 1000UL || lastTemperatureSent == 0) {
    float t = readTemp();
    if (isnan(t)) {
          Serial.println("Failed getSendTemp!");
          return;
    }
    Homie.setNodeProperty(temperatureNode, "degrees").send(String(t));
    lastTemperatureSent = millis();
  }
}

bool tempReadHandler(HomieRange range, String value) {
  if (value == "true") {
      float t = readTemp();
      if (isnan(t)) {
          Serial.println("Failed ReadTemp!");
          return true;
      }
      Homie.setNodeProperty(temperatureNode, "read").send("true");
      Serial.print("Send Temperature: ");
      Serial.print(t);
      Serial.println(" °C");
      Homie.setNodeProperty(temperatureNode, "degrees").send(String(t));
      return true;
  } else {
      return false;
  }
}

void loopHandler() {
  getSendTemp();
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  dht.begin();

  Homie_setFirmware("my-dht22", "1.0.0");

  temperatureNode.advertise("read").settable(tempReadHandler);
  temperatureNode.advertise("unit");
  temperatureNode.advertise("degrees");

  Homie.setSetupFunction(setupHandler).setLoopFunction(loopHandler);

  Homie.setup();
}

void loop() {
  Homie.loop();
}

For example if i send a message with mosquitto_pub -t 'devices/012092e1/temperature/read/set' -m true

the output is

Calling global input handler...
Calling node input handler...
Calling property input handler...
Failed to read temperature from DHT sensor!

during the loopHandler the output is Read Temperature: 25.60 °C

Thank you

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 21 (6 by maintainers)

Most upvoted comments

There is a piece of code:

boolean DHT::read(bool force) {
  // Check if sensor was read less than two seconds ago and return early
  // to use last reading.
  uint32_t currenttime = millis();
  if (!force && ((currenttime - _lastreadtime) < 2000)) {
    return _lastresult; // return last correct measurement
  }
  _lastreadtime = currenttime;

  // Reset 40 bits of received data to zero.
  data[0] = data[1] = data[2] = data[3] = data[4] = 0;

  // Send start signal.  See DHT datasheet for full signal diagram:
  //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf

  // Go into high impedence state to let pull-up raise data line level and
  // start the reading process.
  digitalWrite(_pin, HIGH);
  delay(250); // <-- LOOK HERE

  // First set data line low for 20 milliseconds.
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delay(20); // <-- LOOK HERE

which explicit calls delay function. Have a look at the exp8266/Arduino project documentation note about delays: link