ガイド · 読了まで21分

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 Uno R3ボード
Arduino Uno:コードは「ツール」>「ボード」で選んだボードのプロセッサー(ここではATmega328P)向けにコンパイルされます。間違ったボードを選ぶと、コードが正しくてもコンパイルエラーになることがあります。

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行の何文字目か。^の印が指す場所
種類errorerrorはコンパイルを止め、warningは警告し、noteは情報を補足する
メッセージエラー:'digitalwrite' was not declared in this scope問題を説明する部分。ネットで検索するのはこのテキスト
提案note: suggested alternative: 'digitalWrite'(つづりの提案)コンパイラーの推測。正しいつづりを示すことが多い
  1. 「ファイル」>「基本設定」で、「より詳細な情報を表示する」の横にある「コンパイル」にチェックを入れます。こうすると、コンパイラーがどのファイルとどのライブラリのフォルダを使ったかも見えます。
  2. ボードはつないでいなくても構いません。「検証」ボタン(チェックマーク)を押します。検証はコンパイルだけを行うので、エラーがコンパイルの段階にあるなら、「書き込み」を押しても時間の無駄です。
  3. 出力パネルを一番上までスクロールし、error:を含む最初の行を探します。そのあとのエラーのほとんどは、最初のエラーの連鎖的な影響です。
  4. メッセージの行番号に移動します。IDE 2ではエラーのある文字に赤い下線が引かれ、1.8版では行全体が赤くなります。その行に問題が見つからなければ、1つ上の行を見てください。
  5. その最初のエラーだけを直し、もう一度「検証」を押します。エラーの数が急に減れば、正しい方向に進んでいます。
  6. ネットで検索するときは、メッセージから自分の変数名やファイルのパスを取り除きます。'counter' was not declared in this scopeではなくwas not declared in this scopeで検索すると、ずっと多くの結果が出ます。一方、フォーラムで助けを求めるときは、出力全体をコピーしてください。
1つの間違いで何十行もの赤い行が出ることがあります。たとえば、Webページからコピーした曲がった引用符で書かれたSerial.printlnの1行で、Unoでは6つのstrayエラーと1つのwas not declaredエラーが出ます。ですからエラーの数に慌てず、一番上のものを直して再コンパイルしてください。波かっこの対応を確かめるには「ツール」>「自動整形」(Ctrl+T)を使います。インデントが思わぬ形でずれたら、どこかで波かっこが足りません。

「was not declared in this scope」エラーとその直し方

このメッセージは、その場所で使った名前をコンパイラーが知らないことを意味します。最もよくある原因は打ち間違いです。Arduinoは大文字と小文字を区別するので、digitalwrite、Digitalwrite、digitalWriteは3つの別の名前です。2つ目の大きな原因はスコープです。変数をsetup()の中で宣言すると、それはsetup()が動いている間だけ存在し、loop()からは見えません。変数を複数の関数で使うなら、ファイルの先頭で、すべての関数の外に宣言してください。使う行より後で変数を宣言しても同じエラーになります。コンパイラーはファイルを上から下へ読むからです。最後に、ライブラリをインクルードしていないオブジェクト(Wire、Servo)や、選んだボードにない機能(UnoのSerial1)を使ったときにも、このエラーが出ます。

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);
別の関数で宣言した変数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 '<' tokenfor文でセミコロンの代わりにカンマを使っている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() {と書く
stray '\342' in programエラーは、コンパイラーが認識できない文字がコードにあることを示しています。数字はその文字のUTF-8のバイトを8進数で表したものです。Webページ、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の行を1つずつ読み、それぞれのライブラリを「ツール」>「ライブラリを管理」からインストールします。依存ライブラリについて聞くウィンドウで「全てをインストール」を選ばないと、メインのライブラリはインストールされても、それが必要とする2つ目のライブラリが足りないままになります。その場合、メッセージのファイル名は自分が書いたものではなく、ライブラリの中から呼ばれたファイル(たとえばAdafruit_Sensor.h)になります。ファイル名の大文字と小文字も重要です。Linuxではdht.hとDHT.hは別のファイルです。ライブラリのインストールの3つの方法とZIPの問題は、Arduinoにライブラリを追加する方法のガイドを参照してください。

メッセージのファイルライブラリマネージャでの検索語備考
DHT.hDHT sensor library(Adafruit)「全てをインストール」を選ぶ。Adafruit Unified Sensorも一緒に入る
Adafruit_Sensor.hAdafruit Unified SensorほかのAdafruitライブラリの足りない依存ライブラリ
LiquidCrystal_I2C.hLiquidCrystal I2C(Frank de Brabander)同じ名前のライブラリを複数インストールしない。下の警告を参照
Adafruit_SSD1306.hAdafruit SSD1306Adafruit GFXとAdafruit BusIOと一緒にインストールされる
MFRC522.hMFRC522(GithubCommunity)RC522 RFIDモジュール用
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など)を期待したのに、書かれた語を認識できなかったことを意味します。よくある原因は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の定義をファイルの先頭、最初の関数より前に移してください。

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」エラー:同じものを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は、プロトタイプは書いたのに中身を書いていない関数、または名前を違うつづりで書いた関数を指しています。

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()の中身を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 R332256バイト2048バイト0.5 KBはブートローダー用に確保されている
Arduino Nano(ATmega328P)30720バイト2048バイトIDEはどちらのブートローダーの選択肢でも2 KBを確保する
Arduino Leonardo28672バイト2560バイト4 KBのブートローダー。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"));は、文字列を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 directoryESP32を選んでいる。このライブラリはESP32のコアに含まれていないESP32のハードウェアシリアルポート(Serial2)を使う
エラー:'LED_BUILTIN' was not declared in this scopeESP32 Dev Moduleのような一部のボード定義では、オンボードLEDの定数が定義されていないピン番号を直接書く(多くのDevKitボードではGPIO 2)
エラー:'D5' was not declared in this scopeD0〜D8のような名前は、NodeMCUやWemosなどのESP8266のボードや一部のボードにはあるが、UnoやESP32 Dev ModuleにはないUnoとESP32ではGPIO番号を使うか、正しいボードを選ぶ
エラー:'TCCR1A' was not declared in this scopeAVRのタイマーレジスタに直接アクセスするコードをESP32向けにコンパイルしているESP32のLEDCとタイマーの関数を使う
エラー:WiFi.h: No such file or directoryまたは'WIFI_STA' was not declared in this scopeESP32のコードをUno向けにコンパイルしている。UnoにはWi-Fiがない「ツール」>「ボード」でESP32 Dev Moduleを選ぶ
エラー:'ledcSetup' was not declared in this scopeESP32のコアはバージョン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)(ライブラリが現在のボードに対応していない可能性がある)のような行が表示されることがあります。これはエラーではなく、ライブラリの作者が対応ボードの一覧にESP32を加えていないことを伝えているだけで、ライブラリはたいていそれでも動きます。本当に注意すべきなのはMultiple libraries were found for "LiquidCrystal_I2C.h"というメッセージです。同じ名前のライブラリが2つインストールされていると、IDEはそのどちらかを選びます。その選択がコードと合わないと、'class LiquidCrystal_I2C' has no member named 'init'のようなエラーになります。メッセージの下のUsedとNot usedの行で、どのフォルダが使われたかがわかります。使っていないほうのコピーをlibrariesフォルダから削除してください。

