Сегодня я решил провести небольшой эксперимент по снижению энергопотребления микроконтроллера ATmega328P - именно он используется в большинстве популярных плат Ардуино. Я настроил его на тактирование от внутреннего RC-генератора и вынул из Ардуино, чтобы уменьшить энергопотребление. О том, что из этого получилось, читайте далее.
Для экспериментов я включил ATmega328P без какой-либо обвязки. Чтобы не отвлекаться на разъяснения относительно обвязки, я посвятил этому вопросу отдельную статью. Процедура настройки ATmega328P на тактирование от внутреннего RC-генератора также была описана ранее.
Итак, сперва я замерил потребление микроконтроллера в активном режиме при различных значениях напряжения питания. Результат представлен на графике:
Для экспериментов я включил ATmega328P без какой-либо обвязки. Чтобы не отвлекаться на разъяснения относительно обвязки, я посвятил этому вопросу отдельную статью. Процедура настройки ATmega328P на тактирование от внутреннего RC-генератора также была описана ранее.
Итак, сперва я замерил потребление микроконтроллера в активном режиме при различных значениях напряжения питания. Результат представлен на графике:
Следующие измерения я провел в режиме энергосбережения PowerDown с отключенными АЦП и BOD (детектор пониженного напряжения питания). Ниже приведены использованные скетчи и график с результатами измерений при работающем/отключенном сторожевом таймере.
Скетч для перехода в спящий режим (АЦП, BOD и сторожевой таймер выключены):
Скетч для перехода в спящий режим (АЦП, BOD и сторожевой таймер выключены):
#include <avr/sleep.h>
void setup() {
}
void loop() {
ADCSRA &= ~(1 << ADEN); // Отключаем АЦП
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Устанавливаем интересующий нас режим
sleep_enable();
// Отключаем детектор пониженного напряжения питания
MCUCR != (1 << BODS) | (1 << BODSE);
MCUCR &= ~(1 << BODSE);
sleep_cpu(); // Переводим МК в спящий режим
sleep_disable();
}
Скетч для перехода в спящий режим (АЦП и BOD выключены, сторожевой таймер активен):
#include <avr/wdt.h>
#include <avr/sleep.h>
void setup() {
}
void loop() {
ADCSRA &= ~(1 << ADEN); // Отключаем АЦП
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Устанавливаем интересующий нас режим
sleep_enable();
wdt_enable(WDTO_8S); //Задаем интервал сторожевого таймера (8с)
WDTCSR |= (1 << WDIE); //Устанавливаем бит WDIE регистра WDTCSR для разрешения прерываний от сторожевого таймера
// Отключаем детектор пониженного напряжения питания
MCUCR != (1 << BODS) | (1 << BODSE);
MCUCR &= ~(1 << BODSE);
sleep_cpu(); // Переводим МК в спящий режим
sleep_disable();
delay(2000);
}
ISR (WDT_vect) {
wdt_disable();
}
С отключенным сторожевым таймером ATmega328p потребляет около 0,1мкА. Напомню, что с аналогичным скетчем на Arduino Pro Mini я добился потребления 136мкА. Также ради интереса я замерил потребление без отключения АЦП и BOD - оно составило 90..140мкА. Поэтому советую отключать эти модули перед уходом микроконтроллера в сон. При необходимости АЦП можно будет снова включить следующей командой:
Итак, что можно сказать в заключение? Во-первых, очевидно, что для устройств, предназначенных для автономной работы от аккумуляторов (батарей), целесообразно использовать не Ардуино, а отдельные микроконтроллеры. Во-вторых, эта и предыдущие две публикации показали, что работать с ATmega328P без Ардуино не так уж сложно, его по-прежнему можно программировать из среды разработки Ардуино (установив обратно в плату или воспользовавшись USB-UART преобразователем). Кроме того микроконтроллер компактнее и дешевле чем Ардуино. Поэтому я советую обзавестись парой-другой AVR микроконтроллеров и использовать их при создании законченных устройств.
ADCSRA |= 1 << ADEN; // Включаем АЦП
Итак, что можно сказать в заключение? Во-первых, очевидно, что для устройств, предназначенных для автономной работы от аккумуляторов (батарей), целесообразно использовать не Ардуино, а отдельные микроконтроллеры. Во-вторых, эта и предыдущие две публикации показали, что работать с ATmega328P без Ардуино не так уж сложно, его по-прежнему можно программировать из среды разработки Ардуино (установив обратно в плату или воспользовавшись USB-UART преобразователем). Кроме того микроконтроллер компактнее и дешевле чем Ардуино. Поэтому я советую обзавестись парой-другой AVR микроконтроллеров и использовать их при создании законченных устройств.
Большое спасибо за внятное и структурированное изложение материала. (Это про весь блог, не только про данную статью. Читаю про энергосбережение, начинающему всё понятно.)
ОтветитьУдалитьСпасибо! Всегда приятно получить хороший отзыв.
УдалитьВ ближайшее время планирую опубликовать статью про прерывания, должно получиться познавательно. Заходите.
Спасибо за статью.
ОтветитьУдалитьДень добрый, Владимир не подскажите, отключение BOD доступно только в контроллерах ATamega328P или в ATamega328-AU (MCRCH) эту функцию все-таки как то можно активировать? И еще вопрос, если в схеме задействован: стабилизатор DC/DC, цифровой датчик, схема RTC, microSD и собственно контроллер, надо ли там вообще включать АЦП? Или выключить и забыть?
ОтветитьУдалитьДобрый!
УдалитьВ ATamega328 BOD отключить нельзя. В даташите так и написано: BOD disable is only available for ATmega328P.
Насчет АЦП, его можно выключить и забыть, раз он не используется.
Спасибо, эх... ладно будет прототип чуть больше жрущий.
УдалитьОчень интересна статья по работе с устройствами в спящем режиме. По типу пробуждения, включение устройства, засыпание. Например, nrf24L01. Спать - проснуться - включить передатчик - передать данные - уснуть. Подписан на автора, буду очень благодарен подобной информации!
ОтветитьУдалитьС Ардуино Про Мини получаются аналогичные результаты, если отпаять стабилизатор (на чипе надпись 4B2X) и индикаторный светодиод. Причем при работе от внутренного генератора и от внешнего результаты в режиме сна мало отличаются. В режиме без отключения сторожевого таймера потребление с внешним генератором (8МГц, 3,3В) даже меньше: 2,6 мкА против 3,2 мкА.
ОтветитьУдалитьПохожие результаты получаются и с Ардуино Нано, только тут нужно отпаять CH340, стабилизатор AMS1117, индикаторный светодиод и еще один маленький стабилизатор с маркировкой 662K (встречается на платах WAVGAT).
В режиме сна генератор отключается, поэтому внутренний/внешний - принципиальной разницы нет.
УдалитьА насчет выпаивания вплоть до CH340, это лучше уж купить голый МК, дешевле выйдет
Хорошо бы купить голый МК дешевле, но он сейчас на Али почему-то стоит примерно так же, как Ардуино Нано, а то и дороже. Ну и обвязка какая-то тоже понадобится.
УдалитьА отпаивается все феном за пару минут.
В Ардуино Про Мини можно вообще ничего не отпаивать, достаточно перерезать пару дорожек (выход стабилизатора и светодиод).
Гораздо проще удалить с платы Ардуино, (например Про Мини) не микроконтроллер, а стабилизатор напряжения и светодиод питания. Делается это обычным паяльником, с хорошей каплей припоя на жале. Секунда-другая. Таким же образом удаляю и обвеску стабилизатора, просто красоты ради, а также для пополнения запасов танталовых электролитов. И кнопку тоже удаляю. И вообще всё удаляю. )))) Спасибо за статью.
ОтветитьУдалить