Курс Arduino с нуля · Первые шаги

Урок 3. Первая программа: мигаем светодиодом

Пишем первую программу с нуля и разбираем каждую строчку: что такое скетч, зачем нужны setup() и loop(). В конце урока плата мигает по вашей команде.

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

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

  • Плата Uno из набора
  • Кабель USB

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

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

Что такое программа для платы

Программа — это список команд, которые плата выполняет по порядку, сверху вниз, ничего не пропуская и ничего не придумывая. Плата очень быстрая (миллионы команд в секунду) и очень послушная: она сделает ровно то, что написано. Вся хитрость программирования — правильно объяснить ей, чего вы хотите.

Программы для Arduino по традиции называют скетчами (от английского sketch — «набросок»). А запись программы в память платы называют прошивкой: «прошить плату» = «загрузить в неё программу».

Шаг 0. Создаём новый проект

Откройте среду и нажмите «Новый проект». Назовите его, например, Мигалка — и перед вами откроется редактор кода.

Создание нового проекта в Trema IDE: имя проекта и кнопка создания
Новый проект: пустой скетч мы наполним сами, шаг за шагом.

Шаг 1. Скелет любой программы: setup() и loop()

Сотрите всё, что есть в редакторе, и напечатайте вот это (руками — так запоминается):

void setup() {
  // Сюда мы напишем то, что выполняется один раз — при включении.
}

void loop() {
  // А сюда — то, что будет повторяться снова и снова.
}

Разберём по косточкам:

  • setup() и loop() — два блока, из которых состоит каждый скетч на свете. Блок setup() («настройка») плата выполняет один раз при включении. Блок loop() («петля») — потом бесконечно по кругу: дошла до конца — начала сначала, и так пока не выключат питание.
  • Фигурные скобки { } обозначают границы блока: всё, что между ними, — внутри. Сейчас внутри пусто.
  • Строки, начинающиеся с //, — комментарии. Плата их полностью игнорирует, они написаны для людей. Мы будем комментировать каждый шаг.
  • Слово void пока примите как ритуал — его смысл объясним, когда доберёмся до собственных функций.

Похоже на работу повара: setup() — «помыть руки, включить плиту» (один раз перед сменой), loop() — «принять заказ, приготовить, отдать» (по кругу весь день).

Попробуйте прямо сейчас: нажмите кнопку «Собрать/Прошить». Среда проверит код, соберёт его и запишет в плату — при этом на плате быстро замигают светодиоды TX и RX: идёт передача. Поздравляем: плата уже выполняет вашу программу! Правда, программа приказывает ей… ничего не делать. Исправим.

Шаг 2. Говорим плате, какой ножкой будем управлять

Светодиод L соединён внутри платы с цифровым выводом 13. Прежде чем командовать выводом, надо объявить, что он будет выходом — то есть плата будет подавать через него напряжение, а не слушать его. Добавьте одну строку в setup():

void setup() {
  // LED_BUILTIN — встроенный светодиод платы (он подписан буквой L).
  // OUTPUT — «выход»: плата будет сама подавать на него напряжение.
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
}
  • pinMode(...) — команда «настроить режим ножки». Читается «пин-мо́уд»: pin — ножка, mode — режим.
  • В скобках — два уточнения через запятую: какая ножка (LED_BUILTIN — «встроенный светодиод», то же самое, что написать 13) и какой режим (OUTPUT — «выход»).
  • В конце строки — точка с запятой. Это «точка» в конце каждого предложения-команды. Забудете — среда подчеркнёт строку и скажет об этом по-русски.

Почему строка стоит в setup()? Потому что настроить режим достаточно один раз при включении — незачем повторять это миллион раз в секунду.

Шаг 3. Включаем светодиод

Теперь добавим первую команду в loop():

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  // HIGH — «подать напряжение». Светодиод загорается.
  digitalWrite(LED_BUILTIN, HIGH);
}

digitalWrite(LED_BUILTIN, HIGH) — «цифровая запись»: подать на ножку сигнал. HIGH («высокий») — есть напряжение, LOW («низкий») — нет напряжения. Прошейте плату — и светодиод L загорится и будет гореть постоянно.

AREFGND1312~11~10~987~6~54~3210RESET3.3V5VGNDGNDVINA0A1A2A3A4A5← USB: сюда кабель← питание7–12 ВATmega328P — «мозг» платы16 МГцкнопка RESETON — питание поданоTX и RX — идёт обмен с компьютеромL — светодиод, которым мы будем управлятьцифровые выводы 0–13питаниеаналоговые входы A0–A5
Найдите на плате светодиод с подписью L — на рисунке он мигает, у вас пока просто горит. Он соединён с выводом 13.

