本文へ移動
Arduinoの次に選ぶなら、
ESP32。無線でつながる電子工作へ。

ESP32は、Wi-FiとBluetoothを標準搭載した低価格マイコンボードです。Arduinoで学んだ知識をそのまま活かしながら、スマホやクラウドと無線でつながる作品が作れます。Arduinoとの違い、ボードの選び方、開発環境構築、Wi-Fi・Bluetooth(BLE)接続、センサーデータ送信までを、配線図とコピペ可能なコード付きで一気に解説します。
ESP32とは?Arduinoとの違いを理解する

ESP32は、中国のEspressif Systemsが開発したWi-FiとBluetooth(BLE)を標準搭載したマイコン(SoC)です。デュアルコアCPU、豊富なGPIO、ADC・DAC・タッチセンサー機能まで1チップに詰め込みながら、Arduino Uno相当かそれ以下の価格で入手できるのが最大の魅力です。詳しい仕様はEspressif公式製品ページ ↗で確認できます。
Arduino UnoのようなAVR系ボードは「シンプルで壊れにくく、電子工作の基礎を学ぶのに最適」な設計です。一方ESP32は「無線通信を前提にしたIoT向け」の設計であり、この違いを知らずにArduino感覚で配線すると、電圧やピンの制約でつまずきやすくなります。まずは全体像を比較表で押さえましょう。
| 項目 | Arduino Uno(AVR系) | ESP32 |
|---|---|---|
| CPU | 8bit・16MHzシングルコア | 32bit・240MHz デュアルコア |
| 動作電圧 | 5Vロジック | 3.3Vロジック(5Vトレラントではない) |
| 無線機能 | なし(外付けモジュールが必要) | Wi-Fi(802.11 b/g/n)+Bluetooth/BLE内蔵 |
| GPIO数 | 14(デジタル)+6(アナログ入力) | 約25〜36(モデルによる、一部入力専用あり) |
| 得意なこと | 基礎学習、単純なセンサー・アクチュエータ制御 | IoT、スマホ連携、クラウド送信、高速処理 |
電子工作の一歩目や配線・ブレッドボードの基礎そのものをまだ押さえていない場合は、先にブレッドボード完全攻略ガイドとArduinoメインボード徹底解説で土台を作ってから読み進めると理解がスムーズです。すでにArduinoのコードに慣れている方は、Arduinoのコードの書き方(コピペ可20選)と本記事を見比べると、共通点と違いがはっきり見えてきます。
Raspberry PiのようなLinuxが動く「小さなパソコン」と、ESP32のような「マイコン」は別物です。両者の違いが気になる方はRaspberry Piコード集20選もあわせて読むと、電子工作用ボードの全体像がつかめます。
ESP32ボードの種類とスペック比較
「ESP32」はチップ単体の名称ですが、実際に購入するのは、そのチップを載せた開発ボードです。代表的なシリーズの違いを把握しておくと、部品選びで失敗しにくくなります。詳細な型番比較はEspressif公式のESP32シリーズ比較 ↗にまとまっています。
| シリーズ | 特徴 | 向いている用途 |
|---|---|---|
| ESP32-DevKitC | Espressif純正の入門用開発ボード。USBシリアル変換・レギュレータ内蔵 | はじめての1台、学習用 |
| ESP32-WROOM-32 | もっとも流通量が多いモジュール。汎用性が高い | 自作基板、量産前の試作 |
| ESP32-S3 | USB OTG対応、AI処理向けベクトル命令を搭載 | カメラ・音声・軽量AI処理 |
| ESP32-C3 | シングルコアRISC-V、低価格・省電力寄り | コスト重視のシンプルなIoTセンサー |
- 初めての1台には、USBケーブル1本で書き込みまで完結するESP32-DevKitCタイプが扱いやすくおすすめです。
- ボードによってUSB-CかMicro-USBかが異なるため、購入前にケーブルも確認しましょう。
- 技適マーク(工事設計認証)の有無は、日本国内でWi-Fi・Bluetoothを利用する上で必ず確認すべきポイントです。
日本国内でESP32のWi-Fi・Bluetooth機能を電波として使用するには、原則として技術基準適合証明(技適)を受けたモジュール・ボードである必要があります。購入時は商品ページやボード裏面の表記で技適マークの有無を必ず確認してください。
開発環境を整える(Arduino IDEにESP32を追加)
ESP32はArduino IDEでそのまま開発できます。Espressifが提供するArduino core for ESP32(GitHub) ↗をボードマネージャーに追加するだけで、使い慣れたArduinoの書き方でESP32を動かせます。
- Arduino IDEを起動し、「ファイル」→「基本設定」を開く
- 「追加のボードマネージャーのURL」に、ESP32公式パッケージのURLを追加する(最新のURLはArduino-ESP32公式インストールガイド ↗に記載されています)
- 「ツール」→「ボード」→「ボードマネージャー」で「esp32」と検索し、Espressif Systems製のパッケージをインストールする
- USBケーブルでESP32を接続し、「ツール」→「ボード」から使用するボード(例:ESP32 Dev Module)を選択する
- 「ツール」→「シリアルポート」で認識されたポートを選び、書き込みテストを行う
Arduinoでの開発経験がある方は、既存のArduinoプログラム集20選のコードをESP32用に移植する練習をすると、両者の共通点・相違点が体感として身につきます。
書き込みができない場合は、ボードによってはBOOTボタンを押しながら書き込み開始する必要があります。エラーメッセージが出た場合は、USBケーブルがデータ通信対応か(充電専用ケーブルではないか)も確認してください。
ArduinoユーザーがつまずくGPIOの注意点

