Arduinoは何言語?答えは「C++」|C言語との違いと裏側の仕組みを実験で解説【初心者向け】

プログラミング・電子工作






Arduinoは何言語?答えは「C++」|C言語との違いと裏側の仕組みを実験で解説【初心者向け】







基礎知識 / 言語

Arduinoは何言語?答えは「C++」|C言語との違いと、書き込みボタンの裏側を実験で解説

「Arduino言語」という特別な言語を勉強しなければ、と思っていませんか。その必要はありません。Arduinoで書くコードの正体はC++です。この記事では、Arduino・C言語・C++の関係と、書き込みボタンを押したときに裏側で起きていることを、実際にコンパイルして動かした結果つきで解説します。

YOFUKASI LAB編集部
公開日:2026年8月27日
最終更新:2026年10月13日(全面改訂・検証結果を追加)
読了目安:15分

結論

Arduinoのプログラムは C++ です。
「Arduino言語」は、C++に電子工作向けの便利な関数と仕組みを足したものです。

  • C言語の知識はほぼそのまま使えます。if・for・変数・配列・関数の書き方は同じです。
  • main()を書かなくていいのは、Arduinoが裏で用意しているから。その中で setup() を1回、loop() をくり返し呼んでいます。
  • ただし、パソコン向けのC++が全部使えるわけではありません。Arduino Uno(AVR)では、例外処理や std::string は使えません。

執筆・実機検証:YOFUKASI LAB運営者

理学療法士/Arduino・Pythonを使った医療機器制作・学会発表経験あり

この記事の検証環境

本文中の「検証」と書かれた結果は、Arduino公式のAVRコア(ArduinoCore-avr)を、Arduino Unoと同じマイコン(ATmega328P)向けにコンパイルし、マイコンシミュレータ(simavr)で動かして確かめたものです。コンパイラは、Arduino IDEがAVRボード用に使っているものと同じバージョンのavr-g++ 7.3.0で、オプションも公式の設定ファイル(platform.txt)と同じにしています。プログラムサイズはIDEでの表示と数バイト程度ずれることがあります。

Chapter 01 / Conclusion

01結論:「Arduino言語」の正体はC++

ArduinoはC++をベースにした開発環境であることを示す図解

新しい言語ではなく、C++の上の「道具箱」

Arduinoで書くコード(スケッチ)は、独自に作られた新しい言語ではありません。書き込みの直前にC++のプログラムに変換され、C++のコンパイラで機械語に直されます。Arduinoの公式ドキュメントも、ビルドの前処理を「スケッチをC++のプログラムに変える」ものだと説明しています。

C++はC言語をもとに作られた言語なので、C言語の書き方の多くもそのまま通ります。そのため「CでもC++でも書ける環境」と言われることがありますが、正確には「C++として動く。C言語風に書くこともできる」です。この違いは第6章で具体例を見ると、はっきりします。

それでも「Arduino言語」と呼ばれる理由

Arduino公式のリファレンスは「Arduino programming language」という呼び方をしていて、内容を「関数・値(変数と定数)・構造」の3つに分けて紹介しています。ここに並んでいるのは、digitalWrite() や analogRead() のような電子工作向けの関数と、setup() と loop() という決まった形です。

つまり、Arduinoで新しく覚えるのは文法ではなく、道具箱の中身です。if文やfor文の書き方はC++そのままで、そこに「ピンを光らせる」「センサーの値を読む」といった道具が最初から入っている、と考えると混乱しません。

「Arduino言語」という呼び名の由来

Arduinoは2005年ごろ、イタリアのイヴレーアにあったデザイン学校(Interaction Design Institute Ivrea)で生まれました。その少し前、同じ学校の学生だったエルナンド・バラガンが、デザイナーでもマイコンを扱えるようにと「Wiring」という仕組みを作っています。setup()とloop()に分けて書く形や、digitalWrite()のような関数の考え方は、このWiringから受け継がれたものです。

つまり「Arduino言語」は、最初からC++を使いやすくするための枠組みとして育ってきたもので、新しい文法として設計されたものではありません。

よくある言い方 正確には
Arduino言語 C++ + Arduinoの関数群(Arduino API)
ArduinoはC言語 C++。C言語風にも書けるが、中身はC++として処理される
Arduino IDEで書くプログラム スケッチ(.inoファイル)。ビルド時に.cppに変換される