Шаг 4. Эксперимент, который «не сработает»

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

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // включили
  digitalWrite(LED_BUILTIN, LOW);   // и тут же выключили
}

Прошейте. И… светодиод просто горит, разве что чуть тусклее. Мигания нет. Так и задумано — это самый поучительный момент урока.

Вспомните: плата выполняет миллионы команд в секунду. Она честно включает и выключает светодиод — сотни тысяч раз в секунду! Человеческий глаз просто не успевает заметить такое мигание и видит ровный (чуть ослабленный) свет. Плата не сломалась и не ошиблась — это мы не сказали ей подождать.

Шаг 5. Добавляем паузы — и всё получается

Команда delay(1000) («дилэ́й» — задержка) приказывает плате замереть на указанное число миллисекунд. В одной секунде их 1000: значит, delay(1000) — пауза в секунду, delay(500) — в полсекунды. Вставим паузы после включения и после выключения:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);   // ножка светодиода — выход
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // включили светодиод
  delay(1000);                      // ждём 1000 миллисекунд = 1 секунду
  digitalWrite(LED_BUILTIN, LOW);   // выключили
  delay(1000);                      // и снова ждём секунду
}

Прошейте плату. Светодиод горит секунду, гаснет на секунду — и так без конца. Ваша первая настоящая программа работает.

Проследим один круг «петли» глазами платы:

  1. включить светодиод;
  2. ждать 1000 миллисекунд (светодиод всё это время горит);
  3. выключить светодиод;
  4. ждать 1000 миллисекунд (светодиод погашен);
  5. конец блока loop() — начинаем с пункта 1.

Шаг 6. Крутим настройки

Теперь самое приятное в программировании — менять числа и смотреть, что будет. Замените оба 1000 на 200 и прошейте: мигание станет быстрым и нервным. А можно сделать паузы разными — короткая вспышка и длинная темнота, как у настоящего маяка:

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // короткая вспышка...
  delay(100);
  digitalWrite(LED_BUILTIN, LOW);   // ...и длинная пауза, как у маяка
  delay(1900);
}

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

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

  • Среда подчёркивает строку и не собирает. Почти всегда — опечатка: потерялась точка с запятой, скобка или буква (команды пишутся точно как в уроке, с большими буквами в середине: pinMode, digitalWrite). Прочитайте объяснение над консолью — среда пишет причину по-русски и показывает номер строки.
  • «Плата не найдена». Вернитесь к уроку 2: кабель, драйвер, порт.
  • Прошилось, но не мигает. Проверьте, что паузы на месте (шаг 4 вы уже проходили — без delay() мигания не видно) и что вы прошили именно этот проект, а не другой.

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

  • РазминкаСделайте так, чтобы светодиод горел три секунды, а гас на одну.
  • ПосложнееДобейтесь «двойного мигания»: две короткие вспышки подряд — длинная пауза — снова две вспышки. Подсказка: команды в loop() можно повторять, блок не обязан состоять из четырёх строк.
  • Со звёздочкой ⭐Передайте светодиодом сигнал SOS азбукой Морзе: три короткие вспышки, три длинные, снова три короткие, затем большая пауза — и всё сначала.

Что мы узнали

  • Скетч состоит из setup() (выполняется один раз) и loop() (крутится вечно).
  • Каждая команда заканчивается точкой с запятой; // — комментарий для людей.
  • pinMode() настраивает ножку, digitalWrite() подаёт или снимает напряжение.
  • Плата слишком быстрая для наших глаз — паузы делает delay(), время в миллисекундах.
  • Менять числа в чужой программе — лучший способ понять, как она работает.

Пока мы командовали светодиодом, впаянным в плату. В следующем уроке возьмём в руки настоящие детали: макетную плату, светодиод и резистор — и соберём первую электрическую цепь своими руками.

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

Я загружу неправильную программу — плата сломается?

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

Что значит «прошить плату»?

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

Почему команды на английском, а не на русском?

Это общий стандарт языка программирования — как латинские названия в медицине. Команд немного, и они быстро запоминаются: pinMode — «режим ножки», digitalWrite — «цифровая запись». А все пояснения среды и наши комментарии — на русском.

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