Cómo lograr un bajo consumo de energía con ATTINY85

Estoy creando un proyecto que usa un ATTINY85. La mayor parte del tiempo, el circuito debe estar apagado y consumir la menor cantidad de energía posible. Según la hoja de datos, en el modo de apagado, el microcontrolador consume 0,1 μA a 1,8 V. Estoy alimentando el circuito con dos baterías AAA en serie, lo que da alrededor de 3 V, por lo que espero un mayor consumo de energía, pero aún en el mismo orden, pero hasta ahora obtengo 300 μA en modo de apagado.

Eliminé todo de mi código excepto el código de administración de energía para tratar de aislar el problema:

#include "Arduino.h"
#include <avr/sleep.h>
#include <avr/power.h>

void setup()
{
  cli();  // Disable interrupts

  // Reduce the clock frequency to conserve power
  clock_prescale_set(clock_div_128);

  // Disable all modules
  power_all_disable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Configure all ports as output
  // (does not seem to make any difference)
  DDRB = 0b0011111;
  PORTB = 0;
}    

void loop()
{
  sleep_enable();
  sleep_bod_disable();
  sleep_cpu();
}

Como se puede inferir del código, estoy usando la biblioteca Arduino para programar porque fue más rápido de configurar, pero no creo que esto haga ninguna diferencia. ¿Me equivoco?

Los fusibles son E:FF, H:DF, L:62, así que estoy usando el oscilador interno de 8 MHz, dividido por 8. También uso el preescalador de reloj para dividirlo por 128, porque parece que debería reducir el consumo de energía.

Mi circuito es el siguiente:

Diagrama de circuito

Este diagrama no lo muestra, pero las resistencias están conectadas a los ánodos de cuatro LEDS, cuyos cátodos están conectados a tierra (por lo que los leds se encienden cuando los pines están altos).

Estoy midiendo la corriente con un multímetro cuya configuración de escala más baja es 200 μA, por lo que creo que debería poder medir esta corriente con una precisión razonable.

¿Que me estoy perdiendo aqui? ¿Por qué mi consumo actual es más alto de lo esperado?

