Arduinoのexit status 1エラー:コンパイルエラーの直し方
Arduinoのexit status 1とは?was not declared in this scopeやexpected ';'、No such file、does not name a type、Sketch too bigのエラーをすばやく直す方法を解説します。
Arduinoのexit status 1エラーは、コードをコンパイルできなかった、つまりコンパイラーがプログラムをプロセッサーが理解できる機械語に変換できなかったことを知らせる一般的なメッセージで、本当の原因はこの行には書かれていません。原因は、出力パネルでその数行上にある、error:という語を含む最初の行にあります。名前を打ち間違えた、セミコロンを忘れた、ライブラリがインストールされていない、あるいはコードが別のボード向けに書かれていた、などです。Arduino IDE 2の右下に出るCompilation error: exit status 1の通知も、旧1.8版のError compiling for board Arduino Uno.という行も、まったく同じ意味です。
このガイドでは、まずコンパイルが裏側でどう動くか、エラーメッセージをファイル、行、列に分けてどう読むかを見ます。次に、最もよくあるコンパイルエラーを1つずつ見ていきます。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のexit status 1とは?コンパイルと書き込みの違い
「検証」(チェックマーク)や「書き込み」を押すと、Arduino IDEは裏でいくつかのプログラムを実行します。まずスケッチのフォルダにある.inoファイルをまとめ、先頭にArduino.hのヘッダーと関数のプロトタイプを加えて、普通のC++ファイルにします。次に、Unoならavr-g++、ESP32ならxtensa-esp32-elf-g++のようなコンパイラーがそのファイルと使っているライブラリをコンパイルし、リンカーがすべての部品を1つのプログラムにつなぎ、最後に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 ...(多重定義) | リンク | 同じ変数や関数が2つの別々のファイルで定義されている |
| Sketch too bigと、text section exceeds available space in board | サイズの確認 | プログラムがボードのフラッシュメモリに収まらない |
| Not enough memoryと、data section exceeds available space in board | サイズの確認 | グローバル変数がRAMに収まらない |
| Failed uploading: uploading error: exit status 1(書き込みの失敗) | 書き込み | コードはコンパイルできたが、ボードに書き込めなかった。avrdudeやesptoolの行を見る |
Arduinoのエラーメッセージの読み方
コンパイラーのエラー行はどれも同じ形をしています。まずファイル名、次にコロンで区切った行と列の番号、続いてエラーの種類と説明です。そのすぐ上には、どの関数の中のエラーかを示すIn function 'void loop()':のような行があることが多く、下には問題の行のコピーと、問題の場所を指す小さな^の印があります。errorはコンパイルを止める本当のエラー、warningは警告だけでコードはコンパイルされ、noteは前のメッセージに情報を補足します。コンパイラーは提案を加えることもよくあります。下の例ではsuggested alternative: 'digitalWrite'で正しいつづりを自ら示しています。
| 部分 | 例での値 | 意味 |
|---|---|---|
| ファイル | Blink.ino | エラーを含むファイル。タブが複数あれば、どれかがわかる |
| 行 | 6 | コンパイラーがエラーに気づいた行。本当の間違いは1つ上の行にあることもある |
| 列 | 3 | 行の何文字目か。^の印が指す場所 |
| 種類 | error | errorはコンパイルを止め、warningは警告し、noteは情報を補足する |
| メッセージ | エラー:'digitalwrite' was not declared in this scope | 問題を説明する部分。ネットで検索するのはこのテキスト |
| 提案 | note: suggested alternative: 'digitalWrite'(つづりの提案) | コンパイラーの推測。正しいつづりを示すことが多い |
- 「ファイル」>「基本設定」で、「より詳細な情報を表示する」の横にある「コンパイル」にチェックを入れます。こうすると、コンパイラーがどのファイルとどのライブラリのフォルダを使ったかも見えます。
- ボードはつないでいなくても構いません。「検証」ボタン(チェックマーク)を押します。検証はコンパイルだけを行うので、エラーがコンパイルの段階にあるなら、「書き込み」を押しても時間の無駄です。
- 出力パネルを一番上までスクロールし、error:を含む最初の行を探します。そのあとのエラーのほとんどは、最初のエラーの連鎖的な影響です。
- メッセージの行番号に移動します。IDE 2ではエラーのある文字に赤い下線が引かれ、1.8版では行全体が赤くなります。その行に問題が見つからなければ、1つ上の行を見てください。
- その最初のエラーだけを直し、もう一度「検証」を押します。エラーの数が急に減れば、正しい方向に進んでいます。
- ネットで検索するときは、メッセージから自分の変数名やファイルのパスを取り除きます。'counter' was not declared in this scopeではなくwas not declared in this scopeで検索すると、ずっと多くの結果が出ます。一方、フォーラムで助けを求めるときは、出力全体をコピーしてください。
「was not declared in this scope」エラーとその直し方
このメッセージは、その場所で使った名前をコンパイラーが知らないことを意味します。最もよくある原因は打ち間違いです。Arduinoは大文字と小文字を区別するので、digitalwrite、Digitalwrite、digitalWriteは3つの別の名前です。2つ目の大きな原因はスコープです。変数をsetup()の中で宣言すると、それはsetup()が動いている間だけ存在し、loop()からは見えません。変数を複数の関数で使うなら、ファイルの先頭で、すべての関数の外に宣言してください。使う行より後で変数を宣言しても同じエラーになります。コンパイラーはファイルを上から下へ読むからです。最後に、ライブラリをインクルードしていないオブジェクト(Wire、Servo)や、選んだボードにない機能(UnoのSerial1)を使ったときにも、このエラーが出ます。
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); |
| 別の関数で宣言した変数 | setup()の中でint led = 13;を宣言し、loop()の中でledを使う | int led = 13;の行を、すべての関数の外の先頭に移す |
| 使ったあとに宣言した変数 | counter++;の行よりあとにint counter = 0;がある | 宣言を使う場所より上に移す |
| ライブラリをインクルードしていない | #includeの行がないのにWire.begin();を使う | ファイルの先頭に#include <Wire.h>を追加する |
| ボードにない機能 | Unoを選んだままSerial1.begin(9600);を使う | Megaのような複数のシリアルポートを持つボードを選ぶか、SoftwareSerialを使う |
| 追加の.cppファイルでの順番 | .cppのタブで、定義より前に関数を呼んでいる | .cppファイルの先頭にプロトタイプ(void blink();)を書く。.inoファイルではIDEが代わりにやってくれる |
「expected ';' before」とそのほかの構文エラー
C++では、どの文もセミコロンで終わります。行末のセミコロンを忘れると、コンパイラーは次の語を読んだときに初めて気づきます。そのため、Unoのコンパイラーではexpected ';' before 'delay'の行番号が間違いの1つ下の行を指します。足りないセミコロンは、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ではメッセージの行の1つ上、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 | 前の関数の閉じ波かっこがない | メッセージの関数の1つ前の関数の終わり |
| エラー: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の行を1つずつ読み、それぞれのライブラリを「ツール」>「ライブラリを管理」からインストールします。依存ライブラリについて聞くウィンドウで「全てをインストール」を選ばないと、メインのライブラリはインストールされても、それが必要とする2つ目のライブラリが足りないままになります。その場合、メッセージのファイル名は自分が書いたものではなく、ライブラリの中から呼ばれたファイル(たとえばAdafruit_Sensor.h)になります。ファイル名の大文字と小文字も重要です。Linuxではdht.hとDHT.hは別のファイルです。ライブラリのインストールの3つの方法とZIPの問題は、Arduinoにライブラリを追加する方法のガイドを参照してください。
| メッセージのファイル | ライブラリマネージャでの検索語 | 備考 |
|---|---|---|
| DHT.h | DHT sensor library(Adafruit) | 「全てをインストール」を選ぶ。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) | RC522 RFIDモジュール用 |
| 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など)を期待したのに、書かれた語を認識できなかったことを意味します。よくある原因は3つです。1つ目はライブラリの#includeの行を忘れることです。Servo.hなしでServo lid;をコンパイルすると'Servo' does not name a typeになります。2つ目は型のつづりの誤りです。正しいのはstringではなくString、Intではなくintで、コンパイラーはdid you mean 'String'?で助けてくれることがよくあります。3つ目で最も意外なのは、関数の外にコマンドを書くことです。関数の外では宣言しかできません。int angle = 0;は有効ですが、そのあとの行にangle = 90;を単独で書くと、コンパイラーはangleを型名と受け取り、'angle' does not name a typeと報告します。Arduino特有の落とし穴がもう1つあります。IDEは関数のプロトタイプを最初の関数の直前に自動で追加します。自分のstruct型を返す関数を書き、そのstructをsetup()より下で宣言していると、プロトタイプがstructより前に来てしまい、同じエラーになります。直すには、structの定義をファイルの先頭、最初の関数より前に移してください。
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」エラー:同じものを2回定義している
redefinition of 'void setup()'エラーは、同じ名前の定義が2つあることを示しています。そのすぐ下のnote: 'void setup()' previously defined hereの行が、1つ目がどこにあるかを示します。初心者に最もよくある原因は、2つのスケッチ例を1つのファイルに続けて貼り付けることです。setup()とloop()が2つずつできてしまいます。2つ目の原因はタブです。Arduino IDEはコンパイルの前に、スケッチのフォルダにあるすべての.inoファイルを1つにまとめます。フォルダにコピーした古いバックアップ(たとえばproject_old.ino)や、独自のsetup()とloop()を持つ2つ目のタブがあると、そのタブを一度も開いていなくてもこのエラーになります。直すには、そのファイルをフォルダの外に移してください。同じ変数を2回宣言しても似たメッセージredefinition of 'int led'が出ます。このエラーのリンカー版はmultiple definition ofで、ヘッダー(.h)ファイルで値を与えた変数を2つの別々の.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()の中身を1つのsetup()に、両方のloop()の中身を1つのloop()に入れます。片方のスケッチが長いdelay()を使っていると、もう片方の邪魔をします。これはdelay()の代わりにmillis()を使う時間管理の手法で解決できます。最後に、2つのスケッチが同じピンを使っていないか確認してください。コンパイラーは気づきませんが、回路は思ったとおりに動きません。
「Sketch too big」とメモリ不足のエラー
コンパイルが成功すると、最後に2つの行が表示されます。上のスコープの例をUno向けにコンパイルすると、Sketch uses 2212 bytes (6%) of program storage space. Maximum is 32256 bytes.(プログラムの使用量と最大値)という行がプログラムがどれだけのフラッシュメモリを使うかを、Global variables use 190 bytes (9%) of dynamic memoryという行がグローバル変数がRAMをどれだけ使うかを示します。プログラムがフラッシュに収まらないと100パーセントを超え、続いてSketch too bigの警告とtext section exceeds available space in boardのエラーが出ます。グローバル変数がRAMに収まらない場合は、代わりにNot enough memoryとdata section exceeds available space in boardが出ます。RAMの使用量が75パーセントを超えると、IDEはLow memory available, stability problems may occur(メモリが少なく、不安定になる可能性がある)という警告を出すことがあります。コードはコンパイルされますが、実行中にローカル変数の置き場所がなくなるため、ボードがランダムに固まったり勝手に再起動したりすることがあります。Unoでは32 KBのフラッシュのうち0.5 KBをブートローダーが使うので、上限は32256バイトです。
| ボード | プログラムメモリの上限 | RAM(ダイナミックメモリ) | 備考 |
|---|---|---|---|
| Arduino Uno R3 | 32256バイト | 2048バイト | 0.5 KBはブートローダー用に確保されている |
| Arduino Nano(ATmega328P) | 30720バイト | 2048バイト | IDEはどちらのブートローダーの選択肢でも2 KBを確保する |
| Arduino Leonardo | 28672バイト | 2560バイト | 4 KBのブートローダー。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"));は、文字列をRAMにコピーせずフラッシュから直接読みます。LCDやOLEDのディスプレイに表示する固定の文字列も同じです。
- 大きな配列をPROGMEMに移す:音符の表、ディスプレイのビットマップ、長い文章が変わらないなら、RAMに置く必要はありません。より詳しい手法はArduinoのメモリ不足の記事を参照してください。
- 正しいデータ型を選ぶ:0〜255の値にはbyte(1バイト)で十分です。Unoではintは2バイト、longとfloatは4バイトを使います。
- Stringクラスを減らす:何度も連結されるStringオブジェクトはRAMを断片化させます。固定長のchar配列のほうが予測しやすくなります。
- ディスプレイのライブラリの隠れた必要量を知る:Adafruit SSD1306は、128×64のOLEDディスプレイ用に、実行時に1 KBのバッファを確保します。このメモリはコンパイルの報告には現れないので、報告が70パーセントでもディスプレイが起動しないことがあります。
- 大きなボードに移る:Unoに詰め込めないプロジェクトも、MegaやESP32なら余裕で動きます。ESP32では、「ツール」>「Partition Scheme」でHuge APP (3MB No OTA/1MB SPIFFS)を選ぶと、プログラムの領域を1.25 MBから3 MBに増やせます。この選択肢では無線でのアップデート(OTA)は使えません。
間違ったボードを選んだことによるエラー
コンパイラーは、常に「ツール」>「ボード」(IDE 2では上部のボード選択欄)で選んだボードのプロセッサー向けにコードをコンパイルします。同じコードでも、Megaならきれいにコンパイルできて、Unoを選ぶと失敗することがあります。ボードごとにハードウェア、ピンの名前、ボードパッケージに付属するライブラリが違うからです。ネットで見つけたプロジェクトを開いたら、まずどのボード向けに書かれたかを確認してください。ESP32向けのコードはUnoを選ぶとコンパイルできず、プロセッサーのレジスタに直接アクセスするUno向けのコードはESP32を選ぶとコンパイルできません。一覧に自分のボードがまったく見当たらない場合は、ボードパッケージがインストールされていません。ESP32とRaspberry Pi Picoのパッケージはボードマネージャからインストールする必要があります。手順はArduino IDEのインストール方法のガイドを参照してください。
| エラーメッセージ | 何が起きた? | 解決法 |
|---|---|---|
| エラー:'Serial1' was not declared in this scope | コードはMegaかLeonardo向けなのに、Unoを選んでいる。Unoにはハードウェアシリアルポートが1つしかない | 正しいボードを選ぶか、UnoではSoftwareSerialを使う |
| エラー:SoftwareSerial.h: No such file or directory | ESP32を選んでいる。このライブラリはESP32のコアに含まれていない | ESP32のハードウェアシリアルポート(Serial2)を使う |
| エラー:'LED_BUILTIN' was not declared in this scope | ESP32 Dev Moduleのような一部のボード定義では、オンボードLEDの定数が定義されていない | ピン番号を直接書く(多くのDevKitボードではGPIO 2) |
| エラー:'D5' was not declared in this scope | D0〜D8のような名前は、NodeMCUやWemosなどのESP8266のボードや一部のボードにはあるが、UnoやESP32 Dev Moduleにはない | UnoとESP32ではGPIO番号を使うか、正しいボードを選ぶ |
| エラー:'TCCR1A' was not declared in this scope | AVRのタイマーレジスタに直接アクセスするコードをESP32向けにコンパイルしている | ESP32のLEDCとタイマーの関数を使う |
| エラー: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ではつまずくことがあります。最もよくある理由はコアのバージョンです。ESP32 Arduinoコアのバージョン3.xではPWMの関数が変わり、ledcSetup()とledcAttachPin()が削除されて、チャンネル番号ではなくピン番号で動くledcAttach()とledcWrite()に置き換えられました。そのため、ネットの古い例では'ledcSetup' was not declared in this scopeが出ます。コードを新しい関数に書き換えるか、ボードマネージャからバージョン2.0.17をインストールしてください。2つ目の違いはコンパイラーの設定です。Unoのコアはコードを-fpermissiveオプションでコンパイルし、一部のエラーを警告にとどめます。ESP32はこれを使いません。たとえば、switchの中で波かっこなしに変数を宣言すると、Unoではコンパイルできますが、ESP32ではjump to case labelエラーになります。最近のESP32のコアは-Werror=return-typeでもコンパイルします。値を返すべき関数でreturnを忘れると、「コンパイラの警告」(Compiler warnings)を「なし」(None)以外にしている限り、no return statement in function returning non-voidになります。バージョン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で、つまりEarle Philhower氏のarduino-picoコアでプログラムする場合、コンパイラーはやはりGCCで、この記事のメッセージはすべてそのまま当てはまります。MicroPythonは違います。事前の独立したコンパイルの段階はなく、Picoは起動時にファイルをバイトコードに変え、1行ずつ実行します。そのため、エラーはThonnyの下部のShellペインに、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にない | Thonnyでssd1306.pyをPicoに保存する |
| エラー: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 ... | 前の行にセミコロンがない | 示された行の1つ上(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()が2つある、またはフォルダに余分な.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の中に変数を宣言している(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 | グローバル変数がRAMに収まらない | F()マクロ、小さなデータ型、配列をPROGMEMに移す |
| エラー:#error This library only supports boards with ... | ライブラリが選んだボードのアーキテクチャに対応していない | 自分のボード用に作られたライブラリをインストールするか、ボードを変える |
エラーのないコードを書くための次のステップ
- 基本を固める:Arduinoプログラミングの基本の記事で、変数、スコープ、関数、ループを解説しています。この記事のエラーのほとんどは、これらのテーマから生じます。
- コマンドの正しい書き方を覚える:Arduinoのコマンド一覧では、すべてのコマンドの構文と引数を例付きで示しています。
- ライブラリを正しくインストールする:Arduinoにライブラリを追加する方法のガイドで、No such file or directoryとMultiple libraries were foundのメッセージを詳しく扱っています。
- 実行中のコードの動きを見る:コンパイルはできるのに思ったとおりに動かないコードでは、シリアルモニタで変数を表示するのが最も早い診断方法です。
- ボードなしで試す:WokwiやTinkercadのシミュレーターでは、コードをコンパイルして回路と一緒に動かせます。
- AIが書いたコードを確認する:チャットボットが作るコードは、古いライブラリの版や別のボード向けに書かれていることがよくあります。AIでArduinoのコードを書くの記事で、こうした問題の見つけ方を説明しています。
コンパイルエラーは最初は怖く見えるかもしれませんが、コンパイラーは実際には問題の場所と、多くの場合その直し方まで教えてくれます。ファイル、行、列、そして短い説明です。最初のエラーを読み、それだけを直し、再コンパイルするというループを繰り返しましょう。いくつかのプロジェクトをこなすうちに、数秒でエラーを解決できるようになります。コードがコンパイルされて書き込めたら、BlueGraysアプリのLED、ボタン、センサー、ディスプレイのプロジェクトに進めます。Arduino、ESP32、Raspberry Pi Picoのどのプロジェクトにも、回路図ときれいにコンパイルできるコードがステップごとに付いています。
よくある質問
Arduinoのexit status 1とはどういう意味?
exit status 1は、コンパイルや書き込みの間に実行したプログラムのどれかがエラーで終わったことを示す一般的なメッセージで、原因自体は教えてくれません。出力パネルを上にスクロールし、error:を含む最初の行を探してください。ファイル名、行番号、説明はそこにあります。そのエラーを直して再コンパイルすれば、exit status 1も消えます。
Arduinoの「was not declared in this scope」を直すには?
その場所で使った変数、関数、定数をコンパイラーが知らないという意味です。最もよくある原因は、大文字と小文字の間違い(digitalwrite)、別の関数の中で宣言した変数、インクルードしていないライブラリです。つづりを確認し、共有する変数をすべての関数の外で宣言すれば、たいてい解決します。
Arduinoの「expected ';' before」とはどういう意味?
このエラーはセミコロンが足りないことを示しています。Unoのコンパイラーは次の語を読んだときに初めて気づくので、メッセージの行はたいてい1行下になっています。すぐ上の行の末尾にセミコロンを追加してください。ESP32やPicoでは、メッセージはセミコロンがない行を直接指します。forループのかっこの中でセミコロンの代わりにカンマを使っても、同じメッセージが出ます。
Arduinoで「does not name a type」が出るのはなぜ?
コンパイラーは行の先頭にデータ型を期待しているのに、書かれた語を認識できていません。ライブラリの#includeの行を忘れる(たとえばServo)、Stringではなくstringと書く、angle = 90;のような代入だけを関数の外に置く、の3つが最もよくある原因です。Arduinoで自分のstruct型を使う場合は、最初の関数より前に定義してください。
Arduinoの「Sketch too big」を直すには?
このメッセージは、プログラムがボードのフラッシュメモリに収まらないことを意味します。Unoの上限は32256バイトです。使っていないライブラリやデバッグ用の行を削り、大きな定数の配列をPROGMEMに移すか、MegaやESP32のようなメモリの多いボードに移ってください。ESP32では、Partition SchemeメニューでHuge APPを選ぶと、プログラムの領域が約3 MBに増えます。
コードはコンパイルできるのにArduinoに書き込めないのはなぜ?
コンパイルが成功すると、プログラムが何バイト使うかを示すSketch usesの行が表示されます。そのあとのエラーは書き込みの段階のもので、コードではなく、ケーブル、ドライバ、ポート、ボードの選択に関係しています。UnoとNanoではavrdudeで始まる行が、ESP32ではesptoolの行が書き込みの問題を示します。その場合は、Arduinoに書き込めないときのガイドの手順を順番に進めてください。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
LEDの点滅
電子工作の第一歩は、1個のLEDを点けたり消したりすることです。Arduinoで短い間隔で点灯と消灯を繰り返すと、LEDが素早く点滅します。ボードが光を制御する仕組みを最もシンプルな形で確かめ、これから取り組むプロジェクトの基礎を身につけます。

ボタンでLEDを点灯(押している間のみ)
呼び鈴のように、押している間は点灯し、離すと消灯します。Arduinoはボタンの状態を常に読み取り、押されている間はLEDを点灯させ、指を離した瞬間に消灯させます。このシンプルな回路で、ボードが外部からの操作を検知する仕組みを学べます。

HC-SR04で距離を測定(シリアルモニタ表示)
HC-SR04センサーは、コウモリが暗闇で道を見つけるのと同じ仕組みで動作します。人には聞こえない音を出し、その反響を捉えて前方の物体までの距離を測ります。Arduinoは0.5秒ごとに距離をセンチメートル単位でコンピューターの画面に表示し、3〜100センチメートルの測定値を示します。駐車センサーや障害物を避けるロボットなどのプロジェクトの基礎になります。

DHT11で温度と湿度を測定
部屋の温度は何度で、空気は湿っているでしょうか、それとも乾燥しているでしょうか?DHT11センサーが温度と湿度を測定し、Arduinoが2行のLCDディスプレイに値を表示して、数秒ごとに更新します。センサーに異常があればエラーメッセージが表示されます。自分だけの小さな気象観測装置を作る第一歩です。

ESP32でLEDを点滅
ESP32のGPIO出力の基本を学びます。デジタルピンからLEDを点灯・消灯させて、点滅させます。Arduino UNOの定番のLED点滅プロジェクトのESP32版です。Arduino環境で使う基本的な点滅コマンドは同じですが、ESP32のピン配置と3.3 VのGPIO電圧レベルはArduino UNOとは異なります。

Raspberry Pi Picoの内蔵LEDを点滅(PicoとPico W)
Raspberry Pi Picoシリーズの最初のプロジェクトです!ボード上の緑色LEDを点滅させて動作を確認する、定番の「Hello World」に相当する実験です。外付け部品は不要で、PicoとUSBケーブルだけで始められます。コードはMicroPython(Raspberry Pi Foundationが公式にサポートする言語)で書きます。Thonny IDEでmachine.Pinクラス、Pin.OUTモード、led.on()/off()メソッド、time.sleep()を学びます。シリアル(REPL)出力で、切り替わる様子をリアルタイムに確認できます。

I2CでLCDディスプレイを使う
Arduinoにディスプレイを接続し、最初のメッセージを表示します。2行のLCDディスプレイは数本の配線だけで接続できます。まず上の行にあいさつを表示し、次に下の行にもう1つのメッセージを表示します。その後、表示を消去して最初から繰り返します。温度や時刻、スコアを表示するプロジェクトは、すべてこのステップから始まります。

サーボモーターの使い方
小型サーボモーターのアームが、一方の端、中央、もう一方の端の3つの位置へ順番に回り、それぞれの位置で2秒間止まります。Arduinoが保持する角度をモーターに指示すると、モーターはその位置まで動いて止まります。ロボットアームや自動開閉するふたが動く仕組みを学べます。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

