ATtiny85 consumo de energía doble esperado

Estoy tratando de hacer que un ATTiny85 funcione con batería. Lo tengo cronometrado desde un cristal de 16.384 MHz, con el conjunto de fusibles de división por 8. Vcc es de 3,3 voltios. La Figura 22-7 en la hoja de datos dice que en reposo ( set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode();), debería consumir alrededor de 300 µA. De hecho, lo veo dibujando más como 850 µA. No puedo entender por qué el consumo de energía es el doble esperado. Apagué todo en PRR excepto el temporizador 0, que configuré para interrumpir cada 25 ms. Por lo tanto, debería pasar la mayor parte de su tiempo en estado inactivo, que es lo mejor que puedo hacer dado que todavía quiero que los temporizadores cuenten.

Los fusibles son 0x7f, 0xdf, 0xff.

Aquí está el código que se está ejecutando para esta prueba:

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

#define P0 0
#define P1 1
#define P_UNUSED 2

ISR(TIMER0_COMPA_vect) {
  // do nothing - just wake up
}

void setup() {
  power_adc_disable();
  power_usi_disable();
  power_timer1_disable();
  //PRR = _BV(PRADC) | _BV(PRTIM1) | _BV(PRUSI); // everything off but timer 0.
  TCCR0A = _BV(WGM01); // mode 2 - CTC
  TCCR0B = _BV(CS02) | _BV(CS00); // prescale = 1024
  // xtal freq = 16.384 MHz.
  // CPU freq = 16.384 MHz / 8 = 2.048 MHz
  // count freq = 2.048 MHz / 1024 = 2000 Hz
  OCR0A = 50; // 25 msec per irq
  TIMSK = _BV(OCIE0A); // OCR0A interrupt only.

  set_sleep_mode(SLEEP_MODE_IDLE);

  pinMode(P_UNUSED, INPUT_PULLUP);
  pinMode(P0, OUTPUT);
  pinMode(P1, OUTPUT);
  digitalWrite(P0, LOW);
  digitalWrite(P1, LOW);

  while(1) { sleep_mode(); }
}
void loop() {}
¿Qué estás usando para medir la corriente? ¿Está interrumpiendo las líneas Vcc directamente a la MCU o hay un regulador de voltaje en el medio? ¿A qué están conectadas sus entradas/salidas?
Estoy usando un µCurrent Gold. Todo esto está en una placa de prueba, por lo que es muy directo. No hay entradas. Las dos salidas están conectadas a los LED por el momento, pero es un punto discutible dado que escribimos BAJO (por lo que los LED están apagados) y luego dormimos para siempre.
Además, si cambio el sueño a SLEEP_MODE_PWR_DOWN, veo el nivel de consumo que espero, del orden de 200 nA.
¿Qué revisión del chip estás usando?
Es uno PDIP. Hay un montón de letras en la parte inferior. De izquierda a derecha, de arriba a abajo: 3W1 160 B1 1P 1328 B3. La parte superior solo dice 1328 ATTINY85 20PU.
¿Ha probado un cristal de 2 MHz en lugar de ejecutar el oscilador a 16 MHz y dividir dentro de la uC?
@HannoBinder No. Pero no fabrican cristales de bajo valor en la huella que tengo en los tableros que vienen. Si esa es la respuesta final, que así sea, pero no hay nada en la hoja de datos que sugiera que la frecuencia preescalada daría como resultado el doble de consumo de energía. Todo lo contrario.
Mataste al comparador?
@IgnacioVazquez-Abrams Si no está implícito en los 0 bits del código anterior, entonces no. ¿Me puede dar una hoja de datos de referencia?
Sección de comparador analógico, ACSRregistro.
@IgnacioVazquez-Abrams Agregar ACSR = _BV(ACD);no cambió nada de manera apreciable.
¿Has echado un vistazo a algunos de los trucos que hizo el chico de Jeelabs? Vea aquí (comience a leer en la parte inferior): jeelabs.org/tag/lowpower
@RJR Eché un vistazo y, lamentablemente, muchos de sus trucos no funcionarán porque solo puedo usar SLEEP_MODE_IDLE porque necesito mantener el temporizador en funcionamiento. Esta aplicación es un reloj.
¿Funciona el detector de oscurecimiento?
@HannoBinder No. La configuración de fusible alto de 0xDF lo desactiva.
Si se trata de un reloj, ¿puedo sugerir ejecutar el oscilador interno y usar un cristal de reloj en el temporizador 2 para disparar la interrupción del perro guardián? A continuación, puede utilizar el sueño profundo. Creo que también hay una publicación de blog de jeelabs sobre eso en alguna parte.
Todas las búsquedas en Google que veo sugieren que están usando un módulo RTC externo. Si tiene un RTC, entonces sí, puede usar el perro guardián y el oscilador interno porque el reloj de la CPU no es importante. En este caso, sin embargo, quiero la precisión del cristal. Y también, este es un ATTiny85: no hay temporizador 2, solo 0 y 1, y el temporizador 1 consume un orden de magnitud más de energía que el temporizador 0. No sé cómo conectaría un cristal a un ATTiny sin cualquier componente externo adicional que no sea el reloj del sistema.
ah Encontré jeelabs.org/2011/06/28/jeenode-with-a-32-khz-crystal . De eso estabas hablando, pero eso es un ATMega, no un ATTiny.

