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. My Project
  3. My 2AA battery sensor

My 2AA battery sensor

Scheduled Pinned Locked Moved My Project
90 Posts 27 Posters 106.7k Views 36 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.
  • TheoLT Online
    TheoLT Online
    TheoL
    Contest Winner
    wrote on last edited by
    #56

    Not sure if any one has had the same question. But the other day I stumbled on this little thing ;)
    https://www.adafruit.com/product/1572 It's a really small rechargeable battery. Now I don't no much about batteries. But I know that my LiOn powerd handdrill is very strong. The batteries of my handdril hardly lose power over time.

    So I was wondering if this could be used to power an Arduino and some sensors and how long it will take for the battery te become empty. It would make my 3.3V Sensors really small. I could almost install them in a small matchbox. Which I think is really cool!

    m26872M 1 Reply Last reply
    0
    • TheoLT TheoL

      Not sure if any one has had the same question. But the other day I stumbled on this little thing ;)
      https://www.adafruit.com/product/1572 It's a really small rechargeable battery. Now I don't no much about batteries. But I know that my LiOn powerd handdrill is very strong. The batteries of my handdril hardly lose power over time.

      So I was wondering if this could be used to power an Arduino and some sensors and how long it will take for the battery te become empty. It would make my 3.3V Sensors really small. I could almost install them in a small matchbox. Which I think is really cool!

      m26872M Offline
      m26872M Offline
      m26872
      Hardware Contributor
      wrote on last edited by
      #57

      @TheoL There are endless discussions about different batteries in the forum. Just search and read. I recall one issue with LiXx batteries is that max voltage is too high for the NRF24L01+ radio.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Meister_Petz
        wrote on last edited by
        #58

        Ok, another thing: why not sending everything at once?

        As I understand you are using FHEM which allows a lot of coding on the controller side. So you could send batteryLevel, humidity and temperature in one go.

        Something like (this is no real code, just an idea):
        theValues = "battlvl:hum:temp"
        gw.send(msgAll.set(theValues, 1));

        and in fhem you split it at ":"

        So you have just one instead of 3 transmits.

        m26872M 1 Reply Last reply
        0
        • M Meister_Petz

          Ok, another thing: why not sending everything at once?

          As I understand you are using FHEM which allows a lot of coding on the controller side. So you could send batteryLevel, humidity and temperature in one go.

          Something like (this is no real code, just an idea):
          theValues = "battlvl:hum:temp"
          gw.send(msgAll.set(theValues, 1));

          and in fhem you split it at ":"

          So you have just one instead of 3 transmits.

          m26872M Offline
          m26872M Offline
          m26872
          Hardware Contributor
          wrote on last edited by
          #59

          @Meister_Petz I think it's a very good idea! It would be a nice option to have. Parsing with Perl should be simple even for a beginner like me, but to change the Mysensors core and fhem plugin is far beyond what I can. If you can do it, just go ahead and plz share.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Meister_Petz
            wrote on last edited by
            #60

            ok, I did some testing and succeeded:

            This is the important part of the Arduino code:

            String allSens = String(sensor1) + " " + String(sensor2);
            gw.send(msg1.set(allSens.c_str()));
            

            This is the FHEM code:

            define Sensor MYSENSORS_DEVICE 20
            attr Sensor IODev MSGateway
            attr Sensor mapReading_brightness1 1 brightness
            attr Sensor mode node
            attr Sensor version 1.5
            attr Sensor userReadings Bat Deg
            
            # split and copy to userReadings
            define Sensor.copy at +*00:02:00 {my $a = ReadingsVal("Sensor","brightness1",1);; my @b = split(/\ /,$a);; fhem("setreading Sensor Bat $b[0]");; fhem("setreading Sensor Grad $b[1]");;}
            

            P.S.: when I had this in fhem.cfg I had to use @@ instead of only one @

            This is my complete Arduino code for a Battery Sensor with Dallas Temp:

              
            #include <MySensor.h>
            #include <SPI.h>
            
            #define SketchName "Sensor-send-all"
            #define SketchVer "1.2"
            #define NodeID 20
            
            unsigned long SleepTime = 828523; // 55234 = 1 Minute --- 828523 = 15 Minuten
              
            MySensor gw;
            
            // this is the one which sends everything
            #define SENSOR1_ID 1 // Sensor 1 - allAtOnceMessage
                
              //------------------------------------------------
              // Sensor PINS 
                #define SENSOR1_PIN  A0 // BattLevel
                #define SENSOR2_PIN  6  // Dallas
                  
              // MyMessage V_TEMP, V_LIGHT_LEVEL, ... depending on Sensor Type
                 MyMessage msg1(SENSOR1_ID,V_LIGHT_LEVEL); // Sensor 5 - allAtOnceMessage
            
              //------------------------------------------------
              // Dallas Temp
                 #include <OneWire.h>
                 #include <DallasTemperature.h>      
                 OneWire oneWire(SENSOR2_PIN);
                 DallasTemperature sensors(&oneWire);
                 boolean receivedConfig = false;
                     
                 float firstRun = 1;
                 boolean metric = true;
              
            void setup()  
              {  
                // use the 1.1 V internal reference
                analogReference(INTERNAL);
                delay(500); // Allow time for radio if power used as reset <<<<<<<<<<<<<< Experimented with good result 
              
                gw.begin(NULL, NodeID, false);
              
                // Send the sketch version information to the gateway and Controller
                gw.sendSketchInfo(SketchName, SketchVer);
                    
                // present all Sensors to Gateway - S_TEMP, S_LIGHT_LEVEL,... depending an SENSOR type
                gw.present(SENSOR1_ID, S_LIGHT_LEVEL);     
                    
                sensors.begin();  
              }
              
              
            void loop() 
              {
                gw.process();
            
                   // wait some time to get all parts powered up
                   if (firstRun == 1){
                      delay(5000);
                      firstRun = 0;
                   } else {
                      delay(1000);
                   }
                   
                   //----------------------
                   // Sensor1 - Battery Voltage - Part 1
                      int sensorRead10 = analogRead(SENSOR1_PIN); 
            
                   //----------------------
                   // Sensor2 - DAL
                     sensors.requestTemperatures();
                     int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                     gw.sleep(conversionTime);
                     float sensorRead2 = static_cast<float>(static_cast<int>((metric?sensors.getTempCByIndex(0):sensors.getTempFByIndex(0)) * 10.)) / 10.;
            
                   //----------------------
                   // Sensor1 - Battery Voltage - Part 2
                      int sensorRead11 = analogRead(SENSOR1_PIN);
                      //Volt der Battery
                      
                      float sensorRead1 = (sensorRead10 + sensorRead11 + sensorRead12) / 3 * 0.0033;  // should be 0.003363075 my Batteries are different
                      float test = sensorRead10;
            
            
                   //----------------------
                   // send all to fhem
                      String allComb = String(sensorRead1) + " " + String(sensorRead2);
                      gw.send(msg1.set(allComb.c_str()));
            
                  gw.sleep(SleepTime);
              } 
              
             
            
            m26872M 1 Reply Last reply
            2
            • M Meister_Petz

              ok, I did some testing and succeeded:

              This is the important part of the Arduino code:

              String allSens = String(sensor1) + " " + String(sensor2);
              gw.send(msg1.set(allSens.c_str()));
              

              This is the FHEM code:

              define Sensor MYSENSORS_DEVICE 20
              attr Sensor IODev MSGateway
              attr Sensor mapReading_brightness1 1 brightness
              attr Sensor mode node
              attr Sensor version 1.5
              attr Sensor userReadings Bat Deg
              
              # split and copy to userReadings
              define Sensor.copy at +*00:02:00 {my $a = ReadingsVal("Sensor","brightness1",1);; my @b = split(/\ /,$a);; fhem("setreading Sensor Bat $b[0]");; fhem("setreading Sensor Grad $b[1]");;}
              

              P.S.: when I had this in fhem.cfg I had to use @@ instead of only one @

              This is my complete Arduino code for a Battery Sensor with Dallas Temp:

                
              #include <MySensor.h>
              #include <SPI.h>
              
              #define SketchName "Sensor-send-all"
              #define SketchVer "1.2"
              #define NodeID 20
              
              unsigned long SleepTime = 828523; // 55234 = 1 Minute --- 828523 = 15 Minuten
                
              MySensor gw;
              
              // this is the one which sends everything
              #define SENSOR1_ID 1 // Sensor 1 - allAtOnceMessage
                  
                //------------------------------------------------
                // Sensor PINS 
                  #define SENSOR1_PIN  A0 // BattLevel
                  #define SENSOR2_PIN  6  // Dallas
                    
                // MyMessage V_TEMP, V_LIGHT_LEVEL, ... depending on Sensor Type
                   MyMessage msg1(SENSOR1_ID,V_LIGHT_LEVEL); // Sensor 5 - allAtOnceMessage
              
                //------------------------------------------------
                // Dallas Temp
                   #include <OneWire.h>
                   #include <DallasTemperature.h>      
                   OneWire oneWire(SENSOR2_PIN);
                   DallasTemperature sensors(&oneWire);
                   boolean receivedConfig = false;
                       
                   float firstRun = 1;
                   boolean metric = true;
                
              void setup()  
                {  
                  // use the 1.1 V internal reference
                  analogReference(INTERNAL);
                  delay(500); // Allow time for radio if power used as reset <<<<<<<<<<<<<< Experimented with good result 
                
                  gw.begin(NULL, NodeID, false);
                
                  // Send the sketch version information to the gateway and Controller
                  gw.sendSketchInfo(SketchName, SketchVer);
                      
                  // present all Sensors to Gateway - S_TEMP, S_LIGHT_LEVEL,... depending an SENSOR type
                  gw.present(SENSOR1_ID, S_LIGHT_LEVEL);     
                      
                  sensors.begin();  
                }
                
                
              void loop() 
                {
                  gw.process();
              
                     // wait some time to get all parts powered up
                     if (firstRun == 1){
                        delay(5000);
                        firstRun = 0;
                     } else {
                        delay(1000);
                     }
                     
                     //----------------------
                     // Sensor1 - Battery Voltage - Part 1
                        int sensorRead10 = analogRead(SENSOR1_PIN); 
              
                     //----------------------
                     // Sensor2 - DAL
                       sensors.requestTemperatures();
                       int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                       gw.sleep(conversionTime);
                       float sensorRead2 = static_cast<float>(static_cast<int>((metric?sensors.getTempCByIndex(0):sensors.getTempFByIndex(0)) * 10.)) / 10.;
              
                     //----------------------
                     // Sensor1 - Battery Voltage - Part 2
                        int sensorRead11 = analogRead(SENSOR1_PIN);
                        //Volt der Battery
                        
                        float sensorRead1 = (sensorRead10 + sensorRead11 + sensorRead12) / 3 * 0.0033;  // should be 0.003363075 my Batteries are different
                        float test = sensorRead10;
              
              
                     //----------------------
                     // send all to fhem
                        String allComb = String(sensorRead1) + " " + String(sensorRead2);
                        gw.send(msg1.set(allComb.c_str()));
              
                    gw.sleep(SleepTime);
                } 
                
               
              
              m26872M Offline
              m26872M Offline
              m26872
              Hardware Contributor
              wrote on last edited by
              #61

              @Meister_Petz Wow! Well done! I think this can be very useful.
              In theory some power should be saved. Estimation from here is that a 250kbit/s transmission of a maximum size (32 byte) packet is >1.5ms. I think at around 20mA. Massage header is 7 byte, but a normal massage just a few bytes, i.e. just 30% of a message. Startup time for radio is fast (140us), so that shouldn't be an issue. (A side note here is that wake up atmega328p from sleep takes long (6ms?).)

              Is there a reason that you wrote the Fhem sonsor.copy macro as an "at" and not a "notify" ? The intuitive way would be to copy upon a new reading.

              M 1 Reply Last reply
              0
              • m26872M m26872

                @Meister_Petz Wow! Well done! I think this can be very useful.
                In theory some power should be saved. Estimation from here is that a 250kbit/s transmission of a maximum size (32 byte) packet is >1.5ms. I think at around 20mA. Massage header is 7 byte, but a normal massage just a few bytes, i.e. just 30% of a message. Startup time for radio is fast (140us), so that shouldn't be an issue. (A side note here is that wake up atmega328p from sleep takes long (6ms?).)

                Is there a reason that you wrote the Fhem sonsor.copy macro as an "at" and not a "notify" ? The intuitive way would be to copy upon a new reading.

                M Offline
                M Offline
                Meister_Petz
                wrote on last edited by
                #62

                @m26872 there is no special reason for "at"... I think I got it from some where and it worked ;-)

                1 Reply Last reply
                0
                • m26872M Offline
                  m26872M Offline
                  m26872
                  Hardware Contributor
                  wrote on last edited by
                  #63

                  Soon 11 months of production including a fair amount of too frequent battery uppdates. Most exciting is wheter the initially used batteries in 106 will make it 12 months or not.
                  Node105_20151002.PNG
                  Node106_20151002.PNG

                  AnticimexA 1 Reply Last reply
                  0
                  • m26872M m26872

                    Soon 11 months of production including a fair amount of too frequent battery uppdates. Most exciting is wheter the initially used batteries in 106 will make it 12 months or not.
                    Node105_20151002.PNG
                    Node106_20151002.PNG

                    AnticimexA Offline
                    AnticimexA Offline
                    Anticimex
                    Contest Winner
                    wrote on last edited by
                    #64

                    @m26872 perhaps you could reduce the redundant updates by filtering. If the current sample is lower than the "next" sample ignore it. If your node does not support charging, it will never really truly read an increase in battery voltage.

                    Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                    m26872M 1 Reply Last reply
                    0
                    • AnticimexA Anticimex

                      @m26872 perhaps you could reduce the redundant updates by filtering. If the current sample is lower than the "next" sample ignore it. If your node does not support charging, it will never really truly read an increase in battery voltage.

                      m26872M Offline
                      m26872M Offline
                      m26872
                      Hardware Contributor
                      wrote on last edited by
                      #65

                      @Anticimex Yes, but in this particular case its double. Conclusion from above was that frequency and magnitude of the "low spikes" gives you information of how near the end you are. On the other hand I would never run like this if it wasn't for keeping the experiment "untouched". I think my thought for future sensors is to preserve that information, but save battery, just by reducing the number of samples.

                      I'm still not sure of the best filter/algorithm to predict battery end of life from present and historic data. It will probably differ a lot wheter there's a step-up or a nicer load.

                      YveauxY 1 Reply Last reply
                      0
                      • m26872M m26872

                        @Anticimex Yes, but in this particular case its double. Conclusion from above was that frequency and magnitude of the "low spikes" gives you information of how near the end you are. On the other hand I would never run like this if it wasn't for keeping the experiment "untouched". I think my thought for future sensors is to preserve that information, but save battery, just by reducing the number of samples.

                        I'm still not sure of the best filter/algorithm to predict battery end of life from present and historic data. It will probably differ a lot wheter there's a step-up or a nicer load.

                        YveauxY Offline
                        YveauxY Offline
                        Yveaux
                        Mod
                        wrote on last edited by
                        #66

                        @m26872 Just a suggestion: once the node dies you could take the raw data and run some filtering on it like @Anticimex suggested.
                        It'll give you a quick way to experiment with different filter settings.
                        Once you find an optimal filter you can implement it in the node(s).

                        http://yveaux.blogspot.nl

                        m26872M 1 Reply Last reply
                        0
                        • YveauxY Yveaux

                          @m26872 Just a suggestion: once the node dies you could take the raw data and run some filtering on it like @Anticimex suggested.
                          It'll give you a quick way to experiment with different filter settings.
                          Once you find an optimal filter you can implement it in the node(s).

                          m26872M Offline
                          m26872M Offline
                          m26872
                          Hardware Contributor
                          wrote on last edited by
                          #67

                          @Yveaux You're right. I expect a good correlation between "spike depth" and the load profile just prior to sample. By controling this it should be quite repeatable.

                          1 Reply Last reply
                          0
                          • mntlvrM Offline
                            mntlvrM Offline
                            mntlvr
                            wrote on last edited by
                            #68
                            This post is deleted!
                            m26872M 1 Reply Last reply
                            0
                            • mntlvrM mntlvr

                              This post is deleted!

                              m26872M Offline
                              m26872M Offline
                              m26872
                              Hardware Contributor
                              wrote on last edited by
                              #69

                              @mntlvr Interesting discussion but why in this thread?

                              mntlvrM 1 Reply Last reply
                              0
                              • m26872M m26872

                                @mntlvr Interesting discussion but why in this thread?

                                mntlvrM Offline
                                mntlvrM Offline
                                mntlvr
                                wrote on last edited by
                                #70
                                This post is deleted!
                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  ahhk
                                  Hardware Contributor
                                  wrote on last edited by
                                  #71

                                  i think it would be better to open a new thread for this, instead to discuss two topics in one thread....the 2xaa battery sensor is very interesting ;)

                                  1 Reply Last reply
                                  0
                                  • m26872M m26872

                                    I declare the 6 months criteria easily passed. And the chinese step up regulator to be good value for money. Next target; 12 months.
                                    Nod105106_maj09.png

                                    m26872M Offline
                                    m26872M Offline
                                    m26872
                                    Hardware Contributor
                                    wrote on last edited by m26872
                                    #72

                                    The 12 months target was done a few days ago. Today's status 105: 63% and 106: 27%
                                    I had a thought to celebrate their birthday by retrieve old Vera data and make nice plot, but that has to wait. Next, 18 months.

                                    Just to clarify that these are no "sleeping" nodes; they transmit 100-150 messages each every day.

                                    1 Reply Last reply
                                    3
                                    • m26872M Offline
                                      m26872M Offline
                                      m26872
                                      Hardware Contributor
                                      wrote on last edited by
                                      #73

                                      Battery level status report after 18 months:
                                      Node 105: 51%
                                      Node 106 (with used batteries): Died early January.

                                      Next 24 months.

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

                                        Hey @m26872 Congrats on the testing and results! Looks great! I was wondering if I could get your feedback on something. 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 ( not implemented yet ). Because these components use power hungry devices ( PIR, DHT ), I have already moded the PIR to work at 3.3, and have removed the regulator / LED from the pro mini. Would it make sense to use a step up / down regulator, or power directly from the VCC pin? I can't decide what would be more effective in prolonging battery life? Also, in terms of reporting battery state. I'm not sure what would be best also, hence the question around the VCC library?

                                        Below is my sketch. It is really taken from various posts on this forum and stitched together. If you could have a peak at it, and see if it is "optimal", as I don't believe it is today. ie: Perhaps I could only report temp / hum if it changes +/- a degree? Or send everything in a single radio announcement, then "Deep Sleep"? Lots of questions, and of course I am sure there are lots of answers. I'm just trying to build the most optimal battery efficient ( 2 x AA ) powered sensor no problem right! :) Below is my current code:

                                         #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("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()      
                                        
                                        {  
                                        
                                           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);
                                          }
                                          
                                          // 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
                                        
                                          // 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 
                                          }
                                          
                                           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, 0 );
                                        }
                                        

                                        thanks very much!

                                        AWIA 1 Reply Last reply
                                        0
                                        • rhuehnR rhuehn

                                          Hey @m26872 Congrats on the testing and results! Looks great! I was wondering if I could get your feedback on something. 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 ( not implemented yet ). Because these components use power hungry devices ( PIR, DHT ), I have already moded the PIR to work at 3.3, and have removed the regulator / LED from the pro mini. Would it make sense to use a step up / down regulator, or power directly from the VCC pin? I can't decide what would be more effective in prolonging battery life? Also, in terms of reporting battery state. I'm not sure what would be best also, hence the question around the VCC library?

                                          Below is my sketch. It is really taken from various posts on this forum and stitched together. If you could have a peak at it, and see if it is "optimal", as I don't believe it is today. ie: Perhaps I could only report temp / hum if it changes +/- a degree? Or send everything in a single radio announcement, then "Deep Sleep"? Lots of questions, and of course I am sure there are lots of answers. I'm just trying to build the most optimal battery efficient ( 2 x AA ) powered sensor no problem right! :) Below is my current code:

                                           #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("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()      
                                          
                                          {  
                                          
                                             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);
                                            }
                                            
                                            // 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
                                          
                                            // 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 
                                            }
                                            
                                             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, 0 );
                                          }
                                          

                                          thanks very much!

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

                                          @rhuehn It looks like you are repeating the conversation in this thread. Its better to continue the discussion there.

                                          1 Reply Last reply
                                          1
                                          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