Arduino中断替代方案

从我所读到的,我的问题的解决方案是使用中断,但如果我正确理解它,我不能在中断调用的例程中使用延迟。 我有一个大按钮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  0; i--){ analogWrite(greenPin,i); delay(((60000/rate)*.2)/pmw); } for(i = 0; i  0; i--){ analogWrite(greenPin,i); delay(((60000/rate)*.6)/pmw); } } 

在大多数假设中,你是对的。 处理此问题的正确方法是使用中断,并且在中断服务例程(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 } 

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

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

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

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

我是一名专业程序员,但我是Arduino世界的新手。 我注意到许多Arduino所有者不了解编程的基础知识,并且在使用这种神奇的技术时无法取得好成绩。

特别是,我想建议不要使用Arduino中断,如果没有必要,因为它们只有两个,即使你可以为一个传感器或执行器写一个“漂亮”的代码,当你必须实现一个更复杂的项目,你不能使用它们。 当然,你使用中断处理单个按钮是正确的,但如果你有四个按钮要管理怎么办?

出于这个原因,我使用“时间片”或“单步”技术重写了“心跳”草图。 使用这种技术,每次执行循环function时,只运行控制function的“单步”,因此您可以根据需要插入任意数量,并且同样快速响应您正在使用的所有传感器。 为此,我为每个必须实现的控制函数使用全局计数器,每次执行循环函数时,我执行每个函数的一个步骤。 这是新的草图:

 // Interrupt.ino - this sketch demonstrates how to implement a "virtual" interrupt using // the technique of "single step" to avoid heavy duty cycles within the loop function. int maxPwm = 128; // max pwm amount int myPwm = 0; // current pwm value int phase = 1; // current beat phase int greenPin = 11; // output led pin int buttonPin = 9; // input button pin int buttonFlag = 1; // button flag for debounce int myDir[] = {0,1,-1,1,-1}; // direction of heartbeat loop int myDelay[] = {0,500,1000,500,3000}; // delay in microseconds of a single step void setup() { pinMode(buttonPin, INPUT); // enable button pin for input // it's not necessary to enable the analog output } void loop() { if(phase>0) heartbeat(); // if phase 1 to 4 beat, else steady buttonRead(); // test if button has been pressed } // heartbeat function - each time is executed, it advances only one step // phase 1: the led is given more and more voltage till myPwm equals to maxPwm // phase 2: the led is given less and less voltage till myPwm equals to zero // phase 3: the led is given more and more voltage till myPwm equals to maxPwm // phase 4: the led is given less and less voltage till myPwm equals to zero void heartbeat() { myPwm += myDir[phase]; analogWrite(greenPin, myPwm); delayMicroseconds(myDelay[phase]); if(myPwm==maxPwm||myPwm==0) phase = (phase%4)+1; } // buttonRead function - tests if the button is pressed; // if so, forces phase 0 (no beat) and enlightens the led to the maximum pwm // and remains in "inoperative" state till the button is released void buttonRead() { if(digitalRead(buttonPin)!=buttonFlag) // if button status changes (pressed os released) { buttonFlag = 1 - buttonFlag; // toggle button flag value if(buttonFlag) // if pressed, toggle between "beat" status and "steady" status { if(phase) myPwm = maxPwm; else myPwm = 0; phase = phase==0; analogWrite(greenPin, myPwm); } } } 

如您所见,代码非常紧凑且执行速度快。 我将心跳循环划分为四个“阶段”,由myDelay数组调节,其计数方向由myDir数组调节。 如果没有任何反应,则pwm led引脚的电压在每一步增加,直到达到maxPwm值,然后环路进入阶段2,其中电压递减直到零,依此类推,实现原始心跳。

如果按下按钮,则循环进入零相位(无心跳),并且使用maxPwm电压对LED进行补偿。 从现在开始,循环保持稳定的led,直到按钮被释放(这实现了“去抖”算法)。 如果再次按下该按钮,buttonReadfunction将重新启动心跳function,使其再次进入阶段1,从而恢复心跳。

如果再次按下按钮,心跳停止,依此类推。 一切都没有任何激动或弹跳。