Chapter 02 / Relationship

02C言語・C++・Arduinoの関係

C言語:手順を順番に書く、組み込みの定番

C言語は1970年代初めにアメリカのベル研究所で生まれた言語です。変数、if文、for文、関数、配列、構造体といった基本の部品を使い、処理の手順を上から順に書いていきます。OSやマイコンのプログラムなど、機械に近い分野で今も広く使われています。

C++:C言語に「クラス」を足した言語

C++は、C言語に新しい機能を足して作られた言語です。一番大きな追加はクラスで、データとそれを扱う処理を1つにまとめられます。たとえば「サーボモーター」というクラスに、「今の角度」というデータと「回す」という処理をまとめておく、といった使い方です。ほかにも、同じ名前の関数を引数の違いで使い分ける機能(オーバーロード)や、型を問わない関数を作るテンプレートなどが加わっています。

Arduino:C++に、電子工作向けの仕組みを足した環境

Arduinoは、このC++の上に「すぐ動かせる」ための仕組みを重ねたものです。言語というより、開発環境とライブラリのセットと考えるのが正確です。

Arduinosetup()/loop()、digitalWrite() などの関数、ライブラリ、自動の前処理
C++クラス、オーバーロード、テンプレート、名前空間
C言語の土台変数、if、for、while、関数、配列、構造体、ポインタ

下の層の書き方は、上の層でもほぼそのまま使えます。

C言語のコードは、どこまでそのまま通るか

「C言語の書き方がほぼ使える」のは本当ですが、「完全に同じ」ではありません。CとC++でふるまいが違う代表例を、Arduino Uno向けの設定でコンパイルして確かめました。

書き方 C言語 Arduino(C++)
構造体を SensorData d; と書く(struct を省略) エラー 通る
int *p = malloc(...);(型の変換を書かない) 通る 警告は出るが通る(※)
変数名に new や class を使う 通る エラー(C++の予約語)
関数を定義より前で呼ぶ(宣言なし) エラー .inoなら通る(自動で宣言が足される)

※Arduino AVRの設定には -fpermissive という「一部のエラーを警告に格下げする」オプションが入っているためです。このオプションを外した普通のC++ではエラーになります。いずれも avr-g++ 7.3.0 で検証。

つまり、C言語の入門書で学んだことはそのまま役に立ちますが、Arduinoの中では「C++のルールで判定されている」と覚えておくと、思わぬエラーに出会ったときに原因を探しやすくなります。

Chapter 03 / Build Process

03書き込みボタンを押すと、裏で何が起きているか

ArduinoのinoファイルがC++としてコンパイルされる流れの図解

Arduino IDEの「書き込み」ボタンを押すと、数秒のあいだに次の5つの段階が進みます。Arduino IDE 2では、この処理を裏で動いている「Arduino CLI」というプログラムが担当しています。Arduino公式の「Sketch build process」の説明をもとに、流れを整理しました。

  1. 前処理:.inoを.cppに変えるスケッチをC++のファイルに作りかえます。中身は次の項目で説明します。
  2. ライブラリを探す#include されているファイルを、ボードのコア→インストール済みのライブラリの順に探し、見つかった場所をコンパイラに伝えます。
  3. コンパイルスケッチ、使っているライブラリ、ボードのコア(Arduinoの土台部分)を、それぞれ機械語のファイル(.o)にします。Arduino Unoならavr-g++、ほかのマイコンならそれぞれ専用のコンパイラが使われます。
  4. リンクばらばらの機械語をつなぎ合わせて1つのプログラムにします。使われていない部分は省かれ、最後に.hexファイルができます。
  5. 書き込みできたプログラムを、USBケーブル経由でマイコンに送ります。

前処理で、スケッチはこう変わる

公式の説明によると、前処理では主に次のことが行われます。

  • スケッチのフォルダに.inoファイルが複数あるときは、フォルダと同じ名前のファイルを先頭に、残りを名前順につなげて1つにする
  • 先頭に #include <Arduino.h> がなければ追加する
  • 宣言(プロトタイプ)のない関数に、宣言を自動で追加する
  • エラーの行番号が元のスケッチと合うように、#line という目印を入れる

たとえば、次のスケッチを書いたとします。

