Курс Arduino с нуля · Кнопки

Урок 10. Кнопка: свет горит, пока держишь

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

Урок 10 из 31⏱ примерно 50 минутОбновлено: 25 июля 2026

Что понадобится

  • Плата Uno из набора
  • Кабель USB
  • Макетная плата
  • Тактовая кнопка
  • Резистор 10 кОм
  • Светодиод (любого цвета)
  • Резистор 470 Ом
  • 5 проводов «папа-папа»

Все детали есть в обучающем наборе, по которому идёт курс.

Девять уроков подряд плата только командовала: зажги, погаси, прибавь яркости. Она была говорящей, но глухой — что бы вы ни делали руками, программа шла своим чередом. Сегодня это меняется. Плата научится слушать, и первым, кого она услышит, будете вы.

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

Вход и выход: два режима одной ножки

Вспомните строку, которую мы писали в каждом уроке:

pinMode(LED, OUTPUT);

OUTPUT означает «выход»: плата сама подаёт на эту ножку напряжение. Ножка работает ртом — говорит. Но у каждой ножки есть и второй режим:

pinMode(BUTTON, INPUT);

INPUT — «вход». Теперь плата ничего не подаёт, а наоборот, замеряет, что происходит на ножке снаружи. Ножка работает ухом — слушает. И спросить её можно новой командой:

digitalRead(BUTTON)

Она возвращает одно из двух значений — HIGH (на ножке есть напряжение) или LOW (напряжения нет). Те же самые слова, что мы писали в digitalWrite, только теперь они не приказ, а ответ.

Одна ножка — но не одновременно. Любой цифровой вывод Uno умеет быть и входом, и выходом, но в каждый момент работает в одном режиме. Режим задаётся в setup() и держится, пока программа не поменяет его сама. Поэтому кнопку и светодиод мы вешаем на разные выводы: 2 и 10.

Знакомимся с кнопкой

В наборе лежит тактовая кнопка — светлый квадратик шесть на шесть миллиметров с круглым толкателем посередине и четырьмя короткими ножками по бокам. На чертежах её обозначают буквами SB.

Внешний видквадрат 6 × 6 мм,четыре ножки по бокамВид сбокуножки загнуты вниз —деталь стоит на макеткеОбозначениеSBтак кнопку рисуютна чертежах
Та самая деталь из набора: сверху — толкатель и заклёпки по углам, сбоку видно, что ножки загнуты вниз.

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

Четыре ножки обычно и сбивают с толку: кажется, что это четыре разных контакта. На самом деле независимых контактов только два. Заглянем внутрь — мысленно разрежем корпус пополам:

Отпущена — разреззазорМостик приподнят: леваяи правая стороны разделеныНажата — разрезМостик прогнулся и соединилвсе четыре ножки в одну цепьДве ножкиодной сторонысоединенывсегда
Ножки одной стороны соединены внутри всегда. Нажатие соединяет одну сторону с другой.

Две ножки на одной стороне корпуса — это просто два вывода одного и того же контакта, они спаяны внутри намертво. То же самое со второй парой. А в середине сидит упругая металлическая пластинка-мостик. Пока кнопку не трогают, мостик приподнят, и половинки разделены. Нажали — он прогнулся и соединил обе стороны. Отпустили — сам распрямился.

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

Как посадить кнопку на макетку

Расстояние между ножками кнопки подобрано так, чтобы она садилась верхом на канавку посередине макетной платы — по две ножки с каждой стороны. Это не прихоть: канавка разделяет столбик на две независимые половинки, и кнопка как раз соединяет их между собой при нажатии.

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

ПравильноcdefghПеремычки идут вдоль рядов: половинкистолбика разделены канавкой, покакнопку не нажали.Повёрнута на 90°cdefghПеремычки легли поперёк канавки:половинки столбика соединены всегда —плата видит вечно нажатую кнопку.
Отверстия те же самые — отличаются только невидимые перемычки внутри корпуса.

