中断运行时Arduino无法入睡

时间:2019-06-16 05:30:28

标签: arduino sleep

我写了一个小脚本来用风速计测量风速。 我想测量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
}

1 个答案:

答案 0 :(得分:2)

即使使用I未设置全局cli(),外部中断(一旦被“取消屏蔽”)也能够唤醒设备。

更改

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手册中:

  

发生中断时,将清除全局中断允许I位,并禁用所有中断。用户软件可以将逻辑1写入I位以启用嵌套中断。然后,所有允许的中断都可以中断当前的中断程序。当执行“从中断返回”指令RETI时,会自动设置I位。