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.