Если кнопка повёрнута, её внутренние перемычки ложатся поперёк канавки и соединяют половинки столбика напрямую — постоянно, без всякого нажатия. Схема при этом собрана «правильно», выглядит идеально, а ведёт себя так, будто кнопку кто-то держит нажатой круглые сутки. Запомните этот симптом: вечно нажатая кнопка — поверните её на 90°.

Как проверить, не вставляя в схему. Возьмите кнопку и посмотрите на неё сбоку: ножки выходят из двух противоположных стенок корпуса, парами. Эти пары и должны оказаться по разные стороны канавки. Если сомневаетесь — соберите схему, и, если светодиод горит сразу и не гаснет, просто выньте кнопку, поверните и вставьте обратно.

Почему одной кнопки мало

Казалось бы, всё просто: соединяем кнопкой вывод 2 с гнездом 5V — нажали, напряжение пришло, плата прочитала HIGH. Но что плата читает, когда кнопка отпущена?

А ничего определённого. Вывод оказывается ни к чему не подключён — он «висит в воздухе». Такой вход работает как маленькая антенна: он ловит наводки от проводки в стене, от зарядки телефона, от вашей руки, поднесённой к плате. Плата будет читать то ноль, то единицу, совершенно случайно. Светодиод замигает сам по себе — это выглядит как поломка, а на самом деле схема просто не закончена.

Без резистора5 ВSB1D2?наводки из воздухаdigitalRead → как повезётС резистором, отпущена5 ВSB1D210 кОмdigitalRead → LOW (0)С резистором, нажата5 ВSB1D210 кОмdigitalRead → HIGH (1)Стягивающий резистор держит вывод на нуле, пока кнопка отпущена, и не мешает нажатию.
Резистор 10 кОм не даёт входу «болтаться»: пока кнопка отпущена, он держит на нём ноль.

Лечится это одним резистором. Мы соединяем вывод 2 через резистор 10 кОм с землёй. Теперь у входа всегда есть определённое состояние:

  • кнопка отпущена — вывод соединён с землёй через резистор, плата уверенно читает LOW;
  • кнопка нажата — к выводу приходят 5 вольт напрямую, и плата читает HIGH.

Такой резистор называют стягивающим (или «подтягивающим к земле»): он стягивает вход к нулю, когда больше некому. Если бы мы поставили его к плюсу, он назывался бы подтягивающим — с ними мы встретимся в конце урока.

Почему 10 кОм, а не 470 Ом, как у светодиода? Резистор должен решить две задачи сразу. Во-первых, надёжно тянуть вход к нулю — для этого он не должен быть слишком большим. Во-вторых, не мешать, когда кнопка нажата: в этот момент через него течёт ток прямо из 5 вольт в землю, и чем больше сопротивление, тем меньше эта бесполезная утечка. Десять килоом — классический компромисс: ток утечки всего полмиллиампера, а вход держится твёрдо. С резистором 470 Ом схема тоже работала бы, но грела бы воздух в двадцать раз сильнее.

Собираем схему

Отключите USB перед сборкой. В схеме два резистора, и они разные: 10 кОм для кнопки (кольца коричневое, чёрное, оранжевое) и 470 Ом для светодиода (жёлтое, фиолетовое, коричневое). Перепутаете — светодиод будет еле тлеть, а кнопка станет капризной.

++abcdefghij120581012151781012345671Кнопка — верхом на канавке: ножки в столбиках 8 и 10, по обе стороны.2Жёлтый провод: вывод 2 платы → столбик 8 (ряд a). Это сигнал.3Резистор 10 кОм: столбик 8 → столбик 5 (ряд c).4Синяя перемычка: столбик 5 → шина «−». Резистор стягивает вход к нулю.5Красная перемычка: нижняя половина столбика 8 → нижняя шина «+».6Светодиод: вывод 10 → резистор 470 Ом → длинная ножка; короткая — в шину «−».7Питание: 5V платы → нижняя шина «+», GND платы → верхняя шина «−».
Кнопка — на вывод 2 со стягивающим резистором, светодиод — на вывод 10 через 470 Ом.

