Включение и выключение с Arduino: Запуск и остановка действия кнопкой

Запуск и остановка действия кнопкой

Это руководство демонстрирует, как использовать кнопку для запуска и остановки мигания светодиода на Arduino. При нажатии кнопки светодиод начинает мигать; при повторном нажатии — мигание прекращается.

Схема подключения

Подключение пинов:

  • Пин D10: резистор 330 Ом + светодиод к GND

  • Пин D2: резистор 10 кОм к GND + кнопка к VCC

Макетная плата Схема подключения

Первый скетч: Базовая реализация

//  Sketch: Using a push button switch to turn on and off a blinking LED
//  www.martyncurrey.com
//
//  An  example of using a button switch as a toggle switch to turn a blinking LED on or off
//
//  Pins
//  D10 to resister and LED
//  D2 to push button switch
//

// Define the pins being used
int pin_LED = 10;
int pin_switch = 2;


// variables to hold the new and old switch states
boolean oldSwitchState = LOW;
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;

// variables to hold the times
unsigned long timeNow = 0;
unsigned long timePrev = 0;
unsigned int timeWait = 100;

// variables used to control the LED
boolean flashingLEDisON = false;
boolean LEDstatus = LOW;
boolean keyPressed = false;


void setup()
{
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println(__FILE__);
    Serial.print("Uploaded: ");   Serial.println(__DATE__);
    Serial.println(" ");

    pinMode(pin_LED, OUTPUT);
    digitalWrite(pin_LED,LOW);

    pinMode(pin_switch, INPUT);
}

void loop()
{
    newSwitchState1 = digitalRead(pin_switch);      delay(1);
    newSwitchState2 = digitalRead(pin_switch);      delay(1);
    newSwitchState3 = digitalRead(pin_switch);

    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
        if ( newSwitchState1 != oldSwitchState )
        {
            if ( newSwitchState1 == HIGH ) { keyPressed = true; } else { keyPressed =  false; }
            oldSwitchState = newSwitchState1;
        }
    }


    if ( keyPressed )
    {
         // turn on or turn off the blinking LED
         if ( flashingLEDisON == false)
         {
             flashingLEDisON = true;
         }
         else
         {
              flashingLEDisON = false;
              // the LED may be on so to be safe we turn it off. If you wished you could check LEDstatus
              LEDstatus = LOW;  digitalWrite(pin_LED, LEDstatus);
         }
         keyPressed = false;
    }


    // if the blinking LED is on. See if it is time to blink it
    if ( flashingLEDisON == true )
    {
        timeNow = millis();
        if (timeNow-timePrev >= timeWait )
        {
              timePrev = timeNow;
              if (LEDstatus == LOW) { LEDstatus = HIGH; } else { LEDstatus = LOW; }
              digitalWrite(pin_LED, LEDstatus);
        }
    }
}

Пояснение кода

Скетч использует три основных раздела:

Раздел 1: Обнаружение нажатия кнопки

Считывает состояние кнопки три раза с небольшими задержками для устранения дребезга и обнаружения изменений состояния.

Раздел 2: Логика переключения

Когда обнаружено нажатие кнопки (keyPressed == true), код переключает переменную flashingLEDisON между true и false. Это определяет, должен ли светодиод мигать.

Раздел 3: Реализация мигания

Использует технику «мигание без delay» (blink without delay), которая позволяет Arduino проверять нажатия кнопки, одновременно управляя таймингом мигания светодиода.

Ключевые переменные

  • flashingLEDisON — булевый флаг, указывающий, активно ли мигание

  • LEDstatus — отслеживает текущее состояние светодиода (вкл/выкл)

  • keyPressed — устанавливается в true при обнаружении нажатия кнопки

  • timeWait — управляет частотой мигания (100 мс в этом примере)

Второй скетч: С функциями

Эта версия реализует ту же функциональность, но использует функции для улучшения организации и читаемости кода:

//  Sketch: Using a push button switch to turn on and off a blinking LED with added functions
//  www.martyncurrey.com
//
//  An  example of using a button switch as a toggle switch to turn a blinking LED on or off
//  now using functions
//
//  Pins
//  D10 to resister and LED
//  D2 to push button switch
//

// Define the pins being used
int pin_LED = 10;
int pin_switch = 2;


// variables to hold the new and old switch states
boolean oldSwitchState = LOW;

// variables to hold the times
unsigned long timeNow = 0;
unsigned long timePrev = 0;
unsigned int timeWait = 100; // This is the LED blink rate

// variables used to control the LED
boolean flashingLEDisON = false;
boolean LEDstatus = LOW;
boolean keyPressed = false;


void setup()
{
    Serial.begin(9600);
    Serial.print("Sketch:   ");   Serial.println(__FILE__);
    Serial.print("Uploaded: ");   Serial.println(__DATE__);
    Serial.println(" ");

    pinMode(pin_LED, OUTPUT);
    digitalWrite(pin_LED,LOW);

    pinMode(pin_switch, INPUT);
}

void loop()
{
    keyPressed = checkButtonSwitch();
    if ( keyPressed )
    {
        keyPressed = false;
        startAndStop();
    }
    if ( flashingLEDisON == true )  { blinkTheLED();   }
}


boolean checkButtonSwitch()
{
    boolean key = false;

    boolean newSwitchState1 = digitalRead(pin_switch);      delay(1);
    boolean newSwitchState2 = digitalRead(pin_switch);      delay(1);
    boolean newSwitchState3 = digitalRead(pin_switch);

    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
        if ( newSwitchState1 != oldSwitchState )
        {
            if ( newSwitchState1 == HIGH ) { key = true; } else { key =  false; }
            oldSwitchState = newSwitchState1;
        }
    }
    return key;
}

void startAndStop( )
{
     // turn on or turn off the blinking LED
     if ( flashingLEDisON == false)
     {
         flashingLEDisON = true;
     }
     else
     {
         flashingLEDisON = false;
         // the LED may be on so we turn it off just is case
         LEDstatus = LOW;
         digitalWrite(pin_LED, LEDstatus);
     }
}


void blinkTheLED()
{
    timeNow = millis();
    if (timeNow-timePrev >= timeWait )
    {
          timePrev = timeNow;
          if (LEDstatus == LOW) { LEDstatus = HIGH; } else { LEDstatus = LOW; }
          digitalWrite(pin_LED, LEDstatus);
    }
}

Подход с функциями

Функция loop становится чище благодаря разделению на отдельные функции:

  • checkButtonSwitch() — обнаруживает и устраняет дребезг нажатий кнопки

  • startAndStop() — переключает состояние мигания

  • blinkTheLED() — обрабатывает фактическое мигание светодиода с помощью логики таймера

Этот модульный подход делает код более читаемым, обновляемым и расширяемым для дополнительной функциональности.

Примечания к проектированию

Скетч использует переменные состояния вместо прямых булевых операций, чтобы разделить логику на отдельные блоки. Этот подход улучшает читаемость и поддерживаемость кода, хотя теоретически код можно было бы сократить, если требуется только базовая функциональность включения/выключения.

Техника «мигание без delay» позволяет одновременно мониторить ввод с кнопки и управлять таймингом светодиода — это фундаментальный паттерн для многозадачных приложений Arduino.


Оригинал статьи: Martyn Currey — martyncurrey.com