Энергопотребление Arduino
Как известно, микроконтроллеры ATmega (а соответственно и Arduino) имеют различные режимы энергосбережения. Некоторые из них отключают только некоторые неиспользуемые компоненты микроконтроллера (ADC, SPI, TWI, USART и т.д.). Некоторые — полностью вводят процессор в режим сна, из которого его можно вывести либо по таймеру, либо по внешнему прерыванию. Применение этим режимам можно найти в устройствах, питающихся автономно от батарей (возможно напишу об этом более подробно в одной из статей). А пока я решил просто измерить энергопотребление Arduino в каждом из режимов.

Для экспериментов использовалась Freeduino Through-Hole — аналог Arduino Diecimila. Напряжение подавалось от стабилизированного источника питания 5 вольт.

Итак, для начала замерим силу тока питания Arduino в обычном режиме во время выполнения пустого цикла.
void setup() { while (1) {} } void loop() { }

Теперь загрузим микроконтроллер работой, а именно — заставим его вычислять простые числа.
long i = 1000000; //начинаем с миллиона void setup() { } long found = 0; void loop() { is_prime(i); i++; } int is_prime(long num) { int upper = sqrt(num); for (long cnum = 2; cnum <= upper; cnum++) { long mod = num % cnum; if (mod == 0) { //not simple return 0; } } //simple return 1; }
Сила тока немного возрасла:

Теперь переходим собственно к режимам энергосбережения. Итак, первый режим — понижение тактовой частоты. Данный скетч демонстрирует перевод микроконтроллера на пониженную частоту работы = 62.5 КГц (штатная = 16 МГц). При этом скорость работы резко замедляется, а потребление энергии уменьшается, что видно по графику.
void setup() { delay(10000); pinMode(13, OUTPUT); noInterrupts(); CLKPR = 1<<CLKPCE; CLKPR = 8; interrupts(); } void loop() { digitalWrite(13, HIGH); delay(50); digitalWrite(13, LOW); delay(50); }
Замерим ток, когда светодиод на 13 выводе погашен:

Теперь код, который не изменяет скорости работы, но может полностью приостановить любую деятельность процессора, до наступления определённого события:
/* 5 режимов энергосбережения: SLEEP_MODE_IDLE SLEEP_MODE_ADC SLEEP_MODE_PWR_SAVE SLEEP_MODE_STANDBY SLEEP_MODE_PWR_DOWN */ #include <avr/sleep.h> extern volatile unsigned long timer0_millis; void setup() { pinMode(13, OUTPUT); interrupts(); } void loop() { while(timer0_millis < 5000) { set_sleep_mode(SLEEP_MODE_IDLE); // выбор режима sleep_mode(); // уходим в спячку } timer0_millis = 0; // сброс счётчика bitSet(PINB, 5); // переключение светодиода }
SLEEP_MODE_IDLE:

SLEEP_MODE_ADC:

SLEEP_MODE_PWR_SAVE:

SLEEP_MODE_STANDBY:

SLEEP_MODE_PWR_DOWN:

И теперь график этих 5 режимов:
Сводная таблица:
Режим | Сила тока, миллиампер |
---|---|
Пустой цикл | 22.68 |
Простые числа | 23.81 |
Снижение частоты | 14.45 |
SLEEP_MODE_IDLE | 17.52 |
SLEEP_MODE_ADC | 15.29 |
SLEEP_MODE_PWR_SAVE | 12.82 |
SLEEP_MODE_STANDBY | 12.79 |
SLEEP_MODE_PWR_DOWN | 11.69 |
Как мы видим, энергопотребление Arduino в различных режимах может различаться более чем в два раза, что в некоторых случаях позволяет экономить заряд батарей в автономных устройствах. К сожалению не все режимы возможно применить в большинстве устройств, так как некоторые из них переводят микропроцессор в «глубокий сон» из которого его можно вывести лишь внешними «раздражителями» — прерываниями. Для создания электронных часов вполне можно использовать понижение частоты, иногда повышая её для чтения данных из RTC и обновления показаний.