我正在研究Arduino睡眠和外部中断。我从here获得了示例代码,效果很好。我在代码中做了一些更改和添加,在AVR唤醒时我正在检查按钮状态,等待按钮被按下。单击按钮会将闹钟关闭几秒钟,然后Arduino进入睡眠模式。按下INT0按钮唤醒Arduino,检查按钮,进入睡眠状态。
我的问题是这段代码工作一次,如果我们按下第二次唤醒,它会检查按下按钮并进入睡眠状态,但是按下按钮它不会唤醒。
请告诉我代码中的问题。
#include <avr/sleep.h>
const int LED = 13;
const int LEDT = 11;
const unsigned long KEEP_RUNNING = 10000; //milliseconds
const byte overflowPin = 6;
const byte buzzer1 = 8;
const byte buzzer2 = 9;
void setup(void) {
//to minimize power consumption while sleeping, output pins must not source
//or sink any current. input pins must have a defined level; a good way to
//ensure this is to enable the internal pullup resistors.
for (byte i = 0; i < 20; i++) {
//make all pins inputs with pullups enabled
pinMode(i, INPUT_PULLUP);
}
pinMode(LED, OUTPUT); //make the led pin an output
pinMode(LEDT, OUTPUT); //make the led pin an output
digitalWrite(LED, LOW); //drive it low so it doesn't source current
digitalWrite(LEDT, LOW); //drive it low so it doesn't source current
pinMode (overflowPin, INPUT_PULLUP);
pinMode(buzzer1, OUTPUT);
pinMode(buzzer2, OUTPUT);
Serial.begin(9600);
}
void loop(void) {
Serial.println("Wake up!");
Serial.println("Flashed 5 Times");
for (byte i = 0; i < 5; i++) {
//flash the LED
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
Serial.println("Reading" );
while (digitalRead(overflowPin) == HIGH) {
calibrate();
}
Serial.println ("Hey....");
Serial.println("Alarm!!!" );
for (byte i = 0; i < 5; i++) {
//Flash the Alarm 5 Times
alarmSound();
}
Serial.println("Go Sleep in 10 Sec...." );
digitalWrite(LED, HIGH); //one blink before sleeping
delay(100);
digitalWrite(LED, LOW);
goToSleep();
}
void alarmSound(void) {
// Toggle the buzzer at various speeds
for (byte x = 250 ; x > 70 ; x--) {
for (byte y = 0 ; y < 3 ; y++) {
digitalWrite(buzzer2, HIGH);
digitalWrite(buzzer1, LOW);
delayMicroseconds(x);
//microDelay(x);
digitalWrite(buzzer2, LOW);
digitalWrite(buzzer1, HIGH);
delayMicroseconds(x);
}
}
}
void calibrate(void) {
Serial.println ("Listening....");
for (byte i = 0; i < 5; i++) {
//flash the LED
digitalWrite(LEDT, HIGH);
delay(100);
digitalWrite(LEDT, LOW);
delay(100);
}
}
void goToSleep(void) {
byte adcsra = ADCSRA; //save the ADC Control and Status Register A
ADCSRA = 0; //disable the ADC
EICRA = _BV(ISC01); //configure INT0 to trigger on falling edge
EIMSK = _BV(INT0); //enable INT0
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cli();
//stop interrupts to ensure the BOD timed sequence executes as required
sleep_enable();
//disable brown-out detection while sleeping (20-25µA)
uint8_t mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);
uint8_t mcucr2 = mcucr1 & ~_BV(BODSE);
MCUCR = mcucr1;
MCUCR = mcucr2;
sleep_bod_disable();
//for AVR-GCC 4.3.3 and later, this is equivalent to the previous 4 lines of code
sei();
//ensure interrupts enabled so we can wake up again
sleep_cpu(); //go to sleep
sleep_disable(); //wake up here
ADCSRA = adcsra; //restore ADCSRA
}
//external interrupt 0 wakes the MCU
ISR(INT0_vect) {
EIMSK = 0; //disable external interrupts (only need one to wake up)
}