我是一名专业程序员,但我是 Arduino 世界的新手。我注意到许多Arduino所有者不了解编程的基础知识,并且在使用这项令人惊叹的技术时无法取得良好的效果。
特别是,如果没有必要,我想建议不要使用 Arduino 中断,因为它们只有两个,即使你可以为单个传感器或执行器编写“漂亮”的代码,当你必须实现一个更复杂的项目,你不能使用它们。当然,您使用中断来处理单个按钮是正确的,但是如果您有四个按钮需要管理呢?
出于这个原因,我使用“时间片”或“单步”技术重写了“心跳”草图。使用这种技术,每次执行循环功能时,您只运行控制功能的“单步”,因此您可以根据需要插入任意数量,并且对您正在使用的所有传感器同样快速和响应。为此,我为必须实现的每个控制功能使用全局计数器,并且每次执行循环功能时,我都会执行每个功能的一个步骤。这是新草图:
// 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,在此阶段电压减少到零,依此类推,实现原始心跳。
如果按下按钮,则环路进入零相(无心跳),并且 LED 会以 maxPwm 电压供电。从现在开始,循环保持稳定的 LED,直到释放按钮(这实现了“去抖动”算法)。如果再次按下按钮,buttonRead函数会重新启动心跳函数,使其再次进入阶段1,从而恢复心跳。
如果再次按下按钮,心跳停止,依此类推。完全没有任何兴奋或弹跳。