Hello AVR experts,
The datasheet of the attiny1614 claims a low power consumption of 0.71uA in standby mode with RTC running at 1.024kHz from internal ULP oscillator.
But I have difficulties to get those 0.71uA. my best result are (for 5V from USB socket) :
- 5uA with RTC running.
- 120nA in full power down (wake on external interrupt / reset).
Even if I run it at 5V, I was expecting something closer to 1uA.
Update: I have similar results for 3V (3.3V from a linear voltage regulator) with 100nF decoupling caps:
- 3.46uA with RTC running, measured with a 100kOhm (99.1k) shunt resistor (346mV voltage drop)
- 3.9uA measured with the uA functionality of my DDM.
- Measuring tool: Multimetrix DMM 120 (Input resistance for DC voltage measurement > 10MOhm, datasheet www.multimetrix.fr/docs/NF/694310A01_DMM121_FR_Ed_02.pdf)
- I also tried with several digital multimeters, measurements are the same.
This is my setup:
- The bare 1614 SFR chip is directly hooked with test clips to 5V from USB.
- I measure current with a 100kOhm shunt resistor (I short it when the chip resets to have enough power to start it).
- The chip is configured using the atmel start configuration stated in assignment 2 from this application note: http://ww1.microchip.com/downloa... (ADC and Power Optimization with tinyAVR® 0- and 1-series, and megaAVR® 0-series) i.e:
- Sleep controller enabled and set in standby mode,
- RTC enabled and configured at 1.024kHz (prescale 32 + ULP 32kHz internal oscillator),
- Global Interruption enabled + RTC interruption + flag cleared inside ISR.
- In main, loop on sleep_cpu() : while(1){sleep_cpu();}
- No extra user code.
- BOD disabled (I checked the corresponding fuse, all zero).
- Input buffer disabled on all I/Os.
Maybe I miss something really obvious, I am not an expert with these new avr chips.
If you have a similar chip (817 /1616/ 1617 etc..) laying around, could you check if you can achieve the 0.71uA or close? (My solar project design needs such a low power consumption to run indoor, 5uA is way more consumption than the 1-2uA produced).
Thanks in advance for your help.
UPDATE: If made no mistake, I think I have the correct power consumption with this bare code example compiled with Atmel Studio:
- 0.68uA ( 68mV voltage drop), what a perfect match for the claimed 0.71uA @ 3V, 25°C.
- I am investigating the difference with the previous tests.
Test code with RTC running, MCU in eternal sleep (no interrupt, wake on reset only)
/* * LowPowerRTC.c * * Created: 07/11/2018 19:31:59 * Author : Cedric */ #include <avr/io.h> #include <avr/sleep.h> #define F_CPU 3333333UL #include <util/delay.h> int main(void) { //Configure pins: //////////////////////////////////////// // Set all pins to low power mode: for (uint8_t i = 0; i < 8; i++) { *((uint8_t *)&PORTA + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; } for (uint8_t i = 0; i < 8; i++) { *((uint8_t *)&PORTB + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; } //RTC INIT: ////////////////////////////////////////////// while (RTC.STATUS > 0) {} // Wait for all register to be synchronized RTC.CTRLA = RTC_PRESCALER_DIV1_gc //NO Prescaler | 1 << RTC_RTCEN_bp //Enable RTC | 1 << RTC_RUNSTDBY_bp; //Run in standby RTC.CLKSEL = RTC_CLKSEL_INT1K_gc; // 32KHz divided by 32, i.e run at 1.024kHz _delay_ms(6000); //Consumes high power for 6secs before going into eternal sleep (to see a change in measurement on the DMM). //Main loop: ///////////////////////////////////////////// while (1) { set_sleep_mode(SLEEP_MODE_STANDBY); sleep_enable(); sleep_cpu(); //Go into eternal sleep //Dead code: _delay_ms(2000); //If MCU is awoken from any mysterous interrupt, stay still for power measurement with DMM. } }
UPDATE: Test code with periodic wake every 10 sec using RTC:
- Less than 0.7uA when in sleep mode
- More than 1mA when awoken (stay still for few seconds for slow current measuring with DMM).
/* * LowPowerRTC.c * * Created: 07/11/2018 19:31:59 * Author : Cedric */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #define F_CPU 3333333UL #include <util/delay.h> //RTC ISR ////////////////////////////////////////////////////// ISR(RTC_CNT_vect) { RTC.INTFLAGS = RTC_OVF_bm; } int main(void) { //Configure pins: //////////////////////////////////////// // Set all pins to low power mode: for (uint8_t i = 0; i < 8; i++) { *((uint8_t *)&PORTA + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; } for (uint8_t i = 0; i < 8; i++) { *((uint8_t *)&PORTB + 0x10 + i) |= 1 << PORT_PULLUPEN_bp; } //RTC INIT: ////////////////////////////////////////////// while (RTC.STATUS > 0) {} // Wait for all register to be synchronized RTC.PER = 1024*10; //10 secs between wakes. RTC.INTCTRL = 0 << RTC_CMP_bp | 1 << RTC_OVF_bp; //Overflow interrupt. RTC.CTRLA = RTC_PRESCALER_DIV1_gc //NO Prescaler | 1 << RTC_RTCEN_bp //Enable RTC | 1 << RTC_RUNSTDBY_bp; //Run in standby RTC.CLKSEL = RTC_CLKSEL_INT1K_gc; // 32KHz divided by 32, i.e run at 1.024kHz _delay_ms(6000); //Consumes high power for 6secs before going into eternal sleep (to see a change in measurement on the DMM). //Enable interrupts ////////////////////////////////////// sei(); //Main loop: ///////////////////////////////////////////// while (1) { set_sleep_mode(SLEEP_MODE_STANDBY); sleep_enable(); sleep_cpu(); //Go into sleep //On awakening _delay_ms(2000); //Stay still for power measurement with DMM. } }