9 votos

El consumo de energía del ATtiny85 se duplica

Estoy intentando que un ATTiny85 funcione con una batería. Lo tengo cronometrado desde un cristal de 16,384 MHz, con el fusible de división por 8 puesto. Vcc es de 3,3 voltios. La figura 22-7 de la hoja de datos dice que en reposo ( set_sleep_mode(SLEEP_MODE_IDLE); sleep_mode(); ), debería consumir unos 300 µA. En realidad, veo que consume más bien 850 µA. No puedo entender por qué el consumo de energía es el doble de lo esperado. He apagado todo en PRR excepto el timer0, que he configurado para interrumpir cada 25 ms. Así que debería pasar la mayor parte de su tiempo en estado de reposo, que es lo mejor que puedo hacer dado que todavía quiero que los temporizadores cuenten.

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

Este es el código que se ejecuta 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() {}

0 votos

¿Qué está utilizando para medir la corriente? ¿Interrumpes las líneas Vcc directamente a la MCU o hay un regulador de voltaje en medio? ¿A qué están conectadas tus entradas/salidas?

0 votos

Estoy utilizando un µCurrent Gold. Todo esto está en una protoboard, así que es muy directo. No hay entradas. Las dos salidas están conectadas a LEDs por el momento, pero es un punto discutible dado que escribimos LOW (por lo que los LEDs están apagados) y luego dormimos para siempre.

0 votos

Además, si cambio la suspensión a SLEEP_MODE_PWR_DOWN, me hacer ver el nivel de consumo que espero: del orden de 200 nA.

6voto

Joe Kearney Puntos 425

Dices que según la figura 22-7 de la hoja de datos sólo debería consumir 300µA, pero ese gráfico muestra el consumo de corriente para el funcionamiento sin división del reloj. Un oscilador de cristal que funcione a 16MHz está obligado a consumir más corriente que uno que funcione a 2MHz, y el divisor de 3 etapas añadirá un poco más. La cuestión es cuánto ¿más?

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

Si no puedes utilizar un cristal de menor frecuencia en las placas que tienes en camino, es posible que no puedas hacer nada. Sin embargo, mientras tienes el circuito en una protoboard podrías al menos probar con un cristal de 2MHz, para ver si ese es realmente el problema.

enter image description here

0 votos

Ok. Morderé el anzuelo. Iré hoy a la tienda a comprar un cristal de 2 MHz y volveré a fundir el chip para que no haya división de reloj y lo comprobaré.

0 votos

Otra dificultad es la necesidad de 2^x frecuencias de cristal. 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 difícil escoger un valor de preescala y OCR0A que resulte en interrupciones de fracciones de segundo. Pero si 8,192 MHz dividido entre 16 ahorra una cantidad significativa de energía, ciertamente estaría contento con eso sobre 16,384 dividido entre 32.

2 votos

Con un cristal de 4,096 MHz y un valor de preescala del reloj de la CPU de 8, ahora consume unos 450 µA.

3voto

arclight Puntos 499

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

Los problemas eran los GPIO no utilizados.

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

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

¿Está seguro de que las clavijas están colocadas correctamente? En tu código parece que sí, pero ¿lo has comprobado?

0 votos

Bueno, mierda. Si pinMode(P_UNUSED, INPUT_PULLUP); no es suficiente, entonces WTF?

0 votos

Sí, pero a veces esto no es suficiente. Por ejemplo, puedes tener pines que son entrada ADC o entrada analógica por defecto, independientemente de la dirección que programes. Ahí, primero tienes que desactivar la función secundaria. A eso me refería con "comprobar".

0 votos

Esto es un ATTiny85. Tiene 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 poner los pines xtal a OUTPUT por el consumo de energía.

2voto

Allen Pike Puntos 4806

Me gustaría añadir que para un proyecto separado, pedí esta pregunta y la respuesta impactó dramáticamente en esta pregunta también. aclaración ADCSRA ha reducido el consumo en reposo a lo que la figura 22-6 dice que debe tomar - alrededor de 100 µA a una frecuencia de reloj del sistema dividida de 500 kHz - y esa es la frecuencia de reloj post-dividida, no la frecuencia del cristal.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X