Respuestas (3)

Usted dice que de acuerdo con la Figura 22-7 en la hoja de datos, solo debería consumir 300 µA, pero ese gráfico muestra el consumo de corriente para la operación sin división de reloj. Un oscilador de cristal que funciona a 16 MHz consumirá más corriente que uno que funcione a 2 MHz, y el divisor de 3 etapas agregará un poco más. La pregunta es: ¿cuánto más?

La hoja de datos también sugiere que la corriente inactiva se puede reducir dividiendo el reloj, pero nuevamente no dice cuánto se reducirá. Extrapolar la línea de 3,3 V sugiere que normalmente consumiría alrededor de 1,5 mA a 16,4 MHz, y 850 µA es una reducción significativa, pero ¿debería ser menor?

Si no puede usar un cristal de frecuencia más baja en los tableros que viene, es posible que no haya nada que pueda hacer. Sin embargo, mientras tiene el circuito en una placa de prueba, al menos podría probar un cristal de 2 MHz, para ver si ese es realmente el problema.

ingrese la descripción de la imagen aquí

Está bien. Morderé. Iré a la tienda hoy y recogeré un cristal de 2 MHz y volveré a fusionar el chip sin división de reloj y lo comprobaré.
Otra dificultad es la necesidad de frecuencias de cristal 2^x. Fui a la tienda y encontré uno de 4.096 MHz, pero 1.024 y 2.048 son difíciles de encontrar. Pero no usar un reloj 2^x hace que sea difícil elegir una preescala y un valor OCR0A que resulte en interrupciones de fracciones de segundo. Pero si 8,192 MHz dividido por 16 ahorra una cantidad significativa de energía, ciertamente estaría feliz con eso sobre 16,384 dividido por 32.
Con un cristal de 4,096 MHz en su lugar y un valor de preescala de reloj de CPU de 8, ahora consume alrededor de 450 µA.
algunos años tarde, pero ¿por qué no comprar un RTC y usar su PPS, dormir el procesador y hacer que solo se active en la interrupción?

Tuve un problema similar con ese chip. El consumo de energía fue un 30% más de lo esperado.

¡Los problemas fueron GPIO sin usar!

Se configuraron como entradas y se dejaron flotando. La falta de un estado de entrada claramente definido hizo que el controlador GPIO consumiera mucho más de lo que se especifica.

La respuesta fue habilitar los pull-ups o configurar pines no utilizados como salidas.

¿Estás seguro de que los pines están colocados correctamente? En su código parece que sí, pero ¿lo comprobó?

Bueno, mierda. Si pinMode(P_UNUSED, INPUT_PULLUP);no es suficiente, entonces WTF?
Sí, pero a veces esto no es suficiente. Por ejemplo, puede tener pines que sean entrada ADC o entrada analógica de forma predeterminada, independientemente de la dirección que programe. Allí, primero debe deshabilitar la función secundaria. Eso es lo que quise decir con "verificar".
Este es un ATTiny85. Hay 6 pines, pero 3 de ellos son RESET y los dos pines xtal. Dos de ellos son salidas y uno es P_UNUSED. Todo el ADC se ha apagado explícitamente. Probaré el truco INPUT_PULLUP en los otros 3 pines, pero sospecho que no cambiará nada. Hay una errata para el Tiny45 que habla de no configurar los pines xtal en SALIDA debido al consumo de energía.
Sumar pinMode(3, INPUT_PULLUP);y lo mismo para 4 y 5 no hizo nada.

Me gustaría agregar que para un proyecto separado, hice esta pregunta y la respuesta también impactó dramáticamente esta pregunta. la limpieza ADCSRAredujo el consumo inactivo a lo que se supone que debe tomar la figura 22-6, alrededor de 100 µA a una frecuencia de reloj del sistema dividida de 500 kHz, y esa es la frecuencia de reloj posdividida, no la frecuencia del cristal.