Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. Low Bat Powered 3 in 1 sensor Please Help

Low Bat Powered 3 in 1 sensor Please Help

Scheduled Pinned Locked Moved Troubleshooting
12 Posts 3 Posters 4.4k Views 7 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • rhuehnR Offline
    rhuehnR Offline
    rhuehn
    wrote on last edited by
    #1

    Hello:

    I'm trying to build a very low powered ( 2 x AA ) Battery powered 3 in 1 sensor. ( Platform is a Pro Mini 8Mhz, 3.3v, with an PIR HC-SR501, NRF24L01, and a DHT 11 Temp and Hum sensor. The sensor should also report battery power periodically ideally using the vcc library.

    The code below, primarily taken from here works well, thanks very much to @AWI sam-ple code

    @AWI also mentions a great sketch here Good Example

    And I really want to implement it, using the vcc library to report battery power, but am having a really hard time getting these sketched together. There are several good post about low power consumption, and combining gw.send functions in one burst at the end of the sketch to save power. Also, clocking the pro mini down to 1Mhz to save power, and only update the gateway when temp or humidity levels change by .5 - 1 deg.

    Below is my code that is lacking a lot of this functionality. I've been trying for two weeks to try and implement this, but keep banging my head against the desk.... Is anyone able to help a newbie out? Thanks very much for any assistance.

     #define MY_GW_ID 31
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <SPI.h>
    #include <MySensor.h>  
    #include <DHT.h>  
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    //Constants
    #define SKETCH_NAME           "3 in 1 Sensor"
    #define SKETCH_VERSION        "1.0"
    #define CHILD_ID_HUM 0                    // Child id for Humidity
    #define CHILD_ID_TEMP 1                   // Child id for Temperature
    #define CHILD_ID_MOT 2                   // Id of the sensor child
    #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
    #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)
    
    //Misc. variables
    uint8_t switchState = 2;
    unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
    unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
    uint8_t cycleInProgress = 0;
    uint8_t firstReportDone = 0;
    uint8_t firstReportWithZeroDone = 0;
    int oldBatteryPcnt = 0;
    
    MySensor gw;
    DHT dht;
    float lastTemp = 0 ;
    float lastHum = 0 ;
    boolean lastTripped = false ;
    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()  
    { 
       // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
      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()      
    
    {  
      // get the battery Voltage
       int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       Serial.println(sensorValue);
       #endif
       
       // 1M, 470K divider across battery and using internal ADC ref of 1.1V
       // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
       // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
       // 3.44/1023 = Volts per bit = 0.003363075
       float batteryV  = sensorValue * 0.003363075;
       int batteryPcnt = sensorValue / 10;
    
       #ifdef DEBUG
       Serial.print("Battery Voltage: ");
       Serial.print(batteryV);
       Serial.println(" V");
    
       Serial.print("Battery percent: ");
       Serial.print(batteryPcnt);
       Serial.println(" %");
       #endif
    
       if (oldBatteryPcnt != batteryPcnt) {
         // Power up radio after sleep
         gw.sendBatteryLevel(batteryPcnt);
         oldBatteryPcnt = batteryPcnt;
       }
         
         
      // Read digital motion value
      boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
      
      if (tripped != lastTripped ) {      
        Serial.println(tripped);
        gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
      }
      delay(dht.getMinimumSamplingPeriod());
    
      float temperature = dht.getTemperature();
      float humidity = dht.getHumidity();
      
      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);
      }
      
      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);
      }
    
       if (oldBatteryPcnt != batteryPcnt) {
         // Power up radio after sleep
         gw.sendBatteryLevel(batteryPcnt);
         oldBatteryPcnt = batteryPcnt;
       }
      
     
      // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
      gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
    }
    
    dynamiteD AWIA 3 Replies Last reply
    0
    • rhuehnR rhuehn

      Hello:

      I'm trying to build a very low powered ( 2 x AA ) Battery powered 3 in 1 sensor. ( Platform is a Pro Mini 8Mhz, 3.3v, with an PIR HC-SR501, NRF24L01, and a DHT 11 Temp and Hum sensor. The sensor should also report battery power periodically ideally using the vcc library.

      The code below, primarily taken from here works well, thanks very much to @AWI sam-ple code

      @AWI also mentions a great sketch here Good Example

      And I really want to implement it, using the vcc library to report battery power, but am having a really hard time getting these sketched together. There are several good post about low power consumption, and combining gw.send functions in one burst at the end of the sketch to save power. Also, clocking the pro mini down to 1Mhz to save power, and only update the gateway when temp or humidity levels change by .5 - 1 deg.

      Below is my code that is lacking a lot of this functionality. I've been trying for two weeks to try and implement this, but keep banging my head against the desk.... Is anyone able to help a newbie out? Thanks very much for any assistance.

       #define MY_GW_ID 31
      // Enable debug prints
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      #include <SPI.h>
      #include <MySensor.h>  
      #include <DHT.h>  
      
      int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
      
      //Constants
      #define SKETCH_NAME           "3 in 1 Sensor"
      #define SKETCH_VERSION        "1.0"
      #define CHILD_ID_HUM 0                    // Child id for Humidity
      #define CHILD_ID_TEMP 1                   // Child id for Temperature
      #define CHILD_ID_MOT 2                   // Id of the sensor child
      #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
      #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)
      
      //Misc. variables
      uint8_t switchState = 2;
      unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
      unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
      uint8_t cycleInProgress = 0;
      uint8_t firstReportDone = 0;
      uint8_t firstReportWithZeroDone = 0;
      int oldBatteryPcnt = 0;
      
      MySensor gw;
      DHT dht;
      float lastTemp = 0 ;
      float lastHum = 0 ;
      boolean lastTripped = false ;
      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()  
      { 
         // use the 1.1 V internal reference
      #if defined(__AVR_ATmega2560__)
         analogReference(INTERNAL1V1);
      #else
         analogReference(INTERNAL);
      #endif
        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()      
      
      {  
        // get the battery Voltage
         int sensorValue = analogRead(BATTERY_SENSE_PIN);
         #ifdef DEBUG
         Serial.println(sensorValue);
         #endif
         
         // 1M, 470K divider across battery and using internal ADC ref of 1.1V
         // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
         // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
         // 3.44/1023 = Volts per bit = 0.003363075
         float batteryV  = sensorValue * 0.003363075;
         int batteryPcnt = sensorValue / 10;
      
         #ifdef DEBUG
         Serial.print("Battery Voltage: ");
         Serial.print(batteryV);
         Serial.println(" V");
      
         Serial.print("Battery percent: ");
         Serial.print(batteryPcnt);
         Serial.println(" %");
         #endif
      
         if (oldBatteryPcnt != batteryPcnt) {
           // Power up radio after sleep
           gw.sendBatteryLevel(batteryPcnt);
           oldBatteryPcnt = batteryPcnt;
         }
           
           
        // Read digital motion value
        boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
        
        if (tripped != lastTripped ) {      
          Serial.println(tripped);
          gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
        }
        delay(dht.getMinimumSamplingPeriod());
      
        float temperature = dht.getTemperature();
        float humidity = dht.getHumidity();
        
        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);
        }
        
        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);
        }
      
         if (oldBatteryPcnt != batteryPcnt) {
           // Power up radio after sleep
           gw.sendBatteryLevel(batteryPcnt);
           oldBatteryPcnt = batteryPcnt;
         }
        
       
        // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
        gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
      }
      
      dynamiteD Offline
      dynamiteD Offline
      dynamite
      wrote on last edited by
      #2

      @rhuehn hi maybe you can have a look at this sketch. https://github.com/sweebee/Arduino-home-automation/blob/master/MySensors 1.5/Arduino/multiSensor/multiSensor.ino This had been the basis for my multisensor as Well. The battery input is directly on vcc pin. And the voltage regulator and led are disabled on the pro mini. No need to attach additional resistor for measuring battery power. You can make the interval as long as you like for sending over. Info is only submitted if the value is changed. 1 MHz is optimal for power consumption. But i have not been able
      To upload the sketch in that mode.

      1 Reply Last reply
      0
      • rhuehnR Offline
        rhuehnR Offline
        rhuehn
        wrote on last edited by
        #3

        Hey @dynamite Thanks for the link. The sketch looks great, but I don't believe it deviates much from the sketch I have posted above. If we are trying to conserve utmost battery and only wake when the PIR triggers, or if there is a change in temp ( +/- a deg ), and then fire everything over in 1 burst, or alternatively every hour. Then look at possibly slowing down the pro mini to 1Mhz vs 8. I don't know what do you think?

        1 Reply Last reply
        0
        • rhuehnR rhuehn

          Hello:

          I'm trying to build a very low powered ( 2 x AA ) Battery powered 3 in 1 sensor. ( Platform is a Pro Mini 8Mhz, 3.3v, with an PIR HC-SR501, NRF24L01, and a DHT 11 Temp and Hum sensor. The sensor should also report battery power periodically ideally using the vcc library.

          The code below, primarily taken from here works well, thanks very much to @AWI sam-ple code

          @AWI also mentions a great sketch here Good Example

          And I really want to implement it, using the vcc library to report battery power, but am having a really hard time getting these sketched together. There are several good post about low power consumption, and combining gw.send functions in one burst at the end of the sketch to save power. Also, clocking the pro mini down to 1Mhz to save power, and only update the gateway when temp or humidity levels change by .5 - 1 deg.

          Below is my code that is lacking a lot of this functionality. I've been trying for two weeks to try and implement this, but keep banging my head against the desk.... Is anyone able to help a newbie out? Thanks very much for any assistance.

           #define MY_GW_ID 31
          // Enable debug prints
          #define MY_DEBUG
          
          // Enable and select radio type attached
          #define MY_RADIO_NRF24
          //#define MY_RADIO_RFM69
          
          #include <SPI.h>
          #include <MySensor.h>  
          #include <DHT.h>  
          
          int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
          
          //Constants
          #define SKETCH_NAME           "3 in 1 Sensor"
          #define SKETCH_VERSION        "1.0"
          #define CHILD_ID_HUM 0                    // Child id for Humidity
          #define CHILD_ID_TEMP 1                   // Child id for Temperature
          #define CHILD_ID_MOT 2                   // Id of the sensor child
          #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
          #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)
          
          //Misc. variables
          uint8_t switchState = 2;
          unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
          unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
          uint8_t cycleInProgress = 0;
          uint8_t firstReportDone = 0;
          uint8_t firstReportWithZeroDone = 0;
          int oldBatteryPcnt = 0;
          
          MySensor gw;
          DHT dht;
          float lastTemp = 0 ;
          float lastHum = 0 ;
          boolean lastTripped = false ;
          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()  
          { 
             // use the 1.1 V internal reference
          #if defined(__AVR_ATmega2560__)
             analogReference(INTERNAL1V1);
          #else
             analogReference(INTERNAL);
          #endif
            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()      
          
          {  
            // get the battery Voltage
             int sensorValue = analogRead(BATTERY_SENSE_PIN);
             #ifdef DEBUG
             Serial.println(sensorValue);
             #endif
             
             // 1M, 470K divider across battery and using internal ADC ref of 1.1V
             // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
             // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
             // 3.44/1023 = Volts per bit = 0.003363075
             float batteryV  = sensorValue * 0.003363075;
             int batteryPcnt = sensorValue / 10;
          
             #ifdef DEBUG
             Serial.print("Battery Voltage: ");
             Serial.print(batteryV);
             Serial.println(" V");
          
             Serial.print("Battery percent: ");
             Serial.print(batteryPcnt);
             Serial.println(" %");
             #endif
          
             if (oldBatteryPcnt != batteryPcnt) {
               // Power up radio after sleep
               gw.sendBatteryLevel(batteryPcnt);
               oldBatteryPcnt = batteryPcnt;
             }
               
               
            // Read digital motion value
            boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
            
            if (tripped != lastTripped ) {      
              Serial.println(tripped);
              gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
            }
            delay(dht.getMinimumSamplingPeriod());
          
            float temperature = dht.getTemperature();
            float humidity = dht.getHumidity();
            
            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);
            }
            
            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);
            }
          
             if (oldBatteryPcnt != batteryPcnt) {
               // Power up radio after sleep
               gw.sendBatteryLevel(batteryPcnt);
               oldBatteryPcnt = batteryPcnt;
             }
            
           
            // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
            gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
          }
          
          AWIA Offline
          AWIA Offline
          AWI
          Hero Member
          wrote on last edited by AWI
          #4

          @rhuehn Just a few things to consider if building an ultra low power sensor:

          1. The sensor has to work at low voltages (if using 2AA), so either change the power source to something that delivers > 3V (i.e. Lithium CR123(no rechargable) and/ or use sensors that are capable of low power operation.
          2. The DHT22 sensor is not very reliable at < 3.3V, consider Si7021/ SHT21 and use the I2C interface
          3. PIR HC-SR501 is standard a 5V sensor. You need to modify / connect it different to have it work at 3.3V
          4. The PIR will not allow for lower consumption that around 60uA (that is what it takes).
          5. Using the gw.sleep() with a timer value takes around 6uA , you can only go lower by using only interrupt.
          6. A pro-mini should be modified. At least remove/ disconnect the led and preferably the regulator.
          7. Burning a bootloader to run on 1 mHz will reduce the consumption by a few percent only when active (not in sleep). But keeps the arduino awake longer when a lot of processing is to be done. So just keep it at 8 mHz.
          8. Use sensor libraries that allow for low power. Sometimes there are long "delays()" when waiting for results. This will keep the arduino (and probably radio) active while doing nothing. [I still need to do some more research on this]

          and:

          • Put things into perspective.. not very much use to go for the last uA if your sensors take more that 50 uA (i.e. PIR).
          • Be patient. 1 thing at a time. Start easy and observe the differences when you add more functionality.

          0_1462210662323_upload-e1aa30d9-3d72-404d-8ccf-1651bda2f754

          next is your sketch...

          1 Reply Last reply
          2
          • rhuehnR rhuehn

            Hello:

            I'm trying to build a very low powered ( 2 x AA ) Battery powered 3 in 1 sensor. ( Platform is a Pro Mini 8Mhz, 3.3v, with an PIR HC-SR501, NRF24L01, and a DHT 11 Temp and Hum sensor. The sensor should also report battery power periodically ideally using the vcc library.

            The code below, primarily taken from here works well, thanks very much to @AWI sam-ple code

            @AWI also mentions a great sketch here Good Example

            And I really want to implement it, using the vcc library to report battery power, but am having a really hard time getting these sketched together. There are several good post about low power consumption, and combining gw.send functions in one burst at the end of the sketch to save power. Also, clocking the pro mini down to 1Mhz to save power, and only update the gateway when temp or humidity levels change by .5 - 1 deg.

            Below is my code that is lacking a lot of this functionality. I've been trying for two weeks to try and implement this, but keep banging my head against the desk.... Is anyone able to help a newbie out? Thanks very much for any assistance.

             #define MY_GW_ID 31
            // Enable debug prints
            #define MY_DEBUG
            
            // Enable and select radio type attached
            #define MY_RADIO_NRF24
            //#define MY_RADIO_RFM69
            
            #include <SPI.h>
            #include <MySensor.h>  
            #include <DHT.h>  
            
            int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
            
            //Constants
            #define SKETCH_NAME           "3 in 1 Sensor"
            #define SKETCH_VERSION        "1.0"
            #define CHILD_ID_HUM 0                    // Child id for Humidity
            #define CHILD_ID_TEMP 1                   // Child id for Temperature
            #define CHILD_ID_MOT 2                   // Id of the sensor child
            #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
            #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)
            
            //Misc. variables
            uint8_t switchState = 2;
            unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
            unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
            uint8_t cycleInProgress = 0;
            uint8_t firstReportDone = 0;
            uint8_t firstReportWithZeroDone = 0;
            int oldBatteryPcnt = 0;
            
            MySensor gw;
            DHT dht;
            float lastTemp = 0 ;
            float lastHum = 0 ;
            boolean lastTripped = false ;
            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()  
            { 
               // use the 1.1 V internal reference
            #if defined(__AVR_ATmega2560__)
               analogReference(INTERNAL1V1);
            #else
               analogReference(INTERNAL);
            #endif
              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()      
            
            {  
              // get the battery Voltage
               int sensorValue = analogRead(BATTERY_SENSE_PIN);
               #ifdef DEBUG
               Serial.println(sensorValue);
               #endif
               
               // 1M, 470K divider across battery and using internal ADC ref of 1.1V
               // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
               // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
               // 3.44/1023 = Volts per bit = 0.003363075
               float batteryV  = sensorValue * 0.003363075;
               int batteryPcnt = sensorValue / 10;
            
               #ifdef DEBUG
               Serial.print("Battery Voltage: ");
               Serial.print(batteryV);
               Serial.println(" V");
            
               Serial.print("Battery percent: ");
               Serial.print(batteryPcnt);
               Serial.println(" %");
               #endif
            
               if (oldBatteryPcnt != batteryPcnt) {
                 // Power up radio after sleep
                 gw.sendBatteryLevel(batteryPcnt);
                 oldBatteryPcnt = batteryPcnt;
               }
                 
                 
              // Read digital motion value
              boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
              
              if (tripped != lastTripped ) {      
                Serial.println(tripped);
                gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
              }
              delay(dht.getMinimumSamplingPeriod());
            
              float temperature = dht.getTemperature();
              float humidity = dht.getHumidity();
              
              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);
              }
              
              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);
              }
            
               if (oldBatteryPcnt != batteryPcnt) {
                 // Power up radio after sleep
                 gw.sendBatteryLevel(batteryPcnt);
                 oldBatteryPcnt = batteryPcnt;
               }
              
             
              // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
              gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
            }
            
            AWIA Offline
            AWIA Offline
            AWI
            Hero Member
            wrote on last edited by AWI
            #5

            @rhuehn Your sketch.. there is nothing wrong with these... not optimized, but on first glance these should work.

            A few observations:

            1. When you battery power the whole thing (without regulator) you can read the voltage without the external resistors. Use the vvc library. A great, effective and simple library to measure voltage by our fellow member @Yveaux. Simplifies the code too. Look at his thread

            2. The line
              delay(dht.getMinimumSamplingPeriod());
              is a potential long wait time, depending on the library used. Try to move it to a position early in the sketch before the radio is alive.

            3. The line
              gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
              will keep the arduino internal timer alive (> 5uA). But why bother if you use a PIR :smirk: use:
              gw.sleep(INTERRUPT1, CHANGE, 0 );
              if you want to have deep sleep.

            4. Try to wake the radio at the end of the sketch. So read the sensors, save the values and send in the end. (you can move the "if's" i.e
              if (oldBatteryPcnt != batteryPcnt) {
              to the end to)

            A long post (maybe not relevant) being typed by consultant (me :blush: )... before asking the question... "What is the problem, in what are you not succeeding?"

            dynamiteD 1 Reply Last reply
            0
            • AWIA AWI

              @rhuehn Your sketch.. there is nothing wrong with these... not optimized, but on first glance these should work.

              A few observations:

              1. When you battery power the whole thing (without regulator) you can read the voltage without the external resistors. Use the vvc library. A great, effective and simple library to measure voltage by our fellow member @Yveaux. Simplifies the code too. Look at his thread

              2. The line
                delay(dht.getMinimumSamplingPeriod());
                is a potential long wait time, depending on the library used. Try to move it to a position early in the sketch before the radio is alive.

              3. The line
                gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME);
                will keep the arduino internal timer alive (> 5uA). But why bother if you use a PIR :smirk: use:
                gw.sleep(INTERRUPT1, CHANGE, 0 );
                if you want to have deep sleep.

              4. Try to wake the radio at the end of the sketch. So read the sensors, save the values and send in the end. (you can move the "if's" i.e
                if (oldBatteryPcnt != batteryPcnt) {
                to the end to)

              A long post (maybe not relevant) being typed by consultant (me :blush: )... before asking the question... "What is the problem, in what are you not succeeding?"

              dynamiteD Offline
              dynamiteD Offline
              dynamite
              wrote on last edited by
              #6

              @AWI for my understanding in case I do keep the voltage regulator and feed my pro mini 3v with the 3 AAA of the Ikea PIR. Will it keep working even of the voltage drops to 2v. (Of course i need to change the bootloader.) can i also use the simple battery level routine? The power at the vcc will be 3v or lower even if I feed it with 3 batteries?

              AWIA 1 Reply Last reply
              0
              • dynamiteD dynamite

                @AWI for my understanding in case I do keep the voltage regulator and feed my pro mini 3v with the 3 AAA of the Ikea PIR. Will it keep working even of the voltage drops to 2v. (Of course i need to change the bootloader.) can i also use the simple battery level routine? The power at the vcc will be 3v or lower even if I feed it with 3 batteries?

                AWIA Offline
                AWIA Offline
                AWI
                Hero Member
                wrote on last edited by
                #7

                @dynamite not sure if I understand your question. If you use a regulator you need to measure the battery voltage by measuring on an analog input.
                Your arduino probably won't work below 2.3 volts when powered from the raw pin. The LDO voltage drop would cause this.

                1 Reply Last reply
                1
                • rhuehnR Offline
                  rhuehnR Offline
                  rhuehn
                  wrote on last edited by
                  #8

                  Hello @AWI and @dynamite

                  My apologies for the delay in this reply as I was travelling and did not have access to the net... Thank you both for the replies, I just got back and couldn't wait to reply:

                  @AWI I will comment on the items below from your first post, below:

                  PIR HC-SR501 is standard a 5V sensor. You need to modify / connect it different to have it work at 3.3V
                  This has been modified to work @ 3.3V

                  The PIR will not allow for lower consumption that around 60uA (that is what it takes).
                  Using the gw.sleep() with a timer value takes around 6uA , you can only go lower by using only interrupt.
                  I believe I need to look at this at this seems to be a better option, and more suitable for the application

                  A pro-mini should be modified. At least remove/ disconnect the led and preferably the regulator.
                  These have also been modified as mentioned by yourself.

                  Burning a bootloader to run on 1 mHz will reduce the consumption by a few percent only when active (not in sleep). But keeps the arduino awake longer when a lot of processing is to be done. So just keep it at 8 mHz.
                  Sounds like a great idea, I will keep it as is

                  I believe @dynamite is referencing this post above, and BTW @dynamite I want to do the EXACT same thing:

                  link Here

                  So a few things, based on that Ikea module, We are trying to acheive the lowest power consumption from either 2 or 3 X AA Batteries. modified to work with perhaps a PIR HC-SR501 ( discarding the original ), along with a DHT11 ( or 22 ), and report battery levels, and send the information back to a gateway, perhaps every hour unless the temp changes +/- 1 degree, or the PIR wakes, causing an action to be triggered, then go back to deep sleep.

                  I tried a few modification to your suggestions, but lost functionality with the PIR, and battery reporting. My sketch is below, and not working very well:

                   #define MY_NODE_ID 31
                  // Enable debug prints
                  #define MY_DEBUG
                  
                  // Enable and select radio type attached
                  #define MY_RADIO_NRF24
                  //#define MY_RADIO_RFM69
                  
                  #include <SPI.h>
                  #include <MySensor.h>  
                  #include <DHT.h>
                  #include <Vcc.h>  
                  
                  
                  
                  //Constants
                  #define SKETCH_NAME           "3 in 1 Sensor"
                  #define SKETCH_VERSION        "1.0"
                  #define CHILD_ID_HUM 0                    // Child id for Humidity
                  #define CHILD_ID_TEMP 1                   // Child id for Temperature
                  #define CHILD_ID_MOT 2                   // Id of the sensor child
                  #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
                  #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)
                  
                  //Misc. variables
                  uint8_t switchState = 2;
                  unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
                  unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
                  uint8_t cycleInProgress = 0;
                  uint8_t firstReportDone = 0;
                  uint8_t firstReportWithZeroDone = 0;
                  const float VccExpected   = 3.0;
                  const float VccCorrection = 2.860/2.92;  // Measured Vcc by multimeter divided by reported Vcc
                  Vcc vcc(VccCorrection);
                  static int oldBatteryPcnt = 0;
                  
                  MySensor gw;
                  DHT dht;
                  float lastTemp = 0 ;
                  float lastHum = 0 ;
                  boolean lastTripped = false ;
                  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("3 in 1 Sensor", "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; 
                    
                    if (tripped != lastTripped ) {      
                      Serial.println(tripped);
                      gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
                    }
                    delay(dht.getMinimumSamplingPeriod());
                  
                    float temperature = dht.getTemperature();
                    float humidity = dht.getHumidity();
                    
                    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);
                    }
                    
                    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);
                    }
                    // Read Battery Value
                      int batteryPcnt = (int)vcc.Read_Perc(VccExpected);
                      if (oldBatteryPcnt != batteryPcnt)
                      {
                          gw.sendBatteryLevel(batteryPcnt);
                          oldBatteryPcnt = batteryPcnt;
                      }
                    // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
                    gw.sleep(DIGITAL_INPUT_SENSOR, CHANGE, 0 );
                  }
                  
                  AWIA 1 Reply Last reply
                  0
                  • rhuehnR rhuehn

                    Hello @AWI and @dynamite

                    My apologies for the delay in this reply as I was travelling and did not have access to the net... Thank you both for the replies, I just got back and couldn't wait to reply:

                    @AWI I will comment on the items below from your first post, below:

                    PIR HC-SR501 is standard a 5V sensor. You need to modify / connect it different to have it work at 3.3V
                    This has been modified to work @ 3.3V

                    The PIR will not allow for lower consumption that around 60uA (that is what it takes).
                    Using the gw.sleep() with a timer value takes around 6uA , you can only go lower by using only interrupt.
                    I believe I need to look at this at this seems to be a better option, and more suitable for the application

                    A pro-mini should be modified. At least remove/ disconnect the led and preferably the regulator.
                    These have also been modified as mentioned by yourself.

                    Burning a bootloader to run on 1 mHz will reduce the consumption by a few percent only when active (not in sleep). But keeps the arduino awake longer when a lot of processing is to be done. So just keep it at 8 mHz.
                    Sounds like a great idea, I will keep it as is

                    I believe @dynamite is referencing this post above, and BTW @dynamite I want to do the EXACT same thing:

                    link Here

                    So a few things, based on that Ikea module, We are trying to acheive the lowest power consumption from either 2 or 3 X AA Batteries. modified to work with perhaps a PIR HC-SR501 ( discarding the original ), along with a DHT11 ( or 22 ), and report battery levels, and send the information back to a gateway, perhaps every hour unless the temp changes +/- 1 degree, or the PIR wakes, causing an action to be triggered, then go back to deep sleep.

                    I tried a few modification to your suggestions, but lost functionality with the PIR, and battery reporting. My sketch is below, and not working very well:

                     #define MY_NODE_ID 31
                    // Enable debug prints
                    #define MY_DEBUG
                    
                    // Enable and select radio type attached
                    #define MY_RADIO_NRF24
                    //#define MY_RADIO_RFM69
                    
                    #include <SPI.h>
                    #include <MySensor.h>  
                    #include <DHT.h>
                    #include <Vcc.h>  
                    
                    
                    
                    //Constants
                    #define SKETCH_NAME           "3 in 1 Sensor"
                    #define SKETCH_VERSION        "1.0"
                    #define CHILD_ID_HUM 0                    // Child id for Humidity
                    #define CHILD_ID_TEMP 1                   // Child id for Temperature
                    #define CHILD_ID_MOT 2                   // Id of the sensor child
                    #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
                    #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)
                    
                    //Misc. variables
                    uint8_t switchState = 2;
                    unsigned long SLEEP_TIME = 820000;      // Sleep time between reads (in milliseconds) (close to 15')
                    unsigned long SLEEP_TIME2 = 275000;     // Sleep time after int. (in milliseconds) (close to 5')
                    uint8_t cycleInProgress = 0;
                    uint8_t firstReportDone = 0;
                    uint8_t firstReportWithZeroDone = 0;
                    const float VccExpected   = 3.0;
                    const float VccCorrection = 2.860/2.92;  // Measured Vcc by multimeter divided by reported Vcc
                    Vcc vcc(VccCorrection);
                    static int oldBatteryPcnt = 0;
                    
                    MySensor gw;
                    DHT dht;
                    float lastTemp = 0 ;
                    float lastHum = 0 ;
                    boolean lastTripped = false ;
                    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("3 in 1 Sensor", "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; 
                      
                      if (tripped != lastTripped ) {      
                        Serial.println(tripped);
                        gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw 
                      }
                      delay(dht.getMinimumSamplingPeriod());
                    
                      float temperature = dht.getTemperature();
                      float humidity = dht.getHumidity();
                      
                      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);
                      }
                      
                      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);
                      }
                      // Read Battery Value
                        int batteryPcnt = (int)vcc.Read_Perc(VccExpected);
                        if (oldBatteryPcnt != batteryPcnt)
                        {
                            gw.sendBatteryLevel(batteryPcnt);
                            oldBatteryPcnt = batteryPcnt;
                        }
                      // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
                      gw.sleep(DIGITAL_INPUT_SENSOR, CHANGE, 0 );
                    }
                    
                    AWIA Offline
                    AWIA Offline
                    AWI
                    Hero Member
                    wrote on last edited by
                    #9

                    @rhuehn At first glance.. int batteryPcnt = (int)vcc.Read_Perc(VccExpected); needs more arguments, try
                    int batteryPcnt = (int)vcc.Read_Perc(VccMinimal, VccMaximal); where VccMaximal / VccMinimal is the highest/lowest battery level expected ... For a DHT sensor this would be around 3 volts.. which makes this sensor less interesting for low power applications...

                    1 Reply Last reply
                    0
                    • rhuehnR Offline
                      rhuehnR Offline
                      rhuehn
                      wrote on last edited by
                      #10

                      Thanks @AWI I have modified the sketch, and everything below seems to be working ok. If you can look at it, and post a comment if you think it is the most optimal for power use, and the vcc readings are correct it would be greatly appreciated. The complete sketch is below. I will likely look at changing the DHT's to HTU21 in the future. Is there a low powered PIR that you know of?:

                       #define MY_GW_ID 31
                      // Enable debug prints
                      #define MY_DEBUG
                      
                      // Enable and select radio type attached
                      #define MY_RADIO_NRF24
                      //#define MY_RADIO_RFM69
                      
                      #include <SPI.h>
                      #include <MySensor.h>  
                      #include <DHT.h>  
                      #include <Vcc.h>
                      
                      //Constants
                      #define SKETCH_NAME           "3 in 1 Sensor"
                      #define SKETCH_VERSION        "1.0"
                      #define CHILD_ID_TEMP 1                  // Child id for Temperature
                      #define CHILD_ID_HUM 0                   // Child id for Humidity
                      #define CHILD_ID_VOLT 3                  // Child id for battery reading
                      #define CHILD_ID_MOT 2                   // Id of the sensor child
                      #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
                      #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)
                      
                      int node_id=31;                        // What is my node id
                      
                      //Misc. variables
                      unsigned long SLEEP_TIME =60000UL;    // Sleep time between reads (in milliseconds)
                      int sleepcycle=1;                     // Counter to count the amout of time not sending data
                      int humoffset=2;                      // only data is send if humidity is changed for this amout
                      int tempoffset=1.0;                   // only data is if temperature is changed for this amout 
                      int gwsendtimout=20;                  // each 20*sleep_time (20 minutes) data will be send
                      
                      const float VccMin   = 1.7;           // Minimum expected Vcc level, in Volts.
                      const float VccMax   = 3.1;           // Maximum expected Vcc level, in Volts.
                      const float VccCorrection = 1.0/1.0;  // Measured Vcc by multimeter divided by reported Vcc
                      
                      Vcc vcc(VccCorrection);
                      
                      MySensor gw;
                      DHT dht;
                      //Store last values
                      float lastTemp = 0 ;                  
                      float lastHum = 0 ;
                      float batteryV=0;
                      int oldBatteryPcnt = 0;             
                      
                      boolean lastTripped = false ;
                      boolean metric = true; 
                      
                      boolean gwsend = true;              // to determin if data has to be send
                      
                      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
                      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
                      MyMessage msgVolt(CHILD_ID_VOLT, V_VOLTAGE);
                      MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
                      
                      void setup()  
                      { 
                        gw.begin(NULL,node_id,false);
                        dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
                      
                        // Send the Sketch Version Information to the Gateway
                        gw.sendSketchInfo("3 in 1 Sensor", "1.0",true);
                      
                      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,"Kitchen Humidity");
                        gw.present(CHILD_ID_TEMP, S_TEMP,"Kitchen Temperature");
                        gw.present(CHILD_ID_VOLT, S_MULTIMETER,"Kitchen Battery Voltage");
                         
                        metric = gw.getConfig().isMetric;
                      }
                      
                      void loop()      
                      
                      {  
                        // get the battery Voltage
                         batteryV  = vcc.Read_Volts();
                         int batteryPcnt = vcc.Read_Perc(VccMin, VccMax);
                      
                         if (oldBatteryPcnt != batteryPcnt) {
                           // Power up radio after sleep
                           gwsend=true;
                           oldBatteryPcnt = batteryPcnt;
                         }
                          
                        delay(dht.getMinimumSamplingPeriod());
                      
                        float temp1 = dht.getTemperature();
                        float humidity = dht.getHumidity();
                      
                        if (isnan(temp1)) {
                      //      Serial.println("Failed reading temperature from DHT");
                        } else if ((temp1 <= lastTemp-tempoffset)||(temp1 >= lastTemp+tempoffset)) {
                          lastTemp = temp1;
                          if (!metric) {
                            temp1 = dht.toFahrenheit(temp1);
                          }
                          gwsend=true;
                        }
                      
                        if (isnan(humidity)) {
                          //      Serial.println("Failed reading humidity from DHT");
                        } else if ((humidity <= lastHum-humoffset)||(humidity >= lastHum+humoffset)) {
                            lastHum = humidity;
                            gwsend=true;
                          }
                      
                        if (sleepcycle>gwsendtimout){
                          gwsend=true;
                         }
                      
                        // Read digital motion value
                        boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
                        
                        if (tripped != lastTripped ) {      
                          Serial.println(tripped);
                           
                      
                      if (gwsend){     
                          gw.sendBatteryLevel(oldBatteryPcnt);
                          gw.send(msgVolt.set(batteryV, 1));
                          gw.send(msgTemp.set(lastTemp, 1));  
                          gw.send(msgHum.set(lastHum, 1));
                          gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw
                          gwsend=false;
                          sleepcycle=1;
                        }
                        sleepcycle++;  
                        gw.sleep(INTERRUPT, CHANGE, 0 );
                      }
                      }
                      

                      Thanks again

                      AWIA 1 Reply Last reply
                      0
                      • rhuehnR rhuehn

                        Thanks @AWI I have modified the sketch, and everything below seems to be working ok. If you can look at it, and post a comment if you think it is the most optimal for power use, and the vcc readings are correct it would be greatly appreciated. The complete sketch is below. I will likely look at changing the DHT's to HTU21 in the future. Is there a low powered PIR that you know of?:

                         #define MY_GW_ID 31
                        // Enable debug prints
                        #define MY_DEBUG
                        
                        // Enable and select radio type attached
                        #define MY_RADIO_NRF24
                        //#define MY_RADIO_RFM69
                        
                        #include <SPI.h>
                        #include <MySensor.h>  
                        #include <DHT.h>  
                        #include <Vcc.h>
                        
                        //Constants
                        #define SKETCH_NAME           "3 in 1 Sensor"
                        #define SKETCH_VERSION        "1.0"
                        #define CHILD_ID_TEMP 1                  // Child id for Temperature
                        #define CHILD_ID_HUM 0                   // Child id for Humidity
                        #define CHILD_ID_VOLT 3                  // Child id for battery reading
                        #define CHILD_ID_MOT 2                   // Id of the sensor child
                        #define HUMIDITY_SENSOR_DIGITAL_PIN 7    // Where is my DHT22 data pin connected to
                        #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)
                        
                        int node_id=31;                        // What is my node id
                        
                        //Misc. variables
                        unsigned long SLEEP_TIME =60000UL;    // Sleep time between reads (in milliseconds)
                        int sleepcycle=1;                     // Counter to count the amout of time not sending data
                        int humoffset=2;                      // only data is send if humidity is changed for this amout
                        int tempoffset=1.0;                   // only data is if temperature is changed for this amout 
                        int gwsendtimout=20;                  // each 20*sleep_time (20 minutes) data will be send
                        
                        const float VccMin   = 1.7;           // Minimum expected Vcc level, in Volts.
                        const float VccMax   = 3.1;           // Maximum expected Vcc level, in Volts.
                        const float VccCorrection = 1.0/1.0;  // Measured Vcc by multimeter divided by reported Vcc
                        
                        Vcc vcc(VccCorrection);
                        
                        MySensor gw;
                        DHT dht;
                        //Store last values
                        float lastTemp = 0 ;                  
                        float lastHum = 0 ;
                        float batteryV=0;
                        int oldBatteryPcnt = 0;             
                        
                        boolean lastTripped = false ;
                        boolean metric = true; 
                        
                        boolean gwsend = true;              // to determin if data has to be send
                        
                        MyMessage msgHum(CHILD_ID_HUM, V_HUM);
                        MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
                        MyMessage msgVolt(CHILD_ID_VOLT, V_VOLTAGE);
                        MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
                        
                        void setup()  
                        { 
                          gw.begin(NULL,node_id,false);
                          dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
                        
                          // Send the Sketch Version Information to the Gateway
                          gw.sendSketchInfo("3 in 1 Sensor", "1.0",true);
                        
                        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,"Kitchen Humidity");
                          gw.present(CHILD_ID_TEMP, S_TEMP,"Kitchen Temperature");
                          gw.present(CHILD_ID_VOLT, S_MULTIMETER,"Kitchen Battery Voltage");
                           
                          metric = gw.getConfig().isMetric;
                        }
                        
                        void loop()      
                        
                        {  
                          // get the battery Voltage
                           batteryV  = vcc.Read_Volts();
                           int batteryPcnt = vcc.Read_Perc(VccMin, VccMax);
                        
                           if (oldBatteryPcnt != batteryPcnt) {
                             // Power up radio after sleep
                             gwsend=true;
                             oldBatteryPcnt = batteryPcnt;
                           }
                            
                          delay(dht.getMinimumSamplingPeriod());
                        
                          float temp1 = dht.getTemperature();
                          float humidity = dht.getHumidity();
                        
                          if (isnan(temp1)) {
                        //      Serial.println("Failed reading temperature from DHT");
                          } else if ((temp1 <= lastTemp-tempoffset)||(temp1 >= lastTemp+tempoffset)) {
                            lastTemp = temp1;
                            if (!metric) {
                              temp1 = dht.toFahrenheit(temp1);
                            }
                            gwsend=true;
                          }
                        
                          if (isnan(humidity)) {
                            //      Serial.println("Failed reading humidity from DHT");
                          } else if ((humidity <= lastHum-humoffset)||(humidity >= lastHum+humoffset)) {
                              lastHum = humidity;
                              gwsend=true;
                            }
                        
                          if (sleepcycle>gwsendtimout){
                            gwsend=true;
                           }
                        
                          // Read digital motion value
                          boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
                          
                          if (tripped != lastTripped ) {      
                            Serial.println(tripped);
                             
                        
                        if (gwsend){     
                            gw.sendBatteryLevel(oldBatteryPcnt);
                            gw.send(msgVolt.set(batteryV, 1));
                            gw.send(msgTemp.set(lastTemp, 1));  
                            gw.send(msgHum.set(lastHum, 1));
                            gw.send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw
                            gwsend=false;
                            sleepcycle=1;
                          }
                          sleepcycle++;  
                          gw.sleep(INTERRUPT, CHANGE, 0 );
                        }
                        }
                        

                        Thanks again

                        AWIA Offline
                        AWIA Offline
                        AWI
                        Hero Member
                        wrote on last edited by
                        #11

                        @rhuehn your sketch looks good. A small optimization can be made by sending the individual values only if they changed.

                        I don't have a low power alternative for the pir but there are some threads in this forum discussing these.

                        Have you measured the consumption of your circuit? That would be the best way to go forward. You don't need an expensive meter to get the grabs

                        1 Reply Last reply
                        0
                        • rhuehnR Offline
                          rhuehnR Offline
                          rhuehn
                          wrote on last edited by
                          #12

                          Thanks @AWI for the reply. I thought I was sending values based on the above code with the following:

                          //Misc. variables
                          unsigned long SLEEP_TIME =60000UL;    // Sleep time between reads (in milliseconds)
                          int sleepcycle=1;                     // Counter to count the amout of time not sending data
                          int humoffset=2;                      // only data is send if humidity is changed for this amout
                          int tempoffset=1.0;                   // only data is if temperature is changed for this amout 
                          int gwsendtimout=20;                  // each 20*sleep_time (20 minutes) data will be send
                          

                          The Temp and Humidity in the sketch is quite honestly of lower importance to me as the PIR. I believe ( please correct me if I am wrong ), but the sensor should only report every 20 minutes, and only if a temp changes by a degree or humidity changes by 2 correct?

                          The PIR, and sensor should sleep as often as possible, but based on motion in the vicinity of the sensor, should trigger an action immediately, and based on that, could send the temp and hum readings at the same time, OR every 20 minutes if there is a change...

                          Thanks @AWI comments welcome.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          16

                          Online

                          11.7k

                          Users

                          11.2k

                          Topics

                          113.0k

                          Posts


                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • MySensors
                          • OpenHardware.io
                          • Categories
                          • Recent
                          • Tags
                          • Popular