Soil Mosisture Sensor: Battery Issue

  • I am building a soil moisture. My atmega328p using custom bootloader Optiboot 1MHz. I am using mysensors easy pcb . it seems to t be chewing on the batteries. I am not sure if it's my code:

    #define MY_DEBUG
    #define MY_RF24_PA_LEVEL RF24_PA_LOW
    #define MY_BAUD_RATE 38400
    //#define MY_BAUD_RATE 9600
    #define MY_NODE_ID 13
    #define MY_RADIO_NRF24
    #define VIEW_READING
    #include <MySensors.h>
    #include <SPI.h>
    #include <math.h>
    #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
    #define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
    #define NUM_READS 10
    #define CHILD_ID_MOISTURE 0
    #define CHILD_ID_BATTERY 1
    #define SLEEP_TIME 1800000 //300000//10000 // Sleep time between reads (in milliseconds), was 10000
    #define STABILIZATION_TIME 500 // Let the sensor stabilize before reading default BOD settings
    #define VOLTAGE_PIN A0
    int index;
    long buffer[NUM_READS];
    const long Known_Resistor = 4700;
    /// @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;
    MyMessage soil_msg(CHILD_ID_MOISTURE, V_LEVEL);
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    void presentation() {
      sendSketchInfo("Soil Moisture", "2.0");
    void setup() {
      pinMode(6, OUTPUT);
      pinMode(7, OUTPUT);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
    void loop() {
      long moistureLevel = readAggSoilMoisture();
      //float coeff = 100.00 / float(dryLevel);
      float voltage = readVoltage() ;//* 1.57368; // Coeff
      float batteryPcnt = voltage / 3.3 * 100;
    #ifdef VIEW_READING
      Serial.print("--Voltage:"); Serial.println(voltage);
      Serial.print("--Battery %:"); Serial.println(batteryPcnt);
      Serial.print("--Soil Sensor value:"); Serial.println(moistureLevel );
      send(soil_msg.set(moistureLevel, 1));
      //send(soil_msg.set(moistureLevel * coeff, 1));
      send(voltage_msg.set(voltage, 3), 1);
    float readVoltage() {
      int sensorValue = analogRead(VOLTAGE_PIN);
      float voltage = sensorValue * 0.003363075;
      return voltage;
    void fakeRead(int pin) {
      for (int counter = 0; counter < 5; counter++) {
    // Averaging algorithm
    void addReading(long resistance){
      buffer[index] = resistance;
      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);
    int readAggSoilMoisture()
      measureRawSoilMoisture(6, 7, A1);
      long read1 = average();
      measureRawSoilMoisture(7, 6, A4);
      long read2 = average();
      long sensor1 = (read1 + read2) / 2;
      return int( ((sensor1 / (float)Known_Resistor) * 100.00));
    void measureRawSoilMoisture (int phase_b, int phase_a, int analog_input)
      // read sensor, filter, and calculate resistance value
      // Noise filter: median filter
      for (int i = 0; i < NUM_READS; i++) {
        // Read 1 pair of voltage values
        digitalWrite(phase_a, HIGH);                 // set the voltage supply on
        int supplyVoltage = analogRead(analog_input);   // read the supply voltage
        digitalWrite(phase_a, LOW);                  // set the voltage supply off
        digitalWrite(phase_b, HIGH);                 // set the voltage supply on
        int sensorVoltage = analogRead(analog_input);   // read the sensor voltage
        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 = abs(Known_Resistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;
        //Serial.print (" ");
        //Serial.print (supplyVoltage);
        //Serial.print (" ");
        //Serial.print (sensorVoltage);
        //Serial.print (" ");
        //Serial.print (resistance);
        //Serial.print ("\t");
      //digitalWrite(phase_a, LOW);
      //digitalWrite(phase_b, LOW);

  • Mod

    How are you powering the moisture sensor?

  • Pin 6,7, A1,A4

  • Mod

    did you check with multimeter where and how much current is used during sleep? And also check if pin 6 and 7 are actually LOW? Sorry I can't help much with this specific sensor as I haven't used it yet. You may also take a look at NodesManager library here on the forum that has already built in the powering of sensors using digital pins that could help in reducing the code.

  • The sketch looks correct. I had a similar issue. Measure how much current is the arduino using to check if it's actually sleeping or not. If it is, measure the current going to the nrf24. You can just build a simple sketch which loops for some seconds and then goes to sleep for some more seconds so you can see the changes in a multimeter. There seem to be a number of those modules that are unable to sleep even when things took do so. In my case 1 of my 10 modules showed this issue. Some people indicate that some of them are recoverable, but in my case I just saved it to use it in a non - battery powered sensor.

  • Does your Arduino board have a power led? Is it on during sleep?

Log in to reply

Suggested Topics