Обратите внимание на две шины питания. Красный провод с гнезда 5V идёт в нижнюю шину «+», потому что «питающая» сторона кнопки оказалась под канавкой. Синий провод с GND идёт в верхнюю шину «−», к которой подключены и стягивающий резистор, и короткая ножка светодиода. Шины друг с другом не соединены — это мы выяснили ещё в четвёртом уроке.

Та же схема на языке чертежей — так её изображают в книгах и документации:

UnoD2D105VGND5 В5 ВSB1R2 10 кОмVD1R1 470 ОмСлева плата слушает: вывод 2 — вход. Справа командует: вывод 10 — выход.
SB1 — кнопка, R2 — стягивающий резистор, VD1 со своим R1 — уже знакомый светодиод.

Проверьте перед включением: кнопка сидит верхом на канавке; резистор 10 кОм идёт со столбика кнопки в шину «−»; красная перемычка приходит на нижнюю половину столбика кнопки; светодиод стоит длинной ножкой к резистору 470 Ом. Только после этого подключайте USB.

Шаг 1. Первая программа, которая спрашивает

Собираем всё вместе. Вывод 2 объявляем входом, вывод 10 — выходом, а в loop() каждый раз спрашиваем кнопку и решаем, что делать:

const int BUTTON = 2;   // к этому выводу подключена кнопка
const int LED = 10;     // а к этому — светодиод

void setup() {
  pinMode(BUTTON, INPUT);   // вход: плата будет СЛУШАТЬ этот вывод
  pinMode(LED, OUTPUT);     // выход: на этом выводе плата говорит сама
}

void loop() {
  // digitalRead отвечает HIGH, если на выводе есть напряжение,
  // и LOW, если напряжения нет.
  if (digitalRead(BUTTON) == HIGH) {
    digitalWrite(LED, HIGH);  // кнопка нажата — свет горит
  } else {
    digitalWrite(LED, LOW);   // кнопка отпущена — свет погашен
  }
}

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

Разберём главную конструкцию — if. Читается она буквально: «если условие верно, выполни то, что в первых фигурных скобках, иначе (else) — то, что во вторых». Условие здесь одно: digitalRead(BUTTON) == HIGH — «то, что мы прочитали на кнопке, равно HIGH».

Два знака равенства — не опечатка. Один знак = означает «положи значение»: brightness = 100. Два знака == означают «сравни»: state == HIGH. Если написать в условии один знак, программа чаще всего соберётся без ошибок, но будет работать неправильно — это классическая ловушка, в которую попадают все без исключения. Проверяйте условия в первую очередь.

Шаг 2. Запоминаем ответ кнопки

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

const int BUTTON = 2;
const int LED = 10;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  // Сначала спрашиваем кнопку и запоминаем ответ...
  int state = digitalRead(BUTTON);

  // ...а потом решаем, что с этим ответом делать.
  if (state == HIGH) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

Работает точно так же, но теперь у ответа есть имя — state (по-английски «состояние»). Это не украшательство: digitalRead опрашивает ножку заново каждый раз, и если вызвать её дважды подряд, теоретически можно получить два разных ответа — кнопку успеют отпустить между ними. Один раз спросили, запомнили, дальше работаем с запомненным.

Почему int, а не что-то специальное? Потому что HIGH и LOW — это просто числа 1 и 0, у них нет отдельного типа. Можете убедиться сами: замените в условии HIGH на 1 — программа будет работать точно так же. Слова придуманы только для читаемости: «высокий уровень» понятнее, чем единица.

Шаг 3. Та же программа в одну строку

Присмотритесь к тому, что мы делаем: если прочитали HIGH — записываем HIGH, если прочитали LOW — записываем LOW. То есть просто перекладываем ответ кнопки на светодиод. А значит, весь if можно выбросить:

