Руководства · 15 мин чтения

Ошибка exit status 1 в Arduino: как исправить ошибки компиляции

Что означает exit status 1 в Arduino? Как быстро исправить ошибки was not declared in this scope, expected ';', No such file, does not name a type и Sketch too big.

Ошибка Arduino exit status 1 — это общее сообщение о том, что код не удалось скомпилировать, то есть компилятор не смог превратить программу в машинный код, понятный процессору; настоящая причина никогда не указана в этой строке. Она находится в первой строке со словом error: на несколько строк выше в панели вывода: опечатка в имени, пропущенная точка с запятой, не установленная библиотека или код, написанный для другой платы. Уведомление Compilation error: exit status 1 в правом нижнем углу Arduino IDE 2 и строка Error compiling for board Arduino Uno. в старой версии 1.8 означают ровно то же самое.

В этом руководстве ты сначала увидишь, как компиляция устроена «за кулисами» и как читать сообщение об ошибке, разбивая его на файл, строку и столбец. Затем по очереди разберём самые частые ошибки компиляции — was not declared in this scope, expected ';' before, No such file or directory, does not name a type, redefinition of и Sketch too big. Для каждой ты найдёшь ситуацию, которая её вызывает, настоящее сообщение компилятора и исправленный пример, который компилируется без ошибок. Мы также добавили ошибки из-за неправильно выбранной платы, проблемы, характерные для ESP32 и Raspberry Pi Pico, и итоговую таблицу «ошибка — решение» в конце, где собрано всё вместе. Если код компилируется нормально, но не попадает на плату, проблема на другом этапе; в этом случае смотри руководство Arduino не загружает код.

Плата Arduino Uno R3
Arduino Uno: код компилируется для процессора платы, выбранной в «Инструменты › Плата» (здесь это ATmega328P); неправильно выбранная плата может вызвать ошибку компиляции, даже если код правильный.

Что такое exit status 1 в Arduino? Компиляция и загрузка

Когда ты нажимаешь «Проверить» (Verify, галочка) или «Загрузка» (Upload), Arduino IDE запускает в фоне несколько программ. Сначала она объединяет файлы .ino из папки скетча и превращает их в обычный файл C++, добавляя в начало заголовок Arduino.h и прототипы твоих функций. Затем компилятор, например avr-g++ для Uno или xtensa-esp32-elf-g++ для ESP32, компилирует этот файл и используемые библиотеки, компоновщик (linker) собирает все части в одну программу, и в конце IDE проверяет, помещается ли программа на плату. Каждая программа по завершении возвращает код выхода: 0 означает успех, а 1 — неудачу. «exit status 1» говорит именно об этом: одна из программ в цепочке завершилась с ошибкой. Поэтому та же фраза появляется и при сбое avrdude во время загрузки; какая именно программа виновата, подскажет сообщение перед ней.

Что видно в выводеЭтапЧто это значит
error: ... и exit status 1 в концеКомпиляцияОшибка C++ в твоём коде или в библиотеке; настоящая причина — в строке error:
fatal error: DHT.h: No such file or directory (файл не найден)Компиляция (препроцессор)Файл, запрошенный через #include, не найден: библиотека не установлена или имя неверное
undefined reference to ... и collect2: error: ld returned 1 exit status (ошибка компоновщика)КомпоновкаФункция объявлена, но её тела нигде нет
multiple definition of ... (повторное определение)КомпоновкаОдна и та же переменная или функция определена в двух разных файлах
Sketch too big и text section exceeds available space in boardПроверка размераПрограмма не помещается во флеш-память платы
Not enough memory и data section exceeds available space in boardПроверка размераГлобальные переменные не помещаются в ОЗУ
Failed uploading: uploading error: exit status 1 (ошибка загрузки)ЗагрузкаКод скомпилирован, но записать его в плату не удалось; смотри строки avrdude или esptool

Как читать сообщение об ошибке Arduino

Каждая строка ошибки от компилятора построена по одной схеме: сначала имя файла, затем номера строки и столбца через двоеточие, а после них тип ошибки и её описание. Чуть выше часто есть строка вроде In function 'void loop()':, которая говорит, в какой функции ошибка; ниже — копия ошибочной строки и маленький значок ^, указывающий на проблему. error — настоящая ошибка, которая останавливает компиляцию, warning — только предупреждение, и код всё равно компилируется, а note дополняет предыдущее сообщение. Часто компилятор добавляет и подсказку: в примере ниже он прямо показывает правильное написание — suggested alternative: 'digitalWrite'.

ЧастьЗначение в примереСмысл
ФайлBlink.inoФайл с ошибкой; если вкладок несколько, видно, в какой именно
Строка6Строка, где компилятор заметил ошибку; иногда настоящая ошибка — строкой выше
Столбец3Номер символа в строке; туда указывает значок ^
Типerrorerror останавливает компиляцию, warning предупреждает, note добавляет информацию
Сообщение'digitalwrite' was not declared in this scope (имя не объявлено в этой области видимости)Часть, описывающая проблему; именно этот текст стоит искать в интернете
Подсказкаnote: suggested alternative: 'digitalWrite' (предлагаемый вариант)Догадка компилятора; часто показывает правильное написание
  1. В Файл › Настройки (File › Preferences) отметь компиляции рядом с Показать подробный вывод во время (Show verbose output during). Так ты увидишь ещё и то, какие файлы и какие папки библиотек использовал компилятор.
  2. Плату подключать не обязательно: нажми кнопку Проверить (Verify, галочка). «Проверить» только компилирует; если ошибка на этапе компиляции, нажатие «Загрузка» лишь отнимает время.
  3. Прокрути панель вывода в самый верх и найди первую строку, где есть error:. Большинство ошибок после неё — следствия этой первой.
  4. Перейди к номеру строки из сообщения. IDE 2 подчёркивает красным символ с ошибкой, а версия 1.8 окрашивает в красный всю строку. Если в этой строке проблемы не видно, посмотри на строку выше.
  5. Исправь только эту первую ошибку и снова нажми «Проверить». Если число ошибок резко уменьшилось, ты на верном пути.
  6. Если ищешь в интернете, убери из сообщения свои имена переменных и пути к файлам: поиск по was not declared in this scope вместо 'counter' was not declared in this scope даёт гораздо больше результатов. А вот когда просишь помощи на форуме, копируй весь вывод целиком.
