Battery powered sensor last 1 week



  • I have made a sensor based an a Easy/Newbie PCB a pro Mini (3,3V 8Mhz with desolderd power LED and Regulator) attached a soil moisture sensor and checking every 2 hrs. The 2 AA batteries last just under a week.

    What do I need to do more to get it to last a little bit longer that just under a week?

    The sensor is the one here: https://www.mysensors.org/build/moisture

    Her is the code I have adapted to check for battery aswell

    /*
       The MySensors Arduino library handles the wireless radio link and protocol
       between your home built sensors/actuators and HA controller of choice.
       The sensors forms a self healing radio network with optional repeaters. Each
       repeater and gateway builds a routing tables in EEPROM which keeps track of the
       network topology allowing messages to be routed to nodes.
    
       Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       Copyright (C) 2013-2015 Sensnology AB
       Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    
       Documentation: http://www.mysensors.org
       Support Forum: http://forum.mysensors.org
    
       This program is free software; you can redistribute it and/or
       modify it under the terms of the GNU General Public License
       version 2 as published by the Free Software Foundation.
    
     *******************************
    
       DESCRIPTION
    
       Arduino soil moisture based on gypsum sensor/resistive sensor to avoid electric catalyse in soil
        Required to interface the sensor: 2 * 4.7kOhm + 2 * 1N4148
    
       Gypsum sensor and calibration:
          DIY: See http://vanderleevineyard.com/1/category/vinduino/1.html
          Built: Davis / Watermark 200SS
              http://www.cooking-hacks.com/watermark-soil-moisture-sensor?_bksrc=item2item&_bkloc=product
              http://www.irrometer.com/pdf/supportmaterial/sensors/voltage-WM-chart.pdf
              cb (centibar) http://www.irrometer.com/basics.html
                  0-10 Saturated Soil. Occurs for a day or two after irrigation
                  10-20 Soil is adequately wet (except coarse sands which are drying out at this range)
                  30-60 Usual range to irrigate or water (except heavy clay soils).
                  60-100 Usual range to irrigate heavy clay soils
                  100-200 Soil is becoming dangerously dry for maximum production. Proceed with caution.
    
       Connection:
        D6, D7: alternative powering to avoid sensor degradation
       A0, A1: alternative resistance mesuring
    
        Based on:
        "Vinduino" portable soil moisture sensor code V3.00
         Date December 31, 2012
         Reinier van der Lee and Theodore Kaskalis
         www.vanderleevineyard.com
       Contributor: epierre
    */
    
    // Copyright (C) 2015, Reinier van der Lee
    // www.vanderleevineyard.com
    
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 3 of the License, or
    // any later version.
    
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU General Public License for more details.
    
    // Enable debug prints to serial monitor
    //#define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #define  MY_NODE_ID 30
    int BATTERY_SENSE_PIN = A0;
    
    #include <math.h>       // Conversion equation from resistance to %
    #include <MySensors.h>
    
    // Setting up format for reading 3 soil sensors
    #define NUM_READS 10    // Number of sensor reads for filtering
    #define CHILD_ID 0
    
    MyMessage msg(CHILD_ID, V_LEVEL);
    unsigned long SLEEP_TIME = 7200000; //  Every 2 hrs //Sleep time between reads (in milliseconds)
    
    long buffer[NUM_READS];
    int index;
    
    int oldBatteryPcnt = 0;
    
    /// @brief Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
    typedef struct {
      int moisture; //!< Moisture
      long resistance; //!< Resistance
    } values;
    
    const long knownResistor = 4700;  // Constant value of known resistor in Ohms
    
    int supplyVoltage;                // Measured supply voltage
    int sensorVoltage;                // Measured sensor voltage
    
    values valueOf[NUM_READS];        // Calculated moisture percentages and resistances to be sorted and filtered
    
    int i;                            // Simple index variable
    
    void setup() {
    
    #if defined(__AVR_ATmega2560__)
      analogReference(INTERNAL1V1);
    #else
      analogReference(INTERNAL);
    #endif
    
    }
    
    void presentation()  {
      sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0");
      present(CHILD_ID, S_HUM);
    }
    
    void loop() {
    
      measure(6, 7, 1);
     //  Serial.print ("\t");
     // Serial.println (average());
      long read1 = average();
    
      measure(7, 6, 0);
      //Serial.print ("\t");
      //Serial.println (average());
      long read2 = average();
    
      long sensor1 = (read1 + read2) / 2;
    
      /*Serial.print ("resistance bias =" );
      Serial.println (read1 - read2);
      Serial.print ("sensor bias compensated value = ");
      Serial.println (sensor1);
      Serial.println ();
      */
      //send back the values
      send(msg.set((long int)ceil(sensor1)));
      // delay until next measurement (msec)
    
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
      //Serial.println(sensorValue);
    
      int batteryPcnt = sensorValue / 10;
    
      /*
      // DEBUG Battery INFO
      float batteryV  = sensorValue * 0.003363075;
       Serial.print("Battery Voltage: ");
       Serial.print(batteryV);
       Serial.println(" V");
    
       Serial.print("Battery percent: ");
       Serial.print(batteryPcnt);
       Serial.println(" %");
      // END DEBUG INFO
      */
      if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
      }
    
      sleep(SLEEP_TIME);
    }
    
    void measure (int phase_b, int phase_a, int analog_input)
    {
      // read sensor, filter, and calculate resistance value
      // Noise filter: median filter
    
      for (i = 0; i < NUM_READS; i++) {
    
        // Read 1 pair of voltage values
        digitalWrite(phase_a, HIGH);                 // set the voltage supply on
        delayMicroseconds(25);
        supplyVoltage = analogRead(analog_input);   // read the supply voltage
        delayMicroseconds(25);
        digitalWrite(phase_a, LOW);                  // set the voltage supply off
        delay(1);
    
        digitalWrite(phase_b, HIGH);                 // set the voltage supply on
        delayMicroseconds(25);
        sensorVoltage = analogRead(analog_input);   // read the sensor voltage
        delayMicroseconds(25);
        digitalWrite(phase_b, LOW);                  // set the voltage supply off
    
        // Calculate resistance
        // the 0.5 add-term is used to round to the nearest integer
        // Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
        long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;
    
        delay(1);
        addReading(resistance);
        Serial.print (resistance);
        Serial.print ("\t");
      }
    }
    
    // Averaging algorithm
    void addReading(long resistance) {
      buffer[index] = resistance;
      index++;
      if (index >= NUM_READS) index = 0;
    }
    
    long average() {
      long sum = 0;
      for (int i = 0; i < NUM_READS; i++) {
        sum += buffer[i];
      }
      return (long)(sum / NUM_READS);
    }
    

  • Hardware Contributor

    Hello.

    I think, depending on how your sensor is connected, it is always powered on. Your node is sleeping but you would need to use a mosfet to power off the sensor when you don't use it. Or use an IO pin to deliver the power instead of a "mosfet switch".



  • @scalz said:

    always powere

    Alright, as you proberbly understand I'm not a electronics engineer :) so please explain that to me.
    This is how its setup:

    Everything is build on @sundberg84 Easy/Newbie PCB (This is my LAB PCB that I try out on before soldering, easier to chane components to see if someone of the cheap once are broken)

    Sensor Vcc connected to 3,3V, GND to GND and sensor to D3.
    So what do I have to do to turn of the sensor when I put the arduino to sleep?

    alt text


  • Hardware Contributor

    @Martin-Tellblom - instead of wire power from VCC to the sensor you could try power it through D3 or another IO pin.
    Then you set this pin to HIGH to power the sensor and then LOW before you sleep the node.

    If you have a multimeter you could measure the ampere when you sleep the node.



  • @sundberg84 said:

    to HIGH to power the sensor and then LOW before you sleep the node.

    If you have a multimeter

    Alright so if I connect the Vcc sron the sensor to D2 (since I use D3 for measurement) and set that HIGH before I measure, should I have a sleep for it to power up aswell?

    Something Like this?

      digitalWrite(SOIL_POWER_PIN , HIGH);  
      delayMicroseconds(25);
    
      moisture = analogRead(SOIL_SENSE_PIN);
      
      delayMicroseconds(25);
      digitalWrite(SOIL_POWER_PIN , LOW);  
    

  • Hardware Contributor

    @Martin-Tellblom - Yes, something like that.
    Dont use delay, use wait(); if tou want to create a pause for reading.



  • @sundberg84
    OK,

    I have now changed to the below code and changed to a SOIL sensor with the LED still on

    The LED is lit up even after digitalWrite(SOIL_POWER_PIN , LOW); so I don't think its working

    void loop()
    {
    
      digitalWrite(SOIL_POWER_PIN , HIGH);
      wait(25);
    
      moisture = analogRead(SOIL_SENSE_PIN);
    
      wait(25);
      digitalWrite(SOIL_POWER_PIN , LOW);
    
      if (oldMoisture != moisture) {
        send(msgSoil.set(moisture, 0));
        sendBatteryLevel(moisture);
        oldMoisture = moisture;
      }
    
      //Check Battery Level
      int sensorValue = analogRead(BATTERY_SENSE_PIN);
    
      int batteryPcnt = sensorValue / 10;
      if (oldBatteryPcnt != batteryPcnt) {
        // Power up radio after sleep
        sendBatteryLevel(batteryPcnt);
        oldBatteryPcnt = batteryPcnt;
      }
      digitalWrite(SOIL_POWER_PIN , LOW);
      digitalWrite(SOIL_POWER_PIN , LOW);
      sleep(SLEEP_TIME);
    }
    


  • @sundberg84

    Stupid me, forgot defining it as output pinMode(SOIL_POWER_PIN, OUTPUT); in the setup

    It's working now


  • Hardware Contributor

    Good! @Martin-Tellblom If you can measure how much uA it consumes in sleep() mode you can then calculate the life expectancy. Around 100uA is fine in my world with a booster and pro mini.



  • @sundberg84 said:

    can measure how much uA it consumes in s

    I thought I could do that with my multimeter but I get no value


  • Hardware Contributor

    @Martin-Tellblom - Put the multimeter in series with VCC. Dont forget to change the input on your multimeter.



  • @sundberg84

    Be aware that depending on the mesurement range a multimeter could introduce a big burdan voltage.

    Just simple and short: To measure in the mA range you the multmeter measures the voltage drop accross a series resistor with an value .. call it A.

    Switching to the µA range the mutltimeter switches to a much larger resistor (e.g. 1000times A) to measure a significat enough voltage drop. With the wrong voltage range .. measuring µA while the board is consuming in the mA range might lead to a huge voltage drop and your circuit not working at all.

    So do this:

    • Switch to mA mode .. take your measurement .. wait until you KNOW for sure your circuit is in sleep mode (add some messages on the serial console) and THEN switch to µA range.


  • I don't think my multimeter is good enough for this, It seems like it put in some power due if I

    I will try this when I get home today and see if I need a new multimeter or not :)


  • Hardware Contributor

    and with a multimeter only, due to burden voltage and depending of the multimeter precision, you won't get the true power consumption, an approx which is still nice, you can know what "looks" power consumption and tendancy. Even if you're using a nice expensive Fluke. Best precision for this is uCurrent Gold+multimeter ;)



  • @scalz

    Or just simply take percentage and date/time and then a few days later see what has changed percentage wise ...
    Its to simple I know but if 1% battery power equals 4 days the sensor probably last for about 9-10 month (the last percentage I suppose you don't get any communication with :) )


  • Hardware Contributor

    @Martin-Tellblom - Im not sure it works that way. It depends on which battery you use.
    Voltage tends to drop faster in the end for normal AA batteries.

    My sensors doesnt drop that much (maybe 5%) the first 6 months.



  • @sundberg84 Hmm What you are saying is that I need to buy a new and better Multimeter :) This is the reason I was waiting for ..... :9


  • Hardware Contributor

    @Martin-Tellblom - I hope you dont give up! Battery operations was the hardest part for me to figure out...



  • I only have two kind of sensors that I need to be battery operated and that's the plants warning that they are out of water and soon gonna die and the dogs water bowl warning that they soon gonna die (KIDDING). The dogs bowl I like to measure the levels and have that to compare with the temperature, just for fun.
    I hope I get this working aswell, It wont be pretty with a cable around the few plants we got



  • @Martin-Tellblom , I'm in this mess as well. Just ordered a new Multimeter off aliexpress :)

    @sundberg84 , have you tried other batteries? I bough some ultrafire 3.7V 8800mAh and will try these.
    They were cheap so no loss if they do not work out..


Log in to reply
 

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