const int BUTTON = 2;
const int LED = 10;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  // Что прочитали на кнопке — то и записали на светодиод.
  digitalWrite(LED, digitalRead(BUTTON));
}

Одна строка вместо пяти, и работает точно так же. Внутренние скобки выполняются первыми: сначала digitalRead(BUTTON) даёт ответ, и этот ответ тут же уезжает вторым аргументом в digitalWrite.

Красиво — не всегда лучше. Короткая запись хороша ровно до тех пор, пока устройство делает одно простое действие. Как только появится «а если удерживать дольше секунды…» — if придётся вернуть. Мы показали этот приём, чтобы вы понимали: команды не только выполняются, но и возвращают значения, которые можно передавать дальше.

Шаг 4. Переворачиваем условие: охранный датчик

Маленькая правка — и устройство меняет смысл. Заменим в условии HIGH на LOW:

const int BUTTON = 2;
const int LED = 10;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  // Теперь тревога горит, ПОКА кнопка отпущена.
  if (digitalRead(BUTTON) == LOW) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

Теперь светодиод горит, пока кнопку не нажимают, и гаснет от нажатия. Выглядит бесполезно — ровно до момента, когда вы представите кнопку не под пальцем, а под дверцей шкафа или под крышкой шкатулки. Закрыта — кнопка прижата, всё спокойно. Открыли — кнопка отпустилась, загорелась тревога. Так устроены сигнализация в автомобиле и лампочка в холодильнике.

Кнопка, нажимаемая не пальцем, а самим предметом, называется концевым выключателем. Деталь та же самая — меняется только то, что на неё давит.

Шаг 5. Тревожная кнопка: мигаем, пока держат

Внутри if может стоять сколько угодно команд — в том числе знакомое нам мигание. Пусть светодиод мигает, пока кнопку держат:

const int BUTTON = 2;
const int LED = 10;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (digitalRead(BUTTON) == HIGH) {
    // Кнопку держат — одна вспышка за проход loop().
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    delay(100);
  } else {
    // Кнопка отпущена — свет выключен.
    digitalWrite(LED, LOW);
  }
}

Обратите внимание, как программа устроена по времени. Один проход loop() — это одна вспышка: включили, подождали 100 мс, выключили, подождали ещё 100 мс. Потом loop() начинается заново, кнопка проверяется снова, и, если её всё ещё держат, будет следующая вспышка.

Тут прячется важная особенность. Пока идут задержки, программа не смотрит на кнопку — delay останавливает всё. Отпустите кнопку в середине вспышки: светодиод честно домигает до конца, и только потом плата заметит, что её отпустили. Задержка в 200 мс незаметна, но с секундными паузами устройство станет «тормозить». Это плата за простоту delay, и в блоке про датчики мы научимся обходиться без него.

Шаг 6. Кнопка плюс плавность

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

const int BUTTON = 2;
const int LED = 10;

// Текущая яркость. Объявлена вне функций, поэтому не сбрасывается
// в конце каждого прохода loop().
int brightness = 0;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (digitalRead(BUTTON) == HIGH) {
    // Кнопку держат — разгораемся.
    brightness = brightness + 3;
    if (brightness > 255) {
      brightness = 255;
    }
  } else {
    // Отпустили — плавно гаснем.
    brightness = brightness - 3;
    if (brightness < 0) {
      brightness = 0;
    }
  }

  analogWrite(LED, brightness);
  delay(10);
}

Ключ к этой программе — переменная brightness, объявленная вне функций. Всё, что объявлено внутри loop(), забывается в конце каждого прохода; всё, что снаружи, — живёт всё время работы платы. Именно поэтому яркость накапливается: за каждый проход прибавляется всего 3, но проходов — сотня в секунду.

Две проверки — if (brightness > 255) и if (brightness < 0) — не украшение, а необходимость. Без них значение вылезет за пределы 0…255, и analogWrite поведёт себя странно: яркость скакнёт с максимума в темноту. Привыкайте ограничивать всё, что копится в переменной.

