Ошибка 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 не загружает код.

Что такое 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 | Номер символа в строке; туда указывает значок ^ |
| Тип | error | error останавливает компиляцию, warning предупреждает, note добавляет информацию |
| Сообщение | 'digitalwrite' was not declared in this scope (имя не объявлено в этой области видимости) | Часть, описывающая проблему; именно этот текст стоит искать в интернете |
| Подсказка | note: suggested alternative: 'digitalWrite' (предлагаемый вариант) | Догадка компилятора; часто показывает правильное написание |
- В Файл › Настройки (File › Preferences) отметь компиляции рядом с Показать подробный вывод во время (Show verbose output during). Так ты увидишь ещё и то, какие файлы и какие папки библиотек использовал компилятор.
- Плату подключать не обязательно: нажми кнопку Проверить (Verify, галочка). «Проверить» только компилирует; если ошибка на этапе компиляции, нажатие «Загрузка» лишь отнимает время.
- Прокрути панель вывода в самый верх и найди первую строку, где есть error:. Большинство ошибок после неё — следствия этой первой.
- Перейди к номеру строки из сообщения. IDE 2 подчёркивает красным символ с ошибкой, а версия 1.8 окрашивает в красный всю строку. Если в этой строке проблемы не видно, посмотри на строку выше.
- Исправь только эту первую ошибку и снова нажми «Проверить». Если число ошибок резко уменьшилось, ты на верном пути.
- Если ищешь в интернете, убери из сообщения свои имена переменных и пути к файлам: поиск по was not declared in this scope вместо 'counter' was not declared in this scope даёт гораздо больше результатов. А вот когда просишь помощи на форуме, копируй весь вывод целиком.
Ошибка 'was not declared in this scope' и как её исправить
Это сообщение означает, что компилятор не узнаёт имя, использованное в этом месте. Самая частая причина — опечатка: Arduino различает регистр букв, поэтому digitalwrite, Digitalwrite и digitalWrite — три разных имени. Вторая большая причина — область видимости (scope): если объявить переменную внутри setup(), она живёт только пока выполняется setup(), и loop() её не видит. Если переменная нужна в нескольких функциях, объяви её вне всех функций, в начале файла. Объявление переменной после строки, где она используется, даёт ту же ошибку, потому что компилятор читает файл сверху вниз. Наконец, эта ошибка появляется и тогда, когда используется объект, библиотека которого не подключена (Wire, Servo), или возможность, которой нет у выбранной платы (Serial1 на Uno).
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(); { |
'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.h | DHT sensor library (Adafruit) | Выбери «Установить все» (Install All), и Adafruit Unified Sensor установится вместе с ней |
| Adafruit_Sensor.h | Adafruit Unified Sensor | Недостающая зависимость другой библиотеки Adafruit |
| LiquidCrystal_I2C.h | LiquidCrystal I2C (Frank de Brabander) | Не устанавливай несколько библиотек с одинаковым именем; см. предупреждение ниже |
| Adafruit_SSD1306.h | Adafruit SSD1306 | Устанавливается вместе с Adafruit GFX и Adafruit BusIO |
| MFRC522.h | MFRC522 (GithubCommunity) | Для RFID-модуля RC522 |
| IRremote.h | IRremote | В новых версиях используется 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(), прототип окажется перед структурой, и появится та же ошибка. Решение — перенести определения структур в начало файла, перед первой функцией.
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, указывает на функцию, у которой есть прототип, но нет тела, или имя которой написано по-другому.
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 R3 | 32256 байт | 2048 байт | 0,5 КБ зарезервировано под загрузчик |
| Arduino Nano (ATmega328P) | 30720 байт | 2048 байт | IDE резервирует 2 КБ для обоих вариантов загрузчика |
| Arduino Leonardo | 28672 байта | 2560 байт | Загрузчик 4 КБ; код USB тоже занимает место |
| Arduino Mega 2560 | 253952 байта | 8192 байта | Простой следующий шаг для проектов, которые не помещаются на Uno |
| ESP32 (схема разделов по умолчанию) | 1310720 байт | 327680 байт | С Huge APP вырастает до 3145728 байт |
| Raspberry Pi Pico (arduino-pico, 2MB no FS) | 2093056 байт | 262144 байта | Если зарезервировать место под файловую систему, область программы уменьшается |
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(¬alar[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() с номером пина |
Ошибки компиляции на ESP32

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.
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 |
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 … (плата не поддерживается) | Библиотека не поддерживает архитектуру выбранной платы | Установи библиотеку для своей платы или смени плату |
Следующие шаги к коду без ошибок
- Укрепи основы: в статье Основы программирования 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 не загружает код».
Что собрать после прочтения
Все проекты
Мигающий светодиод
Самое первое «привет» в электронике: включение и выключение одного светодиода. Arduino включает и выключает светодиод через короткие промежутки, поэтому свет быстро мигает. Ты самым простым способом в

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

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

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

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

Мигание встроенным светодиодом 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).

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

Работа с сервоприводом
Рычаг маленького сервопривода по очереди поворачивается в три положения: до упора в начало, ровно на середину и до упора в конец, задерживаясь на каждой остановке на две секунды. Arduino сообщает мото
Другие статьи
Приложение BlueGrays
Собери эту схему шаг за шагом в телефоне
Схема подключения, код и список деталей на одном экране. 200+ проектов на Arduino, ESP32 и Pico готовы к сборке.
Наведи камеру телефона
Наведи камеру на код — откроется магазин приложений на телефоне.
или открыть магазин

