結論

ESP32はWi-Fi付きのマイコンチップ、M5StackはそれをケースやLCDと一体にした製品です。同じ開発環境で書けます。

この記事でわかること

  • ESP32の8種類の比較表とM5Stack製品群の対応
  • 開発環境5つの選び方と温度を送るコードの実行結果
  • 書き込み失敗・ブラウンアウトなどエラー13件の直し方

2026年10月22日更新|esptool 5.6.0・MicroPython 1.22で実行確認

ESP32 は Espressif 社のチップです。チップを基板に載せた「開発ボード」と、画面・電池・ケースまで付けた「M5Stack」のどちらでも、同じ Arduino や MicroPython のプログラムが動きます。

flowchart TD
    A[ESP32 チップ<br>Espressif 社] --> B[開発ボード<br>DevKit など]
    A --> C[M5Stack<br>画面・電池・ケース付き]
    B --> D[開発環境<br>Arduino・MicroPython など]
    C --> D
    D --> E[USB で書き込み<br>Wi-Fi で通信]

急いでいる人向けに、よく調べられることを先にまとめます。

知りたいこと 答え 詳しい節
最初の1台 画面付きなら CoreS3・Core2、小型なら AtomS3R M5Stackの製品群
どの ESP32 を選ぶか 迷ったら ESP32-S3。5GHz なら C5 ESP32の種類
開発環境 Arduino IDE。ブロックなら UiFlow2 開発環境の選び方
ボードマネージャーの URL espressif.github.io の package_esp32_index.json Arduino IDEの設定
書き込めない ケーブル・ポート・ドライバー・ダウンロードモードの順に確認 よくあるエラー
Brownout detector was triggered 電源の電流不足。USB ポートやケーブルを変える よくあるエラー
ラズパイとの違い ラズパイは Linux が動くコンピューター ラズパイ・Arduinoとの違い
日本で使うときの注意 技適マークのある製品を使う 技適

