Mysensors 2.0 + Relay, DHT, and PIR - No Relay

  • Hello folks:

    I'm trying to put together a powered multi sensor using mysensors 2, that will have a DHT, PIR, and a relay to act as a quick trigger for the garage. ( momentary push ), but I can't seem to get the relay to trigger with the following sketch:

    DHT-Motion, MySensors 2.0.0, motion sensor pin 3, DHT pin 7
    // Enable debug prints
    #define MY_DEBUG
    #define MY_NODE_ID 50         // My Node ID variable
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>
    // Set this to the pin you connected the DHT's data pin to
    #define DHT_DATA_PIN 7
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET -1
    // Sleep time between sensor updates (in milliseconds)
    // Must be >1000ms for DHT22 and >2000ms for DHT11
    static const uint64_t UPDATE_INTERVAL = 60000;
    // Force sending an update of the temperature after n sensor reads, so a controller showing the
    // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
    // the value didn't change since;
    // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
    static const uint8_t FORCE_UPDATE_N_READS = 10;
    #define CHILD_ID_MO 3
    #define CHILD_ID_HUM 10
    #define CHILD_ID_TEMP 11
    #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
    #define CHILD_ID_OPENER 0
    #define CHILD_ID_STATUS 1
    #define TOGGLE_INTERVAL 350  //Tells how many milliseconds the relay will be held closed
    #define CLOSED 0
    #define OPEN 1
    DHT dht;
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    bool metric = true; 
    MyMessage msgMot(CHILD_ID_MO, V_TRIPPED);
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgOpener(CHILD_ID_OPENER, V_STATUS);
    MyMessage msgStatus(CHILD_ID_STATUS, V_TEXT);
    void presentation()  
      // Send the sketch version information to the gateway
      sendSketchInfo("DHT-Motion_Relay", "1.1");
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_MO, S_MOTION);
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_OPENER, S_BINARY);
      present(CHILD_ID_STATUS, S_INFO);
    void setup()
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      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)
      pinMode(RELAY_1, OUTPUT);
      digitalWrite(RELAY_1, loadState(RELAY_1)?RELAY_OFF:RELAY_ON);
    void loop()      
      // 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
       // Read digital motion value
      bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
      send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
      // Sleep for a while to save energy
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, UPDATE_INTERVAL); 
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
         digitalWrite( RELAY_1, RELAY_ON );
        //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
        delay( TOGGLE_INTERVAL );
        digitalWrite( RELAY_1, RELAY_OFF );
        //Added this to tell the controller that we shut off the relay
         // Store state in eeprom
         saveState(message.sensor, message.getBool());
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(", New status: ");

    Can anyone help with where I have gone wrong? Board, NRF, etc all work with the default relay sketch, but when I am combining, I am not having any luck with the relay, everything else appears fine based on serial output:

    Starting sensor (RNNNA-, 2.0.0)
    TSP:MSG:SEND 50-50-255-255 s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=bc:
    TSP:MSG:READ 0-0-50 s=255,c=3,t=8,pt=1,l=1,sg=0:0
    TSP:MSG:FPAR RES (ID=0, dist=0)
    TSP:MSG:PAR OK (ID=0, dist=1)
    TSM:CHKID:OK (ID=50)
    TSP:PING:SEND (dest=0)
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=ok:1
    TSP:MSG:READ 0-0-50 s=255,c=3,t=25,pt=1,l=1,sg=0:1
    TSP:MSG:PONG RECV (hops=1)
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=ok:0100
    !TSP:MSG:SEND 50-50-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=fail:2.0.0
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,ft=1,st=ok:0
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=11,pt=0,l=16,sg=0,ft=0,st=ok:DHT-Motion_Relay
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=ok:1.1
    TSP:MSG:SEND 50-50-0-0 s=3,c=0,t=1,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 50-50-0-0 s=10,c=0,t=7,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 50-50-0-0 s=11,c=0,t=6,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=22,pt=5,l=4,sg=0,ft=0,st=ok:2197
    TSP:MSG:SEND 50-50-0-0 s=0,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=ok:
    TSP:MSG:READ 0-0-50 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    TSP:MSG:SEND 50-50-0-0 s=1,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=ok:
    Request registration...
    TSP:MSG:SEND 50-50-0-0 s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=ok:2
    TSP:MSG:READ 0-0-50 s=255,c=3,t=27,pt=1,l=1,sg=0:1
    Node registration=1
    Init complete, id=50, parent=0, distance=1, registration=1
    TSP:MSG:SEND 50-50-0-0 s=11,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=ok:20.0
    T: 20.00
    TSP:MSG:SEND 50-50-0-0 s=10,c=1,t=1,pt=7,l=5,sg=0,ft=0,st=ok:23.0
    H: 23.00
    TSP:MSG:SEND 50-50-0-0 s=3,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=ok:0

  • Hardware Contributor

    @rhuehn - what does it look like when you send the trigger command? Do you get anything in the node log?

  • Isn't it so, that this code block makes the node unresponsive for UPDATE_INTERVAL 60 s? The only exception would be the digital input 3 (PIR pin).

    // Sleep for a while to save energy
      sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, UPDATE_INTERVAL); nsert Code Here

  • Hello @Nuubi Yes I believe that is exactly why the Relay goes unresponsive. If I remove that sleep block, the PIR floods the gateway, and I am not sure how to get around it? Is there any possible recommendations you could make to the code so that the DHT, PIR AND Relay all work without the PIR flooding the gateway?

    Thanks very much!

  • Hardware Contributor

    @rhuehn - you could with a if statement only send if the value is changed.

  • I did a similar project that is working well. Mine was powered all the time, so I didn't use the sleep code. The main reason I didn't was so that I could manually control the relay/light when there was no motion detected. It also allowed me to get continuous readings from the LDR so I could use that light level for other things if I ever wanted to.

    Here is a link to my project. . Maybe you can get some ideas from my code.

Log in to reply

Suggested Topics

  • 4
  • 6
  • 3
  • 1
  • 5
  • 21
  • 5
  • 1