+1 голос
Во многих передатчиках можно включить режим глубокого сна, где плата ничего не делает, и не потребляет электричество. Есть ли подобный режим у ардуино уно, и как его включить, если он есть?
(917 баллов) 4 55 103

3 Ответы

+5 голосов
 
Лучший ответ

В самом фреймворке Arduino уход в сон реализован с помощью различных библиотек. Я же здесь рассмотрю "низкоуровневый" вариант, который может быть применен к абсолютно любому МК AVR.

МК AVR поддерживает различные режимы сна. Режимы сна реализуются с помощью отключения тактирования различных модулей входящих в состав МК. Самый легкий режим сна это:

IDLE

в этом режиме остановлено тактирование CPU и памяти FLASH. Вся остальная периферия тактируется.

Следующий режим сна связан с АЦП и называется:

 ADC_NOISE_REDUCTION

в этом режиме остановлено всё, кроме тактирования АЦП и таймеров. Это сделано для того, чтобы минимизировать шумы, которые могут ухудшить результат оцифровки.

Режим, который останавливает абсолютно всё:

POWER_DOWN

Остановлено всё, кроме таймеров с внешним тактированием. К таким относятся RTC и WDT.

В различных моделях МК добавлены ещё режимы, но они являются вариациями вышеприведенных.

Как выводить МК из режима сна? По различным событиям, которые генерируют прерывания. Из абсолютно всех режимов сна можно выйти:

по таймерам WDT и RTC

по изменению логического уровня на любом пине, обозначенном PCINT. Сюда же входят пины INT0 и INT1 (в режиме POWER_DOWN rising и falling на этих пинах не работает, т.к. остановлено тактирование!!!).

по получению байта с адресом МК по шине I2C.

Из режима  ADC_NOISE_REDUCTION дополнительно можно выйти по готовности результат оцифровки сигнала АЦП, по прерыванию от таймера, по флагу готовности EEPROM.

Из режима IDLE выйти можно по любому прерыванию.

Ниже я покажу, как уйти в сон и проснуться от WDT. Можно пожонглировать регистрами МК, но в каждом МК уход в сон реализован по-своему, поэтому проще воспользоваться библиотекой от Atmel. Подключим ее:

#include <avr/sleep.h>

Для ухода в сон воспользуемся следующими макросами:


	 set_sleep_mode(Sleep_mode);		// Выбираем режим сна

	 sleep_cpu();			// Уходим в сон здесь

Первый макрос определяет режим сна, второй макрос разрешает сон.  Если режим сна меняться не будет, то первый макрос достаточно написать один раз, второй макрос пишем в том участке кода, где необходимо уйти в сон.

Просыпаться мы будем по вачдогу. Но прежде нам надо его подготовить. В ATMega328 вачдог работает в одном из двух режимов - либо он отслеживает исполнение программы и ресетит МК, если очередной сброс счетчика вачдога пропущен (что приводит к его переполнению), либо он работает как обычный таймер и его переполнение может сгенерировать прерывание. Есть ещё комбинированный режим, который есть и в  ATTiny: первое переполнение счетчика поднимает флаг переполнения и, если разрешено, генерирует прерывание. Последующее переполнение счетчика (если не последовало сброса) генерирует нулевое прерывание - сброс МК.

Итак, первое - выбираем режим работы вачдога - обычный таймер. Для этого я запишу такой макрос:

#define WDT_int_on()     WDTCSR = bit (WDCE) | bit (WDE);

Установки данных битов - табличные значения.

Затем сразу необходимо "взвести" таймер. У меня это будут максимальные 8 секунд:

			WDT_int_on();
			WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0);

бит WDIE разрешает прерывания от вачдога, иначе не проснемся никогда. Ну  и теперь осталось оформить обработчик прерывания (он должен быть обязателен хотя бы пустой):

ISR (WDT_vect)
{
	wdt_disable(); 
} 

Здесь я выключаю таймер вачдога, но можно его и сбросить:

wdt_reset();

Также счетчик таймера вачдога сбрасывает любое изменение периода. Например, 64 мс:

WDTCSR = bit (WDIE) | bit (WDP1) | bit (WDP0); 

Если таймер не выключается, а только лишь сбрасывается или меняется уставка периода, то макрос 

WDT_int_on();

необходимо вызвать только лишь один раз.

Перед глубоким сном обязательно все "лапки" МК необходимо сконфигурировать либо на выход, либо на вход с подтяжкой ( в зависимости от подключенной периферии). Но ни в коем случае не оставлять их как не подключенными входами - любая помеха на входе заставит переключаться входной триггер Шмитта, что отразится повышенным энергопотреблением. Если всё сделали правильно, то типовое энергопотребление AVR в режиме сна bc включенным вачдогом будет составлять порядка 3-4 мкА, без вачдога - 200-300 нА. Также обязательно выключать модуль BOD с помощью фьюзов - он отъест свои законные микроамперы.

(2.2 тыс. баллов) 4 19 52
выбран
0 голосов

Если за глубокий сон принять полное отключение перефирии и работу только таймера , отсчитывающего, когда МК проснётся то это 

 SLEEP_MODE_PWR_DOWN :  0.36 mA.

Потребление указано с учётом только МК , с обвязкой как на Ардуино Уно такой сон бессмысленен.

Данного кода достаточно , чтобы МК ушел в сон сразу после включения:

#include <avr/sleep.h>
void setup ()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
}
void loop()
{
}

Как же его выключить это отдельный вопрос , ответ на который  есть здесь.

Также если хочется сильно в этом разбираться то у Alex Gyverе естьбиблиотека https://alexgyver.ru/gyverpower/.

(2.5 тыс. баллов) 5 15 38
я бы не стал рекомендовать использовать библиотеки этого товарища
Особенно когда скачиваешь с его сайта одну библиотеку, а находишь в архиве все.
Но по моему для начала сойдёт.
–2 голосов

Да, в ардуино уно есть режим энергосбережения. И не один, а целых 6. Более подробно о этих режимах и методе их включения можно прочитать в этой статье

(221 баллов) 4 16
Добро пожаловать на Бредборд! Сайт вопросов и ответов на тему Arduino, Raspberry Pi и хоббийной электроники в целом. Цель Бредборда — быть максимально полезным. Поэтому мы строго следим за соблюдением правил, боремся с холиворами и оффтопиком.
  1. parovoZZ

    70 балл(ов)

  2. Un_ka

    64 балл(ов)

  3. sser

    38 балл(ов)

  4. Тигрыч

    10 балл(ов)

  5. Kiprais

    9 балл(ов)

  6. N08I40K

    8 балл(ов)

Награды месяца
1-е место: Raspberry Pi 3 Model A+
2-е место: Raspberry Pi Zero W
3-е место: Raspberry Pi Zero

...