Arduino中断替代方案

Jos*_*key 0 c embedded microcontroller arduino interrupt

从我读到的,我的问题的解决方案是使用中断,但如果我正确理解它,我不能在中断调用的例程中使用延迟.我有一个大按钮LED开关.我希望它在闲置时有一个心跳,但一旦它被按下,保持绿色并执行代码.

heartbeat()如果我按下按钮足够的次数,我可以打破(我假设在正确的时间完成状态更改,因为它完成了循环heartbeat),但我仍然坚持如何使它在第一次点击时工作.有没有其他方法来做我正在尝试的事情?

void loop(){

heartbeat();                                    //Make LED beat.
buttonVal = digitalRead(buttonPin);             //Check the button.
    if (buttonVal != buttonState) {               //If the button state changed.
        if (buttonVal == HIGH){                   //Check if the button is pressed.
            analogWrite(greenPin, 255);         //Button stays green once pushed.
            functionA                           //Has some delays in it.
            functionB                           //Has some other delays.
        }
    }
}

void heartbeat(){
    for(i = 0; i < pmw; i++) {
        analogWrite(greenPin,i);
        delay(((60000/rate)*.1)/pmw);
    }

    for (i = pmw; i > 0; i--){
        analogWrite(greenPin,i);
        delay(((60000/rate)*.2)/pmw);
    }

    for(i = 0; i < pmw; i++) {
        analogWrite(greenPin,i);
        delay(((60000/rate)*.1)/pmw);
    }

    for (i = pmw; i > 0; i--){
        analogWrite(greenPin,i);
        delay(((60000/rate)*.6)/pmw);
    }
 }
Run Code Online (Sandbox Code Playgroud)

emb*_*yle 5

在大多数假设中,你是对的.处理此问题的正确方法是使用中断,并且在中断服务例程(ISR)中存在延迟并不是一个好主意.所以你想要做的就是在ISR中设置一个标志,并在主循环中检查该标志.

// Flag needs to be volatile if used in an ISR
volatile int buttonFlag = 0; 

void loop()
{
    if (buttonFlag == 0)
    {
        heartbeat();                        //make led beat
    }
    else
    {
        analogWrite(greenPin, 255);         //button stays green once pushed
        functionA                           //has some delays in it
        functionB                           //has some other delays
        buttonFlag = 0;                     //clear flag after executing code
    }

}

// Interrupt Service Routine attached to INT0 vector
ISR(EXT_INT0_vect)
{
    buttonFlag = digitalRead(buttonPin);    //set flag to value of button
}
Run Code Online (Sandbox Code Playgroud)

由于中断只会在按钮状态发生变化时触发,因此您无需检查.

确保您的标志变量是全局的,并声明volatile在ISR中使用.并确保使用正确的中断向量与您正在使用的引脚一起使用.

这是一个关于Arduino中断的好教程.这是你要做的另一个很好的例子.

您可能还希望根据您使用的开关类型来调试您的开关印刷机.如果没有错过第一次按下,你得到太多的印刷机,你需要实施某种类型的去抖动.