Включение и выключение с Arduino: Несколько состояний от одной кнопки
Это руководство демонстрирует, как управлять несколькими светодиодами с помощью одной кнопки на Arduino, циклически переключаясь между различными состояниями при каждом нажатии.
Схема подключения
Схема использует три светодиода, подключённых к пинам Arduino:
Пин 10: Зелёный светодиод (с резистором)
Пин 9: Жёлтый светодиод (с резистором)
Пин 8: Красный светодиод (с резистором)
Пин 2: Кнопка
Пояснение кода
Определение пинов
int pin_LEDgreen = 10;
int pin_LEDyellow = 9;
int pin_LEDred = 8;
Переменная состояния
Переменная типа byte отслеживает текущее состояние (0–3):
state = 0: все светодиоды выключены
state = 1: зелёный светодиод включён
state = 2: жёлтый светодиод включён
state = 3: красный светодиод включён
Логика увеличения состояния
state++;
if (state > 3) { state = 0; }
Управление светодиодами
Код использует простые операторы if для управления светодиодами. Сначала все светодиоды выключаются, затем включается только нужный на основе текущего состояния.
Базовый скетч
// Sketch: Multiple states from a single button switch
// www.martyncurrey.com
//
// An example of using a single button switch to set multiple states or conditions
//
// Pins
// D10 to resister and green LED
// D9 to resister and yellow LED
// D8 to resister and red LED
// D2 to push button switch
//
// state holds the current status.
// 0 = all off.
// 1 = green LED
// 2 = yellow LED
// 3 = red LED
// Define the pins being used
int pin_LEDgreen = 10;
int pin_LEDyellow = 9;
int pin_LEDred = 8;
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;
byte state = 0;
void setup()
{
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println(" ");
pinMode(pin_LEDgreen, OUTPUT); digitalWrite(pin_LEDgreen,LOW);
pinMode(pin_LEDyellow, OUTPUT); digitalWrite(pin_LEDyellow,LOW);
pinMode(pin_LEDred, OUTPUT); digitalWrite(pin_LEDred,LOW);
pinMode(pin_switch, INPUT);
}
void loop()
{
newSwitchState1 = digitalRead(pin_switch);
delay(1);
newSwitchState2 = digitalRead(pin_switch);
delay(1);
newSwitchState3 = digitalRead(pin_switch);
// if all 3 values are the same we can continue
if ( (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
{
if ( newSwitchState1 != oldSwitchState )
{
// has the button switch been closed?
if ( newSwitchState1 == HIGH )
{
// increase the value of state
state++;
if (state > 3) { state = 0; }
// turn all LEDs off
digitalWrite(pin_LEDgreen, LOW);
digitalWrite(pin_LEDyellow, LOW);
digitalWrite(pin_LEDred, LOW);
// Turn on the next LED
if (state==1) { digitalWrite(pin_LEDgreen, HIGH); }
if (state==2) { digitalWrite(pin_LEDyellow, HIGH); }
if (state==3) { digitalWrite(pin_LEDred, HIGH); }
}
oldSwitchState = newSwitchState1;
}
}
}
Улучшенная версия с массивами
Для масштабируемости с большим количеством светодиодов предлагается улучшенная версия с использованием массивов.
Определение массивов
char LED_Pins_array[] = { 10, 9, 8};
char LED_Sequence_array[] = { 10, 9, 8, 9};
byte squenceLength = 4;
Улучшенный скетч
// Sketch: Multiple states from a single button switch, refined
// www.martyncurrey.com
//
// An example of using a single button switch to set multiple states or conditions
// Now using an array to store the LED pins
//
// Pins
// D10 to resister and green LED
// D9 to resister and yellow LED
// D8 to resister and red LED
// D2 to push button switch
//
// state holds the current status.
// 0 = all off.
// 1 = green LED
// 2 = yellow LED
// 3 = red LED
// Define the pins being used for the LEDs
// green/yellow/red
char LED_Pins_array[] = { 10, 9, 8};
// Array to hold the LED sequence. green, yellow, red, yellow, green.
// position 0 is not used (considered not good practice but keeps the code easy to understand)
char LED_Sequence_array[] = { 10, 9, 8, 9};
byte squenceLength = 4;
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;
byte state = -1;
void setup()
{
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println(" ");
for (byte i=0; i< 3; i++)
{
pinMode(LED_Pins_array[i], OUTPUT); digitalWrite(LED_Pins_array[i],LOW);
}
pinMode(pin_switch, INPUT);
}
void loop()
{
newSwitchState1 = digitalRead(pin_switch);
delay(1);
newSwitchState2 = digitalRead(pin_switch);
delay(1);
newSwitchState3 = digitalRead(pin_switch);
// if all 3 values are the same we can continue
if ( (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
{
if ( newSwitchState1 != oldSwitchState )
{
// has the button switch been closed?
if ( newSwitchState1 == HIGH )
{
state++;
if (state > (squenceLength -1) ) { state = 0; }
// turn all LEDs off
for (byte i=0; i< 3; i++)
{
digitalWrite(LED_Pins_array[i],LOW);
}
// Turn on the next LED
digitalWrite(LED_Sequence_array[state],HIGH);
}
oldSwitchState = newSwitchState1;
}
}
}
Ключевые концепции
Устранение дребезга (Debouncing): Код считывает состояние кнопки три раза с небольшими задержками для устранения ложных срабатываний.
Управление состоянием: Переменная state циклически проходит через предопределённые значения, управляя тем, какой светодиод активен.
Преимущества массивов: Улучшенная версия демонстрирует, как массивы делают код более поддерживаемым и масштабируемым для проектов с большим количеством светодиодов.
Упражнения для самостоятельной работы
Храните показания состояния кнопки в массиве вместо отдельных переменных
Создайте отдельную функцию для обработки обнаружения нажатия кнопки
Расширьте последовательность светодиодов дополнительными цветами
Оригинал статьи: Martyn Currey — martyncurrey.com