digitalWrite()やanalogRead()といった関数の書き方はArduinoとほぼ共通ですが、ESP32のGPIOにはArduino Unoにはない制約がいくつもあります。配線前に必ず押さえておきましょう。
ESP32は3.3Vロジックです。Arduino Unoのように5V出力のセンサーやモジュールを信号線へ直結すると、故障につながる恐れがあります。5V専用部品を使う場合はレベル変換IC(ロジックレベルコンバータ)を挟んでください。
GPIO34〜39は入力専用で、内部プルアップ・プルダウン抵抗も持ちません。ボタンやセンサーの出力を読むだけなら使えますが、LEDやモーターの制御には使えません。
GPIO0・GPIO2・GPIO12・GPIO15などは起動モードに影響するピンです。ここに部品を接続したまま電源を入れると、書き込みモードに入ってしまったり、正常に起動しなかったりすることがあります。慣れるまでは避け、汎用的なGPIO(例:GPIO16〜27付近)を優先して使いましょう。
ボタン配線の基礎からもう一度確認したい場合はArduinoとブレッドボードで学ぶボタン回路の基礎から応用まで、圧センサーなどアナログ入力の基礎は圧センサーを用いた電子工作の基礎編が参考になります。考え方はESP32でも共通です。
ESP32とArduinoでピン配置を比較する
Wi-Fi接続の基本コードを読み解く