確認環境:Ubuntu 24.04.4 LTS・Python 3.11.15・esptool 5.6.0・pyserial 3.5・mpremote 1.29.0・PlatformIO Core 6.2.0(pip で導入)・MicroPython 1.22.1(Ubuntu の unix 版)・micropython-lib の requests 1.1.1・g++ 13.3.0。Wi-Fi で温度を送る MicroPython のコードは、パソコンの MicroPython で network と machine(I2C)を差し替えて実行し、自作の受信サーバー(Python の http.server)が受け取ったリクエストを記録しました。Arduino のスケッチは、WiFi・HTTPClient・Wire を最小のスタブに置き換えて g++ でコンパイル・実行し、SHT30 の変換式と送る JSON を確かめました。esptool の接続エラーは、疑似端末(pty)に向けて実行した出力です。ボードの一覧・メニューの既定値・HTTPClient が送るヘッダーは arduino-esp32 3.3.12 のソース(boards.txt・HTTPClient.cpp)で、Arduino IDE の日本語の画面の文言は arduino-ide の翻訳ファイルで、ビルドのメッセージは arduino-cli のソースで確かめました。ESP32 向けのビルドと実機への書き込み、各製品の仕様は、Espressif・M5Stack・Arduino・MicroPython・PlatformIO・Raspberry Pi・総務省の公式ドキュメントで確認しました(確認日 2026年10月22日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「M5Stack・ESP32とは|種類・開発環境・始め方とエラーの直し方」

ESP32とM5Stackとは(違いと関係)

この節では、ESP32 と M5Stack が何で、どう違うのかが分かります。

ESP32 は、中国の Espressif Systems 社が作る、Wi-Fi と Bluetooth を内蔵したマイコン(マイクロコントローラー)のチップです。 マイコンは、センサーを読んだり、モーターや LED を動かしたりする小さなコンピューターで、OS を入れずに1つのプログラムを動かします。ESP32 は無線の機能をチップ1つに持っているので、「温度を測ってネットに送る」ような IoT(モノのインターネット)の機器を少ない部品で作れます。

M5Stack は、ESP32 を使った開発キットのシリーズ名で、会社名でもあります。 手のひらに乗る四角い箱に、ESP32・画面・ボタン・電池・スピーカーなどを入れた「Core」が代表で、ほかにも小さな「Atom」、スティック型の「Stick」などがあります。センサーは「Unit」という部品を Grove(4本線のコネクター)で差すだけでつながり、はんだ付けがいりません。

温度を測って画面に出し、ネットに送る機器を作るとき

ESP32 の開発ボードボード・センサー・画面・電池をブレッドボードと線で自分でつなぐ。安く、形を自由に決められる
→
M5Stack画面と電池は最初から入っている。センサーの Unit を Grove ケーブルで差す。配線なしですぐ動かせる

中身はどちらも ESP32。Arduino や MicroPython のコードはほぼ共通で、違うのはピン番号と画面・電源の扱い

ESP32・M5Stackでできること

1Wi-Fi でデータを送る

温湿度・CO2・電力などを測り、HTTP や MQTT でサーバーやクラウドに送る。この記事では温度を HTTP で送るコードを動かす。

2Bluetooth でつなぐ

スマホのアプリと通信する、BLE のビーコンを出す。初代 ESP32 は Bluetooth Classic も使える。

3画面・ボタンで操作する

M5Stack の Core は画面と電池付きなので、時計・表示板・小さなゲーム機・リモコンになる。

4家電やモーターを動かす

GPIO(汎用の入出力ピン)でリレー・サーボ・LED テープを制御する。Home Assistant につなぐ使い方もある。

M5Stack の公式ドキュメントには、ほかに UiFlow1、ESP-IDF、Home Assistant、MaixPy、nanoFramework などの開発環境の案内も載っています。ESP32 の上ではふつう、Espressif の開発フレームワーク ESP-IDF(中で FreeRTOS という小さな OS が動く)か、その上に作られた Arduino 用のコア(arduino-esp32)を使います。MicroPython を書き込めば Python でも書けます。

ESP32の種類(ESP32・S3・C3・C6・H2・P4)の比較表

この節では、ESP32 の種類ごとの違いと、どれを選ぶかが分かります。

ESP32 は1つのチップの名前であると同時に、S・C・H・P などのシリーズをまとめた呼び名でもあります。 Espressif の製品ページ・データシートで確認した主な違いです(2026年10月22日時点)。

チップ CPU Wi-Fi Bluetooth・その他 向いている用途
ESP32(初代) Xtensa LX6 2コア 240MHz Wi-Fi 4(2.4GHz) Classic と LE(v4.2) Bluetooth Classic を使う機器
ESP32-S2 Xtensa 1コア 240MHz Wi-Fi 4 Bluetooth なし。USB OTG USB 機器として動かす
ESP32-S3 Xtensa LX7 2コア 240MHz Wi-Fi 4(2.4GHz) LE(5)。USB 直結・ベクトル命令 画面・カメラ・音声・AI
ESP32-C3 RISC-V 1コア 160MHz Wi-Fi 4 LE(5) 小型・低価格のセンサー
ESP32-C5 RISC-V 1コア 240MHz Wi-Fi 6(2.4GHz・5GHz) LE(5)・802.15.4 5GHz の Wi-Fi が必要な機器
ESP32-C6 RISC-V 1コア 160MHz+低電力コア Wi-Fi 6(2.4GHz) LE(5)・802.15.4 Matter・Thread・Zigbee
ESP32-H2 RISC-V 1コア なし LE(5)・802.15.4 Thread・Zigbee の末端の機器
ESP32-P4 RISC-V 2コア 400MHz なし(C6 などと組む) MIPI の画面・カメラ・H.264 大きな画面・カメラの高性能機

802.15.4 は、Thread や Zigbee という省電力の無線ネットワークで使う規格です。Wi-Fi が 5GHz に対応するのは、この表では ESP32-C5 だけで、ほかは 2.4GHz の Wi-Fi にしかつながりません。

8種arduino-esp32 が安定版で対応ESP32・S2・S3・C3・C5・C6・H2・P4
5GHzに対応するのは C5ほかは 2.4GHz の Wi-Fi だけ
400MHzESP32-P4 の最大周波数無線は持たず、別チップと組む

arduino-esp32 のドキュメントでは、ESP32-C2・ESP32-C61 は「Arduino as an ESP-IDF component」として使うか、ライブラリを作り直す必要があるとされています。Espressif は ESP8266 について「ESP32-C2(ESP8684)への移行を推奨」と製品ページに書いています。

新しいチップも続いています。esptool 5.6.0 の --chip で選べる値を出すと、次のとおりでした。

esptool --help
│ --chip              -c  [auto|esp8266|esp32|esp3  Target chip type.          │
│                         2s2|esp32s3|esp32c3|esp3                             │
│                         2c2|esp32c6|esp32c61|esp                             │
│                         32c5|esp32e22|esp32h2|es                             │
│                         p32h21|esp32p4|esp32h4|e                             │
│                         sp32s31]                                             │

どのESP32を選ぶかの判断表

状況 選ぶチップ 理由
初めてで、迷っている ESP32-S3 2コアで速く、資料が多い。USB 直結で書き込める
画面・カメラ・音声認識を使う ESP32-S3(大きな画面なら P4) PSRAM 付きの製品が多く、ベクトル命令がある
電池で長く動くセンサー ESP32-C3・C6 1コアで小さく、C6 は低電力コアを持つ
Matter・Thread・Zigbee ESP32-C6・H2 802.15.4 を持つ
5GHz の Wi-Fi しかない場所 ESP32-C5 2.4GHz と 5GHz の両方に対応
Bluetooth のオーディオなど Classic ESP32(初代) S3・C 系は LE だけ
資料や作例をそのまま使いたい ESP32(初代) 登場から長く、作例が多い

初代ESP32のピン(GPIO)で気をつけること

配線を自分でするときに、つまずきやすい点です。ESP-IDF の GPIO のドキュメントとデータシートで確認しました。

ピン 注意 理由
GPIO34〜39 入力だけ。内部のプルアップ・プルダウンも無い 出力には使えない
GPIO0・2・5・12・15 起動時の動きを決める「ストラッピングピン」 起動時に外から引っ張ると書き込みモードや電圧の設定が変わる
GPIO6〜11・16〜17 多くのモジュールでフラッシュ・PSRAM につながっている ほかの用途に使わない
ADC2 のピン Wi-Fi を使っている間は読めない Wi-Fi と共用。ADC1 のピンを使う
電源 データシートの推奨は 3.3V の単一電源 5V で動く部品とは電圧をそろえてつなぐ

GPIO12 は起動時の値で内部のフラッシュの電圧(3.3V か 1.8V)を選ぶので、ここにプルアップの部品をつなぐと起動しないことがあります。M5Stack は、製品ページのピン配置の表に使えるピンがまとまっているので、そこから選びます。

M5Stackの製品群(Core・Atom・Stick・Stamp・Cardputer・Tab5)

この節では、M5Stack の製品のシリーズと、中のチップの対応が分かります。

M5Stack は形と大きさでシリーズが分かれていて、同じシリーズでも中の ESP32 の種類が違います。 M5Stack の公式ドキュメントの製品一覧で確認した、主なコントローラーです(2026年10月22日時点)。

シリーズ 主な製品(チップ) 特徴 向いている用途
Core CoreS3・CoreS3-SE(ESP32-S3)、Core2 v1.3・Basic v2.7(ESP32) 四角い箱。画面・電池・スピーカー付き 最初の1台・表示する機器
Stick StickS3(ESP32-S3)、StickC-Plus2(ESP32) 細長い。小さな画面と電池 持ち歩く・腕に付ける
Atom AtomS3R・AtomS3-Lite(ESP32-S3)、Atom-Lite(ESP32) 指先ほどの大きさ。画面なしか小さな画面 小さな箱・組み込み
Stamp Stamp-S3A(S3)、Stamp-C3U(C3)、Stamp-C5、Stamp-P4 切手大のモジュール 自作基板に載せる
Cardputer Cardputer-Adv(ESP32-S3) キーボードと画面 携帯端末・入力のある道具
Tab5・Paper Tab5(ESP32-P4+C6)、PaperS3(ESP32-S3) 5インチ画面、電子ペーパー 操作パネル・表示板

センサーやボタンは「Unit」として売られていて、Core なら赤い Port A(I2C)に Grove ケーブルで差します。たとえば温湿度・気圧の ENV III Unit は、中に SHT30(I2C アドレス 0x44)と QMP6988(0x70)が入っています。

Espressif の ESP32 のデータシート(v5.3)は、Core2・Basic に使われている ESP32-D0WDQ6-V3 を NRND(新規設計には推奨しない)に分類しています。新しく作る機器の候補には、CoreS3 や AtomS3R など ESP32-S3 の製品もあります。

M5Stackのおすすめの選び方

状況 選ぶ製品 理由
初めて。画面に出しながら学びたい CoreS3 または Core2 画面・ボタン・電池・スピーカーが全部ある
小さく作りたい・値段を抑えたい AtomS3R・AtomS3-Lite 小さく、Grove の口が1つある
持ち歩く・ボタンで操作する StickS3・StickC-Plus2 電池と IMU(加速度・角速度センサー)付き
文字を打てる端末にしたい Cardputer-Adv キーボード付き
大きな画面の操作パネル Tab5 5インチ画面・ESP32-P4

StickC-Plus2 は電源を自分で保持する作りで、公式ドキュメントには「起動したら初期化でG4(HOLD)を HIGH にしないと、また電源が切れる」と書かれています。Arduino のライブラリ(M5Unified や M5StickCPlus2)はこれを内部で行います。

始めるのに必要なもの

この節では、最初に用意するものが分かります。

  • 1ESP32 の開発ボードか M5Stack迷ったら ESP32-S3 の製品。M5Stack の Core なら画面と電池も入っている
  • 2データ通信ができる USB ケーブル充電専用のケーブルではポートが出ない。端子は製品に合わせる(StickS3 などは USB Type-C)
  • 3パソコン(Windows・Mac・Linux)Arduino IDE・esptool・UiFlow2 は3つの OS で使える。Chromebook は Linux 環境を有効にして使う例がある
  • 4USB シリアルのドライバー(必要な機種だけ)CP210x・CH9102 を積む製品。ESP32-S3 などの USB 直結の製品は、変換チップを使わない
  • 52.4GHz の Wi-FiESP32-C5 以外は 5GHz につながらない。SSID とパスワードを控える
  • 6センサー(使うなら)M5Stack なら ENV Unit など。開発ボードならブレッドボードとジャンパー線も

開発環境の選び方(Arduino IDE・PlatformIO・ESP-IDF・UiFlow2・MicroPython)

この節では、5つの開発環境の違いと、どれを選ぶかが分かります。

最初は Arduino IDE、ブロックで作りたいなら UiFlow2、Python で書きたいなら MicroPython、本格的な製品や新しい機能を使うなら ESP-IDF と分けると選びやすくなります。

開発環境 言語 特徴 向いている人
Arduino IDE C++(Arduino) ボードマネージャーで入る。作例・ライブラリが多い 初めての人・作例を動かしたい人
PlatformIO C++(Arduino・ESP-IDF) VS Code の拡張。platformio.ini で版を固定できる VS Code で複数の機器を管理したい人
ESP-IDF C・C++ Espressif 公式。全部の機能と設定(menuconfig) 製品を作る人・新しいチップを使う人
UiFlow2 ブロック・Python M5Stack 公式の Web の開発環境。ブラウザで作る M5Stack を使う初心者・教育
MicroPython Python ファームウェアを書き込み、REPL で対話的に動かす Python に慣れた人・試しながら作る人

2026年10月22日時点の版は次のとおりです。

もの 版 確認した場所
Arduino IDE 2.3.10 arduino.cc のダウンロードページ
arduino-esp32(安定版) 3.3.12(ESP-IDF v5.5.5 ベース) GitHub のリリース
arduino-esp32(プレリリース) 4.0.0-RC1(ESP-IDF v6.1 ベース) GitHub のリリース
ESP-IDF(安定版) v6.1 ESP-IDF のドキュメント
MicroPython(ESP32_GENERIC) v1.29.0(2026年8月24日) micropython.org
PlatformIO の espressif32 7.1.0(Arduino は 2.0.17 を同梱) GitHub のリリース

PlatformIO 公式の espressif32 プラットフォームに入っている Arduino コアは 2.0.17 です。 arduino-esp32 の 3.x を PlatformIO で使うには、コミュニティの「pioarduino」のプラットフォームを指定する方法が README で案内されています(後の「PlatformIO・ESP-IDFで書く」の節)。

flowchart TD
    A{ブロックで<br>作る?} -->|はい| B[UiFlow2]
    A -->|いいえ| C{Python?}
    C -->|はい| D[MicroPython]
    C -->|いいえ| E{製品向け?}
    E -->|はい| F[ESP-IDF]
    E -->|いいえ| G[Arduino IDE<br>PlatformIO]

Arduino(C++)が合う場合

作例・ライブラリをそのまま使いたい

速さ・メモリを詰めたい

M5Unified など M5Stack のライブラリを使う

MicroPython・UiFlow2 が合う場合

書き込まずに REPL で1行ずつ試したい

Python に慣れている

ブロックから始め、後で Python を見たい

Arduino IDEでESP32・M5Stackを使う設定(ボードマネージャーのURL)

この節では、Arduino IDE に ESP32 を追加し、最初のプログラムを書き込むまでの手順が分かります。

[ファイル]→[基本設定](英語表示では File → Preferences)の[追加のボードマネージャのURL]に Espressif の URL を入れ、ボードマネージャで「esp32」を入れます。 [追加のボードマネージャのURL][ボードマネージャ][検証][書き込み][シリアルモニタ]は、Arduino IDE の日本語の翻訳ファイルにある文言です。

https://espressif.github.io/arduino-esp32/package_esp32_index.json
1

Arduino IDE を入れる

arduino.cc から OS に合うものを入れます。2026年10月22日時点の最新は 2.3.10 です。Linux 版は AppImage で、chmod +x で実行の権限を付けてから起動します。

Windows・Mac・Linux

2

追加のボードマネージャのURL に入れる

[ファイル]→[基本設定]を開き、[追加のボードマネージャのURL]に上の URL を貼ります。複数あるときはカンマで区切ります(Espressif のドキュメント)。

開発版は package_esp32_dev_index.json

3

ボードマネージャで esp32 を入れる

左のボードマネージャで「esp32」を検索し、Espressif Systems の esp32 を[インストール]します。

ツールチェーンも一緒に入る

4

ボードとポートを選ぶ

[ツール]→[ボード]→[esp32]から製品を選び、[ツール]→[ポート]で USB のポートを選びます。

上の[ボードを選択]からも選べる

5

検証・書き込み

[検証]でコンパイルし、[書き込み]でボードへ送ります。[シリアルモニタ]の通信速度はスケッチの Serial.begin に合わせます。

ESP32 の作例は 115200 が多い

Linux では、シリアルポートを読み書きするために、ユーザーを dialout グループに入れます(Espressif のドキュメント。ログインし直すと効きます)。

sudo usermod -a -G dialout $USER

Espressifのesp32とM5Stackのボードパッケージの違い

M5Stack の製品は、2つのボードパッケージのどちらでも選べます。

項目 Espressif の esp32 M5Stack の M5Stack
URL espressif.github.io/arduino-esp32/package_esp32_index.json static-cdn.m5stack.com/resource/arduino/package_m5stack_index.json
ボードマネージャで探す名前 esp32 M5Stack
ボードの選び方 [esp32]→ M5CoreS3 など [M5Stack]→ 製品名
入っている M5Stack の製品 3.3.12 の boards.txt で26機種 M5Stack 社が載せる製品

arduino-esp32 3.3.12 の boards.txt には、次のような M5Stack のボードが入っていました(FQBN はコマンドで使うボードの指定名)。

ボード名 チップ FQBN
M5Core(Basic) esp32 esp32:esp32:m5stack_core
M5Core2 esp32 esp32:esp32:m5stack_core2
M5CoreS3 esp32s3 esp32:esp32:m5stack_cores3
M5AtomS3 esp32s3 esp32:esp32:m5stack_atoms3
M5StickCPlus2 esp32 esp32:esp32:m5stack_stickc_plus2
M5NanoC6 esp32c6 esp32:esp32:m5stack_nanoc6
M5Tab5 esp32p4 esp32:esp32:m5stack_tab5
M5Cardputer esp32s3 esp32:esp32:m5stack_cardputer

M5Stack のドキュメントは、一覧に無い新しい製品は同じチップのボードを選ぶよう案内しています(例:M5Dial は ESP32-S3 なので M5StampS3)。CoreS3 のサンプルを動かす手順では、ライブラリマネージャで M5Unified と M5GFX を依存ライブラリごと入れるよう書かれています。

[ツール]メニューの主な設定

ESP32 のボードは、[ツール]メニューに設定が増えます。M5CoreS3 の boards.txt での選択肢と既定値(いちばん上が既定)です。

設定 既定 変えるとき
USB CDC On Boot Enabled USB 直結の S3 で Serial を USB に出す。UART の口を使うなら Disabled
PSRAM QSPI PSRAM モジュールが OPI の PSRAM なら OPI PSRAM
Partition Scheme Default 4MB with spiffs(1.2MB APP) 大きなスケッチは Huge APP(3MB)など
Upload Speed 921600 書き込みが途中で失敗するなら 115200

既定のパーティションでは、スケッチに使える大きさは 1,310,720 バイト(upload.maximum_size)です。これを超えると「スケッチが大きすぎます」になります(後の「よくあるエラー」の節)。

ドライバーとポートの名前

OS ポートの名前 ドライバー
Windows COM3 など(デバイスマネージャーで確認) CP210x・CH9102 の製品は各社のドライバー
Mac /dev/cu.usbserial-… など(ls /dev/cu.*) 同上
Linux /dev/ttyUSB0(変換チップ)、/dev/ttyACM0(USB 直結のことが多い) 多くは OS に入っている

M5Stack の Core2 は、USB シリアルの変換チップが CP2104 か CH9102F(公式ドキュメントでは機能の差はない)、StickC-Plus2 は CH9102 です。ESP32-S3 は USB の機能をチップに持つので、Espressif のドキュメントのとおり変換チップなしで書き込めます。

Wi-Fiに接続して温度を送る(Arduinoのコード)

この節では、ESP32・M5Stack を Wi-Fi につなぎ、温度をサーバーへ HTTP で送るコード全文と、確かめた出力が分かります。

ここでは M5Stack Core2 に ENV III Unit(SHT30)を Port A でつなぐ例にします。Core2 の Port A は SDA が G32、SCL が G33 です(公式ドキュメント)。ほかの機種はピン番号を変えます。

flowchart TD
    A[SHT30<br>温湿度センサー] -->|I2C| B[ESP32<br>M5Stack]
    B -->|Wi-Fi 2.4GHz| C[無線 LAN<br>ルーター]
    C -->|HTTP POST JSON| D[受け取るサーバー]
// ESP32 / M5Stack(Arduino): Wi-Fi につないで、SHT30 の温度を HTTP POST で送る
#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>

const char* SSID = "your-ssid";
const char* PASSWORD = "your-password";
const char* URL = "http://192.168.1.10:32000/api/temp";  // 受け取るサーバー
const char* API_KEY = "demo-key";
const uint8_t SHT30_ADDR = 0x44;                           // ENV III の SHT30

uint8_t crc8(const uint8_t* d, int n) {
  uint8_t crc = 0xFF;
  for (int i = 0; i < n; i++) {
    crc ^= d[i];
    for (int b = 0; b < 8; b++) crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
  }
  return crc;
}

bool readSHT30(float& temp, float& hum) {
  Wire.beginTransmission(SHT30_ADDR);
  Wire.write(0x2C);
  Wire.write(0x06);                                        // 単発測定(高精度)
  if (Wire.endTransmission() != 0) return false;           // 応答なし=配線・アドレスを確認
  delay(20);
  if (Wire.requestFrom(SHT30_ADDR, (size_t)6) != 6) return false;
  uint8_t d[6];
  for (int i = 0; i < 6; i++) d[i] = Wire.read();
  if (crc8(d, 2) != d[2] || crc8(d + 3, 2) != d[5]) return false;
  uint16_t t = (d[0] << 8) | d[1];
  uint16_t h = (d[3] << 8) | d[4];
  temp = -45.0f + 175.0f * t / 65535.0f;
  hum = 100.0f * h / 65535.0f;
  return true;
}

bool connectWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);
  Serial.print("connecting");
  unsigned long t0 = millis();
  while (WiFi.status() != WL_CONNECTED) {
    if (millis() - t0 > 15000) {
      Serial.printf(" timeout (status=%d)\n", WiFi.status());
      return false;
    }
    delay(500);
    Serial.print(".");
  }
  Serial.print(" connected: ");
  Serial.println(WiFi.localIP());
  return true;
}

