Arduino的中断替代品 [英] Arduino interrupt alternatives

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

问题描述

从我读过,解决我的问题是使用中断,但如果我正确地理解他们,我不能在得到由中断称为常规使用的延迟。我有一个大的按钮 LED 开关。我希望它有心跳,而闲置,但一旦它的推出,保持绿色和执行code。

我可以打破心跳()如果我按下按钮足够的时间(我假设得到在恰当的时间状态的变化,因为它完成的一个循环心率),但我卡在如何使它的第一个点击工作。是否有其他的方式做什么,我试图?

 无效循环(){心跳(); //使LED节拍。
buttonVal = digitalRead(buttonPin); //检查按钮。
    如果(buttonVal!= buttonState){//如果按钮状态改变。
        如果(buttonVal == HIGH){//检查按钮pressed。
            analogWrite(greenPin,255); //按钮常亮绿灯一次推动。
            泛函//中有一些延误。
            functionB //有一些其他的延误。
        }
    }
}无效的心跳(){
    对于(i = 0; I< PMW;我++){
        analogWrite(greenPin,I);
        延时(((60000 /速度)* 1)/ PMW);
    }    为(ⅰ= PMW;我大于0; I - ){
        analogWrite(greenPin,I);
        延时(((60000 /速度)* 2)/ PMW);
    }    对于(i = 0; I< PMW;我++){
        analogWrite(greenPin,I);
        延时(((60000 /速度)* 1)/ PMW);
    }    为(ⅰ= PMW;我大于0; I - ){
        analogWrite(greenPin,I);
        延时(((60000 /率)* 6)/ PMW);
    }
 }


解决方案

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

  //下垂需要挥发,如果在使用ISR
挥发性INT buttonFlag = 0;无效循环()
{
    如果(buttonFlag == 0)
    {
        心跳(); //使领导节拍
    }
    其他
    {
        analogWrite(greenPin,255); //按钮保持绿色一次推
        泛函//中有一些延误
        functionB //有一些其他方面的延迟
        buttonFlag = 0;执行code后//清除标志
    }}//中断服务程序连接到INT0矢量
ISR(EXT_INT0_vect)
{
    buttonFlag = digitalRead(buttonPin); //设置标志按钮的价值
}

由于中断将只在按钮的状态变化触发,你并不需要检查这一点。

请确保您的标志变量是全球性的声明 挥发性 在ISR使用。并确保你使用了正确的中断向量与您正在使用的针使用。

下面是一个<一个href=\"http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/\">good在Arduino的教程中断。这里有另外​​一个你要什么好榜样做的。

您可能还需要寻找到<一个href=\"http://electronics.stackexchange.com/questions/41674/switch-debouncing-would-toggle-switch-still-bounce/41690#41690\">debouncing交换机取决于你使用什么类型的交换机presses。如果不是失踪的第一个preSS,你得到了太多presses,你将需要实现某种类型的反跳的。

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.

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

解决方案

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.

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.

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