¿A qué van los puertos de salida conectados a las 4 resistencias cuando están en modo de apagado, es decir, tal vez los haya configurado como pull-ups débiles? ¿Su entrada no utilizada está configurada como una salida? ¿Por qué tiene un botón directamente en el suministro? ¿Algún capacitor de desacoplamiento que olvidó mostrar en el circuito?
¿Ha leído cuidadosamente los gráficos y tablas en la hoja de datos? La ÚNICA manera de lograr algo cercano 1 m A es si apaga TODOS los osciladores, incluido el oscilador RC y el perro guardián. Consulte la página 178, Figura 22-11. Si habilita el perro guardián, pero mantiene el oscilador principal apagado, esto se eleva a múltiplos de 1 m A . Todo esto también supone que no hay nada adjunto a la MCU que pueda alterar estas cifras. El RC solo, si es de 128 kHz, masticará 60 m A más o menos.
Si desea una corriente extremadamente baja, puede estar bajo 1 m A mientras mantiene un oscilador de diapasón funcionando a 32 kHz con el MSP430. (Sin embargo, la garantía absoluta sobre todas las temperaturas es más alta). Tiene un inversor de oscilador de cristal especial diseñado para cristales de diapasón, que en sí mismos solo requieren mucho menos. 1 m W para operar correctamente. MSP430, agregando DCO en 1 megahercio (para dos osciladores funcionando a la vez) es 22 m A típico. Los dispositivos Atmel no pueden acercarse a eso.
@andy alias, traté de deshabilitar los pullups internos, pero eso no hizo ninguna diferencia medible. El pin no utilizado se establece como salida. En cuanto al botón, eso es un error en el diagrama. En su lugar, conecta el reinicio a tierra. No hay condensadores de desacoplamiento por ahora.
@jonk, leí la hoja de datos y deshabilité todo lo que podría deshabilitarse. Cuando el micro está en modo de apagado, creo que todos los osciladores deberían detenerse. Realmente no necesito ir tan bajo como 1uA, pero quiero ahorrar tanta batería como pueda con este diseño.
¿Qué pasa con adc_disable ()
¿Power_all_disable() no desactiva también el adc?
@AntoineAubry El modo de apagado admite un mecanismo de vigilancia que funciona al mismo tiempo. Sin embargo, no tiene en cuenta la corriente que ves. No es tan alto incluso con el perro guardián habilitado. ¿Está deshabilitando específicamente el perro guardián? ¿Y puede, en cambio, no usar una rutina de biblioteca sino escribir directamente los bits SM, usted mismo? (Puede ser útil no asumir que las cosas se están haciendo bien y, en cambio, hacerlas usted mismo, solo para estar seguro). No he verificado su configuración, pero el apagón en sí mismo también puede absorber corriente. ¿Está deshabilitado?
@AntoineAubry Tiene el perro guardián activado y el BOD apagado debido a la configuración de su fusible H. Tiene el RC Osc configurado en 8 MHz, configurado para un aumento lento de la potencia y CKOUT habilitado debido a la configuración de su fusible L. ¿Por qué habilitas CKOUT? Dado el consumo de energía, ¿puede ver un reloj aquí cuando está apagado? (No debería, pero creo que es posible que deba probarse para ver si realmente está apagado. Todo está en duda en este momento).
@jonk No habilité CKOUT a propósito. Ese era el valor predeterminado de los fusibles. Revisaré entonces e informaré aquí tan pronto como pueda.
@jonk Revisé los fusibles con esta herramienta y veo que la salida del reloj está deshabilitada, la detección de Brown Out está deshabilitada y el perro guardián también está apagado. No creo que haya nada que cambiar en los fusibles. ¿Estás de acuerdo?
@AntoineAubry Bueno, utilicé los números que vi en su pregunta y los busqué en la hoja de datos. Es posible que haya cometido un error. Pero traté de no hacerlo. Si esos números siguen siendo precisos, entonces el documento es incorrecto, cometí un error al leerlo, usted escribió incorrectamente o su herramienta está informando incorrectamente. Probablemente solo yo. Pero esas son las opciones que veo.
Revisé los fusibles con la hoja de datos y eso coincide con la información proporcionada por la herramienta. Tenga en cuenta, sin embargo, que los fusibles se activan cuando son iguales a cero. Eso puede explicar el malentendido.
@AntoineAubry Entonces estoy casi seguro de que fue mi propio problema. No hice un seguimiento de todas las lecturas de sección requeridas. Mi error. Supongo que "programar un fusible" significa configurarlo en "0", ya que "1" sería el estado borrado (no programado).
@AntoineAubry Tiene lecturas actuales que superan seriamente las especificaciones. Nunca me he encontrado con esta situación a menos que: (1) la MCU estuviera dañada; o (2) mis suposiciones sobre algo eran falsas; o (3) hubo un error de silicio y/o la documentación era incorrecta y el fabricante tuvo que corregir sus documentos. No creo que esto sea (3). Y revisé la configuración de tus fusibles. Está utilizando rutinas de biblioteca (en las que casi nunca confío cuando me enfrento a un problema como este y, en cambio, las reemplazo con un ensamblaje en línea). Entonces está dañado o le falta algo más que los fusibles.
@AntoineAubry Recomiendo que aísle la MCU de cualquier influencia de circuito externo y pruebe su programa de forma aislada con el programa. (Omita lo que necesita omitir para que esto funcione). (Y/o use un cable de demostración comercial si es posible). Pruebe la corriente con la nueva MCU. Esto elimina cualquier influencia externa. Si el problema continúa, es software/su comprensión.
No sé acerca de los modos de suspensión, pero parece que el interruptor SW1 para restablecer solo cortará la fuente de alimentación si se presiona. Un extremo de SW1 debe conectarse al pin 1 de Attiny (es decir, el otro extremo de esa resistencia) y el otro a GND.

Respuestas (2)

Lo que faltaba era que el ADC debe desactivarse antes de apagarlo:

ADCSRA &= ~ bit(ADEN); // disable the ADC
power_all_disable();

Esto redujo el consumo de energía a ~16 μA. Dado que hay otros componentes en el circuito, no espero alcanzar el 1 μA anunciado en la hoja de datos.

¡Este es un caso perfecto para responder a su propia pregunta! Me alegra saber que lo rastreaste. Casi siempre es algo como esto, en mi experiencia.

Para lograr los números de baja potencia de Microchip, debe configurar todos los pines como entradas y tener el voltaje de cada pin a tierra o VCC (sin permitir que floten entre VCC y GND). Agregue pull-downs o pull-ups en los pines, e incluso agregue pull-downs en paralelo con sus LED.

Lo intentaré e informaré aquí.
Intenté agregar menús desplegables, pero esto no hizo ninguna diferencia medible.
No uso esta parte exacta, pero tengo que configurar todos los puertos como entradas antes de que te vayas a dormir y luego volver a configurarlos cuando te despiertes. También asegúrese de que la detección de caída de tensión esté desactivada.