Arduino中断选项 [英] Arduino interrupt alternatives

查看:225
本文介绍了Arduino中断选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我所看到的,我的问题的解决方案是使用中断,但是如果我们正确理解它,我不能在中断所调用的例程中使用延迟。我有一个很大的按钮 LED 切换。我想让它在空闲的时候有一个心跳,但一旦被推送,保持绿色并执行代码。

From what I've read, the solution to my problem is to use an interrupt, but if I understand them correctly, I can't use a delay in the routine that gets called by the interrupt. I've got a large pushbutton LED switch. I want it to have a heartbeat while sitting idle, but once it's pushed, stay green and execute code.

我可以打破 heartbeat() 如果我按下足够的时间(我假设在正确的时间获得状态更改,因为它完成了心跳的循环),但是我被困在如何使它的第一次点击工作。有没有办法做我想尝试的东西?

I can break the heartbeat() if I push the button enough times (I assume getting the state change at just the right time as it finishes a loop of the heartbeat), but I'm stuck on how to make it work on the first click. Is there an alternative way to do what I'm attempting?

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);
    }
 }


推荐答案

你在大多数假设中都是正确的。处理这种情况的正确方法是使用中断,在中断服务程序(ISR)中延迟不是一个好主意。所以你想做的是在你的ISR中设置一个标志,并检查主循环中的标志。

You are correct in most of your assumptions. The proper way to handle this is using an interrupt and it is not a good idea to have delays in your interrupt service routines (ISR). So what you want to do is set a flag in your ISR and check that flag in your main loop.

// 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
}

由于中断只会在更改按钮的状态,您不需要检查。

Since the interrupt will only trigger on a change in the state of the button, you don't need to check for that.

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

Make sure that your flag variable is global and is declared volatile for use in the ISR. And make sure you are using the correct interrupt vector for use with the pin you are using.

这是一个关于Arduino中断的好教程。而这是另一个好的例子你想做什么。

Here is a good tutorial on Arduino interrupts. And here is another good example of what you're trying to do.

您可能还想查看

You may also want to look into debouncing your switch presses depending on what type of switch you're using. If instead of missing the first press, you're getting too many presses, you will need to implement some type of debouncing.

这篇关于Arduino中断选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