Первая программа: заставляем светодиод мигать

Тот самый момент, ради которого всё затевалось: ты пишешь пять строк — и в реальном мире начинает мигать лампочка.

Blink — это «Hello, world» для железа. Если он замигал, значит цепочка «код → компьютер → плата → светодиод» работает целиком. Дальше — только интереснее.

Сейчас заставим встроенный светодиод (он есть на каждой Uno, рядом с пином 13) мигать раз в секунду. Никакой пайки — светодиод уже на плате. Это идеальный первый запуск.

Структура любого скетча

Программа для Arduino называется скетч и всегда состоит из двух функций:

void setup() {
  // выполняется ОДИН раз при включении
}

void loop() {
  // выполняется БЕСКОНЕЧНО, по кругу
}

В setup() мы один раз настраиваем плату. В loop() кладём то, что должно повторяться вечно. Вот полный Blink:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);   // пин 13 - на выход
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH); // подаём 5В - светодиод горит
  delay(1000);                     // ждём 1000 мс = 1 секунда
  digitalWrite(LED_BUILTIN, LOW);  // 0В - гаснет
  delay(1000);                     // снова ждём
}

Залей этот код (стрелка Upload) — встроенный светодиод замигает. Поздравляю, ты запрограммировал железо.

Как работает под капотом

  • pinMode(пин, OUTPUT) — говорит чипу: «этот пин будет выдавать напряжение». Без этого digitalWrite не сработает как надо.
  • digitalWrite(пин, HIGH) — выставляет на пине 5 В. LOW — 0 В.
  • delay(1000) — замораживает программу на 1000 миллисекунд. Чип просто стоит и ждёт.

То есть физически: пин 13 то поднимает напряжение до 5 В (ток течёт через светодиод — он светит), то опускает до 0 В (тока нет — темно). Мигание — это быстрое переключение напряжения.

А теперь та же логика мигания, но в виде модели на Python — чтобы увидеть ритм без железа:

# Та же логика на Python: имитируем мигание на 6 циклов
state = False  # False = погашен, True = горит
for tick in range(6):
    state = not state                 # переключаем состояние
    level = "HIGH (5В, горит)" if state else "LOW (0В, тьма)"
    print("Секунда", tick, "->", level)

Запусти — увидишь ту же последовательность HIGH/LOW, что бежит по пину 13.

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

  • Забыли pinMode в setup. digitalWrite может вести себя странно — пин не настроен на выход.
  • Перепутали HIGH и LOW. Светодиод горит наоборот — не страшно, но сбивает с толку.
  • Ошибка заливки «port busy». Закрой монитор порта или другую программу, занявшую порт.

Best practices

  • Используй константу LED_BUILTIN вместо числа 13 — код понятнее и переносимее между платами.
  • Меняй задержку (например, delay(200)) и заливай снова — так ты чувствуешь связь кода и реальности.
  • Комментируй каждую строку, пока учишься. Потом комментарии можно сократить.

Поиграй с программой

Лучший способ почувствовать связь кода и реальности — менять и заливать снова. Поставь delay(100) вместо delay(1000) — светодиод замигает быстро, почти сольётся. Сделай задержки разными (свет 100 мс, темнота 900 мс) — получишь эффект «сердцебиения» или маячка. Каждое изменение — это маленький эксперимент, который укрепляет понимание: программа — не магия, а точная инструкция, которую плата исполняет буквально.

Обрати внимание на важную деталь: после загрузки программа остаётся в плате навсегда. Отключи USB, подключи Arduino к батарейке через разъём питания — светодиод продолжит мигать без всякого компьютера. Это и есть суть микроконтроллера: он автономен. Компьютер нужен только чтобы один раз залить программу; дальше плата живёт сама. Именно поэтому на Arduino делают устройства, которые работают месяцами вдали от любого ПК.

Итоги

setup() — один раз, loop() — вечно. pinMode настраивает пин, digitalWrite задаёт напряжение, delay тормозит. Светодиод мигает, потому что напряжение на пине прыгает между 5 В и 0 В. Дальше подключим внешний светодиод на макетку.

Проверьте себя
1. Что выполняется в функции loop()?
AКод один раз при старте
BКод бесконечно по кругу
CТолько настройка пинов
DНичего
2. Что физически делает digitalWrite(pin, HIGH)?
AИзмеряет напряжение
BВыставляет на пине ~5 вольт
CСбрасывает плату
DУдаляет программу