Одна-единственная ошибка может дать десятки красных строк. Например, одна строка Serial.println, написанная с типографскими кавычками, скопированными с веб-страницы, даёт на Uno шесть отдельных ошибок stray и одну ошибку was not declared. Так что не паникуй из-за количества ошибок: исправь самую верхнюю и скомпилируй снова. Чтобы проверить, все ли фигурные скобки на месте, используй Инструменты › Автоформатирование (Tools › Auto Format, Ctrl+T): если отступы неожиданно съезжают, где-то не хватает скобки.

Ошибка 'was not declared in this scope' и как её исправить

Это сообщение означает, что компилятор не узнаёт имя, использованное в этом месте. Самая частая причина — опечатка: Arduino различает регистр букв, поэтому digitalwrite, Digitalwrite и digitalWrite — три разных имени. Вторая большая причина — область видимости (scope): если объявить переменную внутри setup(), она живёт только пока выполняется setup(), и loop() её не видит. Если переменная нужна в нескольких функциях, объяви её вне всех функций, в начале файла. Объявление переменной после строки, где она используется, даёт ту же ошибку, потому что компилятор читает файл сверху вниз. Наконец, эта ошибка появляется и тогда, когда используется объект, библиотека которого не подключена (Wire, Servo), или возможность, которой нет у выбранной платы (Serial1 на Uno).

C++ (Arduino IDE)
1// Kapsam (scope) örneği / Scope example
2const int LED_PIN = 13;   // global: her fonksiyon görür / global: every function can see it
3int yanmaSayisi = 0;      // setup() içine taşırsan loop() göremez / move it into setup() and loop() can't see it
4
5void setup() {
6  pinMode(LED_PIN, OUTPUT);
7  Serial.begin(9600);
8}
9
10void loop() {
11  int sure = 500;                // yerel: yalnız loop() içinde / local: only inside loop()
12  digitalWrite(LED_PIN, HIGH);   // digitalwrite yazarsan: was not declared / typing digitalwrite: was not declared
13  delay(sure);
14  digitalWrite(LED_PIN, LOW);
15  delay(sure);
16  yanmaSayisi++;
17  Serial.println(yanmaSayisi);   // kaç kez yandı / how many times it blinked
18}
ПричинаНеправильноПравильно
Регистр буквdigitalwrite(13, HIGH);digitalWrite(13, HIGH);
Опечатка в константеpinMode(13, OUPUT);pinMode(13, OUTPUT);
Переменная объявлена в другой функцииint led = 13; объявлено внутри setup(), а led используется внутри loop()Перенеси строку int led = 13; наверх, вне всех функций
Переменная объявлена после использованияint counter = 0; стоит после строки counter++;Перенеси объявление выше места, где переменная используется
Библиотека не подключенаWire.begin(); без строки #includeДобавь #include <Wire.h> в начало файла
Возможность, которой нет у платыSerial1.begin(9600); при выбранной UnoВыбери плату с несколькими последовательными портами, например Mega, или используй SoftwareSerial
Порядок в дополнительном файле .cppФункция вызывается до своего определения во вкладке .cppНапиши прототип (void blink();) в начале файлов .cpp; в файлах .ino IDE делает это за тебя

'expected ';' before' и другие синтаксические ошибки

В C++ каждая инструкция заканчивается точкой с запятой. Если забыть точку с запятой в конце строки, компилятор заметит это только тогда, когда прочитает следующее слово. Поэтому у компилятора Uno номер строки в expected ';' before 'delay' указывает на строку ниже ошибки: пропущенная точка с запятой стоит в конце строки перед delay. Более новые компиляторы в ядрах ESP32 и Pico указывают прямо на конец строки, где не хватает точки с запятой. Если забыть её на последней строке функции, сообщение превращается в expected ';' before '}' token. Похоже ведут себя и ошибки со скобками. Если не закрыть фигурную скобку блока if или функции, компилятор дочитает до конца файла и только тогда скажет expected '}' at end of input. Если незакрытая скобка находится внутри setup(), появится ещё и a function-definition is not allowed here before '{' token, потому что для компилятора loop() теперь — функция, которую пытаются определить внутри setup(). Ещё одна классика этого семейства — запятые вместо точек с запятой в скобках цикла for.