Поменяйте 3 на 1 — разгорание станет втрое медленнее. Сделайте шаг разгорания большим, а шаг гашения маленьким — получится «быстро вспыхнул, медленно затухает», как у люстры с плавным выключением.

Резистор, которого не видно

И напоследок — приём, который экономит детали. Внутри микроконтроллера у каждой ножки уже есть свой подтягивающий резистор. Обычно он отключён, но одним словом в pinMode его можно включить:

внутри микросхемы5 В20–50 кОмD2SB1Отпущена — плата самадержит на выводе HIGH.Нажата — вывод соединёнс землёй, читается LOW.Резистор уже внутри платы — на макетке остаются кнопка и провод на GND.
Встроенный резистор подтягивает вывод к 5 В. Кнопка теперь соединяет вывод с землёй.

Схема при этом меняется: кнопка соединяет вывод не с плюсом, а с землёй, а внешний резистор 10 кОм не нужен вовсе. Логика получается перевёрнутая — ровно как у RGB-светодиода в прошлом уроке:

const int BUTTON = 2;
const int LED = 10;

void setup() {
  // INPUT_PULLUP — вход с ВНУТРЕННИМ подтягивающим резистором.
  // Пока кнопка отпущена, плата сама держит на выводе единицу.
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
}

void loop() {
  // Логика перевёрнута: нажатая кнопка притягивает вывод к земле,
  // поэтому «нажато» — это теперь LOW.
  if (digitalRead(BUTTON) == LOW) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}

Отпущенная кнопка — HIGH (встроенный резистор тянет вывод к пяти вольтам), нажатая — LOW (кнопка притягивает вывод к нулю, и он побеждает). Именно так подключают кнопки в 90 % готовых устройств: меньше деталей, меньше проводов, меньше мест, где что-то отвалится.

Почему тогда мы начали со «сложного» варианта? Потому что со стягивающим резистором видно, что происходит: он лежит на макетке, его можно потрогать и выдернуть. Со встроенным резистором всё то же самое, но спрятано внутри чипа — понять это, ни разу не собрав схему руками, почти невозможно. Дальше в курсе мы будем пользоваться именно INPUT_PULLUP.

Не работает? Разбираемся

  • Светодиод горит постоянно, кнопка ни на что не влияет. Самый частый случай: кнопка повёрнута на 90°, и её внутренние перемычки замкнули половинки столбика. Выньте, поверните и вставьте обратно.
  • Светодиод мигает сам по себе, реагирует на руку рядом с платой. Не работает стягивающий резистор: он вставлен не в тот столбик или перемычка не доходит до шины «−». Вход «висит в воздухе» и ловит наводки.
  • Ничего не происходит вообще. Проверьте, дошло ли питание до кнопки: красный провод из 5V — в нижнюю шину «+», и оттуда перемычка — в нижнюю половину столбика с ножкой кнопки. Заодно убедитесь, что жёлтый провод сидит в столбике кнопки, а не в соседнем.
  • Светодиод не загорается, но и не мигает. Похоже, дело не в кнопке, а в нём самом: проверьте, что длинная ножка смотрит в сторону резистора 470 Ом, а короткая — в шину «−». Проще всего проверить, временно загрузив программу из пятого урока.
  • Работает, но срабатывает через раз или «дважды». Это не поломка, а дребезг контактов — настоящее физическое явление, которому целиком посвящён следующий урок. В сегодняшних программах он не мешает: мы смотрим на состояние кнопки, а не считаем нажатия.
  • Плата вообще перестала прошиваться. Убедитесь, что вы не заняли выводы 0 и 1 — через них плата общается с компьютером. Кнопка должна быть на выводе 2.

