Вечный сон
- Войдите на сайт для отправки комментариев
Задача: с одной кнопки (на D2 или D3) и включать, и выключать. Ну то есть типа как кнопка "положить трубу" на сотике, только не держать долго. Для ясности будем называть состояние системы сразу после включающего прерывания - утром, состояние перед set_sleep_mode() - вечером.
Делаю правильно (с утра снимаем прерывание по detachInterrupt(), вечером ставим заново, а днём работаем, не имея прерывания и нажимание кнопки Power ловим по digitalRead(D2)==LOW) - ингода судя по симптомам уходит в спячку со снятым прерыванием, то есть невозможно разбудить. Делаю неправильно (поднять прерывание в сетюпе и не трогать вообще, на состояние "утром", "вечером" - забить) - пашет на ура.
Что делаю не так?
Как правильно:
#include <avr/sleep.h> #include <avr/power.h> #define BTN_PWR (2) #define BTN_RND (5) volatile boolean ISRflag=false, // the interrupt routine is set ONflag=true; // power state int seconds=0; unsigned long last_on=millis(); void doWake(void){ // wake if(ISRflag){ ONflag=true; ISRflag=false; detachInterrupt(0); } } void doSleep(void){ // sleep ONflag=false; if(!ISRflag){ attachInterrupt(0,doWake,LOW); ISRflag=true; } delay(100); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_mode(); sleep_disable(); power_all_enable(); } void setup(){ pinMode(A0,INPUT); pinMode(BTN_PWR,INPUT_PULLUP); pinMode(BTN_RND,INPUT_PULLUP); randomSeed(analogRead(A0)); doRandom(); // first action } void loop(){ // main if(ONflag){ if(millis()-last_on>=1000){ // shutdown enable tick seconds++; last_on=millis(); } if(digitalRead(BTN_PWR)==LOW && seconds>=2){ // shutdown cmd // if(seconds>=15) - auto shutdown seconds=0; doBlank(); delay(2000); doSleep(); doRandom(); } if(digitalRead(BTN_RND)==LOW){ // action cmd delay(250); doRandom(); } } } void doRandom(void){ // switch random LEDs on } void doBlank(void){ // switch all LEDs off }
Как неправильно, но работает:
#include <avr/sleep.h> #include <avr/power.h> #define BTN_PWR (2) #define BTN_RND (5) volatile boolean ONflag=true; // power state int seconds=0; unsigned long last_on=millis(); void doWake(void){ // wake ONflag=true; } void doSleep(void){ // sleep ONflag=false; delay(100); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_mode(); sleep_disable(); power_all_enable(); } void setup(){ pinMode(A0,INPUT); pinMode(BTN_PWR,INPUT_PULLUP); pinMode(BTN_RND,INPUT_PULLUP); randomSeed(analogRead(A0)); doRandom(); // first action attachInterrupt(0,doWake,LOW); } void loop(){ // main if(ONflag){ if(millis()-last_on>=1000){ // shutdown enable tick seconds++; last_on=millis(); } if(digitalRead(BTN_PWR)==LOW && seconds>=2){ // shutdown cmd // if(seconds>=15) - auto shutdown seconds=0; doBlank(); delay(2000); doSleep(); doRandom(); } if(digitalRead(BTN_RND)==LOW){ // action cmd delay(250); doRandom(); } } } void doRandom(void){ // switch random LEDs on } void doBlank(void){ // switch all LEDs off }