Программирование Arduino: язык, структура скетча и первые команды
Программу для Arduino называют скетчем, и это не случайно: авторы хотели, чтобы она писалась как набросок, а не как программа. Для первых проектов достаточно десяти команд и двух функций. Эта страница про них — без теории языка, только то, что понадобится сегодня.
На каком языке пишут
На C++. Не на «языке Arduino» — такого языка нет. Есть C++ плюс библиотека, которая прячет работу с процессором за простыми словами вроде digitalWrite. Из этого следует важное: всё, что умеет C++, умеет и Arduino — переменные, условия, циклы, функции, массивы. Просто на первых порах это не нужно.
Есть и другие варианты: MicroPython на ESP32 и Raspberry Pi Pico, визуальные блоки в Scratch-подобных средах для детей. Но девяносто процентов примеров, библиотек и ответов на форумах — на C++ в Arduino IDE, и учиться проще всего именно там.
Как устроен скетч
Две функции, и обе обязательны. setup выполняется один раз при включении: здесь назначаются роли выводам и открывается связь с компьютером. loop крутится по кругу, пока есть питание: закончился — начался снова. Всё, что плата делает, живёт внутри loop.
// Всё, что до setup, выполняется один раз при старте
const int LED = 13; // константа: номер вывода
int counter = 0; // переменная: будет меняться
void setup() {
// выполняется один раз после включения или сброса
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
// выполняется по кругу, пока есть питание
counter = counter + 1;
Serial.println(counter);
delay(1000);
}Всё, что написано выше setup, — объявления: переменные, константы, подключение библиотек через #include. Строка с const int LED = 13 даёт выводу имя, чтобы не переписывать номер в пяти местах, когда решите перепаять.
Десять команд, которых хватает
pinMode(pin, mode) | Назначить выводу роль: OUTPUT, INPUT или INPUT_PULLUP. Делается один раз в setup. |
digitalWrite(pin, HIGH) | Подать на вывод 5 В (HIGH) или 0 В (LOW). Зажечь светодиод, щёлкнуть реле. |
digitalRead(pin) | Узнать, что на выводе: HIGH или LOW. Нажата ли кнопка, сработал ли датчик. |
analogRead(pin) | Прочитать напряжение на A0–A5 числом от 0 до 1023. Потенциометр, фоторезистор, термистор. |
analogWrite(pin, value) | ШИМ от 0 до 255 на выводах с ~. Яркость светодиода, скорость мотора. |
delay(ms) | Остановить всё на указанное число миллисекунд. Просто, но плата в это время глухая. |
millis() | Сколько миллисекунд прошло со старта. Основа любого кода, который делает несколько дел сразу. |
Serial.begin(9600) | Открыть связь с компьютером. Дальше Serial.println выводит что угодно в монитор порта. |
map(x, 0, 1023, 0, 255) | Перевести число из одного диапазона в другой. Из analogRead в analogWrite — одной строкой. |
tone(pin, freq) | Пищать на заданной частоте. Зуммер, мелодия, сигнал тревоги. noTone останавливает. |
Три скетча, которые стоит набрать руками
Не копируйте — набирайте. Так запоминаются скобки, точки с запятой и то, что HIGH пишется большими буквами. Каждый скетч собран под UNO, схемы к ним — на страницах кнопки и потенциометра.
Кнопка и светодиод
Первое условие. Кнопка между выводом 2 и землёй, подтяжка включена в коде, поэтому в покое на входе единица, а нажатие даёт ноль. Это не оговорка, а норма: так подключают кнопки почти везде.
// Кнопка на выводе 2 зажигает светодиод на выводе 13
const int BUTTON = 2;
const int LED = 13;
void setup() {
pinMode(BUTTON, INPUT_PULLUP); // вход с подтяжкой: не нажата — HIGH
pinMode(LED, OUTPUT);
}
void loop() {
if (digitalRead(BUTTON) == LOW) { // нажата — замкнута на землю
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}Потенциометр и яркость
Аналоговый вход, ШИМ и перевод диапазона. Плюс монитор порта: откройте его кнопкой с лупой в правом верхнем углу среды, и увидите, что читает плата.
// Потенциометр на A0 задаёт яркость светодиода на выводе 9
const int POT = A0;
const int LED = 9; // вывод с ШИМ, помечен ~
void setup() {
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
int raw = analogRead(POT); // 0..1023
int bright = map(raw, 0, 1023, 0, 255); // 0..255 для ШИМ
analogWrite(LED, bright);
Serial.print("raw=");
Serial.print(raw);
Serial.print(" bright=");
Serial.println(bright);
delay(50);
}Мигание без delay
Тот же Blink, но плата не спит. Пока внутри delay она не слышит ни кнопок, ни датчиков. Как только в проекте появляется вторая задача, переходят на millis — и этот шаблон стоит запомнить целиком.
// Мигаем без delay: плата остаётся свободной для других дел
const int LED = 13;
unsigned long lastToggle = 0;
bool ledOn = false;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
unsigned long now = millis(); // миллисекунд с момента старта
if (now - lastToggle >= 500) {
lastToggle = now;
ledOn = !ledOn;
digitalWrite(LED, ledOn ? HIGH : LOW);
}
// здесь можно читать кнопки, датчики — ничего не ждёт
}Ошибки компиляции по-русски
Сообщения компилятора не переводятся даже в русифицированной среде. Вот что они значат на самом деле.
expected ';' before ...
Пропущена точка с запятой в предыдущей строке. Компилятор указывает на следующую, и это сбивает: смотрите строкой выше.
'x' was not declared in this scope
Используете имя, которое не объявили — или объявили внутри другой функции, где его не видно. Чаще всего опечатка: Led вместо LED, регистр важен.
expected '}' at end of input
Не хватает закрывающей фигурной скобки. Нажмите Ctrl+T — среда расставит отступы, и место разрыва станет видно.
No such file or directory
Не найдена библиотека из строки #include. Она не установлена или называется иначе. Как ставить библиотеки и что делать, если не находится.
Скетч компилируется, но не работает
Это не ошибка кода, а ошибка схемы или загрузки. Проверьте, что выбрана та плата и тот порт, потом — что провода стоят на тех выводах, которые написаны в коде. Если загрузка вообще не идёт — разбор причин.
Что учить дальше
Функции: как только кусок кода повторяется дважды, он выносится в функцию со своим именем. Массивы: когда светодиодов становится восемь, номера выводов удобно держать списком. Библиотеки: дисплей, датчик или серво — это всегда #include и пара команд, а не сотня строк своих.
И главное: не читайте про это заранее. Берите схему с сайта, собирайте, ломайте скетч и чините. Это единственный способ, которым программирование Arduino вообще учится.
Что дальше
- Схемы для первых скетчей: от кнопки до метеостанции
- Библиотеки: где брать и как ставить
- Arduino IDE: установка и настройка
Все три скетча на этой странице собраны под Arduino UNO перед публикацией