Задания для тренировки

  • РазминкаПеренесите кнопку на вывод 4: переставьте жёлтый провод и поправьте программу. Сколько строк пришлось изменить? Если больше одной — вы не пользуетесь константой BUTTON.
  • ПосложнееСделайте «тревожную кнопку с разгоном»: пока кнопку держат, светодиод мигает всё быстрее — от медленных вспышек до частой дроби. Подсказка: заведите переменную с длительностью паузы и уменьшайте её при каждом проходе.
  • Со звёздочкой ⭐Защитите устройство от случайного касания: пусть свет включается, только если кнопку удерживают дольше секунды. Так работают кнопки включения на телефонах и мойках высокого давления. Разбор ниже.
Показать разбор «включение по удержанию»

Плата не умеет спрашивать «сколько секунд держат кнопку» — такой команды не существует. Значит, время придётся считать самим: раз проход loop() занимает ровно 10 мс (из-за delay(10) в конце), достаточно прибавлять по 10 за каждый проход, пока кнопку держат.

const int BUTTON = 2;
const int LED = 10;

// Сколько миллисекунд нужно держать кнопку, чтобы свет включился.
const int HOLD_MS = 1000;

// Сколько времени кнопку держат прямо сейчас.
int held = 0;

void setup() {
  pinMode(BUTTON, INPUT);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (digitalRead(BUTTON) == HIGH) {
    // Кнопку держат: копим время порциями по 10 мс.
    if (held < HOLD_MS) {
      held = held + 10;
    }
  } else {
    // Отпустили — счётчик обнуляется, отсчёт начнётся заново.
    held = 0;
  }

  if (held >= HOLD_MS) {
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }

  delay(10);
}

Главное здесь — строка held = 0 в ветке else. Отпустили кнопку — счётчик мгновенно обнуляется, и отсчёт начнётся заново. Именно поэтому нельзя «накопить» секунду десятью короткими касаниями: каждое обрывает счёт.

Попробуйте поменять HOLD_MS на 3000 — получится кнопка, которую нужно удерживать три секунды, как при выключении зависшего телефона. А в следующем уроке мы научимся измерять время точнее и без delay.

Что мы узнали

  • У каждой ножки платы два режима: OUTPUT — говорить, INPUT — слушать. Спрашивают вход командой digitalRead.
  • У тактовой кнопки четыре ножки, но контактов два: ножки одной стороны соединены внутри всегда. На макетку кнопка садится верхом на канавку — поворот на 90° ломает всю схему.
  • Вход нельзя оставлять «в воздухе»: он ловит наводки. Стягивающий резистор 10 кОм держит на нём уверенный ноль, пока кнопка отпущена.
  • if / else — развилка программы. В условиях сравнивают двумя знаками ==, а не одним.
  • Переменная, объявленная вне функций, живёт всё время работы платы — на этом строятся счётчики, накопители и плавные переходы.
  • INPUT_PULLUP включает встроенный резистор: внешний не нужен, но логика переворачивается — нажатие даёт LOW.

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

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

Зачем кнопке резистор, разве нельзя подключить её напрямую?

Без резистора вывод платы в отпущенном состоянии остаётся ни к чему не подключён и работает как антенна: он ловит наводки, и плата читает то ноль, то единицу. Стягивающий резистор 10 кОм держит на входе уверенный ноль, пока кнопка отпущена.

Почему кнопка ведёт себя так, будто её всё время держат нажатой?

Почти наверняка она вставлена в макетную плату с поворотом на 90 градусов. Тогда её внутренние перемычки ложатся поперёк канавки и соединяют половинки столбика постоянно. Выньте кнопку, поверните и вставьте обратно в те же отверстия.

Почему у тактовой кнопки четыре ножки, а не две?

Контакта на самом деле два. Две ножки одной стороны корпуса спаяны внутри намертво и служат просто двумя выводами одного контакта — так деталь устойчиво держится в плате. Нажатие соединяет одну сторону с другой.

Что такое INPUT_PULLUP и когда его применять?

Это режим входа со встроенным подтягивающим резистором внутри микроконтроллера. Внешний резистор при нём не нужен, а кнопка подключается к земле. Логика переворачивается: нажатие даёт LOW. Так подключают кнопки в большинстве готовых устройств.

← Все уроки курса