void setup() {
  Serial.begin(115200);
  Wire.begin(32, 33);  // Core2 の Port A(SDA=G32, SCL=G33)。機種で変わる
  connectWiFi();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED && !connectWiFi()) {
    delay(10000);
    return;
  }
  float temp, hum;
  if (readSHT30(temp, hum)) {
    char body[96];
    snprintf(body, sizeof(body), "{\"device\":\"m5-core2-01\",\"temp_c\":%.2f,\"humidity\":%.1f}", temp, hum);
    HTTPClient http;
    http.begin(URL);
    http.addHeader("Content-Type", "application/json");
    http.addHeader("X-Api-Key", API_KEY);
    int code = http.POST(body);
    if (code > 0) {
      Serial.printf("HTTP %d %s\n", code, http.getString().c_str());
    } else {
      Serial.printf("HTTP error %d: %s\n", code, HTTPClient::errorToString(code).c_str());
    }
    http.end();
  } else {
    Serial.println("SHT30 read failed");
  }
  delay(60000);
}

コードのポイントです。

  • SHT30 の温度は「-45 + 175 × 生の値 ÷ 65535」で求めます。 6バイトのうち3バイト目と6バイト目は CRC(読み間違いの検出用)で、合わなければ捨てます。
  • WiFi.status() の値は、arduino-esp32 3.3.12 の WiFiType.h で WL_CONNECTED = 3、WL_NO_SSID_AVAIL = 1(SSID が見つからない)、WL_CONNECT_FAILED = 4、WL_DISCONNECTED = 6 です。タイムアウトのときに表示される数字で原因の見当がつきます。
  • http.POST() の戻り値が負の数のときは、通信そのものの失敗です。-1 は connection refused(サーバーが動いていない・IP やポートの間違い)、-11 は read Timeout です(HTTPClient.cpp の errorToString)。
  • arduino-esp32 には temperatureRead() という関数もありますが、これはチップ内部の温度で、部屋の温度ではありません。初代 ESP32 向けの実装には、ソースに「Undocumented!!!」とコメントがあります。

