中断时 Arduino 不会睡觉 运行
Arduino not going to sleep when interrupt running
我写了一个用风速计测量风速的小脚本。
我想测量 2 秒而不是睡眠 8 秒...
如果没有风,睡眠工作正常,但是当风速计旋转时,arduino 不会进入睡眠状态。无论如何,我将如何修复我的代码以进入睡眠状态。
这是我的代码..
#include "LowPower.h"
const byte interruptPin = 3; // anemomter input to digital pin
volatile unsigned long elapsedTime = 0;
int interval;
long WindAvr = 0; // sum of all wind speed between update
int measure_count = 0; // count each mesurement
unsigned int WindSpeed;
void setup() {
Serial.begin(9600);
attachInterrupt(
digitalPinToInterrupt(interruptPin), anemometerISR,
FALLING); // setup interrupt on anemometer input pin, interrupt will
// occur whenever falling edge is detected
}
void loop() {
WindAvr = 0;
measure_count = 0;
sei(); // Enables interrupts
delay(2000); // Wait x second to average
cli(); // Disable interrupts
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
WindSpeed = WindAvr / measure_count;
Serial.println(WindSpeed);
}
void anemometerISR() {
cli(); // Disable interrupts
static unsigned long previousTime = 0;
unsigned long time = millis();
if (time - previousTime > 15) { // debounce the switch contact.
elapsedTime = time - previousTime;
previousTime = time;
if (elapsedTime < 2000) {
interval = (22500 / elapsedTime) * 0.868976242;
WindAvr += interval; // add to sum of average wind values
++measure_count; // add +1 to counter
} else {
++measure_count; // add +1 to counter
}
}
sei(); // Enables interrupts
}
外部中断 - 一旦 'un-masked' - 能够唤醒设备,即使使用 cli()
.
取消设置全局 I
标志也是如此
改变
cli(); // Disable interrupts
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
到
detachInterrupt(digitalPinToInterrupt(interruptPin));
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
attachInterrupt(digitalPinToInterrupt(interruptPin), anemometerISR, FALLING);
另外...我认为您在 ISR 中的 cli()
和 sei()
语句是不必要的。全局中断使能位在进入/退出 ISR 时自动禁用/启用。来自 Atmega644 手册:
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.
我写了一个用风速计测量风速的小脚本。 我想测量 2 秒而不是睡眠 8 秒...
如果没有风,睡眠工作正常,但是当风速计旋转时,arduino 不会进入睡眠状态。无论如何,我将如何修复我的代码以进入睡眠状态。
这是我的代码..
#include "LowPower.h"
const byte interruptPin = 3; // anemomter input to digital pin
volatile unsigned long elapsedTime = 0;
int interval;
long WindAvr = 0; // sum of all wind speed between update
int measure_count = 0; // count each mesurement
unsigned int WindSpeed;
void setup() {
Serial.begin(9600);
attachInterrupt(
digitalPinToInterrupt(interruptPin), anemometerISR,
FALLING); // setup interrupt on anemometer input pin, interrupt will
// occur whenever falling edge is detected
}
void loop() {
WindAvr = 0;
measure_count = 0;
sei(); // Enables interrupts
delay(2000); // Wait x second to average
cli(); // Disable interrupts
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
WindSpeed = WindAvr / measure_count;
Serial.println(WindSpeed);
}
void anemometerISR() {
cli(); // Disable interrupts
static unsigned long previousTime = 0;
unsigned long time = millis();
if (time - previousTime > 15) { // debounce the switch contact.
elapsedTime = time - previousTime;
previousTime = time;
if (elapsedTime < 2000) {
interval = (22500 / elapsedTime) * 0.868976242;
WindAvr += interval; // add to sum of average wind values
++measure_count; // add +1 to counter
} else {
++measure_count; // add +1 to counter
}
}
sei(); // Enables interrupts
}
外部中断 - 一旦 'un-masked' - 能够唤醒设备,即使使用 cli()
.
I
标志也是如此
改变
cli(); // Disable interrupts
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
到
detachInterrupt(digitalPinToInterrupt(interruptPin));
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
attachInterrupt(digitalPinToInterrupt(interruptPin), anemometerISR, FALLING);
另外...我认为您在 ISR 中的 cli()
和 sei()
语句是不必要的。全局中断使能位在进入/退出 ISR 时自动禁用/启用。来自 Atmega644 手册:
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed.