Основы · 3 мин чтения

Как подключить кнопку к Arduino: подтяжка pull-up, pull-down и защита от дребезга

Как подключить кнопку к Arduino? Устройство кнопки с 4 ножками, подтягивающие резисторы pull-up и pull-down, INPUT_PULLUP, защита от дребезга (debounce) и пример включения и выключения светодиода.

Кнопка — самая простая деталь, чтобы передать в проект на Arduino касание пользователя. При нажатии она соединяет два контакта, при отпускании разъединяет. Хоть это и выглядит просто, при неправильном подключении кнопка читает случайные значения или засчитывает одно нажатие несколько раз. В этом руководстве разбираем, как правильно подключить и прочитать кнопку.

Кнопка
Тактовая кнопка с 4 ножками. Ножки попарно соединены внутри.

Как устроена кнопка с 4 ножками

У тактовой кнопки 6×6 мм, которую чаще всего ставят на макетную плату, 4 ножки, но всего 2 точки подключения: противоположные пары ножек уже соединены внутри. При нажатии кнопка соединяет эти две пары. Если поставить кнопку поверх центральной канавки макетной платы, каждая пара попадёт в свои ряды, и правильную ориентацию найти легко.

Если с ориентацией есть сомнения, переведи мультиметр в режим прозвонки: ножки, которые пищат без нажатия, — это уже соединённая пара. Ножки, которые пищат только при нажатии, — это те, которые кнопка замыкает.

Зачем нужен подтягивающий резистор pull-up или pull-down?

Когда кнопка не нажата, входной пин Arduino ни к чему не подключён; такой вход называют «висящим в воздухе» (floating). Он ловит электрические помехи и читает случайные значения HIGH или LOW. Решение — притянуть пин через резистор к постоянному уровню:

СпособПодключениеНе нажатаНажата
Подтяжка к земле (pull-down)10 kΩ от пина к GND, кнопка от пина к 5VLOWHIGH
Подтяжка к питанию (pull-up, внешняя)10 kΩ от пина к 5V, кнопка от пина к GNDHIGHLOW
INPUT_PULLUP (встроенная)Кнопка от пина к GND, резистор не нуженHIGHLOW

Самый практичный способ — pinMode(pin, INPUT_PULLUP): включается встроенный резистор Arduino примерно на 20–50 kΩ, и остаётся только подключить кнопку между пином и GND. Единственное отличие — логика инвертирована: при нажатии читается LOW.

Дребезг контактов: почему одно нажатие считается несколько раз?

В момент, когда металлические контакты кнопки соприкасаются, они несколько миллисекунд вибрируют, и цепь много раз замыкается и размыкается. Arduino читает так быстро, что может увидеть одно нажатие как 3–5 нажатий. Это называется дребезгом контактов (bounce). Чтобы исправить это программно, новые изменения игнорируют примерно 50 мс после последнего изменения.

C++ (Arduino IDE)
1const int BUTTON_PIN = 2;   // buton pin ile GND arasında / button between pin and GND
2const int LED_PIN = 13;     // karttaki LED / onboard LED
3
4bool ledOn = false;
5int lastReading = HIGH;
6int stableState = HIGH;
7unsigned long lastChange = 0;
8
9void setup() {
10  pinMode(BUTTON_PIN, INPUT_PULLUP); // dahili pull-up / internal pull-up
11  pinMode(LED_PIN, OUTPUT);
12}
13
14void loop() {
15  int reading = digitalRead(BUTTON_PIN);
16  if (reading != lastReading) lastChange = millis();   // değişti / changed
17  if (millis() - lastChange > 50 && reading != stableState) {
18    stableState = reading;                              // 50 ms kararlı / stable for 50 ms
19    if (stableState == LOW) {                           // basıldı / pressed
20      ledOn = !ledOn;                                   // LED'i değiştir / toggle LED
21      digitalWrite(LED_PIN, ledOn ? HIGH : LOW);
22    }
23  }
24  lastReading = reading;
25}

Этот код переключает светодиод один раз на каждое нажатие; если держать кнопку, он не будет переключаться снова и снова. Поскольку здесь используется millis() вместо delay(), цикл не ждёт и может одновременно выполнять другие задачи.

Частые ошибки

  • Кнопка вставлена не той стороной: если использовать уже соединённую пару ножек, кнопка всегда читается как нажатая. Поверни её на 90°.
  • Нет резистора: без подтяжки pull-up или pull-down прочитанное значение меняется случайным образом.
  • Ожидание обратной логики с INPUT_PULLUP: при нажатии читается LOW, а не HIGH; пиши условия с учётом этого.
  • Длинный delay() для защиты от дребезга: всё это время программа ничего не может делать; отсчёт времени через millis() лучше.
  • Пины 34–39 на ESP32: у этих пинов нет встроенной подтяжки; добавь внешний резистор или выбери другой пин.

Как правильно разместить кнопку и резистор на макетной плате, смотри в статье Что такое макетная плата?, а чтобы разобраться с номиналом подтягивающего резистора, — в статье Что такое резистор?.

Частые вопросы

Какой резистор нужен для кнопки?

Для подтяжки pull-up или pull-down стандартно берут 10 kΩ. С INPUT_PULLUP внешний резистор вообще не нужен.

Почему при нажатии кнопки читается LOW?

С INPUT_PULLUP или внешней подтяжкой pull-up пин обычно в состоянии HIGH; кнопка соединяет его с GND, поэтому при нажатии читается LOW. Так и должно быть.

Какой должна быть задержка защиты от дребезга?

Для большинства кнопок хватает 20–50 мс. Старым или некачественным кнопкам может понадобиться 80–100 мс.

Как читать несколько кнопок?

Подключи каждую кнопку к своему пину и переведи все в режим INPUT_PULLUP. Для большого количества кнопок используют клавиатуру (keypad) или читают их через один аналоговый пин с разными резисторами.

Все проекты
Управление светодиодом кнопкой (удержание)
#9Новичок

Управление светодиодом кнопкой (удержание)

Как дверной звонок: свет горит, пока ты нажимаешь, и гаснет, когда отпускаешь. Arduino всё время слушает кнопку; пока она нажата, светодиод горит, а как только ты убираешь палец, он гаснет. Эта просте

4.8(113)
229
Включение и выключение светодиода кнопкой (вкл/выкл)
#10Новичок

Включение и выключение светодиода кнопкой (вкл/выкл)

Нажми кнопку один раз — свет загорится, нажми ещё раз — погаснет, совсем как выключатель в твоей комнате. Arduino замечает каждое нажатие и переводит светодиод в противоположное состояние, выжидая кор

4.8(100)
167
Простое пианино на зуммере и кнопках
#26Продвинутый
Premium

Простое пианино на зуммере и кнопках

Собери своё маленькое пианино из восьми кнопок. Каждая кнопка — одна нота, от низкой к высокой: до, ре, ми, фа, соль, ля, си и верхнее до. Нота звучит через зуммер, пока ты держишь кнопку, и замолкает

4.9(66)
88
Счётчик на семисегментном индикаторе с кнопками
#43Продвинутый
Premium

Счётчик на семисегментном индикаторе с кнопками

Простой счётчик с тремя кнопками: нажми одну — цифра на индикаторе увеличится на единицу, нажми другую — уменьшится, а третья возвращает её к нулю. Одноразрядный семисегментный индикатор считает от 0

4.6(35)
47
Управление светодиодом кнопкой на ESP32 (удержание)
#104Новичок

Управление светодиодом кнопкой на ESP32 (удержание)

Светодиод горит, когда кнопка нажата, и гаснет, когда её отпускают. Показывает, как используются цифровой входной пин ESP32 и встроенный подтягивающий резистор. Режим INPUT_PULLUP избавляет от внешнего резистора.

4.6(36)
55
Управление светодиодом кнопкой на ESP32 (переключение)
#105Новичок

Управление светодиодом кнопкой на ESP32 (переключение)

При каждом нажатии кнопки состояние светодиода меняется: если горел — гаснет, если не горел — загорается. Классический шаблон переключения. Антидребезг убирает механический шум кнопки, чтобы одно нажатие давало одно переключение.

4.6(39)
57
Переключение светодиода кнопкой на Pico
#156Новичок

Переключение светодиода кнопкой на Pico

Кнопка + светодиод — следующий уровень! В отличие от базового проекта с кнопкой, держать кнопку не нужно. Нажми и отпусти → светодиод горит. Нажми и отпусти ещё раз → гаснет (переключение). Схема та же (светодиод GP14, кнопка GP2), но код сильно отличается. Изучи определение фронта (ловлю момента спада 1→0), отслеживание состояния и антидребезг (фильтр механического дребезга). Метод led.toggle() в MicroPython меняет состояние одной строкой.

0.0(0)
9
Антидребезг кнопки на Pico: IRQ против программного опроса
#159Средний
Premium

Антидребезг кнопки на Pico: IRQ против программного опроса

Нажимаешь кнопку один раз, а код насчитывает 3–4? Это дребезг контактов — металлические контакты колеблются доли миллисекунды! Сравни в мониторе два способа подсчёта рядом: сырой опрос (ловит дребезг и считает лишнее) и IRQ + программный антидребезг (точно). Изучи физику дребезга, программный антидребезг (ticks_diff() > 50ms), регистрацию прерывания Pin.irq(), триггер IRQ_FALLING, обработчики ISR и безопасность global в ISR.

0.0(0)
12