blink_twice.ino(あなたが書くもの)
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  blinkTwice();      // まだ定義していない関数を先に呼んでいる
  delay(1000);
}

void blinkTwice() {
  for (int i = 0; i < 2; i++) {
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
}

前処理のあとは、おおよそ次のようなC++ファイルになります(実際のファイルには #line の行なども入ります)。

blink_twice.ino.cpp(前処理後のイメージ)
#include <Arduino.h>    // ← 自動で追加

void setup();           // ← 宣言が自動で追加される
void loop();
void blinkTwice();

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  blinkTwice();
  delay(1000);
}

void blinkTwice() {
  /* 省略 */
}

検証

宣言の自動追加がないとどうなるかを確かめるため、前処理をせずに同じ内容をC++としてコンパイルしました。結果は error: 'blinkTwice' was not declared in this scope(宣言されていない)というエラーです。普通のC++では宣言が必要なところを、Arduinoは黙って補ってくれていることがわかります。

なお、公式ドキュメントには「まれに宣言の自動生成に失敗することがある」とも書かれています。そのときは、関数の宣言を自分でスケッチの上のほうに書けば解決します。また、前処理の対象は.inoファイルだけで、同じフォルダに置いた.cppや.hファイルはそのままコンパイルされます。



Chapter 04 / Hidden main()

04隠れたmain()の正体【検証あり】

普通のC++のプログラムは、必ず main() という関数から動き始めます。ところがArduinoのスケッチには、main()を書いた覚えがないはずです。main()はどこにあるのでしょうか。

本物のmain()は、ボードのコアの中にある

答えは、ボードごとに用意されている「コア」と呼ばれる土台のプログラムの中です。Arduino Unoなどが使うAVRコアでは、cores/arduino/main.cpp というファイルにあり、中身は次のとおりです(説明のためのコメントは編集部が追加)。

ArduinoCore-avr / cores/arduino/main.cpp より
int main(void)
{
	init();            // タイマーやアナログ入力などの準備

	initVariant();     // ボードごとの追加の準備(多くは空)

#if defined(USBCON)
	USBDevice.attach(); // USB機能を内蔵したボード(Leonardoなど)のみ
#endif

	setup();           // あなたの setup() を1回だけ呼ぶ

	for (;;) {         // ここから無限ループ
		loop();        // あなたの loop() を呼ぶ
		if (serialEventRun) serialEventRun();  // serialEvent() があれば呼ぶ
	}

	return 0;
}

setup()を1回、loop()を無限にくり返す、という形はよく知られていますが、注目してほしいのはsetup()より前にある init()です。この中で、マイコンのタイマーやアナログ入力の準備が行われています。delay() や millis() が時間を測れるのも、analogWrite() でLEDの明るさを変えられるのも、この準備のおかげです。

検証:自分でmain()を書くとどうなるか

Arduinoのスケッチにも、自分でmain()を書くことはできます。そこで、「start」と表示し、10ミリ秒待ってから「end」と表示するプログラムを、3通りの方法で動かしてみました。

検証に使ったプログラム(main()を自分で書いた版)
void setup() {
  Serial.begin(9600);
  Serial.println("start");
  delay(10);
  Serial.println("end");
}

void loop() {
}

int main(void) {
  // init();   ← この1行があるかないかで結果が変わる
  setup();
  while (true) {
    loop();
  }
  return 0;
}
書き方 シリアルモニタの表示 結果
ふつうのスケッチ(main()なし) start → end 正常
main()を自分で書き、init()なし 何も表示されない 動かない
main()を自分で書き、割り込みの許可(sei())だけ追加 start だけ表示され、止まる delay()で止まる
main()を自分で書き、init()あり start → end 正常

ArduinoCore-avrをATmega328P向けにビルドし、simavrで実行して確認。

init()の中では、割り込みの許可、時間を測るタイマーの起動、アナログ入力の準備などが行われています。表の2行目と3行目を比べると、原因が2つあることがわかります。割り込みが許可されていないと、シリアル通信の文字を送り出す処理が進みません。割り込みだけ許可しても、タイマーが動いていないので delay() が時間を測れず、待ったまま先に進めなくなります。「setup()とloop()を呼ぶだけ」と考えて自分でmain()を書くと、こうした落とし穴にはまります。

旧版からの訂正

この記事の以前の版では、隠れたmain()のイメージを「setup()とloop()を呼ぶだけ」のコードで紹介し、「もしmain()を自分で書くとしたら」という例も同じ形で載せていました。上の検証のとおり、この形では実際には動きません。本物のmain()に合わせて訂正しました。

覚えておくこと:Arduinoではmain()を書かないのが正解です。どうしても書く場合は、最初に init(); を呼ぶ必要があります。
Chapter 05 / What Arduino Does for You

05Arduinoが肩代わりしてくれている5つのこと

ここまでの内容をまとめると、Arduinoは普通のC++で必要な手間を、次の5つの形で引き受けてくれています。

普通のC++では Arduinoでは 担当している仕組み
main()を自分で書く setup()とloop()を書くだけ コアのmain.cpp
マイコンの初期設定を自分で書く 何もしなくていい init()
関数の宣言を先に書く 省略できる 前処理(プロトタイプ自動生成)
必要なヘッダを自分で読み込む 基本の関数はすぐ使える 前処理(Arduino.hの自動追加)
マイコンの「レジスタ」を直接操作する digitalWrite(13, HIGH) と書くだけ Arduinoの関数とライブラリ

便利さの代わりに払っているもの

最後の行の「レジスタ」は、マイコンの中の設定用スイッチのようなものです。Arduino Unoの13番ピンのLEDは、本来は PORTB |= _BV(PB5); のようにレジスタを直接操作して点けます。digitalWrite() は、ピン番号からレジスタを調べるといった処理を代わりにやってくれる関数です。

検証

LEDを1秒ごとに点滅させるプログラムを、2通りで書いてサイズを比べました。

書き方 プログラムサイズ
digitalWrite(13, HIGH) を使う 924 バイト
PORTB |= _BV(PB5) とレジスタを直接操作 640 バイト

差は約280バイト。Arduino Unoのプログラム領域(32KB)から見ればわずかです。初心者のうちは、わかりやすさを優先してdigitalWrite()を使えば十分です。とても速い処理が必要になったり、容量が足りなくなったりしたときに、はじめてレジスタ操作を検討します。

編集部見解

Arduinoの便利さは、新しい言語を作ったことではなく、実績のあるC++の上に親切な仕組みを積み重ねたことにあります。この構造がわかっていると、エラーメッセージが「C++のエラー」として読めるようになり、ライブラリの中身を開いて読む力もついてきます。



Chapter 06 / C-style vs C++-style

06C言語風とC++風の書き方を比べる

ArduinoにおけるC言語風とC++風のプログラムの違いを比較した図解

同じ「2つのセンサー値を読んで表示する」処理を、C言語風とC++風の2通りで書いてみます。どちらもArduino Uno向けにコンパイルできることを確認済みです。

C言語風:構造体と関数で分けて書く

c_style.ino
// データの入れ物(構造体)
struct SensorData {
  int temperature;
  int humidity;
};

SensorData data;   // ← C言語なら struct SensorData data; と書く必要がある

// データを受け取って表示する関数
void printSensorData(const SensorData &d) {
  Serial.print(d.temperature);
  Serial.print(' ');
  Serial.println(d.humidity);
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  data.temperature = analogRead(A0);
  data.humidity = analogRead(A1);
  printSensorData(data);
  delay(500);
}

データ(構造体)と処理(関数)が別々に書かれているのがC言語風の特徴です。ただし、2か所にC++の書き方が混ざっています。struct を省いた SensorData data; と、引数の &(参照)です。どちらもC言語ではエラーになり、C++だから通る書き方です。「C言語風」と言っても、Arduinoの中ではC++として書いていることがわかります。

C++風:クラスにデータと処理をまとめる

cpp_style.ino
class Sensor {
  public:
    // コンストラクタ:オブジェクトを作るときに、使うピンを受け取る
    Sensor(uint8_t tempPin, uint8_t humPin) : tempPin_(tempPin), humPin_(humPin) {}

    void update() {                 // 値を読み直す
      temperature_ = analogRead(tempPin_);
      humidity_ = analogRead(humPin_);
    }

    void print() const {            // 値を表示する
      Serial.print(temperature_);
      Serial.print(' ');
      Serial.println(humidity_);
    }

  private:                          // クラスの外からは直接さわれない
    uint8_t tempPin_, humPin_;
    int temperature_ = 0, humidity_ = 0;
};

Sensor sensor(A0, A1);              // クラスからオブジェクトを作る

void setup() {
  Serial.begin(9600);
}

void loop() {
  sensor.update();
  sensor.print();
  delay(500);
}

データ(温度・湿度・ピン番号)と処理(読む・表示する)が Sensor の中にまとまっています。センサーが2組に増えても、Sensor sensor2(A2, A3); と1行足すだけで済むのがクラスの強みです。

どちらを選ぶか

C言語風(構造体+関数) C++風(クラス)
読みやすさ 上から順に読めて、初心者にやさしい 慣れるまでは書き方が多く感じる
部品が増えたとき 変数と関数が増えて散らばりやすい 1行足すだけで同じ部品を増やせる
ライブラリ化 しにくい しやすい(公式ライブラリもこの形)
プログラムサイズ(検証) 2,020 バイト 2,050 バイト

サイズは上の2つのコードをArduino Uno向けにコンパイルした結果。クラスにしてもサイズはほとんど変わりません。

公式ライブラリは、クラスでできている

いつも書いている Servo myServo; は、Servo というクラスから myServo というオブジェクトを作る、というC++の書き方そのものです。myServo.write(90); の「.(ドット)」は、そのオブジェクトの機能を呼び出す記号です。MPU6050やRFIDなどのセンサーのライブラリも、同じ形で作られています。クラスの書き方を知ると、こうしたライブラリのコードが急に読めるようになります。

Chapter 07 / C++ Features

07使えるC++、使えないC++【検証あり】

Arduinoの正体はC++ですが、パソコン向けのC++の機能が全部使えるわけではありません。動かす相手が、メモリの小さなマイコンだからです。Arduino Uno(AVR)向けの設定で、実際にコンパイルして確かめました。

機能 例 Uno(AVR)
クラス・オブジェクト class Sensor { ... }; 使える
関数のオーバーロード 同じ名前で引数の違う関数 使える
テンプレート template <typename T> 使える
名前空間 namespace app { ... } 使える
C++11の書き方 auto、範囲for、ラムダ式 使える
new / delete new int[4] 使えるが注意
例外処理 try / throw 使えない
標準ライブラリ(STL) std::string、std::vector 使えない

C++の規格はArduino AVRの設定どおり gnu++11 で検証。

使えなかったものの、実際のエラー

  • 例外処理:throw を書くと exception handling disabled, use -fexceptions to enable。Arduino AVRの設定で、例外処理がオフ(-fno-exceptions)になっているためです
  • std::string:#include <string> と書いた時点で fatal error: string: No such file or directory。AVR向けのコンパイラには、C++の標準ライブラリが入っていません

new と delete は動きますが、メモリが2KBしかないUnoでは、動かしながらメモリを確保したり返したりすると、すき間だらけになって足りなくなる危険があります(次の章で説明します)。配列の大きさが決まっているなら、最初から普通の配列で用意するほうが安全です。

ボードによって変わります

この表はArduino Uno R3など、AVRマイコンのボードの場合です。同じ「Uno」でもUno R4は別のマイコン(AVRではない)を使っています。ESP32なども含め、AVR以外のボードでは、使うコンパイラも設定も違うため、使える機能が変わります。パソコン向けのC++のサンプルを試すときは、使うボードで一度コンパイルしてみるのが確実です。

Chapter 08 / String vs char[]

08Stringとchar配列、どちらを使うか【検証あり】

Arduinoには String という、文字列を扱う便利なクラスがあります。名前が似ていますが、パソコン向けC++の std::string とは別物で、Arduinoが独自に用意したものです(前の章のとおり、Unoでは std::string 自体が使えません)。

Stringの注意点:メモリの「すき間」

Stringは、文字列をつなげるたびに、必要な大きさのメモリをその場で確保します。これをくり返すと、使い終わったメモリがあちこちに小さく空き、大きな文字列を置ける場所がなくなっていくことがあります(メモリの断片化)。メモリが2KBしかないUnoでは、長時間動かすと突然止まる、といった原因になります。

検証

「アナログ値を読んで TEMP=123 C のように表示する」処理を、3通りで書いてサイズを比べました。

書き方 プログラム RAM(起動時)
String で文字列をつなげてから表示 3,372 バイト 206 バイト
char 配列に snprintf で書き込んで表示 3,236 バイト 198 バイト
Serial.print を3回に分けて表示 1,916 バイト 196 バイト
上と同じで、文字を F("...") で囲む 1,972 バイト 188 バイト

RAMの数字は起動時に確保される分だけで、Stringが動きながら使うメモリは含まれていません。それでも、表示するだけなら、文字列をつなげずに Serial.print を分けて呼ぶのが一番小さいことがわかります。

使い分けの目安

  • シリアルモニタに表示するだけ:Stringでつなげず、Serial.print() を並べる
  • 決まった文字(メッセージなど):F("...") で囲むと、文字をRAMではなくプログラム領域に置ける。上の検証でもRAMが8バイト減りました
  • 文字列を組み立てて保存・送信したい:大きさを決めた char 配列と snprintf()
  • 短い試作や、すぐ止めるプログラム:Stringで書いて問題ありません。わかりやすさを優先しましょう


Chapter 09 / Other Languages

09C++以外の言語でArduinoは動かせる?(Python・MicroPython)

「C++は難しそうなので、Pythonで書けないか」という相談はよくあります。答えは「ボードと目的しだいで、できる」です。ただし、Arduino Uno R3のような小さなマイコンでは、選べる方法が限られます。

方法 しくみ 使えるボードの例 向いている人
C++(ふつうのArduino) スケッチをマイコンに書き込んで動かす すべてのArduino はじめての人、作品を単体で動かしたい人
MicroPython マイコンの中でPythonを動かす Nano ESP32、Nano RP2040 Connect、Nano 33 BLE、Portentaなど Pythonに慣れていて、対応ボードを持っている人
Python + Firmata Arduinoに通信用のスケッチを入れ、パソコンのPythonから操作する Unoを含む多くのボード パソコンとつないだまま使う人
ブロックプログラミング ブロックを並べると、ツールがコードを作って書き込む ツールが対応するボード 子ども、プログラミングが初めての人

MicroPythonは、Arduinoが公式にサポートしています。Uno R3(ATmega328P)はメモリが2KBしかなく、MicroPythonを動かすことはできません。

迷ったら、まずはC++(ふつうのArduino)で始めるのがおすすめです。説明やサンプルコード、ライブラリの数が圧倒的に多く、つまずいたときに答えが見つかりやすいからです。パソコン側の処理はPythonで書き、マイコン側はC++で書く、という組み合わせもよく使われます。

Chapter 10 / Misunderstandings

10初心者が誤解しやすい5つのポイント

!

誤解1:「Arduino言語」の教科書が必要

必要ありません。C言語かC++の入門で文法を学び、Arduinoの関数はリファレンスで調べる、が一番の近道です。

!

誤解2:ArduinoはC言語で動いている

中身はC++です。C言語風に書けますが、判定はC++のルールで行われます。new を変数名に使えないのはそのためです。

!

誤解3:main()は「setup()とloop()を呼ぶだけ」

実際は、その前に init() でタイマーなどを準備しています。自分でmain()を書くとdelay()などが動かなくなります。

!

誤解4:パソコンのC++のサンプルがそのまま動く

Uno(AVR)では、std::string や std::vector、例外処理は使えません。ボードによっても違います。

!

誤解5:エラーはArduino特有のもの

表示されるエラーは、C++のコンパイラ(avr-g++など)が出しているものです。エラー文をそのまま検索すると、C++の情報で解決できることが多くあります。

Chapter 11 / How to Learn

11学習の進め方:何から手をつけるか

ここまでを踏まえた、おすすめの順番です。上から順に、1つずつ進めてください。

段階 覚えること できるようになること
1. 文法の基本 変数、if、for、関数、配列 LEDの点滅、ボタンで分岐
2. Arduinoの関数 digitalWrite、analogRead、Serial、millis センサーの値を読んで表示する
3. ライブラリを使う Servo myServo; のような書き方 モーターや表示器を動かす
4. クラスを読む・作る class、コンストラクタ、public / private 自分の部品をまとめて管理する
5. メモリを意識する String と char 配列、F() 長時間止まらず動くプログラム
C言語とC++、どちらの入門書から始める? どちらでも大丈夫です。段階1で学ぶ文法は共通だからです。迷ったら、Arduinoに特化した入門書かWeb記事から始め、文法でつまずいた部分だけC言語の入門で補う、という進め方が一番早く手が動きます(編集部見解)。

クラスは最初から完璧に理解しなくて大丈夫です。段階3までは Servo myServo; を「こう書くもの」として使い、慣れてきたら段階4でライブラリの中身をのぞいてみる、という進め方で十分です。段階を追った学び方は、当サイトのロードマップ記事でも紹介しています。

Chapter 12 / Cheat Sheet

12よく使うArduinoの関数一覧

「Arduino言語」として覚えるのは、実質このあたりの関数です。文法はC++、道具はこの表、と考えると整理しやすくなります。詳しい使い方は公式リファレンスで確認できます。

分類 関数 役割
ピン pinMode(pin, mode) ピンを入力・出力のどちらで使うか決める
ピン digitalWrite(pin, HIGH/LOW) ピンの出力をオン・オフする
ピン digitalRead(pin) ボタンなどのオン・オフを読む
アナログ analogRead(pin) センサーの電圧を数値で読む(Unoでは0〜1023)
アナログ analogWrite(pin, value) LEDの明るさやモーターの速さを変える(0〜255)
時間 delay(ms) 指定したミリ秒だけ待つ
時間 millis() 起動してからの経過ミリ秒を返す
通信 Serial.begin(9600) パソコンとのシリアル通信を始める
通信 Serial.print() / Serial.println() シリアルモニタに文字や数値を表示する
計算 map(value, a, b, c, d) 数値の範囲を別の範囲に置きかえる
計算 constrain(value, min, max) 数値を決めた範囲におさめる
音 tone(pin, freq) ブザーから指定した高さの音を出す
割り込み attachInterrupt(...) ピンの変化をきっかけに関数を呼ぶ
メモリ F("文字") 決まった文字をRAMではなくプログラム領域に置く
Chapter 13 / FAQ

13よくある質問

Arduinoのsetup関数とloop関数の役割と実行順序の図解

Q.「Arduino言語」という独自の言語を勉強する必要はありますか?
A.必要ありません。Arduinoで書くコードの正体はC++です。C言語かC++の入門で、変数・if文・for文・関数・配列といった基本の文法を学べば、そのままArduinoのコードを読み書きできます。digitalWrite()などArduino独自の関数は、必要になったときに公式リファレンスで調べれば十分です。

Q.C言語の入門書で勉強した知識は、Arduinoに活かせますか?
A.十分に活かせます。if文、for文、変数、配列、関数、構造体の書き方は、ほぼそのまま通用します。ただしArduinoの中ではC++として処理されるため、newやclassを変数名に使えないなど、一部のルールはC++に従います。

Q.setup()やloop()を自分でmain()から呼び出す必要はないのですか?
A.必要ありません。main()はボードのコア(Arduino UnoならArduinoCore-avrのmain.cpp)に用意されていて、その中でinit()による準備のあと、setup()を1回、loop()をくり返し呼び出しています。自分でmain()を書くことも可能ですが、init()を呼ばないとdelay()やシリアル通信が正しく動きません。

Q.ArduinoでC++のクラスを自分で作ることはできますか?
A.できます。ServoなどArduinoの公式ライブラリの多くはクラスとして作られています。同じように、センサーの値と処理をまとめたクラスを自分で作ることもできます。Arduino Uno向けに試したところ、構造体と関数で書いた場合とプログラムサイズはほとんど変わりませんでした。

Q.パソコン向けのC++の機能は、すべて使えますか?
A.すべては使えません。Arduino Uno(AVR)では、例外処理(try / throw)が無効になっており、std::stringやstd::vectorなどの標準ライブラリも入っていません。クラス、テンプレート、名前空間、autoやラムダ式などC++11の書き方は使えます。ESP32など別のボードでは使える機能が変わります。

Q.Stringとchar配列、どちらで文字列を扱うべきですか?
A.短い試作ならStringで問題ありません。長時間動かすプログラムやメモリの少ないボードでは、Stringをくり返しつなげるとメモリの断片化で止まる原因になります。表示するだけならSerial.print()を分けて呼び、決まった文字はF()で囲み、文字列を組み立てる必要があるときはchar配列とsnprintf()を使うのが目安です。

Q.エラーメッセージは何を見て調べればいいですか?
A.Arduino IDEに表示されるエラーは、C++のコンパイラ(Arduino Unoならavr-g++)が出しているものです。「was not declared in this scope」のようなエラー文をそのまま検索すると、C++の情報で解決できることが多くあります。行番号は元のスケッチの行に合わせて表示されます。

Q.ArduinoはPythonで書けますか?
A.ボードによっては書けます。Arduinoは公式にMicroPythonに対応していて、Nano ESP32やNano RP2040 Connectなどの対応ボードではマイコンの中でPythonを動かせます。Uno R3はメモリが少なくMicroPythonは動きませんが、Firmataという通信用のスケッチを入れれば、パソコンのPythonからArduinoを操作することはできます。

Q.Arduino Uno R4でも、この記事の内容は同じですか?
A.前処理やsetup()・loop()の仕組み、C++として書くことは同じです。ただしUno R4はUno R3とは別のマイコン(AVRではない)を使っているため、コンパイラや使えるC++の機能、プログラムサイズは変わります。この記事の検証結果はUno R3と同じATmega328Pでのものです。

Q..inoファイルと.cppファイルは何が違いますか?
A..inoはArduinoのスケッチで、ビルドのときに#include <Arduino.h>の追加や関数宣言の自動生成といった前処理を受けて、C++のファイルに変換されます。同じフォルダに置いた.cppファイルは前処理されず、普通のC++としてコンパイルされるため、関数の宣言やインクルードを自分で書く必要があります。

まとめ

Arduinoのプログラムの正体はC++です。「Arduino言語」は、C++に電子工作向けの関数と、main()や宣言を代わりに用意してくれる仕組みを足したものです。C言語の知識はほぼそのまま使えますが、判定はC++のルールで行われ、Arduino Unoでは例外処理や標準ライブラリなど一部の機能が使えません。Pythonで動かす方法もありますが、Uno R3では使える方法が限られるため、まずは文法の基本とArduinoの関数から始め、ライブラリに慣れてきたらクラスの書き方に進みましょう。

関連記事・参考資料

基礎を学べる記事

  1. YOFUKASI LAB「Arduinoのコード・プログラムの書き方(コピペ可20選)」2026年, https://yofukasi-lab-wp.com/2026/07/18/arduino-cord/
  2. YOFUKASI LAB「Arduinoのsetup()とloop()とは?」2026年, https://yofukasi-lab-wp.com/2026/07/30/arduino-setup-loop/
  3. YOFUKASI LAB「Arduinoの関数の作り方・使い方」2026年, https://yofukasi-lab-wp.com/2026/08/18/関数/

応用・関連記事

  1. YOFUKASI LAB「Arduinoでサーボモーターを制御する方法」2026年, https://yofukasi-lab-wp.com/2026/08/18/servo/
  2. YOFUKASI LAB「Arduinoの変数の型(int・float・String)の使い分け」2026年, https://yofukasi-lab-wp.com/2026/08/17/int-float-string/

参考資料(外部・一次情報)

  1. Arduino CLI Documentation「Sketch build process」(前処理・ライブラリ探索・コンパイル・リンクの公式説明), https://arduino.github.io/arduino-cli/latest/sketch-build-process/
  2. Arduino「Language Reference」(Arduinoの関数・値・構造の公式リファレンス), https://docs.arduino.cc/language-reference/
  3. Arduino GitHub「ArduinoCore-avr」cores/arduino/main.cpp(隠れたmain()の実物), https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp
  4. Arduino GitHub「arduino-ide」README(IDE 2のコンパイルと書き込みはArduino CLIが担当), https://github.com/arduino/arduino-ide
  5. Arduino Docs「MicroPython」(Arduinoの公式MicroPython対応), https://docs.arduino.cc/micropython/
  6. Arduino GitHub「ArduinoCore-avr」platform.txt(コンパイラのオプション:gnu++11、-fno-exceptions、-fpermissive など), https://github.com/arduino/ArduinoCore-avr/blob/master/platform.txt

※検証結果は、ArduinoCore-avr(2026年10月13日時点)とavr-g++ 7.3.0、simavrを使った編集部の確認によるものです。Arduino IDEのバージョンやボードによって、サイズや動作が変わることがあります。製品開発など厳密な確認が必要な場合は、公式ドキュメントと実機で確かめてください。



関連記事

特集記事

コメント

この記事へのコメントはありません。

TOP
CLOSE