1

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 <LowPower.h>
#include <NewPing.h>

#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 < 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 && (cur_time - timeOfQuery) > 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 < 7; i++) {
      if (distances[i] <= 200) {
        off = 0;
        // Remember minimum distance
        if (distances[i] < distance) {
          distance = distances[i];

        }
      }
    }
    delayTime = distance;
  }

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

      // Turn off all of the LEDs
      for (int x = 0; x < 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 < 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 >= 200 || distance <= 0) {
      Serial.print(distance);
      Serial.println(" Out of range");
    }
    else {
      Serial.print(distance);
      Serial.println(" cm");
    }
  */
}

Update: The board is Arduino UNO.

  • Are you using an Arduino board or are you using an MCU directly on a breadboard? Could you mention which board/MCU you are using? – jfpoilpret Dec 2 '16 at 5:41
  • @jfpoilpret: It's UNO – Itzie Dec 2 '16 at 5:43
  • Are your other questions answered? It's allowed to ask multiple questions, but don't forget to accept answers and/or give feedback on your other questions' answers. – Paul Dec 2 '16 at 7:22
  • Please see arduino.stackexchange.com/questions/18759/… – Mikael Patel Dec 2 '16 at 15:51
3

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:

  1. work on a breadboard with just the ATmega328,
  2. power it with two 1.5V batteries (AA or AAA)
  3. 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.

  • I work with some radio microphones on a regular basis. We have two sets - old ones and new ones. The old ones use 9V batteries and the batteries often need changing mid concert. The new ones use two AA batteries each, and last for many concerts before they need changing. The difference is staggering. – Majenko Dec 2 '16 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.