ESP32でのコンパイルエラー

ESP32開発ボード
ESP32:Arduino IDEで同じ言語を使ってプログラムしますが、別のコンパイラーとボードパッケージでコンパイルされるので、Unoで動くコードの一部はここで失敗します。

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とは?の記事を見てください。

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で、つまり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] EIOI2Cの機器が応答しない配線、アドレス、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 ...前の行にセミコロンがない示された行の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 ...ライブラリが選んだボードのアーキテクチャに対応していない自分のボード用に作られたライブラリをインストールするか、ボードを変える
コンパイルエラーを最小限にするには、コードを小さなステップで育てることです。動く例から始め、新しい部分を追加するたびに「検証」を押し、エラーが出たら最後に追加した数行だけを見ます。コンパイラーが見つけられない間違いにも注意してください。変数を使って書いたif (state = HIGH)はエラーなくコンパイルされますが、比較ではなく代入をしているので、条件は常に真になります。if (distance < 10);の末尾のセミコロンも条件を無意味にします。「コンパイラの警告」を「全て」にすると、こうした論理の間違いの多くが警告として表示されます。

エラーのないコードを書くための次のステップ

  • 基本を固める: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の点滅

電子工作の第一歩は、1個のLEDを点けたり消したりすることです。Arduinoで短い間隔で点灯と消灯を繰り返すと、LEDが素早く点滅します。ボードが光を制御する仕組みを最もシンプルな形で確かめ、これから取り組むプロジェクトの基礎を身につけます。

4.6(188)
1125
ボタンでLEDを点灯(押している間のみ)
#9初級

ボタンでLEDを点灯(押している間のみ)

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

4.8(113)
229
HC-SR04で距離を測定(シリアルモニタ表示)
#27初級

HC-SR04で距離を測定(シリアルモニタ表示)

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

4.6(46)
71
DHT11で温度と湿度を測定
#55中級

DHT11で温度と湿度を測定

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

4.7(47)
73
ESP32でLEDを点滅
#103初級

ESP32でLEDを点滅

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

4.7(37)
99
Raspberry Pi Picoの内蔵LEDを点滅(PicoとPico W)
#147初級

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)出力で、切り替わる様子をリアルタイムに確認できます。

5.0(1)
10
I2CでLCDディスプレイを使う
#32初級
プレミアム

I2CでLCDディスプレイを使う

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

4.8(53)
70
サーボモーターの使い方
#35初級
プレミアム

サーボモーターの使い方

小型サーボモーターのアームが、一方の端、中央、もう一方の端の3つの位置へ順番に回り、それぞれの位置で2秒間止まります。Arduinoが保持する角度をモーターに指示すると、モーターはその位置まで動いて止まります。ロボットアームや自動開閉するふたが動く仕組みを学べます。

4.7(48)
67