WiFi・HTTPClient・Wireをスタブにして確かめた出力

このスケッチを、WiFi・HTTPClient・Wire をパソコン用の最小のスタブ(同じ関数名で、受け取った値を表示するだけの部品)に置き換え、g++ 13.3.0 で -Wall -Wextra を付けてコンパイルしました。警告は0件でした。SHT30 の生の値として、温度 0x6666・湿度 0x8000、温度 0x6A3D・湿度 0x7AE1、CRC を壊したデータの3つを順に返しています。

connecting... connected: 192.168.1.23
  i2c write 0x44 2c 06
POST http://192.168.1.10:32000/api/temp
  Content-Type: application/json
  X-Api-Key: demo-key
  body: {"device":"m5-core2-01","temp_c":25.00,"humidity":50.0}
HTTP 201 {"ok": true}
  i2c write 0x44 2c 06
POST http://192.168.1.10:32000/api/temp
  Content-Type: application/json
  X-Api-Key: demo-key
  body: {"device":"m5-core2-01","temp_c":27.62,"humidity":48.0}
HTTP 201 {"ok": true}
  i2c write 0x44 2c 06
SHT30 read failed

0x6666 は 25.00℃、0x6A3D は 27.62℃ に変換され、CRC が合わないデータは送らずに捨てました。

実機のHTTPClientが送るヘッダー

arduino-esp32 3.3.12 の HTTPClient.cpp は、POST のときに次の形のヘッダーを組み立てます(ソースで確認)。User-Agent の既定は ESP32HTTPClient、接続を使い回す設定(_reuse = true)が既定なので Connection: keep-alive になります。タイムアウトの既定は 5000 ミリ秒です。

POST /api/temp HTTP/1.1
Host: 192.168.1.10:32000
User-Agent: ESP32HTTPClient
Connection: keep-alive
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/json
X-Api-Key: demo-key
Content-Length: 55

受け取るサーバー(Python)

温度を受け取る側の最小のサーバーです。受けたリクエストをそのまま表示し、X-Api-Key が合えば 201、違えば 401 を返します。

# 温度を受け取る小さなサーバー(受けたリクエストをそのまま記録して表示)
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(n)
        print(f"{self.command} {self.path} {self.request_version}")
        for k, v in self.headers.items():
            print(f"  {k}: {v}")
        print("  body:", body.decode())
        if self.headers.get("X-Api-Key") != "demo-key":
            self.send_response(401); self.end_headers(); return
        data = json.loads(body)
        out = json.dumps({"ok": True, "saved": data["temp_c"]}).encode()
        self.send_response(201)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", str(len(out)))
        self.end_headers()
        self.wfile.write(out)
    def log_message(self, *a):
        pass

