Arduino Uno的中断问题

时间:2019-05-25 19:23:08

标签: arduino interrupt

我在Arduino UNO中处理中断。在这个项目中,我想打开门时LED闪烁10次,然后再次关闭门时,停止LED闪烁并退出功能。但是在此代码中,LED只会打开和关闭一次,并且不会再次闪烁。 我的另一个问题是,当门打开或关闭时,有时打开或关闭的单词在Series监视器中出现几次。

const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin

volatile int SensorState = LOW; // 0 close - 1 open wwitch

void setup()
{
Serial.begin(9600);
pinMode(LED_Red, OUTPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}

void DoAction()
{
    SensorState = digitalRead(DOOR_SENSOR);
    if (SensorState == HIGH) {
    Serial.println("Opened");
    blinkLED(10, 500);
}
    else {
    Serial.println("Closed");
        }
}

void blinkLED(int repeats, int time)
{
    for (int i = 0; i < repeats; i++) {
        if (SensorState == HIGH) {
        digitalWrite(LED_Red, HIGH);
        delay(time);
        digitalWrite(LED_Red, LOW);
        delay(time);
    }
    else
        return;
}
}

void loop()
{
}

1 个答案:

答案 0 :(得分:2)

您不能简单地将delay()放在中断的函数上。您只需要在门打开时并根据主循环内的开始blinkLED设置一个标志即可。

我还建议您使用millis()函数在blinkLED函数内部进行无阻塞延迟(例如,当您想在门关闭时停止闪烁时)。

const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin

// flag to check door is opened
volatile bool isOpened = false;

//flag to check already blinked
volatile bool isBlinked = false;

void setup()
{
    Serial.begin(9600);
    pinMode(LED_Red, OUTPUT);
    pinMode(DOOR_SENSOR, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}

void DoAction()
{
    if (digitalRead(DOOR_SENSOR) == HIGH)
    {
        //Serial.println("Opened");
        isOpened = true;
    }
    else
    {
        isOpened = false;
        isBlinked = false;
        //Serial.println("Closed");
    }
}

void blinkLED(int repeats, int time)
{
    byte LEDState = LOW;
    unsigned long delay_start = millis();
    for (int i = 0; i < 2 * repeats; i++)
    {
        //Toggle LED state
        if (LEDState == HIGH)
            LEDState = LOW;
        else
            LEDState = HIGH;
        // set value
        digitalWrite(LED_Red, LEDState);
        // some unblocking delay
        while (millis() - delay_start < time)
        {
            // return if door is closed
            if (!isOpened)
            {
                // turn off LED
                digitalWrite(LED_Red, LOW);
                return;
            }
        }
        delay_start = millis();
    }
    isBlinked = true;
}

void loop()
{
    // Check isBlinked beacue don't want to blink again until door is closed
    if (isOpened && !isBlinked)
    {
        blinkLED(10, 500);
    }
}