Эта страница только для чтения. Вы можете посмотреть исходный текст, но не можете его изменить. Сообщите администратору, если считаете, что это неправильно. ====== Режимы сна и энергосбережение ====== ===== Введение ===== Рано или поздно, в любом из проектов изобретатель сталкивается с проблемой автономности. Не всегда хочется держать подключенным к розетке устройство, которое большую часть времени работы ничего не делает. Например, для умной теплицы нужно время от времени получать данные о температуре, влажности и включать системы автополива. Но ведь абсолютно не обязательно получать измерения каждую секунду, вполне достаточно измерений раз в несколько минут, потому как погода (температура и влажность) и другие подобные показатели изменяются не быстро. И получается что больше 95% времени плата потребляет электричество впустую. ==== Режимы энергопотребления ==== Для подобных и аналогичных случаев существуют специальные режимы энергопотребления контроллера, которые позволяют значительно снизить энергопотребление платой во время простоя. Эти режимы называются режимами сна, и их несколько - названия и отличия приведены ниже: * **IDLE (режим ожидания)** - в данном режиме приостанавливается работа процессора, но другие компоненты остаются работать (такие как сторожевой таймер, таймеры и счётчик millis(), прерывания, интерфейсы SPI, UART, I2C. Это самый "неэкономный" режим сна. Его основное преимущество - он сохраняет самую большую функциональность. * **ADC (режим подавления шумов АЦП)** - данный режим доступен только для микроконтроллеров, имеющих АЦП * **PWR_SAVE (режим сохранения энергии)** - в данном режиме продолжают работу сторожевой таймер, сравнение адреса I2C устройств, внешние прерывания и таймер. * **STANDBY (режим ожидания)** - один из самых экономичных режимов энергопотребления. Рекомендуется использовать, только если имеется внешний резонатор. * **PWR_DOWN (режим пониженного энергопотребления)** - самый экономичный режим потребления энергии. в данном режиме продолжают работу сторожевой таймер, сравнение адреса I2C устройств и внешние прерывания. ===== Примеры работы с Arduino UNO ===== ==== Как писать скетчи проще ==== Синтаксис описания перевода контроллера в сон и подключения прерываний довольно сложный, и зачастую вызывает появление ошибок и нежелание работать с этими режимами. Очень хорошо, что была написана дополнительная библиотека для ардуино, упрощающая подключение режимов и прерываний. Скачать библиотеку Sleep_n0m1 можно на ресурсе гитхаб или по ссылке ниже: [[https://files.smartelements.ru/know_libs/Sleep_n0m1.zip|Библиотека Sleep_n0m1]] ==== Пример 1. Самый простой ввод в сон ==== В данном примере демонстрируется введение контроллера в режима сна PWR_DOWN на заданное количество времени. Работает скетч следующим образом. В основном цикле выполняются команды (в частности вывод надписей в сериал-монитор). Вы можете добавить свои команды, например, измерение температуры. Для данного примера нам потребуется только контроллер. Результат работы мы сможем наблюдать в мониторе Serial-порта. <file Arduino> #include <Sleep_n0m1.h> //подключение библиотеки Sleep sleep; //объект для работы с режимами сна unsigned long sleepTime; //переменная для задания времени сна void setup(){ Serial.begin(9600); //инициализация монитора Serial-порта sleepTime = 10000; //время сна в милисекундах, максимальное время сна 49.7 дней } void loop() { delay(100); //задержка для того чтобы успеть вывести информацию в сериал порт Serial.println("Execute your code here"); //вывод надписи "Ваш код запускается здесь" Serial.print("Sleeping for "); //вывод надписи "сон на ..." Serial.println(sleepTime); //вывод количества времени сна delay(100); //задержка для того чтобы успеть вывести информацию в сериал порт sleep.pwrDownMode(); //установка режима сна PWR_DOWN sleep.sleepDelay(sleepTime); //заснуть на указанное время } </file> ==== Пример 2. Просыпаться по прерыванию ==== В данном примере контроллер будет введёт в сон, пока не возникнет внешнее прерывание. Простейший способ вызвать прерывание, это послать любые данные в монитор сериал-порта. Выводы прерывания на контроллере Smart UNO - это цифровые выводы 2 и 4. Поэтому нужно взять один провод папа-папа и соединить цифровые выводы 0 и 2 на контроллере. Загрузите скетч на контроллер: <file Arduino> #include <Sleep_n0m1.h> //подключение библиотеки для режимов сна Sleep sleep; //объект для ввода контроллера в сон #define intPin 2 //пин прерывания void setup(){ Serial.begin(9600); //Инициализация монитора порта } void loop(){ delay(100); //задержка для того чтобы успеть вывести информацию в сериал порт Serial.println("Execute your code here"); //вывод надписи "Ваш код запускается здесь" Serial.print("Sleeping for "); //вывод надписи "сон на ..." Serial.println("Sleeping Till Interrupt"); //вывод надписи "Сон до прерывания" delay(100); //задержка для того чтобы успеть вывести информацию в сериал порт sleep.pwrDownMode(); //установка режима сна PWR_DOWN //Сон будет продолжаться пока на выводе intPin не поменяется уровень сигнала //В данном случае "LOW" - это состояние 0. sleep.sleepPinInterrupt(intPin, LOW); //(номер вывода прерывания, состояние прерывания) } </file> После того как контроллер уйдёт в сон (информация об этом появится в мониторе Serial-порта), вывести его из сна можно только с помощью внешнего прерывания. Чтобы создать его искусственно, нужно передать в сериал-порт любую информацию, например, передать единицу: {{ :главная:инфо:com3_arduinogenuino_uno_.jpg?nolink |}} После этого цикл loop запустится заново. ==== Пример 3. Просыпаться по будильнику часов ==== В данном примере формируется минипроект - часы с будильником. Часы показывают время на черырёхразрядном индикаторе. У устройства имеется кнопка - которая переводит контроллер в режим сна до следующей минуты, устанавливая на часах будильник на следующую за текущей минуту. Индикацией установки будильника служит появление на индикаторе надписи "ALAR" - от английского alarm (будильник). Для демонстрации того, что устройство находится в режиме сна, на дисплей выводится информация в виде четырёх тире (- - - -). По пробуждению, дисплей снова отображает время. **Библиотеки** Помимо библиотеки для работы с режимами сна, понадобятся библиотеки для часов и модуля индикатора. Их можно загрузить со страниц в Базе Знаний: [[main:modules:pcf8563]] и [[main:disp:4dig_indicator_m]] ^ Что нужно ^ Кол-во, шт ^ | [[https://smartelements.ru/collection/kontrollery/product/kontroller-smart-uno|Контроллер Smart UNO]] | 1 | | [[httpss://smartelements.ru/collection/shildy/product/sensor-shield|Sensor Shield]] | 1 | | [[httpss://smartelements.ru/collection/moduli/product/modul-chasov-pcf8563|Модуль часов PCF8563]] | 1 | | [[httpss://smartelements.ru/collection/displei-i-indikatory/product/modul-4-razryadnogo-indikatora-krasnyy|Модуль 4-разрядного индикатора ]] | 1 | | [[httpss://smartelements.ru/collection/moduli/product/modul-knopki|Модуль кнопки]] | 1 | | [[httpss://smartelements.ru/collection/provoda-i-kabeli/product/shleyf-mama-mama-h4-20-sm|Шлейф "мама-мама" х4]] | 1 | | [[httpss://smartelements.ru/collection/provoda-i-kabeli/product/shleyf-mama-mama-h3-20-sm|Шлейф "мама-мама" х3]] | 1 | | [[httpss://smartelements.ru/collection/provoda-i-kabeli/product/nabor-provodov-20-sht-20sm-mama-mama|Провода мама-мама]] | 5 | **Скетч для загрузки** <file Arduino> #include "SevenSegmentTM1637.h" //подключение библиотеки для работы с дисплеем #include "SevenSegmentExtended.h" //подключение расширенных функций дисплея #include <Wire.h> //библиотека для работы с I2C #include <Rtc_Pcf8563.h> //библиотека для работы с часами #include <Sleep_n0m1.h> //подключение библиотеки для режимов сна const int wakeUpPin = 3; //вывод прерывания const int button = 6; //вывод подключения кнопки Rtc_Pcf8563 rtc; //инициализация часов SevenSegmentExtended display(13, 12); //создание объекта дисплея Sleep sleep; //объект для ввода контроллера в сон void setup() { display.begin(); //инициализация дисплея display.setBacklight(100); //установка яркости в 100% display.print("INIT"); //отображение надписи INIT (инициализация) на дисплее delay(1000); //задержка в 1 секунду pinMode(button, INPUT); //режим вывода кнопки } void loop() { rtc.getTime(); //получение времени с часов byte hour = rtc.getHour(); //запись в переменную количество часов byte minute = rtc.getMinute(); //запись в переменную количество минут display.printTime(hour, minute, false); //вывод времени if (digitalRead(button)) { //была нажата кнопка set_alarm(minute); //установить будильник display.print("----"); //вывести четыре тире, означающие что контроллер спит sleep.pwrDownMode(); //установка режима сна PWR_DOWN //сон будет продолжаться пока на выводе wakeUpPin не поменяется уровень сигнала //в данном случае с "HIGH" на "LOW" sleep.sleepPinInterrupt(wakeUpPin, FALLING); //(номер вывода прерывания, состояние прерывания) //очистка будильника clr_alarm(); } } /* Процедура очищает регистры будильника на часах. * Требуется для корректной работы модуля часов. */ void clr_alarm() { detachInterrupt(1); //отключить прерывание номер 1 (вывод контроллера - 3) rtc.clearAlarm(); //очистить будильник delay(1000); //секундная задержка } /* Процедура устанавливает будильник на часах на одну минуту больше. * Здесь можно устанавливать будильник на любое время методом setAlarm(), * который принимает четыре параметра: * - минуты будильника * - часы будильника * - день будильника * - день недели будильника * Если любое из значений равно 99 - значит берется значение текущего времени. */ void set_alarm(const int& minute) { rtc.setAlarm(minute + 1, 99, 99, 99); //установка будильника на одну минуту display.clear(); //очистить дисплей display.print("ALAR"); //вывести надпись ALAR (ALARM) delay(1000); //подождать секунду display.clear(); //очистить дисплей } </file>