HTTPServer(("127.0.0.1", 32000), H).serve_forever()  # ESP32 から受けるときは "0.0.0.0"

ESP32 から送る前に、パソコンから curl で同じ形のリクエストを送り、サーバーが動いているかを確かめます。

curl -i -X POST http://127.0.0.1:32000/api/temp -H 'Content-Type: application/json' -H 'X-Api-Key: demo-key' -d '{"device":"test","temp_c":24.5,"humidity":40.0}'
HTTP/1.0 201 Created
Server: BaseHTTP/0.6 Python/3.11.15
Date: Thu, 22 Oct 2026 12:06:07 GMT
Content-Type: application/json
Content-Length: 27

{"ok": true, "saved": 24.5}

ESP32 から届かせるには、サーバーを 0.0.0.0(全部の口)で待ち受け、パソコンのファイアウォールでポートを開け、URL にはパソコンの LAN の IP アドレスを書きます。127.0.0.1 は ESP32 自身を指すので使えません。本番では、サーバーの作り方は関連記事「FastAPI入門|uvで作るCRUD API完成コードと実行結果」で扱っています。201・401 などの意味は、関連記事「HTTPステータスコード 一覧|全コードの原因と対処・curl実例つき」で扱っています。

MicroPythonで同じことをする(実行結果)

この節では、MicroPython で Wi-Fi につないで温度を送るコードと、実際にサーバーが受け取ったリクエストが分かります。

ESP32にMicroPythonを書き込む

micropython.org の ESP32_GENERIC のページから .bin をダウンロードし、esptool で書き込みます。ページに書かれている手順は、フラッシュの消去 → アドレス 0x1000 への書き込みです(ESP32 の場合。S3・C3 などはアドレスが違うので、各チップのページで確認します)。

pip install esptool
esptool erase-flash
esptool --baud 460800 write-flash 0x1000 ESP32_GENERIC-20260824-v1.29.0.bin

esptool 5 では、コマンド名が erase_flash から erase-flash に、プログラム名が esptool.py から esptool に変わっています。 以前の書き方も動きますが、esptool 5.6.0 では次の警告が出ました。

WARNING: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
WARNING: Deprecated: Command 'erase_flash' is deprecated. Use 'erase-flash' instead.

書き込んだ後は、mpremote でボードの中のファイルを操作できます。mpremote cp main.py : で main.py を送り、mpremote repl で対話モードに入ります。

MicroPythonのコード

SHT30 を読む部分を sht30.py に分けました。

# SHT30(M5Stack の ENV III ユニットに入っている温湿度センサー)を I2C で読む
import time

ADDR = 0x44

def crc8(data):
    crc = 0xFF
    for b in data:
        crc ^= b
        for _ in range(8):
            crc = ((crc << 1) ^ 0x31) & 0xFF if crc & 0x80 else (crc << 1) & 0xFF
    return crc

def read(i2c):
    i2c.writeto(ADDR, b"\x2c\x06")   # 単発測定(高精度)
    time.sleep_ms(20)
    d = i2c.readfrom(ADDR, 6)
    if crc8(d[0:2]) != d[2] or crc8(d[3:5]) != d[5]:
        raise ValueError("SHT30 CRC error")
    t_raw = d[0] << 8 | d[1]
    h_raw = d[3] << 8 | d[4]
    temp = -45 + 175 * t_raw / 65535
    hum = 100 * h_raw / 65535
    return round(temp, 2), round(hum, 1)

main.py は、Wi-Fi への接続・測定・送信を繰り返します。MicroPython の ESP32 用のファームウェアには、requests・umqtt.simple(MQTT)・ntptime などが最初から組み込まれています(ports/esp32 の manifest.py で確認)。

# ESP32(MicroPython): Wi-Fi につないで、温度を HTTP POST で送る
import time, json, network, machine
import requests
import sht30

SSID = "your-ssid"
PASSWORD = "your-password"
URL = "http://192.168.1.10:32000/api/temp"   # 受け取るサーバー
API_KEY = "demo-key"
INTERVAL_S = 60

def connect_wifi(timeout_s=15):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print("connecting to", SSID)
        wlan.connect(SSID, PASSWORD)
        t0 = time.time()
        while not wlan.isconnected():
            if time.time() - t0 > timeout_s:
                raise OSError("Wi-Fi timeout, status=%d" % wlan.status())
            time.sleep_ms(200)
    print("connected:", wlan.ipconfig("addr4"))
    return wlan

def send(temp, hum):
    body = json.dumps({"device": "m5-core2-01", "temp_c": temp, "humidity": hum})
    r = requests.post(URL, data=body, headers={"Content-Type": "application/json", "X-Api-Key": API_KEY})
    try:
        print("HTTP", r.status_code, r.text)
        return r.status_code
    finally:
        r.close()

def run(loops=None, interval_s=INTERVAL_S):
    wlan = connect_wifi()
    i2c = machine.I2C(0, sda=machine.Pin(32), scl=machine.Pin(33), freq=100000)  # Core2 の Port A
    n = 0
    while loops is None or n < loops:
        n += 1
        try:
            if not wlan.isconnected():
                wlan = connect_wifi()
            temp, hum = sht30.read(i2c)
            print("temp=%.2f hum=%.1f" % (temp, hum))
            send(temp, hum)
        except Exception as e:
            print("error:", repr(e))
        time.sleep(interval_s)

if __name__ == "__main__":
    run()

r.close() を忘れると、ソケットが閉じられずに残り、何回か送った後に失敗する原因になります。wlan.ipconfig("addr4") は MicroPython のドキュメント(ESP32 のクイックリファレンス)の書き方で、以前の版では wlan.ifconfig() を使います。

パソコンのMicroPythonで動かした結果

パソコン用の MicroPython 1.22.1 で、network と machine だけを偽物に差し替え(Wi-Fi は「つながった」と返し、I2C は前の節と同じ3つのデータを返す)、requests は micropython-lib の本物を使って、上の受信サーバーに実際に送りました。

connecting to your-ssid
connected: ('192.168.1.23', '255.255.255.0')
  i2c write 0x44 2c06
temp=25.00 hum=50.0
HTTP 201 {"ok": true, "saved": 25.0}
  i2c write 0x44 2c06
temp=27.62 hum=48.0
HTTP 201 {"ok": true, "saved": 27.62}
  i2c write 0x44 2c06
error: ValueError('SHT30 CRC error',)

サーバーが受け取ったリクエストです。

POST /api/temp HTTP/1.1
  Host: 127.0.0.1
  Connection: close
  Content-Length: 59
  Content-Type: application/json
  X-Api-Key: demo-key
  body: {"humidity": 50.0, "device": "m5-core2-01", "temp_c": 25.0}

MicroPython の requests は Connection: close で送り、Host にポート番号を付けませんでした。 JSON のキーの順番も、書いた順と違っています(MicroPython の dict は順番を保たない)。サーバー側は順番に頼らずにキーで読みます。

失敗したときの出力も確かめました。API キーを間違えた場合と、サーバーが止まっている場合です。

HTTP 401 
error: OSError(111,)

OSError(111,) の 111 は ECONNREFUSED(接続を断られた)で、サーバーまで届いていないことを表します。401 は届いたうえで断られた状態なので、API キーなど送る中身を見直します。

UiFlow2で作る場合

