Включение и выключение с 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