СообщениеНаиболее вероятная причинаГде искать
expected ';' before 'delay' (не хватает точки с запятой)Нет точки с запятой в конце предыдущей строкиНа Uno — строка выше указанной в сообщении, на ESP32 — конец указанной строки
expected ';' before '}' token (не хватает точки с запятой)Нет точки с запятой в последней строке блокаСтрока прямо перед закрывающей скобкой
expected ';' before '<' token (не хватает точки с запятой)Запятые вместо точек с запятой в инструкции forПиши так: for (int i = 0; i < 10; i++)
expected '}' at end of input (не закрыта фигурная скобка)Фигурная скобка так и не закрытаПроверь отступы через «Автоформатирование»; каждой { нужна своя }
a function-definition is not allowed here before '{' token (здесь нельзя определять функцию)Нет закрывающей скобки предыдущей функцииКонец функции, стоящей перед указанной в сообщении
expected ')' before ';' token (не закрыта круглая скобка)Открывающая круглая скобка так и не закрытаПосчитай скобки в условиях if и вызовах функций
expected primary-expression before ')' token (не хватает значения)В скобках не хватает значенияПустой аргумент, например digitalWrite(13, )
expected constructor, destructor, or type conversion before '(' token (команда вне функции)Команда написана вне какой-либо функцииПеренеси команды вроде pinMode() в setup()
expected unqualified-id before '{' token (лишняя точка с запятой)Точка с запятой после заголовка функцииПиши void loop() { вместо void loop(); {
Ошибка stray '\342' in program говорит, что в коде есть символ, которого компилятор не понимает; цифры — это восьмеричные значения байтов UTF-8 этого символа. Код, скопированный с веб-страниц, из файлов Word или PDF и из мессенджеров, может содержать типографские кавычки (“ ”) вместо прямых ("), тире вместо знака минус или невидимый неразрывный пробел: типографские кавычки и тире выглядят как \342, а неразрывный пробел — как \302. Компилятор Uno также не принимает в именах переменных кириллицу и буквы с диакритикой: int größe или int año дают stray '\303' in program. Решение — заново набрать с клавиатуры кавычки и тире в строке из сообщения и использовать в именах переменных только обычные латинские буквы. А вот кириллица и диакритика внутри текста в двойных кавычках компиляцию не ломают.

'No such file or directory': библиотека не найдена

Строки fatal error: DHT.h: No such file or directory и следующая за ними compilation terminated. говорят, что файл, запрошенный строкой #include в коде, не найден на компьютере. Слово «fatal» означает, что компиляция в этом месте полностью остановилась, поэтому ошибок в остальной части кода не будет видно, пока не исправлена эта. Причина почти всегда — не установленная библиотека. Открывая проект из интернета, прочитай по очереди строки #include в начале и установи библиотеку для каждой через Инструменты › Управлять библиотеками (Tools › Manage Libraries). Если в окне с вопросом о зависимостях не выбрать Установить все (Install All), основная библиотека установится, а вторая, нужная ей, так и не появится; в этом случае в сообщении будет имя не того файла, что указан в твоём коде, а файла, который вызывается изнутри библиотеки (например, Adafruit_Sensor.h). Регистр букв в имени файла тоже важен: в Linux dht.h и DHT.h — разные файлы. О трёх способах установки библиотеки и проблемах с ZIP читай в руководстве Как установить библиотеку Arduino.

Файл в сообщенииЧто искать в Менеджере библиотекПримечание
DHT.hDHT sensor library (Adafruit)Выбери «Установить все» (Install All), и Adafruit Unified Sensor установится вместе с ней
Adafruit_Sensor.hAdafruit Unified SensorНедостающая зависимость другой библиотеки Adafruit
LiquidCrystal_I2C.hLiquidCrystal I2C (Frank de Brabander)Не устанавливай несколько библиотек с одинаковым именем; см. предупреждение ниже
Adafruit_SSD1306.hAdafruit SSD1306Устанавливается вместе с Adafruit GFX и Adafruit BusIO
MFRC522.hMFRC522 (GithubCommunity)Для RFID-модуля RC522
IRremote.hIRremoteВ новых версиях используется IrReceiver.begin(); старые примеры могут давать предупреждения или ошибки
SoftwareSerial.h (при выбранной ESP32)Не устанавливай её: в ядре ESP32 её нетИспользуй аппаратный последовательный порт ESP32 Serial2 или установи библиотеку EspSoftwareSerial

Ошибка 'does not name a type'

does not name a type означает, что компилятор ожидал в начале строки тип данных (например, int, float, Servo или LiquidCrystal_I2C), но не узнал написанное слово. Есть три частые причины. Первая — забытая строка #include библиотеки: если Servo lid; компилируется без Servo.h, получишь 'Servo' does not name a type. Вторая — опечатка в типе: правильно String, а не string, и int, а не Int, и компилятор часто помогает подсказкой did you mean 'String'?. Третья, самая неожиданная, — команда, написанная вне функции. Вне функций можно только объявлять: int angle = 0; допустимо, но если ниже на отдельной строке написать angle = 90;, компилятор примет angle за имя типа и сообщит 'angle' does not name a type. Есть ещё одна ловушка, характерная для Arduino: IDE автоматически добавляет прототипы твоих функций прямо перед первой функцией. Если функция возвращает собственный тип struct, а структура объявлена ниже setup(), прототип окажется перед структурой, и появится та же ошибка. Решение — перенести определения структур в начало файла, перед первой функцией.

C++ (Arduino IDE)
1#include <Servo.h>   // bu satır yoksa: 'Servo' does not name a type / without it: 'Servo' does not name a type
2
3struct Olcum {       // struct'ı ilk fonksiyondan önce tanımla / define structs before the first function
4  int ham;
5  float volt;
6};
7
8Servo kapak;         // tür adı büyük harfle başlar / the type name starts with a capital letter
9int aci = 0;         // dışarıda tanım ve ilk değer serbest / declaring with a value outside is fine
10// aci = 90;         // dışarıda tek başına atama: 'aci' does not name a type / bare assignment outside: error
11
12Olcum potOku() {
13  Olcum o;
14  o.ham = analogRead(A0);           // potansiyometre A0'da / potentiometer on A0
15  o.volt = o.ham * 5.0 / 1023.0;    // 0-1023 değerini volta çevir / convert 0-1023 to volts
16  return o;
17}
18
19void setup() {
20  Serial.begin(9600);
21  kapak.attach(9);   // servo sinyali D9 / servo signal on D9
22}
23
24void loop() {
25  Olcum o = potOku();
26  aci = map(o.ham, 0, 1023, 0, 180);   // atama fonksiyonun içinde / assignment inside a function
27  kapak.write(aci);
28  Serial.println(o.volt);
29  delay(20);
30}

Ошибка 'redefinition of': одно и то же определено дважды

Ошибка redefinition of 'void setup()' говорит, что есть два определения с одним и тем же именем; строка note: 'void setup()' previously defined here прямо под ней показывает, где находится первое. У новичков самая частая причина — два примера скетчей, вставленные друг за другом в один файл: в итоге получаются две функции setup() и две loop(). Вторая причина — вкладки. Перед компиляцией Arduino IDE объединяет все файлы .ino в папке скетча в один. Старая резервная копия, скопированная в папку (например, project_old.ino), или вторая вкладка со своими setup() и loop() вызывает эту ошибку, даже если ни разу не открывать эту вкладку; решение — убрать этот файл из папки. Двойное объявление одной и той же переменной даёт похожее сообщение: redefinition of 'int led'. «Родственница» этой ошибки у компоновщика — multiple definition of; она появляется, когда переменная, получившая значение в заголовочном файле (.h), подключается в двух разных файлах .cpp. Её противоположность, undefined reference to, указывает на функцию, у которой есть прототип, но нет тела, или имя которой написано по-другому.

C++ (Arduino IDE)
1// İki örneği birleştirmek: tek setup(), tek loop() / Merging two sketches: one setup(), one loop()
2const int LED_PIN = 13;          // 1. örnek: Blink / sketch 1: Blink
3const int POT_PIN = A0;          // 2. örnek: potansiyometre / sketch 2: potentiometer
4unsigned long oncekiZaman = 0;   // millis() zamanlayıcısı / millis() timer
5bool ledDurum = false;
6
7void setup() {
8  pinMode(LED_PIN, OUTPUT);      // 1. örneğin setup içeriği / setup body of sketch 1
9  Serial.begin(9600);            // 2. örneğin setup içeriği / setup body of sketch 2
10}
11
12void loop() {
13  // 1. örnek: delay yerine millis ile yanıp sönme / sketch 1: blink with millis instead of delay
14  if (millis() - oncekiZaman >= 500) {
15    oncekiZaman = millis();
16    ledDurum = !ledDurum;
17    digitalWrite(LED_PIN, ledDurum);
18  }
19  // 2. örnek: potansiyometreyi oku ve yaz / sketch 2: read and print the potentiometer
20  int deger = analogRead(POT_PIN);   // 0-1023 arası / between 0 and 1023
21  Serial.println(deger);
22  delay(50);
23}

При объединении соблюдай такой порядок: сначала собери строки #include из обоих скетчей в начале файла без повторов, затем добавь глобальные переменные и константы; если одно и то же имя есть в обоих, переименуй одно из них. Потом помести содержимое обеих функций setup() в одну setup(), а содержимое обеих loop() — в одну loop(). Если в одном из скетчей есть длинный delay(), он задерживает второй; это решается приёмом отсчёта времени millis() вместо delay(). Наконец, проверь, не используют ли оба скетча один и тот же пин: компилятор этого не заметит, но схема будет работать не так, как ожидается.

Ошибки 'Sketch too big' и нехватка памяти

В конце каждой успешной компиляции видны две строки. Если скомпилировать для Uno пример с областью видимости выше, строка Sketch uses 2212 bytes (6%) of program storage space. Maximum is 32256 bytes. говорит, сколько флеш-памяти занимает программа, а Global variables use 190 bytes (9%) of dynamic memory — сколько ОЗУ занимают глобальные переменные. Если программа не помещается во флеш-память, значение превышает 100 процентов, а за ним идут предупреждение Sketch too big и ошибка text section exceeds available space in board. Если глобальные переменные не помещаются в ОЗУ, вместо этого появятся Not enough memory и data section exceeds available space in board. Когда занято больше 75 процентов ОЗУ, IDE может вывести предупреждение Low memory available, stability problems may occur. (мало свободной памяти, возможны сбои): код компилируется, но так как во время работы не остаётся места для локальных переменных, плата может случайно зависать или сама перезагружаться. На Uno загрузчик занимает 0,5 КБ из 32 КБ флеш-памяти, поэтому предел — 32256 байт.

ПлатаПредел памяти программОЗУ (динамическая память)Примечание
Arduino Uno R332256 байт2048 байт0,5 КБ зарезервировано под загрузчик
Arduino Nano (ATmega328P)30720 байт2048 байтIDE резервирует 2 КБ для обоих вариантов загрузчика
Arduino Leonardo28672 байта2560 байтЗагрузчик 4 КБ; код USB тоже занимает место
Arduino Mega 2560253952 байта8192 байтаПростой следующий шаг для проектов, которые не помещаются на Uno
ESP32 (схема разделов по умолчанию)1310720 байт327680 байтС Huge APP вырастает до 3145728 байт
Raspberry Pi Pico (arduino-pico, 2MB no FS)2093056 байт262144 байтаЕсли зарезервировать место под файловую систему, область программы уменьшается
C++ (Arduino IDE)
1// RAM tasarrufu: F() ve PROGMEM / Saving RAM: F() and PROGMEM
2const char mesaj[] PROGMEM = "Bu uzun metin RAM yerine flasta durur";   // flaşta saklanır / stored in flash
3const byte notalar[] PROGMEM = {60, 62, 64, 65, 67, 69, 71, 72};      // byte: int'in yarısı / byte: half of an int
4
5void setup() {
6  Serial.begin(9600);
7  Serial.println(F("Merhaba! Bu metin de flastan okunur"));   // F(): RAM harcamaz / F(): uses no RAM
8  char tampon[48];                                            // geçici RAM tamponu / temporary RAM buffer
9  strcpy_P(tampon, mesaj);                                    // flaştan RAM'e kopyala / copy from flash to RAM
10  Serial.println(tampon);
11  for (byte i = 0; i < sizeof(notalar); i++) {
12    Serial.print(pgm_read_byte(&notalar[i]));                 // flaştan bir bayt oku / read one byte from flash
13    Serial.print(' ');
14  }
15  Serial.println();
16}
17
18void loop() {
19}
  • Оборачивай постоянный текст в F(): Serial.println(F("System ready")); читает текст прямо из флеш-памяти, не копируя его в ОЗУ. То же относится к постоянному тексту, который выводится на LCD- и OLED-дисплеи.
  • Перенеси большие массивы в PROGMEM: если таблицы нот, картинки для дисплея и длинные тексты никогда не меняются, им незачем лежать в ОЗУ. Более подробные приёмы описаны в статье Arduino: не хватает памяти.
  • Выбирай правильный тип данных: для значения от 0 до 255 достаточно byte (1 байт); на Uno int занимает 2 байта, а long и float — по 4.
  • Меньше используй класс String: объекты String, которые постоянно склеиваются, фрагментируют ОЗУ; массивы char фиксированной длины ведут себя предсказуемее.
  • Знай скрытые потребности библиотек дисплеев: Adafruit SSD1306 во время работы выделяет буфер 1 КБ для OLED-дисплея 128×64. Эта память не видна в отчёте компиляции, поэтому дисплей может не запуститься, даже когда отчёт показывает 70 процентов.
  • Перейди на плату побольше: проект, который не удаётся втиснуть в Uno, спокойно работает на Mega или ESP32. На ESP32 область программы можно увеличить с 1,25 МБ до 3 МБ, выбрав Huge APP (3MB No OTA/1MB SPIFFS) в Инструменты › Partition Scheme; с этим вариантом обновление прошивки по воздуху (OTA) недоступно.

Ошибки из-за неправильно выбранной платы

Компилятор всегда компилирует код для процессора платы, выбранной в Инструменты › Плата (в IDE 2 — в селекторе платы вверху). Один и тот же код может чисто компилироваться для Mega и падать с ошибкой при выбранной Uno, потому что у каждой платы своё железо, свои имена пинов и свои библиотеки, которые идут с её пакетом плат. Открывая найденный в интернете проект, сначала проверь, для какой платы он написан: код для ESP32 не скомпилируется при выбранной Uno, а код для Uno, который обращается напрямую к регистрам процессора, не скомпилируется при выбранной ESP32. Если твоей платы вообще нет в списке, её пакет плат не установлен; пакеты ESP32 и Raspberry Pi Pico нужно установить через Менеджер плат (Boards Manager). Шаги описаны в руководстве Как установить Arduino IDE.

Сообщение об ошибкеЧто случилось?Решение
'Serial1' was not declared in this scope (не объявлено)Код написан для Mega или Leonardo, а выбрана Uno; у Uno только один аппаратный последовательный портВыбери правильную плату или используй на Uno SoftwareSerial
SoftwareSerial.h: No such file or directory (файл не найден)Выбрана ESP32; эта библиотека не входит в ядро ESP32Используй аппаратные последовательные порты ESP32 (Serial2)
'LED_BUILTIN' was not declared in this scope (не объявлено)В некоторых описаниях плат, например ESP32 Dev Module, константа встроенного светодиода не определенаУкажи номер пина напрямую (GPIO 2 на многих платах DevKit)
'D5' was not declared in this scope (не объявлено)Имена вроде D0–D8 есть на платах ESP8266, таких как NodeMCU и Wemos, и на некоторых других платах, но не на Uno и не на ESP32 Dev ModuleНа Uno и ESP32 используй номер GPIO или выбери правильную плату
'TCCR1A' was not declared in this scope (не объявлено)Код, напрямую обращающийся к регистрам таймеров AVR, компилируется для ESP32Используй функции LEDC и таймеров ESP32
WiFi.h: No such file or directory или 'WIFI_STA' was not declared in this scopeКод для ESP32 компилируется для Uno; у Uno нет Wi-FiВыбери ESP32 Dev Module в меню Инструменты › Плата
'ledcSetup' was not declared in this scope (не объявлено)Ядро ESP32 версии 3.x, а код написан для 2.xИспользуй ledcAttach() и ledcWrite() с номером пина
В начале компиляции может появиться строка вроде WARNING: library LiquidCrystal_I2C claims to run on avr architecture(s) and may be incompatible with your current board which runs on esp32 architecture(s) (библиотека заявлена для архитектуры avr и может быть несовместима с текущей платой на архитектуре esp32). Это не ошибка: так сообщается, что автор библиотеки не добавил ESP32 в список поддерживаемых плат, и библиотека часто всё равно работает. Сообщение, за которым действительно нужно следить, — Multiple libraries were found for "LiquidCrystal_I2C.h" (найдено несколько библиотек): если установлены две библиотеки с одинаковым именем, IDE выбирает одну из них, и если этот выбор не подходит к твоему коду, получишь ошибку вроде 'class LiquidCrystal_I2C' has no member named 'init'. Строки Used и Not used под сообщением показывают, какая папка использована; удали неиспользуемую копию из папки libraries.

Ошибки компиляции на ESP32

Отладочная плата ESP32
ESP32: в Arduino IDE она программируется на том же языке, но так как компилируется другим компилятором и с другим пакетом плат, часть кода, работающего на Uno, здесь выдаёт ошибки.

ESP32 тоже программируется на языке Arduino, но из-за другого компилятора и пакета плат код, который без ошибок компилируется для Uno, может застрять на ESP32. Самая частая причина — версия ядра: в версии 3.x ядра ESP32 Arduino изменились функции PWM; ledcSetup() и ledcAttachPin() удалены, а на их место пришли ledcAttach() и ledcWrite(), которые работают с номером пина вместо номера канала. Поэтому старые примеры из интернета дают 'ledcSetup' was not declared in this scope (функция не объявлена); либо переведи код на новые функции, либо установи версию 2.0.17 через «Менеджер плат». Второе отличие — настройки компилятора. Ядро Uno компилирует код с опцией -fpermissive, которая превращает некоторые ошибки в простые предупреждения; ESP32 её не использует. Например, объявление переменной внутри switch без фигурных скобок компилируется на Uno, но на ESP32 даёт ошибку jump to case label. Современные ядра ESP32 также компилируют с -Werror=return-type: если забыть return в функции, которая должна возвращать значение, получишь no return statement in function returning non-void (нет return в функции, которая должна возвращать значение), если для «Предупреждения компилятора» (Compiler warnings) выбрано что угодно, кроме «Нет» (None). В версии 2.x выбор «Больше» (More) или «Все» (All) в «Предупреждения компилятора» превращает большинство предупреждений в ошибки. Базовая настройка платы описана в статье Что такое ESP32.

C++ (Arduino IDE)
1// ESP32 Arduino paketi 3.x / ESP32 Arduino core 3.x
2const int LED_PIN = 2;        // birçok DevKit kartında dahili LED / onboard LED on many DevKit boards
3const int FREKANS = 5000;     // PWM frekansı 5 kHz / PWM frequency 5 kHz
4const int COZUNURLUK = 8;     // 8 bit: 0-255 arası / 8 bits: range 0-255
5
6int parlaklik(int adim) {
7  return (adim % 32) * 8;     // return unutulursa 3.x'te derleme hatası olabilir / a missing return can fail to compile on 3.x
8}
9
10void setup() {
11  Serial.begin(115200);
12  // eski 2.x kodu / old 2.x code: ledcSetup(0, FREKANS, COZUNURLUK); ledcAttachPin(LED_PIN, 0);
13  ledcAttach(LED_PIN, FREKANS, COZUNURLUK);   // 3.x: kanal otomatik seçilir / channel is picked automatically
14}
15
16void loop() {
17  for (int adim = 0; adim < 32; adim++) {
18    ledcWrite(LED_PIN, parlaklik(adim));      // 3.x: pin numarasıyla yaz / write using the pin number
19    delay(30);
20  }
21  if (Serial.available()) {
22    switch (Serial.read()) {
23      case 'h': {                             // case içinde değişken varsa süslü parantez şart / braces needed if a case declares a variable
24        int deger = ledcRead(LED_PIN);
25        Serial.println(deger);
26        break;
27      }
28      default:
29        break;
30    }
31  }
32}

Raspberry Pi Pico: ошибки в Arduino IDE и MicroPython

Если программировать Pico в Arduino IDE, то есть с ядром arduino-pico от Earle Philhower, компилятором по-прежнему остаётся GCC, и все сообщения из этой статьи действуют без изменений. С MicroPython всё иначе: отдельного предварительного этапа компиляции нет; Pico превращает файл в байт-код при запуске и выполняет его строка за строкой. Поэтому ошибки появляются в панели Shell внизу Thonny, в сообщении, которое начинается с Traceback (most recent call last):. Читай это сообщение снизу вверх: последняя строка говорит о типе ошибки и её описании, а часть line 7 над ней — о том, в какой это строке. О синтаксических ошибках (SyntaxError, IndentationError) сообщается ещё до запуска программы; остальные ошибки появляются, только когда программа доходит до той строки, поэтому код может какое-то время нормально работать, а потом остановиться. Установка MicroPython и первые шаги описаны в статье Что такое Raspberry Pi Pico.

Ошибка MicroPythonЧто это значитРешение
SyntaxError: invalid syntax (неверный синтаксис)Нарушен синтаксис: нет двоеточия в конце строки if, while или def либо не закрыта скобкаДобавь : в конце строки и посчитай скобки
IndentationError: unexpected indent (неожиданный отступ)Непоследовательные отступы: смешаны пробелы и табуляцияИспользуй 4 пробела в каждом блоке
NameError: name 'led' isn't defined (имя не определено)Имя написано с ошибкой или используется до определенияПроверь регистр букв и место, где имя определено
ImportError: no module named 'ssd1306' (нет такого модуля)Файла драйвера нет на PicoСохрани ssd1306.py на Pico через Thonny
AttributeError: 'Pin' object has no attribute 'toggel' (у объекта нет такого атрибута)У объекта нет такой функцииИсправь имя функции: toggle()
TypeError: can't convert 'int' object to str implicitly (число нельзя неявно превратить в строку)Текст и число соединены через +Используй str(число) или передай значения в print через запятую
OSError: [Errno 5] EIO (ошибка ввода-вывода)Устройство I2C не отвечаетПроверь подключение, адрес и пины SDA и SCL
MicroPython
1from machine import Pin
2import time
3
4led = Pin("LED", Pin.OUT)     # Pico ve Pico W dahili LED / onboard LED on Pico and Pico W
5sayac = 0
6
7while True:                   # iki nokta unutulursa SyntaxError / a missing colon gives SyntaxError
8    led.toggle()              # blok içinde 4 boşluk girinti / 4-space indent inside the block
9    sayac += 1
10    print("Sayac:", sayac)    # "Sayac: " + sayac yazmak TypeError verir / "Sayac: " + sayac raises TypeError
11    time.sleep(0.5)

Таблица ошибок компиляции Arduino и их решений

Сообщение об ошибкеПричинаРешение
exit status 1 / Compilation error: exit status 1 (общее сообщение об ошибке)Сбой одной из программ в цепочке компиляции или загрузкиПрокрути вверх и прочитай первую строку, где есть error:
'x' was not declared in this scope (не объявлено)Опечатка, регистр букв, область видимости или пропущенный #includeИсправь имя, сделай переменную глобальной, подключи библиотеку
expected ';' before ... (не хватает точки с запятой)В предыдущей строке нет точки с запятойПроверь строку выше указанной (Uno) или конец указанной строки (ESP32)
expected '}' at end of input (не закрыта фигурная скобка)Фигурная скобка так и не закрытаСверь скобки через «Автоформатирование» (Ctrl+T)
X.h: No such file or directory (файл не найден)Библиотека не установлена или имя файла неверноеУстанови её через «Менеджер библиотек» вместе с зависимостями
'X' does not name a type (не является типом)Нет #include, неверное имя типа или команда вне функцииПодключи библиотеку, проверь написание String и int, перенеси команду в функцию
redefinition of 'void setup()' (повторное определение)Две функции setup() или лишний файл .ino в папкеОбъедини скетчи, убери старый файл из папки
stray '\342' in program (посторонний символ)Скопированная типографская кавычка или тире либо кириллица или диакритика в имени переменнойНабери кавычки заново, используй в именах только латинские буквы
'class X' has no member named 'y' (у класса нет такого члена)Неверное имя функции или другая версия библиотекиПосмотри примеры самой библиотеки, установи нужную версию
too few arguments to function / too many arguments to function (слишком мало или слишком много аргументов)Функции передано слишком мало или слишком много значенийСравни с определением в строке note: declared here
lvalue required as left operand of assignment (слева от = должна быть переменная)Присваивание вместо сравнения: if (digitalRead(2) = HIGH)Для сравнения используй ==
jump to case label (переход через объявление в case)Переменная объявлена в case без фигурных скобок (на ESP32 это ошибка)Оберни блок case в { }
undefined reference to `blink()' (у функции нет тела)У функции есть только прототип, тела нетНапиши функцию или исправь её имя
Sketch too big / text section exceeds available space in board (не помещается во флеш-память)Программа не помещается во флеш-памятьУменьши код, возьми плату побольше, на ESP32 — Partition Scheme
data section exceeds available space in board (не помещается в ОЗУ)Глобальные переменные не помещаются в ОЗУМакрос F(), более компактные типы данных, массивы в PROGMEM
#error This library only supports boards with … (плата не поддерживается)Библиотека не поддерживает архитектуру выбранной платыУстанови библиотеку для своей платы или смени плату
Чтобы ошибок компиляции было как можно меньше, наращивай код маленькими шагами: начни с работающего примера, нажимай «Проверить» после каждой новой части, а при ошибке смотри только на последние несколько добавленных строк. Остерегайся и ошибок, которые компилятор поймать не может: if (state = HIGH) с переменной компилируется без ошибок, но так как здесь присваивание вместо сравнения, условие всегда истинно; точка с запятой в конце if (distance < 10); тоже делает условие бесполезным. Если выбрать для Предупреждения компилятора (Compiler warnings) значение Все (All), большинство таких логических ошибок будут видны как предупреждения.

Следующие шаги к коду без ошибок

  • Укрепи основы: в статье Основы программирования Arduino объясняются переменные, область видимости, функции и циклы; большинство ошибок из этой статьи связаны именно с этими темами.
  • Выучи правильное написание команд: Список команд Arduino показывает синтаксис и параметры каждой команды с примерами.
  • Устанавливай библиотеки правильно: в руководстве Как установить библиотеку Arduino подробно разобраны сообщения No such file or directory и Multiple libraries were found.
  • Смотри, что делает код во время работы: если код компилируется, но ведёт себя не так, как ожидается, вывод переменных в монитор порта — самый быстрый способ найти причину.
  • Попробуй без платы: в симуляторах Wokwi и Tinkercad можно скомпилировать код и запустить его вместе со схемой.
  • Проверяй код, написанный ИИ: код от чат-ботов часто рассчитан на старые версии библиотек или на другую плату; как ловить такие проблемы, объясняет статья Код для Arduino с помощью ИИ.

Поначалу ошибки компиляции могут пугать, но на самом деле компилятор сообщает, где проблема, а часто и как её исправить: файл, строка, столбец и короткое описание. Читай первую ошибку, исправляй только её, компилируй снова и повторяй цикл; через несколько проектов ошибки будут решаться за секунды. Когда код компилируется и загружается, можно переходить к проектам со светодиодами, кнопками, датчиками и дисплеями в приложении BlueGrays: к каждому проекту для Arduino, ESP32 и Raspberry Pi Pico пошагово прилагаются схема подключения и код, который компилируется без ошибок.

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

Что означает exit status 1 в Arduino?

exit status 1 — это общее сообщение о том, что одна из программ, запущенных при компиляции или загрузке, завершилась с ошибкой; саму причину оно не называет. Прокрути панель вывода вверх и найди первую строку, где есть error:, — там будут имя файла, номер строки и описание. Как только эта ошибка исправлена и код скомпилирован заново, exit status 1 тоже исчезает.

Как исправить 'was not declared in this scope' в Arduino?

Это значит, что компилятор не узнаёт переменную, функцию или константу, использованную в этом месте. Самые частые причины — ошибка в регистре букв (digitalwrite), переменная, объявленная внутри другой функции, и не подключённая библиотека. Обычно достаточно проверить написание и объявить общие переменные вне всех функций.

Что означает «expected ';' before» в Arduino?

Эта ошибка говорит, что не хватает точки с запятой. Поскольку компилятор Uno замечает это, только когда читает следующее слово, строка в его сообщении обычно на одну ниже нужной, поэтому добавь точку с запятой в конце строки чуть выше. На ESP32 и Pico сообщение указывает прямо на строку, где не хватает точки с запятой. Запятые вместо точек с запятой в скобках цикла for дают то же сообщение.

Почему в Arduino появляется 'does not name a type'?

Компилятор ожидает в начале строки тип данных, но не узнаёт написанное слово. Три самые частые причины — забытая строка #include библиотеки (например, Servo), string вместо String и голое присваивание вроде angle = 90; вне функции. Если в Arduino используется собственный тип struct, определи его перед первой функцией.

Как исправить 'Sketch too big' в Arduino?

Это сообщение означает, что программа не помещается во флеш-память платы; на Uno предел — 32256 байт. Удали неиспользуемые библиотеки и отладочные строки, перенеси большие постоянные массивы в PROGMEM или перейди на плату с большим объёмом памяти, например Mega или ESP32. На ESP32 выбор Huge APP в меню Partition Scheme увеличивает область программы примерно до 3 МБ.

Почему код компилируется, но не загружается в Arduino?

Если компиляция прошла успешно, видна строка Sketch uses с числом байтов, которые занимает программа; ошибки после неё относятся к этапу загрузки и связаны не с кодом, а с кабелем, драйвером, портом или выбором платы. Строки, начинающиеся с avrdude, указывают на проблему загрузки на Uno и Nano, а строки esptool — на ESP32. В этом случае по порядку выполни шаги из руководства «Arduino не загружает код».

Все проекты
Мигающий светодиод
#1Новичок

Мигающий светодиод

Самое первое «привет» в электронике: включение и выключение одного светодиода. Arduino включает и выключает светодиод через короткие промежутки, поэтому свет быстро мигает. Ты самым простым способом в

4.6(188)
1125
Управление светодиодом кнопкой (удержание)
#9Новичок

Управление светодиодом кнопкой (удержание)

Как дверной звонок: свет горит, пока ты нажимаешь, и гаснет, когда отпускаешь. Arduino всё время слушает кнопку; пока она нажата, светодиод горит, а как только ты убираешь палец, он гаснет. Эта просте

4.8(113)
229
Измерение расстояния HC-SR04 (вывод в порт)
#27Новичок

Измерение расстояния HC-SR04 (вывод в порт)

Датчик HC-SR04 работает совсем как летучая мышь, которая находит дорогу в темноте: он посылает звук, которого ты не слышишь, слушает эхо и измеряет, насколько далеко предмет перед ним. Arduino каждые

4.6(46)
71
Температура и влажность с DHT11
#55Средний

Температура и влажность с DHT11

Насколько тепло в твоей комнате и влажный ли воздух или сухой? Датчик DHT11 измеряет температуру и влажность, а Arduino выводит значения на двухстрочный LCD-экран и обновляет их каждые пару секунд. Ес

4.7(47)
73
Мигающий светодиод на ESP32
#103Новичок

Мигающий светодиод на ESP32

Учит базовой работе с выходами GPIO на ESP32. Эффект мигания получается включением и выключением светодиода с цифрового пина. Это ESP32-версия классического проекта мигания на Arduino UNO; базовые команды мигания в среде Arduino те же, но расположение пинов ESP32 и уровни GPIO 3,3 V отличаются от Arduino UNO.

4.7(37)
99
Мигание встроенным светодиодом Raspberry Pi Pico (Pico и Pico W)
#147Новичок

Мигание встроенным светодиодом Raspberry Pi Pico (Pico и Pico W)

Первый проект серии Raspberry Pi Pico! Мигаем зелёным встроенным светодиодом, чтобы проверить, что плата работает, — классический первый опыт «Hello World». НИКАКИХ внешних компонентов, только Pico и USB-кабель. Код написан на MicroPython (официальном языке, поддерживаемом Raspberry Pi Foundation). Изучи в Thonny IDE класс machine.Pin, режим Pin.OUT, методы led.on()/off() и time.sleep(). Каждое переключение видно в выводе (REPL).

5.0(1)
10
LCD-экран с I2C
#32Новичок
Premium

LCD-экран с I2C

Дай своему Arduino собственный экран и заставь его написать первое сообщение. Двухстрочный LCD-экран подключается всего несколькими проводами; в верхней строке появляется приветствие, затем второе соо

4.8(53)
70
Работа с сервоприводом
#35Новичок
Premium

Работа с сервоприводом

Рычаг маленького сервопривода по очереди поворачивается в три положения: до упора в начало, ровно на середину и до упора в конец, задерживаясь на каждой остановке на две секунды. Arduino сообщает мото

4.7(48)
67