UiFlow2 は、M5Stack 公式の、ブラウザで使うブロックの開発環境です(uiflow2.m5stack.com)。 M5Burner という書き込みツールで UiFlow2 のファームウェアを書き込み、Wi-Fi を設定してから、Access Code か USB でブラウザの画面とつなぎます。API の説明は uiflow-micropython のドキュメントとして公開されていて、中身は MicroPython です。

手順 すること
1 M5Burner を入れ、製品の UiFlow2 のファームウェアを書き込む(Wi-Fi もここで設定できる)
2 uiflow2.m5stack.com を開き、Access Code か USB で本体とつなぐ
3 ブロックを並べて実行し、本体に転送する(有線・無線のどちらでも)

PlatformIO・ESP-IDFで書く場合(platformio.ini・idf.py)

この節では、Arduino IDE 以外の2つの開発環境の、最小の設定と手順が分かります。

PlatformIO

PlatformIO は VS Code の拡張機能として使うことが多い開発環境で、コマンドの本体(PlatformIO Core)は pip でも入ります。

pip install platformio
pio --version
PlatformIO Core, version 6.2.0

設定は、プロジェクトの直下の platformio.ini に書きます。PlatformIO のドキュメントの例です。

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

board に M5Stack の名前(ドキュメントの一覧にある m5stack-cores3・m5stack-atoms3 など)を入れると、その製品の設定になります。シリアルモニタの速さは monitor_speed = 115200 のように足します。

公式の espressif32(7.1.0)の Arduino コアは 2.0.17 なので、arduino-esp32 3.x で増えた・変わった API を使うコードは、そのままでは通らないことがあります。 pioarduino の README では、3.x(3.3.12・ESP-IDF v5.5.5)を使う場合の指定は次の1行です。

[env:m5stack-cores3]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
board = m5stack-cores3
framework = arduino
monitor_speed = 115200

VS Code の入れ方と日本語化は、関連記事「VSCode日本語化とインストール手順|Win/Mac/Linuxと直し方」で扱っています。

ESP-IDF

ESP-IDF は Espressif の公式の開発フレームワークで、2026年10月22日時点の安定版は v6.1 です。入れ方は ESP-IDF Installation Manager(EIM)か、VS Code の ESP-IDF 拡張機能がドキュメントで案内されています。サンプルの hello_world を動かす手順は次のとおりです。

cp -r $IDF_PATH/examples/get-started/hello_world .
cd hello_world
idf.py set-target esp32s3
idf.py menuconfig          # 設定(hello_world では変えなくてよい)
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor

モニターは Ctrl+] で抜けます。ドキュメントに載っている、ESP32 での出力の例です。

Hello world!
Restarting in 10 seconds...
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision 1, 2 MB external flash
Minimum free heap size: 298968 bytes
Restarting in 9 seconds...
Restarting in 8 seconds...

ESP-IDF は C 言語で書きます。ポインタや malloc など C の基本は、関連記事「C言語とは|入門から環境構築・ポインタ・mallocまで実行例で解説」で扱っています。

よくあるエラーと直し方(書き込み失敗・ポートが見えない・ブラウンアウト)

この節では、エラー文から原因と直し方を引けます。esptool の出力は esptool 5.6.0 で実際に出たもの、そのほかは各ソース・公式ドキュメントにある文言です。

まず、どこで止まっているかで切り分けます。

flowchart TD
    A{ポートが<br>見える?} -->|いいえ| B[ケーブル<br>ドライバー]
    A -->|はい| C{書き込める?}
    C -->|いいえ| D[ダウンロード<br>モード]
    C -->|はい| E{再起動を<br>繰り返す?}
    E -->|はい| F[Brownout は電源<br>Guru はコード]
エラー文・症状 原因 直し方
[ポート]が灰色・ポートが出ない 充電専用ケーブル、ドライバーが無い データ通信のケーブルに替える。CP210x・CH9102 のドライバーを入れる
Could not open /dev/ttyUSB0, the port is busy or doesn't exist. ポート名の間違い、ほかのソフトが開いている ポートを選び直す。シリアルモニタ・mpremote を閉じる
[Errno 13] Permission denied と Hint: Try to add user into dialout or uucp group. Linux でポートの権限が無い sudo usermod -a -G dialout $USER の後にログインし直す
Failed to connect to ESP32: No serial data received. ボードがダウンロードモードにならない、別のポート BOOT を押しながら EN(リセット)を押して離す。ポートを確認
Wrong boot mode detected (0x13)! The chip needs to be in download mode. 通常の起動のまま書こうとした 同上。CoreS3 はリセットを約2秒長押しして緑の LED が点いたら離す
Invalid head of packet (0x65): Possible serial noise or corruption. 通常の起動のメッセージや雑音を受けた ダウンロードモードに入れる。速度を 115200 に下げる。ハブを外す
This chip is ESP32-S3, not ESP32. Wrong chip argument? 選んだボード(チップ)が違う [ボード]か --chip を合わせる
Failed uploading: uploading error: exit status 2 Arduino IDE から見た書き込みの失敗 上に出ている esptool のエラー文を読む
fatal error: WiFi.h: No such file or directory ボードに ESP32 以外(Arduino Uno など)を選んでいる [ボード]で ESP32・M5Stack の製品を選ぶ
Sketch too big と text section exceeds available space in board スケッチがパーティションに入らない [Partition Scheme]で Huge APP などを選ぶ
Brownout detector was triggered 電源の電圧が下がった(電流不足) 別の USB ポート・短く太いケーブル・十分な電源。電池の充電
Guru Meditation Error: Core 0 panic'ed (LoadProhibited) 無効なメモリを読んだ(NULL ポインタなど) 直前の処理・配列の範囲を見直す
シリアルモニタに何も出ない(S3・C3) USB CDC On Boot の設定と使う口が合っていない USB の口なら Enabled、UART の口なら Disabled

書き込みに失敗する(Failed to connect)

ボードが何も応答しないとき、esptool 5.6.0 は次のように出しました(応答しない疑似端末に向けて実行)。

esptool v5.6.0
Serial port /dev/pts/0:
Connecting.....

ERROR: A fatal error occurred: Failed to connect to ESP32: No serial data received.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html

通常の起動中の ESP32 が出すメッセージ(ets Jun 8 2016 00:22:57 で始まるブートログ)を流し続けた疑似端末では、Invalid head of packet (0x65) になりました。0x65 は、ブートログの最初の文字 e です。書き込みのとき ESP32 はダウンロードモード(書き込みを待つ状態)である必要があり、通常の起動のメッセージを受けると、このエラーになります。

Espressif の esptool のドキュメントでは、DevKit なら「Boot ボタンを押したまま EN ボタンを押す」とダウンロードモードに入るとされています。USB シリアルの変換チップを積むボードの多くは、esptool が DTR・RTS の信号で自動で切り替えます(esptool の既定の --before default-reset)。一方、CoreS3 のドキュメントでは「リセットボタンを約2秒長押しし、内部の緑色の LED が点いたら離す」と手動の方法が書かれています。arduino-esp32 のトラブルシューティングには、ほかに「充電専用でないケーブルに替える」「USB ハブを通さない」「書き込み中は GPIO0 を LOW に保つ」も挙がっています。

Wrong boot mode detected の文言は esptool 5.6.0 のソース(loader.py)にあり、括弧の中にはブートログの boot:0x13 の値が入ります。

ポートが見えない・開けない

ポートが無いときは、ポートを開く前に止まります。

