So idea of using this device in wild is to have it sleeping most of the time, then it should wake once in a while, do measuremrnt, send it out and go back to sleep. Therefore battery life will depend heavily on the power consumption in sleep mode, since wakup cycle can be as rare as once per few hours.
So for the first test i want to ensure that when PW_ON pin is low, all my peripherals are off and not drawing current. And here it is, not even a microamp when PW_ON is zero. That's a good start.
Next test I don't care for any of the periferials, they will be off in the sleep mode, now i need to make sure MCU draw as less current as possible.
Okay so here is the first attempt to use sleep mode
My fuses are
board_fuses.efuse = 0xFF board_fuses.hfuse = 0xDE board_fuses.lfuse = 0xF1
BOD set on 1.8V
main.h
#include <avr/io.h>
#define SLEEP_16ms 0
#define SLEEP_32ms 1
#define SLEEP_64ms 2
#define SLEEP_128ms 3
#define SLEEP_256ms 4
#define SLEEP_512ms 5
#define SLEEP_1024ms 6
#define SLEEP_2048ms 7
#define SLEEP_4096ms 8
#define SLEEP_8192ms 9
#define PIN_PWR_SW PINB3
#define PIN_PWR_SW_ _BV(PINB3)
void setup_watchdog(int mode);
void sleep(int mode);
main.c
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "main.h"
#include <Arduino.h>
void setup() {
DDRB = DDRB | PIN_PWR_SW_;
PORTB = 0x00;
}
void loop() {
PORTB |= PIN_PWR_SW_;
_delay_ms(1024);
PORTB &= ~PIN_PWR_SW_;
sleep(SLEEP_2048ms);
}
// =============== SLEEP MODE ===============
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void sleep(int mode) {
setup_watchdog(mode);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode(); // System actually sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
}
void setup_watchdog(int ii) {
uint8_t bb = ii & 7;
if (ii > 7)
bb |= (1 << 5);
bb |= (1 << WDCE);
int ww = bb;
MCUSR &= ~(1 << WDRF);
// start timed sequence
WDTCR |= (1 << WDCE) | (1 << WDE);
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
This gives me two figures, (A) active mcu, soil sensor, nrf and (B) all off, mcu sleeping. Once again case (A) is non optimised, for now i case only for case (B).
(A) Active: 8mA,
(B) Sleep: 0,23mA
Good start.
Now by handbook i'll disable ADC during sleep mode:
void sleep(int mode) {
setup_watchdog(mode);
cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode(); // System actually sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA, ADEN); // switch Analog to Digitalconverter ON
}
(A) Active: 8mA,
(B) Sleep: 24uA
That's 10 times improvement compared to pervious setup.
Now there is a hint to disable BOD during sleep
I'll try to do it softwarewise
void sleep(int mode) {
setup_watchdog(mode);
cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
cli(); // Disable Interrupts
sleep_bod_disable(); // Disable BOD
sei();
sleep_mode(); // System actually sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA, ADEN); // switch Analog to Digitalconverter ON
}
Unfortunately makes no difference on current consumption, does Attiny85 supports it anyway?
So let's disable it completely
New fuses
board_fuses.efuse = 0xFF board_fuses.hfuse = 0xDF board_fuses.lfuse = 0xF1
And now i'm down to
(A) Active: 8mA,
(B) Sleep: 4,5uA
So another 5 times imprevement.
I tried also to set all pins to input mode, but this made no difference as well.
Now that's really the best I've managed so far. Datasheet says it should be under 1uA, and possibly as low as 0.2uA in my conditions, but i'm failing to get the same result. So if you know what I'm missing here, please help me out. Could it be the crappy multimeter tool?
BTW, 200mAH battery would power it for 5 years under constant sleep conditions, which is not so bad, but not as cool as some 40 years:)
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.