Урок 3. Первая программа Blink — мигание светодиодом
Blink («мигать») — первый скетч почти каждого, кто начинает с Arduino. Он мигает светодиодом L, который уже есть на плате, так что для него не нужно ничего, кроме платы и кабеля. В прошлом уроке этот пример был загружен как есть, теперь — разбор, как он устроен, и свой скетч на его основе.
Скетч целиком
Так выглядит пример File → Examples → 01.Basics → Blink (комментарии переведены):
// setup выполняется один раз — после загрузки, включения питания или нажатия RESET
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // вывод светодиода — выход
}
// loop выполняется снова и снова, без конца
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // включить светодиод
delay(1000); // ждать 1000 мс = 1 секунду
digitalWrite(LED_BUILTIN, LOW); // выключить светодиод
delay(1000); // ждать ещё секунду
}Две обязательные функции
У каждого скетча есть две функции, и обе обязательны — даже если одна из них пустая.
setup()выполняется один раз при старте. Здесь настраивают выводы, запускают связь с компьютером, задают начальные значения.loop()выполняется по кругу: дошла до конца — начинается сначала. Это и есть основная работа платы.
Слово void перед именем значит, что функция ничего не возвращает. Тело функции — между фигурными скобками { и }. Каждая команда заканчивается точкой с запятой ;. Текст после // до конца строки — комментарий: компилятор его пропускает, он нужен людям.
В обычной программе на C++ работа начинается с функции main. В скетче её писать не нужно: она уже есть в ядре Arduino и сама вызывает setup() один раз, а потом loop() в бесконечном цикле.
Команды Blink
pinMode(вывод, режим) — назначает выводу роль. OUTPUT — выход: плата сама подаёт на вывод напряжение. INPUT — вход: плата читает, что на выводе (о нём — в уроке про кнопку).
LED_BUILTIN — номер вывода, к которому подключён светодиод на плате. На Uno и Nano это 13, поэтому вместо LED_BUILTIN можно написать 13. Имя удобнее: на других платах номер другой, а скетч остаётся прежним.
digitalWrite(вывод, значение) — включает или выключает выход. HIGH — на выводе 5 В (у плат на 3,3 В — 3,3 В), светодиод горит. LOW — 0 В, светодиод гаснет.
delay(мс) — пауза в миллисекундах: в одной секунде 1000 мс. Пока идёт delay, плата больше ничего не делает; как обойтись без такой остановки — в уроке millis вместо delay.
Выходит такая последовательность: включить → ждать секунду → выключить → ждать секунду → и снова с начала loop.
Поиграйте со временем
Поменяйте числа в delay и загрузите скетч снова:
delay(100)в обоих местах — частое мигание;delay(50)послеHIGHиdelay(1950)послеLOW— короткая вспышка раз в две секунды, как у маячка;delay(5)в обоих местах — мигание станет таким частым, что глаз увидит ровный, чуть тусклый свет.
Последний опыт показывает, как устроена плавная яркость: светодиод быстро-быстро включают и выключают. Это называется ШИМ, о ней — урок Аналоговые входы и ШИМ.
Свой скетч: сигнал SOS
Сигнал бедствия SOS азбукой Морзе — три коротких вспышки, три длинных и снова три коротких. Повторять одно и то же вручную долго, поэтому вспышка вынесена в свою функцию flash:
const int LED = LED_BUILTIN; // вывод 13 на Uno и Nano
// Одна вспышка: duration — сколько миллисекунд светить
void flash(int duration) {
digitalWrite(LED, HIGH);
delay(duration);
digitalWrite(LED, LOW);
delay(200); // пауза между вспышками
}
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
for (int i = 0; i < 3; i++) flash(200); // S: три коротких
for (int i = 0; i < 3; i++) flash(600); // O: три длинных
for (int i = 0; i < 3; i++) flash(200); // S: три коротких
delay(2000); // пауза перед повтором
}Что здесь нового:
const int LED = LED_BUILTIN;— константа: имя для числа, которое не меняется. Захотите мигать другим выводом — поправите одну строку, а не десять.void flash(int duration)— своя функция с параметромduration. Её объявление стоит выше места, где она вызывается, — так понятнее при чтении.for (int i = 0; i < 3; i++)— цикл: повторить вызов три раза.
Переменные, функции и циклы в скетчах работают так же, как в обычном C++, — подробнее в курсе C++.
Частые ошибки
- Регистр букв.
pinmode,digitalwrite,led_builtin— ошибкаwas not declared in this scope: в C++ большие и маленькие буквы различаются. Правильно —pinMode,digitalWrite,LED_BUILTIN. - Пропущенная
;. Компилятор пишетexpected ';' before …и показывает строку после той, где забыта точка с запятой. - Нет
setupилиloop. Даже если вloopнечего делать, она должна быть:void loop() {}. - Забытый
pinMode. БезpinMode(…, OUTPUT)вывод остаётся входом, и светодиод горит еле-еле или не горит.
Коротко
setup()выполняется один раз при старте,loop()— по кругу без конца; обе обязательны.pinMode(вывод, OUTPUT)делает вывод выходом,digitalWriteподаёт на негоHIGH(5 В) илиLOW(0 В).delay(мс)останавливает скетч на заданное число миллисекунд.LED_BUILTIN— светодиод на плате, на Uno и Nano это вывод 13.- Повторяющиеся действия выносят в свою функцию, числа — в константы.