ERROR: A fatal error occurred: Could not open /dev/ttyUSB0, the port is busy or doesn't exist.
([Errno 2] could not open port /dev/ttyUSB0: [Errno 2] No such file or directory: '/dev/ttyUSB0')

Hint: Check if the port is correct and ESP connected

Linux で権限が無いときです。疑似端末を USB シリアルと同じ権限(root:dialout の 660)にして、dialout に入っていないユーザーで esptool を実行しました(表示のデバイス名は /dev/ttyUSB0 に置き換えています)。

ERROR: A fatal error occurred: Could not open /dev/ttyUSB0, the port is busy or doesn't exist.
([Errno 13] could not open port /dev/ttyUSB0: [Errno 13] Permission denied: '/dev/ttyUSB0')

Hint: Try to add user into dialout or uucp group.

Linux・Mac では、ボードをつないだ後に ls /dev/ttyUSB* /dev/ttyACM*(Mac は ls /dev/cu.*)でポートが増えたかを見られます。パソコンから見えているポートは、pyserial でも一覧にできます。ボードを抜き差しして、増えたものがそのボードです。

python -m serial.tools.list_ports
/dev/ttyS0          
1 ports found

この出力の /dev/ttyS0 はパソコンのシリアルポートで、ESP32 ではありません。mpremote が別のプログラムに開かれたポートにつなごうとすると、mpremote: failed to access /dev/ttyUSB0 (it may be in use by another program) が出ます。Arduino IDE のシリアルモニタを開いたまま書き込もうとしたときも、ポートの取り合いになります。

Brownout detector was triggered(ブラウンアウト)

Brownout detector was triggered は、電源の電圧が安全な値より下がったため、ESP32 が自分でリセットしたことを示します。 ESP-IDF のドキュメント(Fatal Errors)によると、ブラウンアウトの検出はチップに入っていて既定で有効です。esptool のドキュメントは、ESP の 3.3V の電源に「連続で最大 70mA、ピークで 200〜300mA」程度を流せることを求めています。電流は一定ではなく、瞬間的なピークで電圧が下がると、このリセットが起きます。

  • 1USB の口を変えるパソコン本体の口に直接。バスパワーのハブ・前面の口は電流が足りないことがある
  • 2ケーブルを短く太いものに細く長いケーブルは電圧が下がる
  • 3電池を充電するM5Stack は電池が減ると電圧が下がる。USB をつないだまま試す
  • 4つないだ部品の電流を見積もるサーボ・LED テープ・モーターは別の電源にし、GND だけを共通にする

ESP-IDF では、検出の有無と電圧は CONFIG_ESP_BROWNOUT_DET と CONFIG_ESP_BROWNOUT_DET_LVL_SEL で設定します。検出を切るとリセットは止まりますが、電圧が足りない原因は残り、動作が不安定になります。

スケッチが大きすぎる

arduino-cli(Arduino IDE の裏で動くビルドの道具)のソースでは、プログラムの領域を超えると次の2つが出ます。日本語表示では1行目が「スケッチが大きすぎます。…には、小さくするコツが書いてあります。」です。

Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
text section exceeds available space in board

ESP32 では、[ツール]→[Partition Scheme]でアプリに使える領域を広げられます。M5CoreS3 の既定は 1.2MB APP で、「Huge APP (3MB No OTA/1MB SPIFFS)」にすると 3MB になります(OTA=無線でのプログラム更新は使えなくなる)。

ラズパイ・Arduinoとの違い

この節では、ESP32・M5Stack と、ラズパイ・Arduino の違いと選び方が分かります。

ラズパイ(Raspberry Pi 5 など)は Linux が動く小さなコンピューター、ESP32 と Arduino は OS を入れずに1つのプログラムを動かすマイコンです。 各社の公式ページで確認した代表的な製品の違いです(2026年10月22日時点)。

項目 ESP32-S3(M5Stack など) Arduino Uno R4 WiFi Raspberry Pi 5 Raspberry Pi Pico 2 W
種類 マイコン マイコン Linux のコンピューター マイコン
CPU Xtensa LX7 2コア 240MHz RA4M1(Cortex-M4)48MHz Cortex-A76 4コア 2.4GHz Cortex-M33 か RISC-V 2コア 150MHz
メモリ SRAM 512KB(+PSRAM の製品) SRAM 32KB・フラッシュ 256KB 1〜16GB SRAM 520KB・フラッシュ 4MB
無線 Wi-Fi 4・BLE 5 ESP32-S3 のモジュールで Wi-Fi・BLE Wi-Fi 5(デュアルバンド)・Bluetooth 5.0 Wi-Fi 4・Bluetooth 5.2
言語 C++・C・MicroPython C++(Arduino) Python・C など何でも C・C++・MicroPython

Arduino Uno R4 WiFi は、Wi-Fi と Bluetooth の部分に ESP32-S3 のモジュールを使っています(Arduino のドキュメント)。Raspberry Pi 5 は 5V/5A の USB-C 電源が推奨されています。

状況 選ぶもの 理由
センサーの値を Wi-Fi で送る・電池で動かす ESP32・M5Stack 無線を内蔵し、電源を入れてすぐ動く
画面・電池まで一体の試作をすぐ作る M5Stack ケース・画面・電池入り
カメラの画像処理・Web サーバー・データベース Raspberry Pi Linux と多くのメモリ
5V の部品・Arduino の教材をそのまま使う Arduino GPIO が 5V で動く(Uno R4 WiFi)
安く小さなマイコンを MicroPython で Pico 2 W・ESP32-C3 小型で、どちらも MicroPython が動く

組み合わせる使い方もあります。ESP32・M5Stack が部屋ごとに温度を測って送り、ラズパイがそれを受け取って保存・グラフ化する形です。ラズパイの始め方とモデルの違いは、関連記事「ラズパイ(Raspberry Pi)とは|始め方・モデル比較・Lチカを実例で解説」で扱っています。集めた値をグラフにする方法は、関連記事「Prometheus Grafana入門|監視構築とPromQL一覧」で扱っています。

日本でESP32・M5Stackを使うときの注意(技適)

この節では、日本で Wi-Fi・Bluetooth の機器を使うときの決まりが分かります。

日本では、電波を出す機器は、技術基準に適合していることを示す「技適マーク」が付いたものを使います。 技適を取っていない無線の機器は、原則として国内で使えません。総務省の資料によると、例外として「技適未取得機器を用いた実験等の特例制度」があり、電波法の技術基準に相当する基準に適合するなどの条件を満たし、総務大臣に届け出た上で、届出の日から180日以内に限って、Wi-Fi・Bluetooth などの機器を実験などに使えます。

確かめること 内容
製品やモジュールに技適の表示があるか 本体・モジュールのシールや、画面の表示、販売ページの記載
日本の正規の販売店で買ったか 国内向けの販売店は技適の有無を記載していることが多い
技適が無い機器を試すとき 特例制度の届出をして、180日以内・条件の範囲で使う

よくある質問

Q. M5Stackとは何ですか? A. ESP32 を使った開発キットのシリーズで、手のひらに乗る箱に画面・ボタン・電池などを入れた Core が代表です。センサーは Unit を Grove ケーブルで差すだけでつながります。

Q. ESP32とM5Stackの違いは? A. ESP32 はチップの名前、M5Stack はそのチップを使った製品です。プログラムは同じ Arduino・MicroPython で書け、違うのはピン番号や画面・電源の扱いです。