ESP32の無線機能は、Arduino core for ESP32に標準搭載されたWiFiライブラリ ↗で扱います。まずは自宅・社内のWi-Fiルーターに接続し、IPアドレスを取得するだけの最小構成から始めます。
// ESP32を自宅Wi-Fiへ接続し、切断時は自動再接続する
#include <WiFi.h>
const char* WIFI_SSID = "your-ssid";
const char* WIFI_PASSWORD = "your-password";
void connectWiFi() {
WiFi.mode(WIFI_STA); // ステーションモード(子機)として動作
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Connecting...");
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
connectWiFi();
}
void loop() {
// 接続が切れていたら再接続する
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Wi-Fi disconnected. Reconnecting...");
connectWiFi();
}
delay(2000);
}
コードのポイントを分解して読む
SSIDやパスワードのようなハードコードした認証情報は、公開リポジトリにそのままアップロードしないよう注意してください。プロンプトの作り方自体をもっと知りたい方は生成AIプロンプト集50選も参考になります。
Bluetooth(BLE)接続の基本
ESP32はBluetooth Classicに加えて、省電力なBLE(Bluetooth Low Energy)にも対応しています。スマホアプリと連携するIoT工作の多くはBLEを使うため、まずは「ESP32がスマホから見える状態を作り、値を1つ公開する」最小構成のBLEサーバーを試してみましょう。ライブラリの実装はArduino-ESP32のBLEライブラリ(GitHub) ↗で公開されています。
// BLEサーバーとしてダミー温度値を5秒ごとに通知する
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLECharacteristic *tempCharacteristic;
unsigned long lastNotifyTime = 0;
const unsigned long NOTIFY_INTERVAL_MS = 5000;
void setup() {
Serial.begin(115200);
BLEDevice::init("ESP32-Sensor"); // スマホ側に表示される名前
BLEServer *server = BLEDevice::createServer();
BLEService *service = server->createService(SERVICE_UUID);
tempCharacteristic = service->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
tempCharacteristic->setValue("no data");
service->start();
server->getAdvertising()->start(); // アドバタイズ開始(スマホから見えるようにする)
Serial.println("BLE server started. Waiting for connections...");
}
void loop() {
if (millis() - lastNotifyTime >= NOTIFY_INTERVAL_MS) {
lastNotifyTime = millis();
float dummyTemp = random(200, 300) / 10.0; // 20.0〜30.0度のダミー値
String payload = String(dummyTemp, 1) + "C";
tempCharacteristic->setValue(payload.c_str());
tempCharacteristic->notify(); // 接続中のスマホへ通知
Serial.println("Notify: " + payload);
}
}
UUID(サービス・キャラクタリスティックの識別子)は、スマホアプリ側の設定と完全に一致させる必要があります。UUIDはUUID Generator ↗のようなツールで生成すると重複を避けられます。動作確認には「nRF Connect」など汎用BLEスキャンアプリが便利です。
センサーそのものの選び方や特性の違いを比較したい場合はArduino用センサー完全ガイド16選も参考になります。ESP32でも多くのセンサーはそのまま流用できます。
センサーデータをWi-Fiで送信する実践編
ここまでの「Wi-Fi接続」と「センサーを読む」を組み合わせ、DHT22温湿度センサーの値を一定間隔でサーバーへHTTP POST送信する実践的な構成を作ります。ArduinoJsonでJSON形式に整形し、HTTPClientライブラリで送信する、IoT工作の定番パターンです。
ESP32、DHT22(またはDHT11)温湿度センサー、10kΩプルアップ抵抗(モジュール品は不要な場合あり)
DATA→GPIO4、VCC→3.3V、GND→GND
// DHT22の温湿度をJSONにまとめてHTTP POSTで送信する
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <DHT.h>
const char* WIFI_SSID = "your-ssid";
const char* WIFI_PASSWORD = "your-password";
const char* API_URL = "https://example.com/api/sensor";
#define DHT_PIN 4
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
unsigned long lastSendTime = 0;
const unsigned long SEND_INTERVAL_MS = 30000; // 30秒間隔
void setup() {
Serial.begin(115200);
dht.begin();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to Wi-Fi...");
}
Serial.println("Wi-Fi connected.");
}
void sendSensorData(float temperature, float humidity) {
HTTPClient http;
http.begin(API_URL);
http.addHeader("Content-Type", "application/json");
JsonDocument doc; // ArduinoJson v7以降の書き方
doc["temperature"] = temperature;
doc["humidity"] = humidity;
String payload;
serializeJson(doc, payload);
int statusCode = http.POST(payload);
Serial.print("POST status: ");
Serial.println(statusCode);
http.end();
}
void loop() {
if (millis() - lastSendTime >= SEND_INTERVAL_MS) {
lastSendTime = millis();
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Warning: Wi-Fi not connected. Skip sending.");
return;
}
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Warning: failed to read from DHT sensor.");
return;
}
sendSensorData(temperature, humidity);
}
}
コードのポイントを分解して読む
実際の医療・介助現場のセンサー活用事例として、Arduino×Python×AIで作るリハビリセンサー自作ガイドや筋電センサー入門では、取得した値をどう解釈し活用するかまで掘り下げています。ESP32で無線化すれば、同じセンサー構成をケーブルレスで運用できます。
httpsの送信先によっては証明書検証(setInsecure()や証明書の登録)が必要になる場合があります。まずはhttp(暗号化なし)のテスト用エンドポイントで動作確認し、本番運用時にhttpsへ切り替えるのが安全な進め方です。
コピペで使えるESP32サンプルコード6選
ここまで解説した内容を踏まえ、実務や工作ですぐ使える独立したスケッチを6本まとめました。検索欄に「Wi-Fi」「BLE」「送信」などと入力すると対象コードだけに絞れます。
| No. | コード | ライブラリ | 難易度 |
|---|---|---|---|
| 01 | ステーションモードでWi-Fiに接続しIPアドレスを表示 | WiFi.h | 入門 |
| 02 | 固定IPアドレスでWi-Fiに接続する | WiFi.h | 入門+ |
| 03 | HTTP GETで外部APIから天気データを取得する | HTTPClient / ArduinoJson | 基礎+ |
| 04 | センサー値をJSON形式でHTTP POST送信する(単体テスト用) | HTTPClient / ArduinoJson | 基礎+ |
| 05 | BLEサーバーでボタン状態をスマホへ通知する | BLEDevice | 基礎+ |
| 06 | Deep Sleepで一定間隔だけ起きる省電力運用 | esp_sleep.h | 基礎+ |
ステーションモードでWi-Fiに接続しIPアドレスを表示
すべてのWi-Fi工作の出発点。まずは接続できることを確認します。
ESP32本体のみ(USBケーブルで給電)
不要(Wi-Fiは基板内蔵アンテナを使用)
コードを表示・コピー
#include <WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {}
固定IPアドレスでWi-Fiに接続する
DHCPに頼らず、毎回同じIPアドレスで起動させたい場合に使います。
ESP32本体のみ
不要
コードを表示・コピー
#include <WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
// 環境に合わせて書き換える(ルーターのDHCP範囲外のアドレスを指定)
IPAddress localIP(192, 168, 1, 50);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(115200);
if (!WiFi.config(localIP, gateway, subnet)) {
Serial.println("Static IP configuration failed.");
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Fixed IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {}
HTTP GETで外部APIから天気データを取得する
Wi-Fi経由でインターネット上のAPIにアクセスし、JSONを受け取る基本形です。
ESP32本体のみ
不要
コードを表示・コピー
// pip相当: ArduinoJsonをライブラリマネージャーから追加
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* API_URL = "https://example.com/api/weather"; // 利用するAPIのURLに置き換える
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
HTTPClient http;
http.begin(API_URL);
int statusCode = http.GET();
if (statusCode == 200) {
String body = http.getString();
JsonDocument doc;
deserializeJson(doc, body);
Serial.print("Response: ");
serializeJsonPretty(doc, Serial);
} else {
Serial.print("GET failed. status: ");
Serial.println(statusCode);
}
http.end();
}
void loop() {}
センサー値をJSON形式でHTTP POST送信する(単体テスト用)
実センサーが無くても、ダミー値の送信でAPI連携部分だけ先にテストできます。
ESP32本体のみ(後で実センサーに差し替え可)
不要
コードを表示・コピー
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* API_URL = "https://example.com/api/sensor";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void loop() {
HTTPClient http;
http.begin(API_URL);
http.addHeader("Content-Type", "application/json");
JsonDocument doc;
doc["value"] = random(0, 100); // 実センサーの値に置き換える
doc["device"] = "esp32-test";
String payload;
serializeJson(doc, payload);
int statusCode = http.POST(payload);
Serial.print("POST status: ");
Serial.println(statusCode);
http.end();
delay(10000); // 10秒間隔
}
BLEサーバーでボタン状態をスマホへ通知する
物理ボタンの押下をBLE経由でスマホアプリへリアルタイム通知します。
押しボタン
ボタン→GPIO27(内蔵プルアップ使用、反対側はGND)
コードを表示・コピー
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#define SERVICE_UUID "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
#define CHARACTERISTIC_UUID "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
#define BUTTON_PIN 27
BLECharacteristic *buttonCharacteristic;
bool lastState = false;
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
BLEDevice::init("ESP32-Button");
BLEServer *server = BLEDevice::createServer();
BLEService *service = server->createService(SERVICE_UUID);
buttonCharacteristic = service->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
buttonCharacteristic->setValue("released");
service->start();
server->getAdvertising()->start();
}
void loop() {
bool pressed = digitalRead(BUTTON_PIN) == LOW; // 内蔵プルアップなのでLOWで押下
if (pressed != lastState) {
lastState = pressed;
buttonCharacteristic->setValue(pressed ? "pressed" : "released");
buttonCharacteristic->notify();
Serial.println(pressed ? "pressed" : "released");
}
delay(30); // 簡易的なチャタリング対策
}
Deep Sleepで一定間隔だけ起きる省電力運用
バッテリー駆動のセンサー端末で必須の、消費電力を抑える定番テクニックです。
ESP32本体(バッテリー運用を想定)
不要
コードを表示・コピー
#define uS_TO_S_FACTOR 1000000ULL // マイクロ秒→秒の変換係数
#define SLEEP_SECONDS 60 // 60秒ごとに起床
void setup() {
Serial.begin(115200);
delay(200);
Serial.println("Woke up. Doing the job...");
// ここで本来はセンサー読み取りやWi-Fi送信を行う
Serial.println("Going to deep sleep now.");
esp_sleep_enable_timer_wakeup(SLEEP_SECONDS * uS_TO_S_FACTOR);
esp_deep_sleep_start(); // ここでCPUがほぼ完全に停止する
}
void loop() {
// Deep Sleep中はloop()に到達しない
}
トラブルシューティング・FAQ・まとめ
書き込み・接続でよくあるつまずき
- 書き込みが始まらない:データ通信対応のUSBケーブルか確認し、ボードの「BOOT」ボタンを押しながら書き込みを開始してみてください。
- Wi-Fiに繋がらない:SSID・パスワードの誤り、5GHz専用ネットワークへの接続を試していないか確認してください(ESP32は2.4GHz帯のみ対応)。
- 頻繁に再起動する(ブラウンアウト):USBのみの給電では電力不足になることがあります。特にWi-Fi送信中は瞬間的に電流が増えるため、安定したUSB電源やACアダプタを使ってください。
- HTTP送信が失敗する:まずステータスコードをシリアル出力し、-1系のエラーコードならWi-Fi未接続、400番台ならAPI側のリクエスト内容の問題を疑ってください。
ESP32とArduinoはどちらを買えばいいですか?
LEDやセンサーの基礎を学ぶだけならArduino Unoのようなシンプルなボードが分かりやすいですが、Wi-FiやBluetoothでスマホ・クラウドと連携したい場合はESP32が圧倒的に有利です。価格もArduino Uno相当かそれ以下で、無線機能とより高速なCPUを内蔵しています。両方を併用し、用途で使い分ける人も多くいます。
ESP32のGPIOはArduinoと同じ感覚で使えますか?
基本的なdigitalWrite()やanalogRead()などの関数はArduinoとほぼ同じですが、ESP32は動作電圧が3.3Vであること、GPIO34〜39が入力専用であること、起動時の状態に影響するピンがあることなど、Arduinoにはない制約があります。データシートやピン配置図で必ず確認してから配線してください。
Wi-FiとBluetoothは同時に使えますか?
ESP32はWi-FiとBluetooth/BLEを同時に利用できるRF回路を搭載していますが、アンテナを共有しているため、両方を同時にフル稼働させると通信が不安定になることがあります。同時利用が前提の設計では、通信のタイミングをずらす、BLEのみ・Wi-Fiのみで役割を分けるといった工夫が必要です。
センサーデータを送る先はどう用意すればいいですか?
最も手軽なのは無料のテスト用HTTPエンドポイントやMQTTブローカーを使う方法です。慣れてきたら、GoogleスプレッドシートAPIやAWS IoT Core、自作のFlaskサーバーなど、目的に合わせた送信先を選べます。まずは本記事のサンプルコードでHTTP POSTが成功することを確認し、その後に本番の送信先へ差し替えるのがおすすめです。
まずは第5節の「Wi-Fi接続」コードでネットワークに繋がることを確認し、次に第8節のBLEコードでスマホから見える状態を作る、という2段階で進めると理解しやすくなります。動いたコードに対して、AIへ「MQTTで送信するように変えて」「Deep Sleepと組み合わせて」「複数のセンサー値をまとめて送るように」と追加依頼すれば、同じ構成から本格的なIoT作品へ発展させられます。
あわせて読みたい関連記事
コメント