Arduino 中断替代方案 [英] Arduino interrupt alternatives

查看:39
本文介绍了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()(我假设在完成 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.

您可能还想查看 去抖动您的switch 按下取决于您使用的开关类型.如果不是错过了第一次按压,而是按压次数过多,则需要实施某种类型的去抖动.

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天全站免登陆