Использование функций в скетче Arduino
Разбираемся, как создавать и использовать собственные функции в скетче Arduino — с примерами, пояснениями и типичными ошибками.
Разбивка кода на функции — один из ключевых навыков программирования. Функция — это именованный блок кода, который выполняет определённую задачу и возвращает управление туда, откуда был вызван. Чаще всего функции создают тогда, когда одно и то же действие нужно повторить несколько раз в разных местах программы.
Если вы раньше программировали на BASIC, то функции в Arduino — это аналог подпрограмм (GOSUB), только значительно мощнее и гибче.
Зачем выносить код в функции
- Порядок в коде. Функции помогают структурировать программу и мыслить о ней по частям, а не как о едином потоке инструкций.
- Одно место — одна задача. Логику нужно продумать и отладить только один раз, а не в каждом месте, где она используется.
- Меньше ошибок при изменениях. Если нужно что-то исправить, достаточно поправить одну функцию, а не искать все её копии по всему скетчу.
- Компактность. Повторно используемые блоки кода сокращают размер скетча.
- Переносимость. Хорошо написанную функцию легко скопировать в другой проект.
- Читаемость. Код с функциями читается почти как описание алгоритма на человеческом языке.
В каждом скетче Arduino обязательно присутствуют две функции: setup() и loop(). Все остальные функции объявляются за пределами этих двух — до или после них, но не внутри.
Анатомия функции

Диаграмма «Анатомия функции C»: тип возвращаемого значения (любой тип данных C; void, если ничего не возвращается), имя функции, параметры (любой тип данных C), оператор return (тип совпадает с объявлением) и обязательные фигурные скобки.
Разберём структуру по элементам:
- Тип возвращаемого значения — указывает, какой тип данных вернёт функция. Если функция ничего не возвращает, пишем
void. - Имя функции — произвольное, но осмысленное. Называйте функции так, чтобы было понятно, что они делают.
- Параметры в скобках — данные, которые передаются в функцию. Если параметров нет, скобки всё равно обязательны:
(). - Тело функции в фигурных скобках
{}— сам код. return— возвращает результат. Тип значения должен совпадать с объявленным типом функции.
Пример: функция умножения
Создадим простую функцию myMultiplyFunction, которая принимает два числа и возвращает их произведение.
Чтобы вызвать функцию, передаём ей аргументы нужного типа:
void loop(){
int i = 2;
int j = 3;
int k;
k = myMultiplyFunction(i, j); // теперь k содержит 6
}
Функцию myMultiplyFunction() нужно объявить вне loop() и setup() — до или после них, на ваш выбор. Полный скетч выглядит так:
void setup(){
Serial.begin(9600);
}
void loop() {
int i = 2;
int j = 3;
int k;
k = myMultiplyFunction(i, j); // теперь k содержит 6
Serial.println(k);
delay(500);
}
int myMultiplyFunction(int x, int y){
int result;
result = x * y;
return result;
}
Как проверить результат
Откройте Serial Monitor (скорость 9600 бод) и убедитесь, что в консоль выводятся ожидаемые произведения чисел. Если вывода нет — проверьте, вызвана ли Serial.begin() в setup().
Ещё один пример: обработка показаний датчика
Эта функция читает датчик пять раз с помощью analogRead(), вычисляет среднее значение из пяти измерений, масштабирует результат до 8 бит (диапазон 0–255) и инвертирует его.
int ReadSens_and_Condition(){
int i;
int sval = 0;
for (i = 0; i < 5; i++){
sval = sval + analogRead(0); // датчик на аналоговом пине 0
}
sval = sval / 5; // среднее значение
sval = sval / 4; // масштабирование до 8 бит (0 - 255)
sval = 255 - sval; // инвертировать выход
return sval;
}
Вызов функции — просто присвоение переменной:
int sens;
sens = ReadSens_and_Condition();
Обратите внимание: даже если функция не принимает параметров и ничего не возвращает, скобки () и точка с запятой ; при вызове обязательны.
Типичные ошибки
- Объявление функции внутри
loop()илиsetup()— так делать нельзя. Arduino (и C++ в целом) не поддерживает вложенные функции. Компилятор выдаст ошибку. - Несоответствие типов. Если функция объявлена как
int, а вы пытаетесь вернуть из неёfloat, данные будут обрезаны без предупреждения. - Забытый
return. Если функция должна что-то возвращать, ноreturnотсутствует — поведение непредсказуемо. - Пропущенные скобки при вызове. Написать
myFunction;вместоmyFunction();— это не вызов функции, а просто ссылка на её адрес. Код скомпилируется, но функция не выполнится.
Практические замечания
- Давайте функциям говорящие имена:
readTemperature()лучше, чемfunc1(). - Если функция используется только в одном месте, но делает что-то сложное — всё равно выносите её отдельно. Это упростит отладку.
- Функции можно вызывать из других функций — это нормальная практика.
- Порядок объявления функций в файле
.inoне важен: Arduino IDE автоматически создаёт прототипы функций перед компиляцией.