How to make battery last for months? I have a simple circuit: detect that a person is walking towards the circuit (with HC-SR04), measure distance, light diodes (a wave effect) according to that distance – the closer, the faster the led wave.

When no person detected, sleep longer:

LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF);


When person detected, sleep shorter (so that diodes can be often turned on/off):

LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);


Without LowPower use – delay() used instead – the current taken is 15 mA. This is with diodes off. After using LowPower – it's still ~15 mA. This is very disappointing. I've expected the battery to last at least for 3 months, but it (9V) was drained within hours. Am I missing something?

Also a curiosity: the execution was fully blocking itself on LowPower calls, I've had to add short delay() before the calls, then they don't block execution.

#include &lt;LowPower.h&gt;
#include &lt;NewPing.h&gt;

#define trigPin 13
#define echoPin 12

NewPing sonar(trigPin, echoPin, 250);

// Defines speed of LEDs traversal
int delayTime = 40;

// Current led
int currentLED = 0;

// Direction of travel over LEDs
int dir = 1;

// Stores the last time LEDs were changed
unsigned long timeChanged = 0;

// Stores the last time sensor was read
unsigned long timeOfQuery = 0;

// LEDs
byte ledPin[] = { 4, 5, 6, 7, 8, 9, 10, 11 };

// Stores if any diodes are on
int leds_used = 1;

// Stores if wave is active
int off = 1;

// 5 last distances, circular buffer;
long distances[7] = { 400, 400, 400, 400, 400, 400, 400 }, currentDistance = 0;

// Last chosen distance
long distance = 400;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  for (int x = 0; x &lt; 8; x++) {
    pinMode(ledPin[x], OUTPUT);
  }
  timeChanged = millis();
}

void loop() {
  long duration, cur_time, cm;

  cur_time = millis();

  /* Read distance when off, or when some time passed */
  if (off || (!off &amp;&amp; (cur_time - timeOfQuery) &gt; 100)) {
    timeOfQuery = cur_time;

    cm = sonar.ping_cm();
    if ( cm == 0 ) {
      cm = 400;
    }


    distances[(++currentDistance) % 7] = cm;
    // At least 1 proper distance?
    off = 1;
    for (int i = 0; i &lt; 7; i++) {
      if (distances[i] &lt;= 200) {
        off = 0;
        // Remember minimum distance
        if (distances[i] &lt; distance) {
          distance = distances[i];

        }
      }
    }
    delayTime = distance;
  }

  if (!off) {
    // Check whether it has been long enough
    if ((cur_time - timeChanged) &gt; delayTime) {

      // Turn off all of the LEDs
      for (int x = 0; x &lt; 8; x++) {
        digitalWrite(ledPin[x], LOW);
      }

      // Turn on the current LED
      digitalWrite(ledPin[currentLED], HIGH);

      // Mark that diodes are being used
      leds_used = 1;

      // Increment by the direction value
      currentLED += dir;

      // If we are at the end of a row, change direction
      if (currentLED == 7) {
        dir = -1;
      }
      if (currentLED == 0) {
        dir = 1;
      }

      // Store the current time as the time we last changed LEDs
      timeChanged = cur_time;
    }

    // Shorter delay when sleeping
    delay(5);
    LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
    //delay(50);
  } else {
    if (leds_used) {
      // Turn off all of the LEDs
      for (int x = 0; x &lt; 8; x++) {
        digitalWrite(ledPin[x], LOW);
      }
      currentLED = 0;
      dir = 1;
      leds_used = 0;

      // Store the current time as the time we last changed LEDs
      timeChanged = cur_time;
    }

    // Longer delay when sleeping
    delay(10);
    LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF);
    //delay(200);
  }

  /*
    if (distance &gt;= 200 || distance &lt;= 0) {
      Serial.print(distance);
      Serial.println(" Out of range");
    }
    else {
      Serial.print(distance);
      Serial.println(" cm");
    }
  */
}


Update: The board is Arduino UNO.
The Arduino UNO always consumes current mainly because:


it has 2 MCU, the ATmega328 which you can power down, and an ATmega16u2 for USB communication which is never powered down. 
in addition, the voltage regulator is permanently leaking some current


To be honest, I am surprised your UNO consumes only 15mA, on my boards, it is rather near 40-50mA.

Also, a 9V battery is probably the battery with the smallest charge capacity.

I would suggest you:


work on a breadboard with just the ATmega328, 
power it with two 1.5V batteries (AA or AAA)
and run @8MHz


That should already reduce current consumption. 

You may even try smaller MCU (e.g. ATtiny84A) which consumes less current than the ATmega328 in the same conditions.

Finally, I highly recommend Nick Gammon's blog on that topic. It includes many good tricks to help you with current consumption.