Вечный сон
- Войдите на сайт для отправки комментариев
Задача: с одной кнопки (на 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
}