Q. 初心者はどのM5Stackを買えばいいですか? A. 画面に結果を出しながら学ぶなら CoreS3 か Core2、小さく安く始めるなら AtomS3R・AtomS3-Lite が候補です。中のチップは CoreS3・AtomS3 系が ESP32-S3、Core2 が ESP32 です。

Q. ESP32-S3とESP32-C3の違いは? A. S3 は Xtensa LX7 の2コア 240MHz で、画面・カメラ・音声向けです。C3 は RISC-V の1コア 160MHz で、小さく安いセンサー向けです。どちらも Wi-Fi 4 と Bluetooth LE を持ちます。

Q. ESP32は5GHzのWi-Fiにつながりますか? A. この記事の表のうち 5GHz に対応するのは ESP32-C5 だけです。ほかは 2.4GHz にしかつながらないので、ルーターの 2.4GHz の SSID を使います。

Q. ESP32のボードマネージャのURLは? A. 安定版は https://espressif.github.io/arduino-esp32/package_esp32_index.json です。M5Stack のパッケージを使う場合は https://static-cdn.m5stack.com/resource/arduino/package_m5stack_index.json です。

Q. ArduinoとESP32の違いは? A. Arduino はボードと開発環境のシリーズの名前で、ESP32 はチップの名前です。ESP32 は Arduino IDE でプログラムを書け、Wi-Fi と Bluetooth を内蔵しています。

Q. MicroPythonとArduinoはどちらがいいですか? A. 作例・ライブラリの多さと速さなら Arduino、REPL で1行ずつ試しながら Python で書くなら MicroPython です。M5Stack をブロックで始めるなら UiFlow2 もあります。

Q. ESP32に書き込めないときは? A. ケーブルがデータ通信用か、ポートが合っているか、ドライバーがあるか、ダウンロードモードに入っているかの順に確かめます。esptool のエラー文ごとの直し方は「よくあるエラーと直し方」の表にあります。

Q. Brownout detector was triggeredとは? A. 電源の電圧が下がって ESP32 がリセットしたという意味です。パソコン本体の USB の口に直接つなぐ、短く太いケーブルにする、電池を充電するなどで電源を強くします。

Q. ESP32とESP8266の違いは? A. ESP8266 は ESP32 より前のチップで、Bluetooth を持ちません。Espressif は製品ページで ESP8266 から ESP32-C2(ESP8684)への移行を勧めています。

Q. 海外で買ったESP32のボードを日本で使ってもいいですか? A. 技適マークの無い無線の機器は、原則として日本で使えません。試すときは総務省の特例制度の届出をして、180日以内・条件の範囲で使います。

まとめ

  • ESP32 は Espressif の Wi-Fi・Bluetooth 付きのマイコンチップ、M5Stack はそれを画面・電池・ケースと一体にした製品。プログラムは共通。
  • 迷ったら ESP32-S3。5GHz なら C5、Thread・Zigbee なら C6・H2、大きな画面なら P4、Bluetooth Classic なら初代 ESP32。
  • 開発環境は、最初は Arduino IDE(ボードマネージャーに espressif.github.io の URL)、ブロックなら UiFlow2、Python なら MicroPython、製品なら ESP-IDF。PlatformIO 公式の Arduino コアは 2.0.17。
  • Wi-Fi で値を送るときは、ESP32 からはパソコンの LAN の IP を指定し、HTTP の戻り値・例外で失敗を見分ける。
  • 書き込めないときは「ポート → ダウンロードモード → 速度」の順、Brownout は電源を疑う。
  • 日本では技適マークの付いた製品を使う。

参考・出典

確認日はいずれも 2026年10月22日です。

  • Espressif「SoCs」:https://www.espressif.com/en/products/socs
  • Espressif「ESP32-S3」:https://www.espressif.com/en/products/socs/esp32-s3
  • Espressif「ESP32-C3」:https://www.espressif.com/en/products/socs/esp32-c3
  • Espressif「ESP32-C5」:https://www.espressif.com/en/products/socs/esp32-c5
  • Espressif「ESP32-C6」:https://www.espressif.com/en/products/socs/esp32-c6
  • Espressif「ESP32-H2」:https://www.espressif.com/en/products/socs/esp32-h2
  • Espressif「ESP32-P4」:https://www.espressif.com/en/products/socs/esp32-p4
  • Espressif「ESP32 Series Datasheet」:https://documentation.espressif.com/esp32_datasheet_en.pdf
  • Arduino-ESP32「Getting Started」:https://docs.espressif.com/projects/arduino-esp32/en/latest/getting_started.html
  • Arduino-ESP32「Installing」:https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html
  • Arduino-ESP32「Troubleshooting」:https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html
  • GitHub「espressif/arduino-esp32 Releases」:https://github.com/espressif/arduino-esp32/releases
  • ESP-IDF「Get Started」:https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/index.html
  • ESP-IDF「Start a Project on Linux and macOS」:https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/linux-macos-start-project.html
  • ESP-IDF「Establish Serial Connection with ESP32-S3」:https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/get-started/establish-serial-connection.html
  • ESP-IDF「Fatal Errors」:https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/fatal-errors.html
  • esptool「Troubleshooting」:https://docs.espressif.com/projects/esptool/en/latest/esp32/troubleshooting.html
  • M5Stack「製品ガイド」:https://docs.m5stack.com/ja/learn/intro
  • M5Stack「Arduino ボードマネージャ」:https://docs.m5stack.com/ja/arduino/arduino_board
  • M5Stack「CoreS3 Arduino プログラム書き込み」:https://docs.m5stack.com/ja/arduino/m5cores3/program
  • M5Stack「StickC-Plus2 Arduino プログラム書き込み」:https://docs.m5stack.com/ja/arduino/m5stickc_plus2/program
  • M5Stack「Core2」:https://docs.m5stack.com/ja/core/core2
  • M5Stack「StickC-Plus2」:https://docs.m5stack.com/ja/core/M5StickC%20PLUS2
  • M5Stack「StickS3」:https://docs.m5stack.com/ja/core/StickS3
  • M5Stack「Unit ENV-III」:https://docs.m5stack.com/ja/unit/envIII
  • M5Stack「UiFlow2 Web IDE」:https://docs.m5stack.com/ja/uiflow2/uiflow_web
  • Arduino「Software」:https://www.arduino.cc/en/software
  • Arduino「UNO R4 WiFi」:https://docs.arduino.cc/hardware/uno-r4-wifi/
  • MicroPython「ESP32_GENERIC」:https://micropython.org/download/ESP32_GENERIC/
  • MicroPython「Quick reference for the ESP32」:https://docs.micropython.org/en/latest/esp32/quickref.html
  • PlatformIO「Espressif 32」:https://docs.platformio.org/en/latest/platforms/espressif32.html
  • GitHub「platformio/platform-espressif32 Releases」:https://github.com/platformio/platform-espressif32/releases
  • GitHub「pioarduino/platform-espressif32」:https://github.com/pioarduino/platform-espressif32
  • Raspberry Pi「Raspberry Pi 5」:https://www.raspberrypi.com/products/raspberry-pi-5/
  • Raspberry Pi「Raspberry Pi Pico 2」:https://www.raspberrypi.com/products/raspberry-pi-pico-2/
  • 総務省「技適未取得機器を用いた実験等の特例制度について」:https://www.soumu.go.jp/main_content/000987309.pdf

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「M5Stack・ESP32とは|種類・開発環境・始め方とエラーの直し方」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?