MQ DHT and Relai receive not working

  • Hello,

    ich habe Probleme beim empfangen von Events bei meinem Sensor.
    Mein Sensor läuft ganz gut (MQ und DHT) nur das schalten eines Relais funktioniert nicht da, void receive nicht richtig ausgeführt wird. Wenn ich aber sleep entferne, bekomme ich keine Daten mehr von dem dht da der UPDATE_INTERVAL nicht zu hoch sein darf. Wenn ich den sleep entferne reagiert das relai. Wenn nicht dann nicht. Was kann ich machen damit ich auch Daten empfangen kann?

    i have a problem by revice events from my sensor.
    my sensor work well (MQ and DHT) but the trigger of a relai does not working. I think that the void receive will not be performed. If i remove the sleep command i receive no data from my dht sensor because the UPDATE_INTERVAL ist to hight for the dht but the trigger of my relai ist working. if i set the sleep command the receive is not working. What can i do the the receiveing ist working?

      Arduino MQ135
      connect the sensor as follows :
      A H A   >>> 5V
      B       >>> A0
      H       >>> GND
      B       >>> 10K ohm >>> GND
      Contribution: epierre
      Based on David Gironi
    // Enable debug prints
    #define MY_DEBUG
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_NODE_ID 4
    #include <MySensors.h>
    #include <Wire.h> 
    #include <SPI.h>
    #include <DHT.h>
    // RELAY
    #define RELAY_1 4           // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1  // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    // DHT
    #define DHT_DATA_PIN 3
    #define SENSOR_TEMP_OFFSET 0
    static const uint64_t UPDATE_INTERVAL = 60000;
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    #define CHILD_ID_HUM 2
    #define CHILD_ID_TEMP 3
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true;
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    DHT dht;
    // MQ
    #define CHILD_ID_AIQ 4
    #define MQ135_DEFAULTPPM 399 //default ppm of CO2 for calibration
    #define MQ135_DEFAULTRO 68550 //default Ro for MQ135_DEFAULTPPM ppm of CO2
    #define MQ135_SCALINGFACTOR 116.6020682 //CO2 gas value
    #define MQ135_EXPONENT -2.769034857 //CO2 gas value
    #define MQ135_MAXRSRO 2.428 //for CO2
    #define MQ135_MINRSRO 0.358 //for CO2
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in seconds)
    float mq135_ro = 10000.0;    // this has to be tuned 10K Ohm
    int val = 0;                 // variable to store the value coming from the sensor
    float valAIQ =0.0;
    float lastAIQ =0.0;
    MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
    void before()
        for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            // Set relay to last known state (using eeprom storage)
            digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
    void setup()  
      dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
      if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
        Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
      // Sleep for the time of the minimum sampling period to give the sensor time to power up
      // (otherwise, timeout errors might occure for the first reading)
    void presentation()
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("MQ DHT LED Switch", "1.0");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_AIQ, S_AIR_QUALITY);  
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      metric = getControllerConfig().isMetric;
      // RELAI
      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
     * get the calibrated ro based upon read resistance, and a know ppm
    long mq135_getro(long resvalue, double ppm) {
    return (long)(resvalue * exp( log(MQ135_SCALINGFACTOR/ppm) / MQ135_EXPONENT ));
     * get the ppm concentration
    double mq135_getppm(long resvalue, long ro) {
    double ret = 0;
    double validinterval = 0;
    validinterval = resvalue/(double)ro;
    if(validinterval<MQ135_MAXRSRO && validinterval>MQ135_MINRSRO) {
    ret = (double)MQ135_SCALINGFACTOR * pow( ((double)resvalue/ro), MQ135_EXPONENT);
    return ret;
    void loop()      
      // MQ    
      uint16_t valr = analogRead(AIQ_SENSOR_ANALOG_PIN);// Get AIQ value
      uint16_t val =  ((float)22000*(1023-valr)/valr); 
      //during clean air calibration, read the Ro value and replace MQ135_DEFAULTRO value with it, you can even deactivate following function call.
      mq135_ro = mq135_getro(val, MQ135_DEFAULTPPM);
      //convert to ppm (using default ro)
      valAIQ = mq135_getppm(val, MQ135_DEFAULTRO);
      Serial.print ( "Val / Ro / value:");
      Serial.print ( val);
      Serial.print ( " / ");
      Serial.print ( mq135_ro);
      Serial.print ( " / ");
      Serial.print ( valAIQ);
      if (valAIQ != lastAIQ) {
        //  gw.send(msg.set(MQ135_DEFAULTPPM+(int)ceil(valAIQ)));
          lastAIQ = ceil(valAIQ);
      // Power down the radio.  Note that the radio will get powered back up
      // on the next write() call.
      //gw.sleep(SLEEP_TIME); //sleep for: sleepTime
      sleep(SLEEP_TIME); //sleep for: sleepTime
      // Force reading sensor, so it works also after sleep()
      // Get temperature from DHT library
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
        Serial.println("Failed reading temperature from DHT!");
      } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
        // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        // Reset no updates counter
        nNoUpdatesTemp = 0;
        temperature += SENSOR_TEMP_OFFSET;
        send(msgTemp.set(temperature, 1));
        #ifdef MY_DEBUG
        Serial.print("T: ");
      } else {
        // Increase no update counter if the temperature stayed the same
      // Get humidity from DHT library
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
        Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
        // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
        lastHum = humidity;
        // Reset no updates counter
        nNoUpdatesHum = 0;
        send(msgHum.set(humidity, 1));
        #ifdef MY_DEBUG
        Serial.print("H: ");
      } else {
        // Increase no update counter if the humidity stayed the same
      // Sleep for a while to save energy
    /*****************************  MQGetPercentage **********************************
    Input:   rs_ro_ratio - Rs divided by Ro
             pcurve      - pointer to the curve of the target gas
    Output:  ppm of the target gas
    Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
             of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
             logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
    int  MQGetPercentage(float rs_ro_ratio, float ro, float *pcurve)
      return (double)(pcurve[0] * pow(((double)rs_ro_ratio/ro), pcurve[1]));
    void receive(const MyMessage &message)
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(", New status: ");

  • Mod

    @scaleoblack try using wait instead of sleep.

  • What @mfalkvidd said, I had the same issue on an esp8266

  • i have found the post. But i don't now how i implement it... i'm just a beginner and make copy and paste :blush:

    if (attachedServo && millis() - timeOfLastChange > DETACH_DELAY) {
        attachedServo = false;
    can you help me?

Log in to reply

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.