Включение и выключение с Arduino: Переключатель (Toggle Switch)

Переключатель (Toggle Switch)

Это руководство демонстрирует, как создать функцию переключателя (toggle) с помощью Arduino. Одно нажатие кнопки включает светодиод, следующее — выключает, и так далее. Кнопку не нужно удерживать.

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

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

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

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

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

Основная идея

Для реализации переключателя необходимо отслеживать две вещи:

  1. Изменилось ли состояние кнопки (обнаружение нового нажатия)

  2. Текущий статус светодиода (включён или выключен)

Переменная LEDstatus хранит текущее состояние светодиода — HIGH (включён) или LOW (выключен), позволяя коду переключаться между состояниями при каждом нажатии кнопки.

Начальный скетч: Функция переключения

//  Sketch: Single button switch toggle function
//  www.martyncurrey.com
//
//  An  example of using a button switch as a toggle switch to turn an 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 newSwitchState = LOW;

boolean LEDstatus = LOW;

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()
{
    newSwitchState = digitalRead(pin_switch);

    if ( newSwitchState != oldSwitchState )
    {
       // has the button switch been closed?
       if ( newSwitchState == HIGH )
       {
           if ( LEDstatus == LOW ) { digitalWrite(pin_LED, HIGH);  LEDstatus = HIGH; }
           else                    { digitalWrite(pin_LED, LOW);   LEDstatus = LOW;  }
       }
       oldSwitchState = newSwitchState;
    }
}

Проблема дребезга контактов (Switch Bounce)

При первоначальном тестировании обнаруживается ненадёжное поведение — светодиод иногда выключается сразу после включения или снова включается после выключения. Это происходит из-за дребезга контактов (switch bounce), когда физические контакты кнопки быстро размыкаются и замыкаются несколько раз, прежде чем стабилизируются, генерируя ложные показания.

Решение: Программное устранение дребезга (Debounce)

Простая техника программного устранения дребезга заключается в многократном считывании пина с небольшими задержками. Если все показания совпадают — произошло «чистое» изменение состояния:

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

Улучшенный скетч с устранением дребезга

//  Sketch: Single push button switch toggle function with added debounce
//  www.martyncurrey.com
//
//  An  example of using a button switch as a toggle switch to turn an LED on or off
//  now with a simple debounce
//
//  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;

boolean LEDstatus = LOW;


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 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 )
           {
               if ( LEDstatus == LOW ) { digitalWrite(pin_LED, HIGH);  LEDstatus = HIGH; }
               else                    { digitalWrite(pin_LED, LOW);   LEDstatus = LOW;  }
           }
           oldSwitchState = newSwitchState1;
        }
    }
}

Результат

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


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