3-in-1 Humidity Temp and Motion



  • I am wanted to share my 3-in-1 sensor in case its of use to anyone
    Its really just a combination of what's already available

    I used the following hardware:

    Arduino Nano LINK - Gave me both 3.3v and 5v output without having to mess with extra hardware(steppers)
    1 x Motion Sensor LINK
    1 x DHT22 LINK

    Connections is as all other guides except:
    Motion Sensor digital to Pin D3
    and the DHT to Pin D4

    Here is my code

    #include <SPI.h>
    #include <MySensor.h>  
    #include <DHT.h>  
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_MOT 2   // Id of the sensor child
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    
    MySensor gw;
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
    
    void setup()  
    { 
      gw.begin();
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo("Humidity/Motion", "1.0");
    
    
     pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
     
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_HUM, S_HUM);
      gw.present(CHILD_ID_TEMP, S_TEMP);
      gw.present(CHILD_ID_MOT, S_MOTION);
       
      metric = gw.getConfig().isMetric;
    }
    
    void loop()      
    
    {  
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
            
      Serial.println(tripped);
      gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
      
      delay(dht.getMinimumSamplingPeriod());
    
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        gw.send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          gw.send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
    
      
     
      // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
      gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
    }
    
    
    

    If anyone wants more info please ask.. I will put up pictures or diagrams if needed


  • Hero Member

    @Konrad-Walsh
    Battery powered?



  • no. usb charger powered. No idea where to start with battery powering this stuff



  • Very cool. Could you list the hardware you used for this project?



  • @chilump
    Yes of course... I'll update the original post shortly..

    EDIT: UPDATED



  • Interested in how you will package this? will the recorded temp be affected by the duino if it's enclosed?



  • No its not affected as the temp sensor is on the outside of the case along with the motion sensor



  • Do you have a picture of it in the case? Pictures rule ๐Ÿ˜ƒ



  • I found out quite marked difference between different setups! On the surface of the enclosure there's >3C warmer than few centimeters further from the enclosure, see pictures ๐Ÿ™‚

    First picture: temp, light level, door sensor, movement, patio PWM led lightning. DS sensor on the bottom of the enclosure
    WP_20141024_14_37_41_Pro.jpg (temp, light level, movement)

    Second: temp, light, movement
    WP_20141024_14_37_58_Pro.jpg


  • Hero Member

    @Nuubi Where did you get those cases?



  • Upper picture: a repurposed old movement alarm unit, was on sale for 2โ‚ฌ several years ago on a local store.
    Lower one: from dx.com (http://www.dx.com/p/wall-mount-pir-motion-detector-with-80db-alarm-siren-7-10-meter-110-degrees-15278), just swapped the internals. A bit small for my spider net constructions, though.



  • Hi,

    I am trying out your 3-in-1 Humidity Temp and Motion sensor with a DHT11 and get the following in the serial out put

    sensor started, id 5
    send: 5-5-0-0 s=255,c=0,t=17,pt=0,l=5,st=ok:1.4.1
    send: 5-5-0-0 s=255,c=3,t=6,pt=1,l=1,st=ok:0
    read: 0-0-5 s=255,c=3,t=6,pt=0,l=1:M
    send: 5-5-0-0 s=255,c=3,t=11,pt=0,l=15,st=ok:Humidity/Motion
    send: 5-5-0-0 s=255,c=3,t=12,pt=0,l=3,st=ok:1.0
    send: 5-5-0-0 s=0,c=0,t=7,pt=0,l=5,st=ok:1.4.1
    send: 5-5-0-0 s=1,c=0,t=6,pt=0,l=5,st=ok:1.4.1
    send: 5-5-0-0 s=2,c=0,t=1,pt=0,l=5,st=ok:1.4.1
    1
    send: 5-5-0-0 s=2,c=1,t=16,pt=0,l=1,st=ok:1
    Failed reading temperature from DHT
    Failed reading humidity from DHT
    1
    send: 5-5-0-0 s=2,c=1,t=16,pt=0,l=1,st=ok:1
    Failed reading temperature from DHT
    Failed reading humidity from DHT
    0
    so the motion is working but not the temp or humidity, do I have to do some thing different in the scetch for the DHT11 over the DHT22?

    Thanks for any help.



  • Hey

    From what I just read it shouldnt matter.. you I would double check you wiring of the DHT11. Your output should be on PIN 4.. Also, have you placed the resistor on the DHT1`1



  • hi,

    thanks I did some reading my self and realised I needed the resistor works a treat now. thanks for the reply.



  • @Opus40 Great!

    I am currently finalising a 5 in 1 sensor... just testing and so far its working fantastic



  • @Konrad-Walsh said:

    I am currently finalising a 5 in 1 sensor... just testing and so far its working fantastic

    Hum-temp-motion-light-???



  • @Nuubi LOL.. its a secret!!!

    and I will share my carefully guarded secret... Air quality sensor!! or in other words.. smoke and gas detector...



  • Did you mount your PIR behind the rounded screen area on those cases? It works through that?

    I have yet to get to integrating PIR's in to my sensors, but do plan to, and was curious how to effectively mount them. Need to offer protection from the circuitry, but visibility to the sensor itself.



  • Question about a minor detail:
    Wouldn't a motionsenser trip be missed during:
    delay(dht.getMinimumSamplingPeriod()); ?
    For a DHT22 this is 2 seconds... or does the interrupt still has precedence?


  • Contest Winner

    @C4Vette you could just use a non-blocking method to read the temperature instead of the delay.

    The delay is method is in the library and used so that multiple reads to the sensor don't affect the reading (overheating the sensor).

    since SLEEP_TIME is 30s in the code above... I'd just read the temperature each time the sensor was awakened.

    you could just timestamp the last reading and check that at least the 2 seconds elapsed since the last reading before you take a new one (in the case that motion was detected.



  • @BulldogLowell
    Ok, thanks for explaining. I'm no programmer but trying to understand the code. So because there is also a sleep-periode, the earlier mentioned delay could be omitted? I do not fully understand how the motion interrupt is working but I replaced the 30 second sleep with a few lines using millis, as you implied so that the loop keeps on running to do other things.
    At the moment my sensor is a working combination of a LED-dimmer with a motion-sensor and now trying to add a DHT. This stuff is fun!
    Posted some photo's at http://forum.mysensors.org/topic/781/my-led-dimmer-motion-temp-hum-sensor



  • Nice set up!



  • @Konrad-Walsh said:

    I am wanted to share my 3-in-1 sensor in case its of use to anyone
    Its really just a combination of what's already available

    If anyone wants more info please ask.. I will put up pictures or diagrams if needed

    I'm having a problem with this build.
    i'm using the same hardware.

    I get nothing in the serial output screen.
    i am able to compile and load the code.
    when i measure on the 3.3 rail i get 3.8 (only when the radio is hooked up, i get 3.3 when nothing is hooked to the board)
    when i measure on the 5v rail, i get 4.7v when the motion and temp sensor are hooked up.

    I suspect my issues may be voltage related. although i'm not sure why i'm getting nothing on the serial monitor.

    since you said you didn't need any steppers, do you have any suggestions?
    thanks



  • @Konrad-Walsh my nano and pro mini on the way! double each! cant wait!! fed up all confused so have ard r3 n mega n nano n promini all tick tick!



  • Works like a charm...

    Thanks for sharing ๐Ÿ™‚



  • dear all.
    What battery u use?
    And what is the battery time?



  • Looks pretty sweet. How is it working comparing to existing products with the same features?



  • Hi Konrad

    Thx for great code. It works like charm but...

    I have a question... It is possible to add to Your code one more (Door/Window) sensor?

    Mayby You can post that code on this forum?
    Best regards



  • Hi to all

    I changed a little Konrad sketch and add to 3in1 Humidity Temp and Motion one more sensor (Door\Window)

    Here is my code:

    #include <SPI.h>
    #include <MySensor.h>
    #include <DHT.h>
    #include <Bounce2.h>

    #define CHILD_ID_DOOR 3
    #define BUTTON_PIN_DOOR 2
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_MOT 2 // Id of the sensor child
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4

    #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
    #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)

    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)

    MySensor gw;
    Bounce debouncer = Bounce();
    int oldValue=-1;

    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true;
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
    MyMessage msgDoor(CHILD_ID_DOOR,V_TRIPPED);

    void setup()
    {
    gw.begin();
    dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);

    pinMode(BUTTON_PIN_DOOR,INPUT);
    digitalWrite(BUTTON_PIN_DOOR,HIGH);

    debouncer.attach(BUTTON_PIN_DOOR);
    debouncer.interval(5);

    // Send the Sketch Version Information to the Gateway
    gw.sendSketchInfo("4in1", "1.0");

    pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input

    // Register all sensors to gw (they will be created as child devices)
    gw.present(CHILD_ID_HUM, S_HUM);
    gw.present(CHILD_ID_TEMP, S_TEMP);
    gw.present(CHILD_ID_MOT, S_MOTION);
    gw.present(CHILD_ID_DOOR, S_DOOR);

    metric = gw.getConfig().isMetric;
    }

    void loop()

    {
    // Read digital motion value
    boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;

    Serial.println(tripped);
    gw.send(msgMot.set(tripped?"1":"0")); // Send tripped value to gw

    delay(dht.getMinimumSamplingPeriod());

    float temperature = dht.getTemperature();
    if (isnan(temperature)) {
    Serial.println("Failed reading temperature from DHT");
    } else if (temperature != lastTemp) {
    lastTemp = temperature;
    if (!metric) {
    temperature = dht.toFahrenheit(temperature);
    }
    gw.send(msgTemp.set(temperature, 1));
    Serial.print("T: ");
    Serial.println(temperature);
    }

    float humidity = dht.getHumidity();
    if (isnan(humidity)) {
    Serial.println("Failed reading humidity from DHT");
    } else if (humidity != lastHum) {
    lastHum = humidity;
    gw.send(msgHum.set(humidity, 1));
    Serial.print("H: ");
    Serial.println(humidity);
    }

    debouncer.update();
    // Get the update value
    int value = debouncer.read();

    if (value != oldValue) {
    // Send in the new value
    gw.send(msgDoor.set(value==HIGH ? 1 : 0));
    oldValue = value;
    }

    // Sleep until interrupt comes in on motion sensor. Send update every two minute.
    //gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
    }

    Now it is 4in1 ๐Ÿ™‚



  • This post is deleted!


  • Has the 3in1 sketch been updated to 2.0 yet? I need some help with it, im not tot keen with coding...



  • @kurniawan77

    This is HUM TEMP and PIR

    This is what I'm using and it runs in mysensors 2.0

    None battery powered. NO sleep mode and dirty code but it runs well enough for me right now.
    If you add or fix anything please post it for everyone.

    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>  
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    
    #define CHILD_ID_MOT 2 //me
    
    
    
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    
    #define DIGITAL_INPUT_SENSOR 2   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    
    
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = false; 
    
    unsigned long interval= 3000;//dht.getMinimumSamplingPeriod(); // the time we need to wait
    unsigned long previousMillis=0; // millis() returns an unsigned long.
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); //me
    
    void setup()  
    { 
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
     // metric = getConfig().isMetric;
    
     pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()  
    { 
      // Send the Sketch Version Information to the Gateway
      sendSketchInfo("3-1 Sensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_MOT, V_TRIPPED); //me
    }
    
    void loop()      
    {  
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
       
    // only run loop if time has passed. 
    unsigned long currentMillis = millis(); // grab current time       
    
     // check if "interval" time has passed
     if ((unsigned long)(currentMillis - previousMillis) >= interval) {
    
     
           send(msgMot.set(tripped?"1":"0")); 
                  
      
          #ifdef MY_DEBUG
           Serial.print("Motion: ");
           Serial.println(tripped);
          #endif
    
    
    
     
      
      // Fetch temperatures from DHT sensor
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        send(msgTemp.set(temperature, 1));
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      }
     
      // Fetch humidity from DHT sensor
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          send(msgHum.set(humidity, 1));
          #ifdef MY_DEBUG
          Serial.print("H: ");
          Serial.println(humidity);
          #endif
      }   
    
    
    
    
       // save the "current" time
       previousMillis = millis();
    
     }  
    
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      //sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    
    }```


  • My sample is here, unfortunately I didn't see this thread before starting it ๐Ÿ™‚
    It works for temp, humidity, door and motion, and interrupts for door and motion, otherwise sleeps the intervals:

    https://github.com/ikke-t/sensebender

    There is also pro-mini to code to monitor only door and motion.

    This is also for 2.0 MySensors.



  • I combined Motion and Air Humidity and Sleep works. This is my first one and I'm pretty sure I have some unnecessary code in it.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Motion: Version 1.0 - Henrik Ekblad
     * 
     * Humidity: Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * Combination of Motion Sensor example and Air Humidity example
     * http://www.mysensors.org/build/motion
     * https://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
     #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <DHT.h>
    
    float lastTemp;
    float lastHum;
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    unsigned long SLEEP_TIME = 60000; // Sleep time between reports (in milliseconds)
    #define MOTION_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define DHT_INPUT_SENSOR 4     // The digital input of attached DHT sensor
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // 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_HUMID 0        // ID of the Humidity child
    #define CHILD_ID_TEMP 1         // ID of the Tempurature child
    #define CHILD_ID_MOTION1 2   // Id of the Motion sensor child
    
    // Initialize motion message
    MyMessage msgMotion(CHILD_ID_MOTION1, V_TRIPPED);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgHum(CHILD_ID_HUMID, V_HUM);
    DHT dht;
    
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Motion Temp Humidity", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_MOTION1, S_MOTION);
      present(CHILD_ID_TEMP, V_TEMP);
      present(CHILD_ID_HUMID, V_HUM);
    }
    
    void setup()
    {
    	pinMode(MOTION_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      dht.setup(DHT_INPUT_SENSOR); // 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)
      sleep(dht.getMinimumSamplingPeriod());
    }
    
    
    
    void loop()
    {
    	// Read digital motion value
    	bool tripped = digitalRead(MOTION_INPUT_SENSOR) == HIGH;
    
    	Serial.println(tripped);
    	send(msgMotion.set(tripped?"1":"0"));  // Send tripped value to gw
    
      #ifdef MY_DEBUG
           Serial.print("Motion: ");
           Serial.println(tripped);
      #endif
    
    
    // DHT ****************************************************************************
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // 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;
        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: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // 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: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
    
    	// Sleep until interrupt comes in on motion sensor. Send update after (SLEEP_TIME) milliseconds has passed.
    	sleep(digitalPinToInterrupt(MOTION_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }


  • I did some work today getting this temp / humidity / motion combo sensor running. The main issue I ran into was that though the temp and humidity did not report their values to the GW unless there was a change in values or the max no update trigger was reached, the motion sensor would report it's state value each cycle. @McPostal you also should be seeing this in your code. While this is not an issue if you are powering with a AC adaptor, I am planning on using batteries down the road for these sensors so I do not want it to broadcast unless required.

    I added some code to resolve this. I am still testing this out but in theory this code should allows the Motion sensor to sleep and only report on a state change or when the max no update trigger is reached.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0: Henrik EKblad
     * Version 1.1 - 2016-07-20: Converted to MySensors v2.0 and added various improvements - Torben Woltjen (mozzbozz)
     * 
     * DESCRIPTION
     * This sketch provides an example of how to implement a humidity/temperature
     * sensor using a DHT11/DHT-22.
     *  
     * For more information, please visit:
     * http://www.mysensors.org/build/humidity
     * 
     */
    
    // Enable debug prints
    #define MY_DEBUG
    //#define MY_DEBUG_VERBOSE_RF24
    
    // 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 4
    #define MOTION_DATA_PIN 3
    
    // Set this offset if the sensor has a permanent small offset to the real temperatures
    #define SENSOR_TEMP_OFFSET 0
    
    // 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_HUM 0
    #define CHILD_ID_TEMP 1
    #define CHILD_ID_MOTION 2
    
    float lastTemp;
    float lastHum;
    bool lastMotion = false;
    
    uint8_t nNoUpdatesTemp;
    uint8_t nNoUpdatesHum;
    uint8_t nNoUpdatesMotion;
    
    bool metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMotion(CHILD_ID_MOTION, V_TRIPPED);
    DHT dht;
    
    
    void presentation()  
    { 
      // Send the sketch version information to the gateway
      sendSketchInfo("Temp Humidity Motion", "1.1");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_MOTION, S_MOTION);
    
      metric = getConfig().isMetric;
    }
    
    
    void setup()
    {
      pinMode(MOTION_DATA_PIN, 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)
      sleep(5000);
      presentation();
    }
    
    
    void loop()      
    {  
      // Force reading sensor, so it works also after sleep()
      dht.readSensor(true);
    
      // Read digital motion value
      bool tripped = digitalRead(MOTION_DATA_PIN) == HIGH;
    
      if (tripped || nNoUpdatesMotion == FORCE_UPDATE_N_READS) {
        lastMotion = tripped;
        Serial.println(tripped);
        send(msgMotion.set(tripped?"1":"0"));  // Send tripped value to gw
        nNoUpdatesMotion = 0;
      }
      else if (lastMotion) {
        Serial.println(tripped);
        send(msgMotion.set(tripped?"1":"0"));  // Send tripped value to gw
        nNoUpdatesMotion = 0;
      }
      else {
        nNoUpdatesMotion++;
      }
    
      
      // 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: ");
        Serial.println(temperature);
        #endif
      } else {
        // Increase no update counter if the temperature stayed the same
        nNoUpdatesTemp++;
      }
    
      // 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: ");
        Serial.println(humidity);
        #endif
      } else {
        // Increase no update counter if the humidity stayed the same
        nNoUpdatesHum++;
      }
    
      // Sleep for a while to save energy
      sleep(digitalPinToInterrupt(MOTION_DATA_PIN), CHANGE, UPDATE_INTERVAL); 
    }
    

    Morkin.



  • Nice! I realized the motion was being updated every cycle after I posted my code. I also left out references to metric temperature readings. I fixed the motion part in my code but didn't post it yet because I had already added a second motion sensor. What I did different was not forcing the motion update. I want the time stamp to reflect the last time someone was in the room.



  • Hi,
    I took your updated code for 2.0 and tried to add a relay.
    The code looks like this:

    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <DHT.h>  
    
    #define CHILD_ID_HUM 10
    #define CHILD_ID_TEMP 11
    #define CHILD_ID_MOT 12 //motion sensor
    
    
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    
    #define RELAY_1  7  // 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 CHILD_ID 5
    #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 dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    
    unsigned long interval= 3000;//dht.getMinimumSamplingPeriod(); // the time we need to wait
    unsigned long previousMillis=0; // millis() returns an unsigned long.
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED); //me
    
    
    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(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
     // metric = getConfig().isMetric;
    
     pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()  
    { 
      // Send the Sketch Version Information to the Gateway
      sendSketchInfo("4-1 Sensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_HUM, S_HUM);
      present(CHILD_ID_TEMP, S_TEMP);
      present(CHILD_ID_MOT, V_TRIPPED); //me
      
      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);
    	}
    }
    
    void loop()      
    {  
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
       
    // only run loop if time has passed. 
    unsigned long currentMillis = millis(); // grab current time       
    
     // check if "interval" time has passed
     if ((unsigned long)(currentMillis - previousMillis) >= interval) {
    
     
           send(msgMot.set(tripped?"1":"0")); 
                  
      
          #ifdef MY_DEBUG
           Serial.print("Motion: ");
           Serial.println(tripped);
          #endif
    
    
    
     
      
      // Fetch temperatures from DHT sensor
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        send(msgTemp.set(temperature, 1));
        #ifdef MY_DEBUG
        Serial.print("T: ");
        Serial.println(temperature);
        #endif
      }
     
      // Fetch humidity from DHT sensor
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          send(msgHum.set(humidity, 1));
          #ifdef MY_DEBUG
          Serial.print("H: ");
          Serial.println(humidity);
          #endif
      }   
    
    
    
    
       // save the "current" time
       previousMillis = millis();
    
     }  
      // Sleep until interrupt comes in on motion sensor. Send update every two minute.
      //sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    
    }
    
    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(message.sensor);
    		Serial.print(", New status: ");
    		Serial.println(message.getBool());
    	}
    }
    

    However, when i look in domoticz the relay isnt presented as a child.
    Plus, the motion sensor is called "S_LIGHT_LEVEL" and not "S_MOTION" as it does in my other device (that only have temp, hum motion and not a relay in the sketch).
    temp/hum sensor and motion sensor works as intended in domoticz.
    My first though is that the motion and relay somehow is a bit mixed up by the sketch, but im kinda new to this so im not sure.
    Would really appreciate if someone can look at the sketch and see if there is any obvious problem ๐Ÿ™‚



  • @stocken

    Under "void presentation()" , present(CHILD_ID_MOT, V_TRIPPED); //me should be

    present(CHILD_ID_MOT, S_MOTION); //me

    that should fix the light level problem.

    I haven't done a relay yet. If no one else responds I look at it later tonight. I also have a relay but haven't had time to try and implement it yet.



  • Hello everybody,

    first off all a big thank you for creating this awsome sketch. It works perfect for me !!
    But, as you might already have guessed I have a little problem.

    I built 2 exact same nodes and flashed the exact same sketch ( only thing I changed is the child IDยดs) but one node works just like a charm ( MSPIRAndy) but the other one (MYSENSOR_106) doesnt transmit its readings (?)

    Via the serial monitor the readings do exist and work perfect.

    Thanks a lot, all help is appreciated

    KOmaandy

    0_1488919647833_106.PNG

    0_1488919653276_mspiraNDY.PNG


  • Mod

    Have you tried swapping radio between the 2 sensors? Just to exclude any radio issue



  • Yes i did swap the radios, but what seems to be the problem is the arduino itself.
    When swapping the arduinos ( both arduino pro mini 3,3 volt) both flashed with the same sketch one works and the other just doesnt.
    I just swapped the arduinos on the breadboard and left everything else in place...
    Thats really strange, given the fact that BOTH transmit good readings when connected to the arduino-serial-monitor ...



  • Do you have a schematic that you could post?


  • Mod

    @ryanbrown204 welcome to the MySensors community!

    This is a long thread with a lot of different people posting, so it is a bit hard to guess which schematic you are looking for. Could you clarify?



  • @mfalkvidd the schematic for the original 3-in-1 Humidity Temp and Motion. I would like to try me hand at building the first version and then adding the additions.


  • Mod

    @ryanbrown204 temperature: https://www.mysensors.org/build/temp
    Motion: https://www.mysensors.org/build/motion

    See the first post in this thread for the modifications Konrad did.



  • This post is deleted!


  • This post is deleted!


Suggested Topics

8
Online

11.4k
Users

11.1k
Topics

112.7k
Posts