<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>江藤良樹の仕事は物づくり</title>
	<atom:link href="https://dlrow-design.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://dlrow-design.net</link>
	<description>技術は、経験から価値になる</description>
	<lastBuildDate>Mon, 24 Aug 2026 17:09:10 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.4</generator>
	<item>
		<title>ESP32とArduino UNOの違い｜どちらを選ぶ？</title>
		<link>https://dlrow-design.net/esp32%e3%81%a8arduino-uno%e3%81%ae%e9%81%95%e3%81%84%ef%bd%9c%e3%81%a9%e3%81%a1%e3%82%89%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25a8arduino-uno%25e3%2581%25ae%25e9%2581%2595%25e3%2581%2584%25ef%25bd%259c%25e3%2581%25a9%25e3%2581%25a1%25e3%2582%2589%25e3%2582%2592%25e9%2581%25b8%25e3%2581%25b6%25ef%25bc%259f</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Mon, 24 Aug 2026 15:30:59 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=847</guid>

					<description><![CDATA[<p>電子工作やマイコン開発を始めるとき、 「ESP32とArduino UNOは何が違う？」「初心者ならどちらを選べばいい？」「Arduino UNOからESP32へ移行するメリットは？」 と迷うことがあ ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%a8arduino-uno%e3%81%ae%e9%81%95%e3%81%84%ef%bd%9c%e3%81%a9%e3%81%a1%e3%82%89%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/">ESP32とArduino UNOの違い｜どちらを選ぶ？</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">電子工作やマイコン開発を始めるとき、</p>



<p class="wp-block-paragraph">「ESP32とArduino UNOは何が違う？」<br>「初心者ならどちらを選べばいい？」<br>「Arduino UNOからESP32へ移行するメリットは？」</p>



<p class="wp-block-paragraph">と迷うことがあります。</p>



<p class="wp-block-paragraph">どちらもArduino IDEから開発できるため似たようなマイコンボードに見えますが、中身は大きく異なります。</p>



<p class="wp-block-paragraph">ESP32はWi-FiやBluetoothを内蔵し、高い処理性能と大容量メモリを持っています。</p>



<p class="wp-block-paragraph">一方、Arduino UNO R3は8bit AVRマイコンを搭載したシンプルな構成で、5V系の電子工作でも扱いやすいボードです。</p>



<p class="wp-block-paragraph">単純にスペックだけを比較するとESP32が圧倒的に高性能ですが、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>高性能だからESP32を選べばよい</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">この記事ではESP32とArduino UNO R3について、</p>



<p class="wp-block-paragraph"><strong>CPU性能</strong><br><strong>メモリ容量</strong><br><strong>GPIO</strong><br><strong>3.3Vと5Vの違い</strong><br><strong>Wi-Fi・Bluetooth</strong><br><strong>ADCやPWM</strong><br><strong>開発環境</strong><br><strong>どちらを選べばよいか</strong></p>



<p class="wp-block-paragraph">を比較します。</p>



<p class="wp-block-paragraph">さらに、Arduino UNOからESP32へ移行するときに注意したいポイントも、回路設計とFirmwareの両面から解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">この記事ではArduino UNO R3と比較する</h2>



<p class="wp-block-paragraph">最初に比較対象を明確にしておきます。</p>



<p class="wp-block-paragraph">この記事で「Arduino UNO」と表記する場合、基本的には<strong>Arduino UNO R3</strong>を指します。</p>



<p class="wp-block-paragraph">UNO R3はATmega328Pを搭載した、長く使われているArduinoの代表的なボードです。</p>



<p class="wp-block-paragraph">現在はUNO R4 MinimaやUNO R4 WiFiも販売されていますが、UNO R4ではMCUがRenesas RA4M1へ変更され、32bit ARM Cortex-M4となっています。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>UNO R3
ATmega328P
8bit AVR
16MHz</code></pre>



<p class="wp-block-paragraph">に対して、</p>



<pre class="wp-block-code"><code>UNO R4
RA4M1
32bit Cortex-M4
48MHz</code></pre>



<p class="wp-block-paragraph">と、内部構成は大きく異なります。</p>



<p class="wp-block-paragraph">Arduino公式によるとUNO R4 MinimaはFlash 256KB、SRAM 32KBを搭載しながら、UNO R3との互換性を意識して5V動作を維持しています。</p>



<p class="wp-block-paragraph">したがって、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Arduino UNOはすべて8bit・16MHz</strong></p>
</blockquote>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">今回はESP32との違いが分かりやすく、広く使われてきた<strong>UNO R3を主な比較対象</strong>とします。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32とArduino UNO R3の違いを比較</h2>



<p class="wp-block-paragraph">まず代表的な仕様を比較してみます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>Arduino UNO R3</th><th>ESP32</th></tr></thead><tbody><tr><td>MCU</td><td>ATmega328P</td><td>ESP32</td></tr><tr><td>CPU</td><td>8bit AVR</td><td>32bit Xtensa LX6</td></tr><tr><td>CPU Clock</td><td>16MHz</td><td>最大240MHz</td></tr><tr><td>Core</td><td>Single Core</td><td>Dual Core</td></tr><tr><td>SRAM</td><td>2KB</td><td>520KB</td></tr><tr><td>Flash</td><td>32KB</td><td>Moduleに数MB搭載</td></tr><tr><td>I/O電圧</td><td>5V系</td><td>3.3V系</td></tr><tr><td>Wi-Fi</td><td>なし</td><td>2.4GHz Wi-Fi</td></tr><tr><td>Bluetooth</td><td>なし</td><td>Bluetooth Classic / BLE</td></tr><tr><td>EEPROM</td><td>1KB</td><td>専用EEPROMなし</td></tr><tr><td>ADC</td><td>6ch</td><td>複数ch</td></tr><tr><td>開発環境</td><td>Arduino IDEなど</td><td>Arduino / PlatformIO / ESP-IDFなど</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Arduino UNO R3はATmega328Pを搭載し、16MHzで動作します。Flash Memoryは32KB、SRAMは2KB、EEPROMは1KBです。</p>



<p class="wp-block-paragraph">一方、従来ESP32ではXtensa LX6 Dual Core CPUを搭載し、最大240MHzで動作します。内部SRAMは520KBあり、ESP32-WROOM-32Eでは数MBのSPI Flashを搭載したModuleが用意されています。</p>



<p class="wp-block-paragraph">数字だけを見ると、かなり大きな差があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">CPU性能はESP32が圧倒的に高い</h2>



<p class="wp-block-paragraph">Arduino UNO R3のATmega328Pは、8bit AVR CPUを16MHzで動作させます。</p>



<p class="wp-block-paragraph">一方ESP32は32bit CPUで、従来ESP32では最大240MHzのDual Core構成です。</p>



<p class="wp-block-paragraph">単純なClockだけでも、</p>



<pre class="wp-block-code"><code>Arduino UNO R3
16MHz

ESP32
最大240MHz</code></pre>



<p class="wp-block-paragraph">と大きな違いがあります。</p>



<p class="wp-block-paragraph">もちろんCPU性能はClock周波数だけで決まるものではありません。</p>



<p class="wp-block-paragraph">CPU Architectureも異なるため、</p>



<pre class="wp-block-code"><code>240 ÷ 16 = 15</code></pre>



<p class="wp-block-paragraph">だから「ESP32はUNOの15倍速い」と単純に比較することはできません。</p>



<p class="wp-block-paragraph">それでも、</p>



<ul class="wp-block-list">
<li>通信処理</li>



<li>複数Task</li>



<li>Display制御</li>



<li>JSON処理</li>



<li>Web Server</li>



<li>暗号化通信</li>



<li>Wi-Fi</li>



<li>Bluetooth</li>
</ul>



<p class="wp-block-paragraph">など、多くの処理を同時に行う用途ではESP32の処理能力が有利です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">メモリ容量は大きく違う</h2>



<p class="wp-block-paragraph">個人的には、CPU Clock以上に実際のFirmware開発で差を感じやすいのが<strong>RAM容量</strong>です。</p>



<p class="wp-block-paragraph">Arduino UNO R3のSRAMは、</p>



<p class="wp-block-paragraph"><strong>2KB</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">ESP32は、</p>



<p class="wp-block-paragraph"><strong>520KB SRAM</strong></p>



<p class="wp-block-paragraph">を搭載しています。</p>



<p class="wp-block-paragraph">UNO R3では2KBしかないため、大きな配列や文字列Bufferを使用すると、すぐにRAM容量を意識する必要があります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>char buffer&#91;1024];</code></pre>



<p class="wp-block-paragraph">だけでも1KBです。</p>



<p class="wp-block-paragraph">UNO R3ではSRAM全体の半分に相当します。</p>



<p class="wp-block-paragraph">一方ESP32では、より大きなBufferを扱えるため、</p>



<pre class="wp-block-code"><code>HTTP
JSON
Wi-Fi
BLE
Display
File System</code></pre>



<p class="wp-block-paragraph">などを組み合わせたApplicationを作りやすくなります。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32ならRAMを気にしなくてよい</strong></p>
</blockquote>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">Wi-FiやBluetooth Stackなどもメモリを使用するため、大規模なFirmwareではESP32でもHeapやStackの管理が必要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32にはWi-FiとBluetoothがある</h2>



<p class="wp-block-paragraph">ESP32を選ぶ大きな理由の一つが無線通信です。</p>



<p class="wp-block-paragraph">従来ESP32には、</p>



<p class="wp-block-paragraph"><strong>2.4GHz Wi-Fi</strong><br><strong>Bluetooth Classic</strong><br><strong>Bluetooth Low Energy（BLE）</strong></p>



<p class="wp-block-paragraph">が内蔵されています。</p>



<p class="wp-block-paragraph">Arduino UNO R3にはWi-FiやBluetooth機能はありません。</p>



<p class="wp-block-paragraph">そのためUNO R3で無線通信を行う場合は、</p>



<pre class="wp-block-code"><code>Arduino UNO
     │
Wi-Fi Module</code></pre>



<p class="wp-block-paragraph">など、外部Moduleを追加する必要があります。</p>



<p class="wp-block-paragraph">ESP32なら、</p>



<pre class="wp-block-code"><code>ESP32
├─ MCU
├─ Wi-Fi
└─ Bluetooth</code></pre>



<p class="wp-block-paragraph">が一つのSoCに統合されています。</p>



<p class="wp-block-paragraph">スマートフォン連携やCloud通信、IoT機器などではESP32を選ぶ大きなメリットになります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32は3.3V、Arduino UNO R3は5V</h2>



<p class="wp-block-paragraph">ここは<strong>Arduino UNOからESP32へ移行するときに特に注意したいポイント</strong>です。</p>



<p class="wp-block-paragraph">Arduino UNO R3は5V系のボードです。</p>



<p class="wp-block-paragraph">そのため5Vで動作するSensorやModuleを接続して使った経験がある人も多いでしょう。</p>



<p class="wp-block-paragraph">一方、ESP32は基本的に<strong>3.3V系</strong>です。</p>



<p class="wp-block-paragraph">ESP32-WROOM-32Eの推奨電源条件は3.0～3.6Vです。</p>



<p class="wp-block-paragraph">したがって、</p>



<pre class="wp-block-code"><code>Arduino UNOで使えた
      ↓
ESP32でも同じように接続</code></pre>



<p class="wp-block-paragraph">とは考えない方がよいでしょう。</p>



<p class="wp-block-paragraph">特に外部回路からGPIOへ入力される信号電圧には注意が必要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">5V信号をESP32 GPIOへそのまま入れない</h2>



<p class="wp-block-paragraph">たとえばUNO R3で、</p>



<pre class="wp-block-code"><code>5V Sensor
   │
   └── Signal → Arduino UNO</code></pre>



<p class="wp-block-paragraph">としていた回路があるとします。</p>



<p class="wp-block-paragraph">ESP32へ変更するときに、</p>



<pre class="wp-block-code"><code>5V Sensor
   │
   └── Signal → ESP32</code></pre>



<p class="wp-block-paragraph">とそのまま置き換えるのは避けます。</p>



<p class="wp-block-paragraph">外部デバイスが5V Logicを出力する場合は、</p>



<p class="wp-block-paragraph"><strong>抵抗分圧</strong><br><strong>Level Shifter</strong><br><strong>適切なInterface IC</strong></p>



<p class="wp-block-paragraph">などを使用し、ESP32側の入力条件に合わせます。</p>



<p class="wp-block-paragraph">「Arduino IDEで同じコードが動く」ということと、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Hardwareをそのまま接続できる</strong></p>
</blockquote>



<p class="wp-block-paragraph">ということは別です。</p>



<p class="wp-block-paragraph">これはUNOからESP32へ移行するときに非常に重要な違いです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">逆にESP32の3.3V出力で5V回路を動かせる？</h2>



<p class="wp-block-paragraph">今度は反対方向です。</p>



<p class="wp-block-paragraph">ESP32のGPIO HIGHは3.3V系です。</p>



<p class="wp-block-paragraph">5Vで動作する外部ICへ信号を入力するとき、</p>



<pre class="wp-block-code"><code>ESP32 3.3V HIGH
       ↓
5V IC Input</code></pre>



<p class="wp-block-paragraph">で正しくHIGHとして認識されるかは、<strong>接続先ICの入力電圧仕様</strong>によります。</p>



<p class="wp-block-paragraph">「5V電源で動いているICだから3.3VではHIGHにならない」とも、「3.3Vなら必ずHIGHになる」とも一律には言えません。</p>



<p class="wp-block-paragraph">確認すべきなのはDatasheetの、</p>



<p class="wp-block-paragraph"><strong>VIH：High-level Input Voltage</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">ESP32と5V系回路を接続するときは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>電源電圧ではなく、実際の入出力Logic Levelを確認する</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOの本数だけでは比較できない</h2>



<p class="wp-block-paragraph">Arduino UNO R3にはDigital I/Oが14本あり、そのうち6本をPWM出力として利用できます。またAnalog Inputは6本です。</p>



<p class="wp-block-paragraph">ESP32にはより多くのGPIOがあります。</p>



<p class="wp-block-paragraph">ただしESP32では、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>GPIO番号が存在する＝すべて自由に同じ用途で使える</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">ESP32ではPinによって、</p>



<ul class="wp-block-list">
<li>Input Only</li>



<li>Boot Strap</li>



<li>Flashとの接続</li>



<li>ADC</li>



<li>Touch Sensor</li>



<li>RTC GPIO</li>
</ul>



<p class="wp-block-paragraph">など、機能や制約が異なります。</p>



<p class="wp-block-paragraph">そのため単純に、</p>



<pre class="wp-block-code"><code>UNO：14本
ESP32：もっと多い

→ ESP32の方が全部自由に使える</code></pre>



<p class="wp-block-paragraph">とは考えない方がよいでしょう。</p>



<p class="wp-block-paragraph">ESP32では、<strong>必要なPeripheralと使用可能GPIOを確認してPin Assignmentを決める</strong>ことが重要です。</p>



<p class="wp-block-paragraph">ここは既存のESP32ピン関連の記事へ内部リンクできるポイントでもあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Arduino UNOにはEEPROMがある</h2>



<p class="wp-block-paragraph">Arduino UNO R3のATmega328Pには<strong>1KBのEEPROM</strong>があります。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>設定値
Calibration値
動作モード</code></pre>



<p class="wp-block-paragraph">など、電源OFF後も残したいデータをEEPROMへ保存できます。</p>



<p class="wp-block-paragraph">ESP32にはUNO R3と同じような専用EEPROMはありません。</p>



<p class="wp-block-paragraph">代わりに、Flash Memory上の**NVS（Non-Volatile Storage）**などを利用して設定値を保存できます。</p>



<p class="wp-block-paragraph">Arduino-ESP32ではPreferences LibraryからNVSを扱うこともできます。</p>



<p class="wp-block-paragraph">つまり、</p>



<pre class="wp-block-code"><code>Arduino UNO R3
     ↓
EEPROM

ESP32
     ↓
NVS / Preferences
     ↓
Flash</code></pre>



<p class="wp-block-paragraph">という違いがあります。</p>



<p class="wp-block-paragraph">ESP32へ移行するときに、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「EEPROMがないから設定を保存できない」</p>
</blockquote>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">保存方法が変わる、と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph">ここから、前回公開した「<a href="https://dlrow-design.net/esp32%e3%81%aeflash%e3%81%ab%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bd%9cnvs%e3%83%bbpreferences%e3%82%92%e8%a7%a3%e8%aa%ac/" target="_blank" rel="noopener" title="">ESP32のFlashにデータを保存する方法｜NVS・Preferencesを解説</a>」へ自然に内部リンクできます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ADCにも違いがある</h2>



<p class="wp-block-paragraph">SensorのAnalog値を読み取る場合も注意が必要です。</p>



<p class="wp-block-paragraph">Arduino UNO R3には10bit ADCがあり、Analog InputとしてA0～A5を利用できます。</p>



<p class="wp-block-paragraph">ESP32にもADCがありますが、UNOとまったく同じ感覚で使えるわけではありません。</p>



<p class="wp-block-paragraph">ESP32ではADC ChannelやAttenuation、入力範囲、ADC特性などを考える必要があります。</p>



<p class="wp-block-paragraph">またWi-Fi使用時など、使用するESP32やADC Unitによって注意すべき条件があります。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>analogRead();</code></pre>



<p class="wp-block-paragraph">という同じようなAPIが使えたとしても、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Hardware内部までArduino UNOと同じ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ではありません。</p>



<p class="wp-block-paragraph">特にSensorの測定精度が重要な用途では、使用するESP32シリーズのADC仕様を確認する必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「Arduino IDEが使える」＝Arduino UNOと同じではない</h2>



<p class="wp-block-paragraph">ESP32ではArduino Coreを利用することで、Arduino IDEからFirmwareを開発できます。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>pinMode();
digitalWrite();
digitalRead();
analogRead();
delay();</code></pre>



<p class="wp-block-paragraph">など、Arduino経験者には馴染みのあるAPIを使用できます。</p>



<p class="wp-block-paragraph">これはESP32へ移行しやすい大きなメリットです。</p>



<p class="wp-block-paragraph">しかし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Arduino IDEで書けるからArduino UNOと同じマイコン</strong></p>
</blockquote>



<p class="wp-block-paragraph">ではありません。</p>



<p class="wp-block-paragraph">CPU Architectureも違えば、</p>



<p class="wp-block-paragraph"><strong>Memory</strong><br><strong>Peripheral</strong><br><strong>Interrupt</strong><br><strong>Timer</strong><br><strong>ADC</strong><br><strong>GPIO</strong><br><strong>Wireless</strong></p>



<p class="wp-block-paragraph">なども異なります。</p>



<p class="wp-block-paragraph">Arduino APIは違いの一部を隠してくれますが、Hardwareそのものを同じにするものではありません。</p>



<p class="wp-block-paragraph">ここを理解しておくと、UNOからESP32へ移行したときのトラブルをかなり減らせます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PWMの仕組みも異なる</h2>



<p class="wp-block-paragraph">Arduino UNO R3では、Digital I/Oのうち6本をPWM出力として利用できます。</p>



<p class="wp-block-paragraph">Arduinoでは、</p>



<pre class="wp-block-code"><code>analogWrite(pin, value);</code></pre>



<p class="wp-block-paragraph">を使ったPWM制御に慣れている人も多いでしょう。</p>



<p class="wp-block-paragraph">ESP32でもPWM出力は可能ですが、内部の仕組みはUNO R3とは異なります。</p>



<p class="wp-block-paragraph">ESP32には<strong>LEDC（LED Control）Peripheral</strong>があり、PWMの周波数やDutyを設定して使用できます。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>Arduino UNO R3
    ↓
Timerを利用したPWM

ESP32
    ↓
LEDCなどを利用したPWM</code></pre>



<p class="wp-block-paragraph">という違いがあります。</p>



<p class="wp-block-paragraph">ESP32ではPWM周波数や分解能を用途に応じて設定できますが、<strong>周波数とDuty Resolutionには関係があります。</strong></p>



<p class="wp-block-paragraph">「分解能を高くして、周波数もいくらでも高くできる」というわけではありません。</p>



<p class="wp-block-paragraph">LEDの調光、Motor制御、Buzzerなど、用途に合わせてPWM条件を決める必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">UART・SPI・I2CはESP32の方が柔軟</h2>



<p class="wp-block-paragraph">外部Deviceとの通信では、</p>



<p class="wp-block-paragraph"><strong>UART</strong><br><strong>SPI</strong><br><strong>I2C</strong></p>



<p class="wp-block-paragraph">などをよく使用します。</p>



<p class="wp-block-paragraph">Arduino UNO R3にもこれらのPeripheralがありますが、ESP32ではより複雑なApplicationを想定した構成になっています。</p>



<p class="wp-block-paragraph">特にESP32には<strong>GPIO Matrix</strong>という仕組みがあります。</p>



<p class="wp-block-paragraph">Peripheral Signalを特定の固定Pinだけでなく、さまざまなGPIOへRoutingできるため、Pin Assignmentの自由度が高くなっています。</p>



<p class="wp-block-paragraph">たとえば基板設計で、</p>



<pre class="wp-block-code"><code>UART TX
UART RX
SPI MOSI
SPI MISO
SPI CLK</code></pre>



<p class="wp-block-paragraph">などを配置するとき、UNOより柔軟にPinを選択できる場合があります。</p>



<p class="wp-block-paragraph">これは自作基板では非常に便利です。</p>



<p class="wp-block-paragraph">ただし自由度が高い分、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>どのGPIOを使っても同じ</strong></p>
</blockquote>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">Boot Strap PinやInput Only Pin、Flashなどで使用されるPin、Peripheral固有の制約を確認する必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32の方が消費電力は大きい？</h2>



<p class="wp-block-paragraph">これは使い方によって変わります。</p>



<p class="wp-block-paragraph">ESP32は高性能CPUに加えてWi-FiやBluetoothを搭載しているため、無線通信中には相応の電流を消費します。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>単純な処理だけを常時実行するなら、ESP32の方が必ず省電力</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは言えません。</p>



<p class="wp-block-paragraph">一方、ESP32にはLight SleepやDeep Sleepなどの省電力機能があります。</p>



<p class="wp-block-paragraph">たとえばBattery駆動Sensorなら、</p>



<pre class="wp-block-code"><code>Deep Sleep
    ↓
TimerでWake-up
    ↓
Sensor測定
    ↓
Wi-Fi接続
    ↓
Data送信
    ↓
再びDeep Sleep</code></pre>



<p class="wp-block-paragraph">という動作ができます。</p>



<p class="wp-block-paragraph">つまり消費電力を比較するときは、</p>



<pre class="wp-block-code"><code>MCUの通常動作電流</code></pre>



<p class="wp-block-paragraph">だけを見るのではなく、</p>



<pre class="wp-block-code"><code>製品が1日を通して
どの状態で何時間動作するか</code></pre>



<p class="wp-block-paragraph">を見る必要があります。</p>



<p class="wp-block-paragraph">ESP32のDeep Sleepについては、既存の「<a href="https://dlrow-design.net/esp32-deep-sleep%e5%ae%8c%e5%85%a8%e3%82%ac%e3%82%a4%e3%83%89%ef%bd%9c%e6%b6%88%e8%b2%bb%e9%9b%bb%e5%8a%9b%e3%82%92%e5%a4%a7%e5%b9%85%e3%81%ab%e5%89%8a%e6%b8%9b%e3%81%99%e3%82%8b%e4%bd%bf%e3%81%84/" target="_blank" rel="noopener" title="">ESP32 Deep Sleep完全ガイド</a>」へ内部リンクできます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">リアルタイム制御ならArduino UNOの方がいい？</h2>



<p class="wp-block-paragraph">「ESP32はWi-FiやRTOSが動いているから、Arduino UNOの方がリアルタイム制御に向いている」</p>



<p class="wp-block-paragraph">という話を見かけることがあります。</p>



<p class="wp-block-paragraph">これは用途を分けて考える必要があります。</p>



<p class="wp-block-paragraph">Arduino UNO R3では、基本的に非常にシンプルなFirmware構成になります。</p>



<pre class="wp-block-code"><code>setup()
  ↓
loop()
  ↓
Interrupt</code></pre>



<p class="wp-block-paragraph">という構成を把握しやすく、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>いつ、どの処理が実行されるのか</strong></p>
</blockquote>



<p class="wp-block-paragraph">を比較的追いやすいというメリットがあります。</p>



<p class="wp-block-paragraph">一方ESP32では、FreeRTOSをベースとしたSoftware環境が使われ、Wi-FiやBluetoothなど複数の処理も動作します。</p>



<p class="wp-block-paragraph">そのため、厳密なTimingが必要な処理を、</p>



<pre class="wp-block-code"><code>delayMicroseconds();</code></pre>



<p class="wp-block-paragraph">だけに頼って実装するのではなく、</p>



<p class="wp-block-paragraph"><strong>Hardware Timer</strong><br><strong>Peripheral</strong><br><strong>Interrupt</strong><br><strong>Task Priority</strong></p>



<p class="wp-block-paragraph">などを適切に使う必要があります。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32ではリアルタイム制御ができない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">重要なのは、必要なTiming精度に応じてHardware PeripheralやSoftware構成を選ぶことです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Dual Coreなら処理能力が2倍になる？</h2>



<p class="wp-block-paragraph">従来ESP32はDual Core CPUを搭載しています。</p>



<p class="wp-block-paragraph">そこで、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「Arduino UNOがSingle Coreなら、ESP32はDual Coreだから単純に2倍？」</p>
</blockquote>



<p class="wp-block-paragraph">と思うかもしれません。</p>



<p class="wp-block-paragraph">これも単純には比較できません。</p>



<p class="wp-block-paragraph">Dual Coreだからといって、一つの処理が自動的に2倍の速度で実行されるわけではありません。</p>



<p class="wp-block-paragraph">ESP32では複数Taskを別Coreで実行する構成も可能ですが、Application側の設計が必要です。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>Task A
Sensor処理

Task B
通信処理</code></pre>



<p class="wp-block-paragraph">のように役割を分けることができます。</p>



<p class="wp-block-paragraph">一方、ESP32-C3やESP32-C5など、<strong>Single CoreのESP32シリーズも存在します。</strong></p>



<p class="wp-block-paragraph">したがって、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32＝すべてDual Core</strong></p>
</blockquote>



<p class="wp-block-paragraph">と覚えないようにしましょう。</p>



<p class="wp-block-paragraph">使用するESP32シリーズによってCPU構成は異なります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32はシリーズによる違いも大きい</h2>



<p class="wp-block-paragraph">ここもArduino UNOとの比較で注意したいところです。</p>



<p class="wp-block-paragraph">「ESP32」と一言で呼んでいますが、現在は複数のシリーズがあります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>ESP32
ESP32-S2
ESP32-S3
ESP32-C3
ESP32-C5
ESP32-C6
ESP32-H2</code></pre>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">シリーズによって、</p>



<p class="wp-block-paragraph"><strong>CPU Architecture</strong><br><strong>Core数</strong><br><strong>Wi-Fi</strong><br><strong>Bluetooth</strong><br><strong>USB</strong><br><strong>GPIO</strong><br><strong>Memory</strong></p>



<p class="wp-block-paragraph">などが異なります。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「ESP32を使いたい」</p>
</blockquote>



<p class="wp-block-paragraph">と決めた後にも、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>どのESP32シリーズを選ぶか</strong></p>
</blockquote>



<p class="wp-block-paragraph">という選定があります。</p>



<p class="wp-block-paragraph">ESP32を選んだ後に「どのシリーズを選べばよいか」で迷った場合は、「<a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/" target="_blank" rel="noopener" title="">ESP32シリーズの選び方</a>」で用途別に詳しく比較しています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Arduino UNOからESP32へコードはそのまま移植できる？</h2>



<p class="wp-block-paragraph">簡単なSketchであれば、そのまま動く場合もあります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>pinMode(2, OUTPUT);

digitalWrite(2, HIGH);
delay(1000);

digitalWrite(2, LOW);
delay(1000);</code></pre>



<p class="wp-block-paragraph">のような基本的なArduino APIを使ったコードなら、Pin番号などを修正するだけで移植できることがあります。</p>



<p class="wp-block-paragraph">しかしFirmwareが複雑になるほど注意点が増えます。</p>



<h3 class="wp-block-heading">1．GPIO番号をそのまま使わない</h3>



<p class="wp-block-paragraph">UNOで、</p>



<pre class="wp-block-code"><code>digitalWrite(13, HIGH);</code></pre>



<p class="wp-block-paragraph">としていたからといって、ESP32でもGPIO13を同じ用途にそのまま割り当てる必要はありません。</p>



<p class="wp-block-paragraph">使用するESP32 BoardやModuleのPin配置を確認して決めます。</p>



<h3 class="wp-block-heading">2．5V前提の外部回路を確認する</h3>



<p class="wp-block-paragraph">Firmwareが移植できてもHardwareが対応しているとは限りません。</p>



<p class="wp-block-paragraph">特に、</p>



<pre class="wp-block-code"><code>Sensor Output
UART
I2C Pull-up
SPI Device</code></pre>



<p class="wp-block-paragraph">などのLogic Voltageを確認します。</p>



<p class="wp-block-paragraph">UNO R3の5V環境からESP32の3.3V環境へ変更するときには、ここを最優先で確認した方がよいでしょう。</p>



<h3 class="wp-block-heading">3．Arduino LibraryがESP32に対応しているか確認する</h3>



<p class="wp-block-paragraph">Arduinoには非常に多くのLibraryがあります。</p>



<p class="wp-block-paragraph">しかし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Arduino用LibraryだからESP32でも必ず動く</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">Library内部で、</p>



<p class="wp-block-paragraph"><strong>AVR固有Register</strong><br><strong>Timer</strong><br><strong>Interrupt</strong><br><strong>Pin構成</strong></p>



<p class="wp-block-paragraph">などへ直接アクセスしている場合、ESP32ではそのまま使用できないことがあります。</p>



<p class="wp-block-paragraph">反対にArduino APIだけで実装されているLibraryなら、比較的移植しやすい場合があります。</p>



<p class="wp-block-paragraph">使用前にESP32対応状況を確認しましょう。</p>



<h3 class="wp-block-heading">4．EEPROM処理を見直す</h3>



<p class="wp-block-paragraph">UNO R3で、</p>



<pre class="wp-block-code"><code>EEPROM.read();
EEPROM.write();</code></pre>



<p class="wp-block-paragraph">などを使用していた場合、ESP32では保存方法を見直します。</p>



<p class="wp-block-paragraph">ESP32ではNVSを利用でき、Arduino-ESP32ならPreferences Libraryを使用できます。</p>



<p class="wp-block-paragraph">単にAPIを置き換えるだけでなく、</p>



<p class="wp-block-paragraph"><strong>保存するデータ</strong><br><strong>書き込み頻度</strong><br><strong>Factory Reset</strong><br><strong>Firmware Update後の互換性</strong></p>



<p class="wp-block-paragraph">まで整理すると、より製品向けの設計になります。</p>



<h3 class="wp-block-heading">5．TimerやInterrupt処理を確認する</h3>



<p class="wp-block-paragraph">Arduino UNO R3のATmega328PとESP32ではTimerやInterrupt Controllerの構造が異なります。</p>



<p class="wp-block-paragraph">そのため、AVR固有のRegisterを直接操作しているコードは、そのまま移植できません。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>TCCR1A
TCCR1B
OCR1A</code></pre>



<p class="wp-block-paragraph">などATmega328P固有Registerを操作している場合は、ESP32のPeripheralに合わせて実装し直す必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Arduino UNO R3を選ぶメリット</h2>



<p class="wp-block-paragraph">ここまで読むと、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「それならESP32を選べばいいのでは？」</p>
</blockquote>



<p class="wp-block-paragraph">と思うかもしれません。</p>



<p class="wp-block-paragraph">しかしUNO R3にもメリットがあります。</p>



<p class="wp-block-paragraph">まず構成が非常にシンプルです。</p>



<p class="wp-block-paragraph">8bit MCU、少ないMemory、基本的なPeripheralという構成なので、マイコンの基本を学ぶには分かりやすいBoardです。</p>



<p class="wp-block-paragraph">また5V系であるため、5V LogicのDeviceを扱う用途では接続しやすい場合があります。</p>



<p class="wp-block-paragraph">さらに長年使われてきたため、TutorialやLibrary、作例などの情報量も非常に多くあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32を選ぶメリット</h2>



<p class="wp-block-paragraph">ESP32の大きなメリットは、やはり機能の多さです。</p>



<p class="wp-block-paragraph"><strong>Wi-Fi</strong><br><strong>Bluetooth</strong><br><strong>高いCPU性能</strong><br><strong>大容量Memory</strong><br><strong>豊富なPeripheral</strong><br><strong>省電力機能</strong></p>



<p class="wp-block-paragraph">を一つのSoCで利用できます。</p>



<p class="wp-block-paragraph">特に、</p>



<pre class="wp-block-code"><code>スマートフォン連携
Cloud通信
Web Server
OTA
BLE
Wi-Fi Sensor
IoT Device</code></pre>



<p class="wp-block-paragraph">などを作るなら、ESP32は非常に有力な選択肢です。</p>



<p class="wp-block-paragraph">またArduino Frameworkから始めて、必要になればESP-IDFへ移行できることもメリットです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">初心者ならどちらを選ぶ？</h2>



<p class="wp-block-paragraph">「初心者にはArduino UNO」と一律に決める必要はないと思います。</p>



<p class="wp-block-paragraph">作りたいものによって選ぶ方がよいでしょう。</p>



<p class="wp-block-paragraph">LEDを点滅させたり、SwitchやSensorを接続したりして、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>まずマイコンの基本を学びたい</strong></p>
</blockquote>



<p class="wp-block-paragraph">のであればArduino UNO R3は分かりやすい選択です。</p>



<p class="wp-block-paragraph">一方、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>最初からWi-Fiやスマートフォン連携をやりたい</strong></p>
</blockquote>



<p class="wp-block-paragraph">のであれば、ESP32から始めても問題ありません。</p>



<p class="wp-block-paragraph">Arduino-ESP32を利用すれば、ESP32でもArduino IDEから、</p>



<pre class="wp-block-code"><code>setup()
loop()</code></pre>



<p class="wp-block-paragraph">という馴染みやすい形で開発できます。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>初心者だから低性能なマイコンを選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことではなく、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>作りたいものに必要な機能を持ったマイコンを選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">製品開発ならどちらを選ぶ？</h2>



<p class="wp-block-paragraph">製品開発では、さらに判断基準が増えます。</p>



<p class="wp-block-paragraph">単純な性能だけでなく、</p>



<p class="wp-block-paragraph"><strong>必要なI/O</strong><br><strong>通信Interface</strong><br><strong>消費電力</strong><br><strong>部品コスト</strong><br><strong>基板面積</strong><br><strong>供給性</strong><br><strong>開発環境</strong><br><strong>Software資産</strong><br><strong>認証</strong></p>



<p class="wp-block-paragraph">などを考えます。</p>



<p class="wp-block-paragraph">Wi-FiやBLEが必要ならESP32は非常に魅力的です。</p>



<p class="wp-block-paragraph">一方、無線通信が不要で、</p>



<pre class="wp-block-code"><code>Switch入力
Sensor入力
Relay制御
UART通信</code></pre>



<p class="wp-block-paragraph">程度のシンプルな制御なら、ESP32ほどの性能が必要ない場合もあります。</p>



<p class="wp-block-paragraph">その場合はArduino UNOそのものを製品へ搭載するという意味ではなく、<strong>要求仕様に合った別のMCUを選ぶ</strong>という判断もあります。</p>



<p class="wp-block-paragraph">製品設計では、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>高性能なMCUを選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことより、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>必要十分なMCUを選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32とArduino UNO R3、どちらを選ぶ？</h2>



<p class="wp-block-paragraph">用途別に整理すると、次のようになります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>用途・条件</th><th>ESP32</th><th>UNO R3</th></tr></thead><tbody><tr><td>Wi-Fiを使いたい</td><td>◎</td><td>△ 外部Module</td></tr><tr><td>Bluetoothを使いたい</td><td>◎</td><td>△ 外部Module</td></tr><tr><td>高い処理性能が必要</td><td>◎</td><td>△</td></tr><tr><td>大きなRAMが必要</td><td>◎</td><td>△</td></tr><tr><td>Web Serverを作りたい</td><td>◎</td><td>△</td></tr><tr><td>5V系回路を扱いたい</td><td>△ 要確認</td><td>◎</td></tr><tr><td>シンプルな電子工作</td><td>○</td><td>◎</td></tr><tr><td>マイコンの基本学習</td><td>○</td><td>◎</td></tr><tr><td>複数Taskを動かしたい</td><td>◎</td><td>△</td></tr><tr><td>Battery機器</td><td>○ 設計次第</td><td>○ 設計次第</td></tr><tr><td>IoT機器</td><td>◎</td><td>△</td></tr><tr><td>Arduino資産を使いたい</td><td>○</td><td>◎</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">単純な勝ち負けではなく、<strong>必要な機能によって選択する</strong>のがよいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Arduino UNOからESP32へ移行するときのチェックリスト</h2>



<p class="wp-block-paragraph">最後に、UNO R3からESP32へ移行するときに確認したいポイントをまとめます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>確認項目</th><th>内容</th></tr></thead><tbody><tr><td>Logic Voltage</td><td>5V → 3.3Vの違いを確認したか</td></tr><tr><td>GPIO</td><td>Pin番号・Pin機能を確認したか</td></tr><tr><td>Sensor</td><td>3.3V Logicに対応しているか</td></tr><tr><td>Pull-up</td><td>I2CなどのPull-up電圧を確認したか</td></tr><tr><td>ADC</td><td>入力条件・ADC特性を確認したか</td></tr><tr><td>PWM</td><td>ESP32のPWM方式に合わせたか</td></tr><tr><td>EEPROM</td><td>NVS / Preferences等へ変更したか</td></tr><tr><td>Library</td><td>ESP32対応を確認したか</td></tr><tr><td>Timer</td><td>AVR固有処理が残っていないか</td></tr><tr><td>Interrupt</td><td>ESP32向けに確認したか</td></tr><tr><td>Memory</td><td>ESP32だから無制限と考えていないか</td></tr><tr><td>Wi-Fi/BLE</td><td>通信時のCPU・Memory・電源負荷を考慮したか</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">特にHardwareでは、<strong>5Vと3.3Vの違い</strong>を最初に確認しましょう。</p>



<p class="wp-block-paragraph">SoftwareがBuildできたからといって、Hardwareまで互換とは限りません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜性能ではなく「何を作るか」で選ぶ</h2>



<p class="wp-block-paragraph">ESP32とArduino UNO R3は、どちらもArduino IDEから開発できますが、中身は大きく異なります。</p>



<p class="wp-block-paragraph">Arduino UNO R3は、</p>



<p class="wp-block-paragraph"><strong>8bit AVR</strong><br><strong>16MHz</strong><br><strong>SRAM 2KB</strong><br><strong>5V系</strong></p>



<p class="wp-block-paragraph">というシンプルな構成です。</p>



<p class="wp-block-paragraph">ESP32は、</p>



<p class="wp-block-paragraph"><strong>32bit CPU</strong><br><strong>高いClock周波数</strong><br><strong>大容量Memory</strong><br><strong>Wi-Fi</strong><br><strong>Bluetooth</strong></p>



<p class="wp-block-paragraph">など、多くの機能を搭載しています。</p>



<p class="wp-block-paragraph">性能だけを見ればESP32が大きく上回ります。</p>



<p class="wp-block-paragraph">しかし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32の方が高性能だから、常にESP32を選ぶべき</strong></p>
</blockquote>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">シンプルな電子工作や5V系回路の扱いやすさを重視するなら、Arduino UNO R3にもメリットがあります。</p>



<p class="wp-block-paragraph">一方、</p>



<p class="wp-block-paragraph"><strong>Wi-Fiを使いたい</strong><br><strong>BLEを使いたい</strong><br><strong>Web通信をしたい</strong><br><strong>より複雑なFirmwareを動かしたい</strong></p>



<p class="wp-block-paragraph">のであれば、ESP32が有力です。</p>



<p class="wp-block-paragraph">そしてArduino UNOからESP32へ移行するときに最も注意したいのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>同じArduino APIが使えることと、Hardwareが互換であることは別</strong></p>
</blockquote>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">GPIO電圧、Pin機能、ADC、Timer、EEPROMなど、それぞれの違いを確認して移植する必要があります。</p>



<p class="wp-block-paragraph">マイコン選定ではスペック表の数字だけを見るのではなく、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>自分が何を作りたいのか</strong></p>
</blockquote>



<p class="wp-block-paragraph">から必要な機能を決めることが、最も重要です。</p>The post <a href="https://dlrow-design.net/esp32%e3%81%a8arduino-uno%e3%81%ae%e9%81%95%e3%81%84%ef%bd%9c%e3%81%a9%e3%81%a1%e3%82%89%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/">ESP32とArduino UNOの違い｜どちらを選ぶ？</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32のFlashにデータを保存する方法｜NVS・Preferencesを解説</title>
		<link>https://dlrow-design.net/esp32%e3%81%aeflash%e3%81%ab%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bd%9cnvs%e3%83%bbpreferences%e3%82%92%e8%a7%a3%e8%aa%ac/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25aeflash%25e3%2581%25ab%25e3%2583%2587%25e3%2583%25bc%25e3%2582%25bf%25e3%2582%2592%25e4%25bf%259d%25e5%25ad%2598%25e3%2581%2599%25e3%2582%258b%25e6%2596%25b9%25e6%25b3%2595%25ef%25bd%259cnvs%25e3%2583%25bbpreferences%25e3%2582%2592%25e8%25a7%25a3%25e8%25aa%25ac</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sun, 23 Aug 2026 12:29:49 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=840</guid>

					<description><![CDATA[<p>ESP32でプログラムを作っていると、 「電源を切っても設定値を残したい」「Wi-Fiの設定を保存したい」「最後に設定した値を次回起動時にも使いたい」 という場面があります。 通常の変数はRAM上に保 ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%aeflash%e3%81%ab%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bd%9cnvs%e3%83%bbpreferences%e3%82%92%e8%a7%a3%e8%aa%ac/">ESP32のFlashにデータを保存する方法｜NVS・Preferencesを解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32でプログラムを作っていると、</p>



<p class="wp-block-paragraph">「電源を切っても設定値を残したい」<br>「Wi-Fiの設定を保存したい」<br>「最後に設定した値を次回起動時にも使いたい」</p>



<p class="wp-block-paragraph">という場面があります。</p>



<p class="wp-block-paragraph">通常の変数はRAM上に保存されるため、ESP32の電源をOFFすると内容は失われます。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>int temperature = 25;</code></pre>



<p class="wp-block-paragraph">と変数へ値を保存しても、これは電源OFF後まで保持される設定データにはなりません。</p>



<p class="wp-block-paragraph">そこでESP32では、Flash Memoryへデータを保存する方法として**NVS（Non-Volatile Storage）**を利用できます。</p>



<p class="wp-block-paragraph">Arduino-ESP32を使用している場合には、NVSを扱いやすくした<strong>Preferences Library</strong>も用意されています。EspressifはPreferencesを従来のArduino EEPROM Libraryに代わる方法として案内しています。</p>



<p class="wp-block-paragraph">この記事では、</p>



<p class="wp-block-paragraph"><strong>NVSとは何か</strong><br><strong>Preferencesとの違い</strong><br><strong>実際に値を保存・読み出す方法</strong><br><strong>Flashの書き換え寿命</strong><br><strong>NVSへ保存するのに向いているデータ</strong></p>



<p class="wp-block-paragraph">まで解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">なぜ普通の変数ではデータを保存できない？</h2>



<p class="wp-block-paragraph">まずESP32のメモリについて簡単に整理します。</p>



<p class="wp-block-paragraph">プログラム実行中に使用する変数の多くはRAM上に置かれます。</p>



<p class="wp-block-paragraph">イメージとしては、</p>



<pre class="wp-block-code"><code>ESP32

RAM
├─ 変数
├─ Stack
└─ Heap

Flash
├─ Firmware
├─ NVS
└─ File Systemなど</code></pre>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">RAMは高速に読み書きできますが、電源がなくなると内容が失われる<strong>揮発性メモリ</strong>です。</p>



<p class="wp-block-paragraph">一方、Flash Memoryは電源を切っても内容を保持できます。</p>



<p class="wp-block-paragraph">したがって、</p>



<pre class="wp-block-code"><code>電源ON
  ↓
設定値を変更
  ↓
電源OFF
  ↓
次回起動
  ↓
前回の設定値を復元</code></pre>



<p class="wp-block-paragraph">という動作を実現するには、設定値を不揮発メモリへ保存する必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32のNVSとは？</h2>



<p class="wp-block-paragraph">NVSは<strong>Non-Volatile Storage</strong>の略です。</p>



<p class="wp-block-paragraph">ESP-IDFに用意されている、Flash Memory上へデータを保存するための仕組みです。</p>



<p class="wp-block-paragraph">NVSではデータを、</p>



<pre class="wp-block-code"><code>Key → Value</code></pre>



<p class="wp-block-paragraph">という<strong>Key-Value形式</strong>で管理します。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>"volume" → 8
"temp"   → 25
"mode"   → 1</code></pre>



<p class="wp-block-paragraph">というように、データへ名前を付けて保存できます。</p>



<p class="wp-block-paragraph">さらにNVSでは<strong>Namespace</strong>を使ってKeyをグループ分けできます。</p>



<pre class="wp-block-code"><code>Namespace : "settings"

├─ "volume" → 8
├─ "temp"   → 25
└─ "mode"   → 1</code></pre>



<p class="wp-block-paragraph">別のNamespaceなら、同じKey名を使用しても衝突しません。ESP-IDFのNVS APIでも、<code>nvs_open()</code>でNamespaceを指定し、取得したHandleを使って<code>nvs_get_*()</code>や<code>nvs_set_*()</code>などを操作する構造になっています。</p>



<p class="wp-block-paragraph">製品Firmwareでも、</p>



<pre class="wp-block-code"><code>"system"
"network"
"sensor"
"user"</code></pre>



<p class="wp-block-paragraph">など、用途ごとにデータを整理できます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSにはどんなデータを保存できる？</h2>



<p class="wp-block-paragraph">NVSでは整数だけでなく、複数種類のデータを扱えます。</p>



<p class="wp-block-paragraph">代表的には、</p>



<ul class="wp-block-list">
<li>8～64bitの整数</li>



<li>String</li>



<li>Blob（Binary Data）</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">Arduino-ESP32のPreferencesでは、さらにAPIとして、</p>



<pre class="wp-block-code"><code>putBool()
putInt()
putUInt()
putFloat()
putDouble()
putString()
putBytes()</code></pre>



<p class="wp-block-paragraph">などが用意されています。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>温度設定値
音量
動作モード
Calibration値
初期設定完了フラグ
Wi-Fi関連の設定</code></pre>



<p class="wp-block-paragraph">など、小さな設定値を保存する用途に向いています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSとPreferencesは何が違う？</h2>



<p class="wp-block-paragraph">ここは混同しやすいポイントです。</p>



<p class="wp-block-paragraph"><strong>NVSとPreferencesは別々の保存媒体ではありません。</strong></p>



<p class="wp-block-paragraph">Arduino-ESP32のPreferences Libraryは、内部でESP32のNVSを利用しています。Espressifの公式Arduino-ESP32 Documentationでも、PreferencesはESP32のNVSを利用してデータを保存すると説明されています。</p>



<p class="wp-block-paragraph">関係を簡単にすると、</p>



<pre class="wp-block-code"><code>Arduino-ESP32
     │
Preferences
     │
    NVS
     │
Flash Memory</code></pre>



<p class="wp-block-paragraph">となります。</p>



<p class="wp-block-paragraph">一方、ESP-IDFを直接使用する場合は、</p>



<pre class="wp-block-code"><code>ESP-IDF
   │
 NVS API
   │
Flash Memory</code></pre>



<p class="wp-block-paragraph">という使い方ができます。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>PreferencesはNVSをArduinoから扱いやすくしたAPI</strong></p>
</blockquote>



<p class="wp-block-paragraph">と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ArduinoでPreferencesを使って値を保存する</h2>



<p class="wp-block-paragraph">Arduino-ESP32では、Preferences Libraryを使用すると比較的簡単にNVSへ値を保存できます。</p>



<p class="wp-block-paragraph">まず、</p>



<pre class="wp-block-code"><code>#include &lt;Preferences.h&gt;

Preferences preferences;</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">そしてNamespaceを開きます。</p>



<pre class="wp-block-code"><code>preferences.begin("settings", false);</code></pre>



<p class="wp-block-paragraph"><code>"settings"</code>がNamespace名です。</p>



<p class="wp-block-paragraph">第2引数の<code>false</code>はRead/Write Modeを意味します。<code>true</code>を指定するとRead Onlyになります。</p>



<p class="wp-block-paragraph">値を保存する場合は、</p>



<pre class="wp-block-code"><code>preferences.putInt("temp", 25);</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">これで、</p>



<pre class="wp-block-code"><code>Namespace : settings
Key       : temp
Value     : 25</code></pre>



<p class="wp-block-paragraph">として保存できます。</p>



<p class="wp-block-paragraph">処理が終わったら、</p>



<pre class="wp-block-code"><code>preferences.end();</code></pre>



<p class="wp-block-paragraph">でNamespaceを閉じます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">保存した値を読み出してみる</h2>



<p class="wp-block-paragraph">次回起動時には、保存した値を読み出せます。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>preferences.begin("settings", true);

int temperature = preferences.getInt("temp", 20);

preferences.end();</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">ここでは<code>"temp"</code>というKeyから値を取得しています。</p>



<p class="wp-block-paragraph">第2引数の<code>20</code>は、Keyが存在しなかった場合に返すDefault値です。</p>



<p class="wp-block-paragraph">つまり初回起動などでまだデータが保存されていなくても、</p>



<pre class="wp-block-code"><code>保存済み
   ↓
保存値を使用

未保存
   ↓
Default値を使用</code></pre>



<p class="wp-block-paragraph">という処理にできます。</p>



<p class="wp-block-paragraph">PreferencesではNamespaceをRead Onlyで開いても値の読み出しは可能です。値を書き込む場合にはRead/Write Modeで開く必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">電源OFFしても本当に値は残る？</h2>



<p class="wp-block-paragraph">残ります。</p>



<p class="wp-block-paragraph">PreferencesはESP32のNVSを利用しているため、保存したデータはRestartや電源断をまたいで保持されます。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>初回起動
temp = 20

   ↓

ユーザー操作
temp = 28

   ↓
NVSへ保存

   ↓
電源OFF

   ↓
再び電源ON

   ↓
NVSから読み出す

temp = 28</code></pre>



<p class="wp-block-paragraph">という動作を作れます。</p>



<p class="wp-block-paragraph">設定値を保存する機器では非常によく使う処理です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">初回起動かどうかを判定することもできる</h2>



<p class="wp-block-paragraph">製品では、</p>



<p class="wp-block-paragraph"><strong>工場出荷状態</strong></p>



<p class="wp-block-paragraph">と</p>



<p class="wp-block-paragraph"><strong>一度設定された状態</strong></p>



<p class="wp-block-paragraph">を区別したいことがあります。</p>



<p class="wp-block-paragraph">Preferencesでは<code>isKey()</code>を使って、特定のKeyが存在するか確認できます。Espressifの公式Tutorialでも、この方法を利用して初回起動時にDefault設定を作成する例が紹介されています。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>preferences.begin("settings", false);

if (!preferences.isKey("init")) {
    preferences.putInt("temp", 25);
    preferences.putBool("init", true);
}

preferences.end();</code></pre>



<p class="wp-block-paragraph">とすれば、<code>"init"</code>が存在しない場合だけ初期値を書き込めます。</p>



<p class="wp-block-paragraph">これを利用すると、</p>



<pre class="wp-block-code"><code>初回起動
   ↓
Factory Defaultを書き込む
   ↓
init = true

以降の起動
   ↓
保存済み設定を読み出す</code></pre>



<p class="wp-block-paragraph">という構成にできます。</p>



<p class="wp-block-paragraph">製品Firmwareでは使いやすい方法です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSは何でも保存する場所ではない</h2>



<p class="wp-block-paragraph">ここからが重要です。</p>



<p class="wp-block-paragraph">NVSは便利ですが、<strong>Flashへ保存できるからといって、あらゆるデータをNVSへ書けばよいわけではありません。</strong></p>



<p class="wp-block-paragraph">EspressifはNVSについて、主に<strong>頻繁には変化しないConfiguration Dataの保存</strong>を推奨しています。反対に、頻繁かつ大量に更新するLogging用途などには適さないと説明しています。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>○ 向いている

温度設定値
Wi-Fi設定
Calibration値
動作モード
ユーザー設定
初期化済みフラグ</code></pre>



<p class="wp-block-paragraph">に対して、</p>



<pre class="wp-block-code"><code>△～× 向いていない

高速Sampling Data
毎秒更新するLog
大量の画像Data
大きなFile
連続的な履歴Data</code></pre>



<p class="wp-block-paragraph">という違いがあります。</p>



<p class="wp-block-paragraph">Arduino-ESP32のPreferences Documentationでも、多数の小さな値の保存に適しており、大量データならLittleFSなどのFile Systemを検討するよう案内されています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Flashには書き換え寿命がある</h2>



<p class="wp-block-paragraph">NVSの保存先であるSPI NOR Flashには、無制限にErase/Writeできるわけではありません。</p>



<p class="wp-block-paragraph">そのため、</p>



<pre class="wp-block-code"><code>void loop()
{
    preferences.putInt("temp", temperature);
}</code></pre>



<p class="wp-block-paragraph">のように、Loopを回るたびにFlashへ書き込む設計は避けます。</p>



<p class="wp-block-paragraph">NVSにはFlashの特定領域だけへ書き込みが集中しないよう、内部にWear Levelingの仕組みがあります。EspressifのFAQでも、NVSには独自のErase/Write balancing mechanismが実装されていることが説明されています。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wear Levelingがある＝何回でも書き込んでよい</strong></p>
</blockquote>



<p class="wp-block-paragraph">ではありません。</p>



<p class="wp-block-paragraph">FlashそのものにはErase Cycleの寿命があります。</p>



<p class="wp-block-paragraph">したがってFirmware側でも、不要な書き込みを減らす設計が重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「値が変わったときだけ保存する」</h2>



<p class="wp-block-paragraph">基本的な考え方はシンプルです。</p>



<p class="wp-block-paragraph">たとえば温度設定値なら、</p>



<pre class="wp-block-code"><code>現在値 25℃
   ↓
ユーザーが28℃へ変更
   ↓
RAM上では28℃
   ↓
設定確定
   ↓
NVSへ28℃を保存</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">毎Loop、</p>



<pre class="wp-block-code"><code>25 → 保存
25 → 保存
25 → 保存
25 → 保存
25 → 保存</code></pre>



<p class="wp-block-paragraph">とする必要はありません。</p>



<p class="wp-block-paragraph">設定値が変化したときや、ユーザーが設定を確定したタイミングなど、<strong>意味のあるタイミングだけFlashへ保存する</strong>方が合理的です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSは電源断にも配慮されている</h2>



<p class="wp-block-paragraph">製品では、Flashへ書き込んでいる途中で突然電源が切れる可能性もあります。</p>



<p class="wp-block-paragraph">NVSはこの点も考慮されており、Espressifは<strong>突然のPower Lossに対する保護とAtomic Update</strong>をNVSの特徴として挙げています。</p>



<p class="wp-block-paragraph">これは設定値を扱ううえで大きなメリットです。</p>



<p class="wp-block-paragraph">ただし、これも、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「いつ電源を切ってもApplication側では何も考えなくてよい」</p>
</blockquote>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">製品全体としては、電源断の可能性、保存するタイミング、設定値の整合性などを考える必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDFでNVSへデータを保存する</h2>



<p class="wp-block-paragraph">Arduino-ESP32ではPreferencesを利用しましたが、ESP-IDFではNVS APIを直接使用できます。</p>



<p class="wp-block-paragraph">基本的な流れは、</p>



<pre class="wp-block-code"><code>NVSを初期化
    ↓
Namespaceを開く
    ↓
値を読み書き
    ↓
Commit
    ↓
Handleを閉じる</code></pre>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">まずNVS Flashを初期化します。</p>



<pre class="wp-block-code"><code>#include "nvs_flash.h"
#include "nvs.h"

esp_err_t ret = nvs_flash_init();

if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
    ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {

    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
}

ESP_ERROR_CHECK(ret);</code></pre>



<p class="wp-block-paragraph">NVS Partitionに空きPageがない場合や、現在のNVS Libraryと互換性のない形式が検出された場合などを考慮した、ESP-IDFで一般的に使われる初期化方法です。EspressifのNVS API Documentationでも同様の初期化処理が示されています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Namespaceを開く</h2>



<p class="wp-block-paragraph">NVSを初期化したら、<code>nvs_open()</code>でNamespaceを開きます。</p>



<pre class="wp-block-code"><code>nvs_handle_t handle;

ESP_ERROR_CHECK(
    nvs_open("settings", NVS_READWRITE, &amp;handle)
);</code></pre>



<p class="wp-block-paragraph">ここでは、</p>



<pre class="wp-block-code"><code>Namespace = settings
Mode      = Read / Write</code></pre>



<p class="wp-block-paragraph">として開いています。</p>



<p class="wp-block-paragraph">読み出しだけでよければ、</p>



<pre class="wp-block-code"><code>NVS_READONLY</code></pre>



<p class="wp-block-paragraph">を指定できます。</p>



<p class="wp-block-paragraph">Preferencesの、</p>



<pre class="wp-block-code"><code>preferences.begin("settings", false);</code></pre>



<p class="wp-block-paragraph">と考え方はよく似ています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDFで整数を保存する</h2>



<p class="wp-block-paragraph">たとえば温度設定値<code>25</code>を保存する場合は、</p>



<pre class="wp-block-code"><code>int32_t temperature = 25;

ESP_ERROR_CHECK(
    nvs_set_i32(handle, "temp", temperature)
);</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">ただし、ESP-IDFではここで終わりではありません。</p>



<p class="wp-block-paragraph">重要なのが、</p>



<pre class="wp-block-code"><code>ESP_ERROR_CHECK(
    nvs_commit(handle)
);</code></pre>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">NVS APIでは、<code>nvs_set_*()</code>を実行しただけでは変更内容が必ずしもNon-Volatile Storageへ確定しているとは限りません。<code>nvs_commit()</code>を呼び出して変更を確定します。</p>



<p class="wp-block-paragraph">最後に、</p>



<pre class="wp-block-code"><code>nvs_close(handle);</code></pre>



<p class="wp-block-paragraph">でHandleを閉じます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDFで保存値を読み出す</h2>



<p class="wp-block-paragraph">保存した値は<code>nvs_get_*()</code>で取得できます。</p>



<pre class="wp-block-code"><code>int32_t temperature = 20;

esp_err_t err =
    nvs_get_i32(handle, "temp", &amp;temperature);

if (err == ESP_ERR_NVS_NOT_FOUND) {
    temperature = 20;
}</code></pre>



<p class="wp-block-paragraph">この例では、<code>"temp"</code>が存在しなければDefault値として20を使用しています。</p>



<p class="wp-block-paragraph">Preferencesの、</p>



<pre class="wp-block-code"><code>preferences.getInt("temp", 20);</code></pre>



<p class="wp-block-paragraph">ではDefault値まで一つのAPIで指定できましたが、ESP-IDFでは戻り値を確認して処理できます。</p>



<p class="wp-block-paragraph">少しコード量は増えますが、</p>



<p class="wp-block-paragraph"><strong>Keyが存在しない</strong><br><strong>データ型が違う</strong><br><strong>その他のErrorが発生した</strong></p>



<p class="wp-block-paragraph">といった状態をApplication側で明確に扱えます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">nvs_commit()を忘れない</h2>



<p class="wp-block-paragraph">ESP-IDFでNVSを初めて使うときに注意したいのが<code>nvs_commit()</code>です。</p>



<p class="wp-block-paragraph">基本的には、</p>



<pre class="wp-block-code"><code>nvs_set_xxx()
     ↓
nvs_set_xxx()
     ↓
nvs_set_xxx()
     ↓
nvs_commit()</code></pre>



<p class="wp-block-paragraph">という流れで変更内容を確定できます。</p>



<p class="wp-block-paragraph">たとえば、</p>



<p class="wp-block-paragraph">ESP_ERROR_CHECK(<br>nvs_set_i32(handle, &#8220;temp&#8221;, 25)<br>);</p>



<p class="wp-block-paragraph">ESP_ERROR_CHECK(<br>nvs_set_u8(handle, &#8220;mode&#8221;, 1)<br>);</p>



<p class="wp-block-paragraph">ESP_ERROR_CHECK(<br>nvs_commit(handle)<br>);</p>



<p class="wp-block-paragraph">のように複数項目を更新したあと、Commitすることもできます。</p>



<p class="wp-block-paragraph">ここでも、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>1回値を変更するたびに、何も考えずFlashへ書き込む</strong></p>
</blockquote>



<p class="wp-block-paragraph">のではなく、Applicationとして設定が確定するタイミングを考えることが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PreferencesとESP-IDF NVS APIはどちらを使う？</h2>



<p class="wp-block-paragraph">どちらを使うかは、使用しているFrameworkによって考えると分かりやすいです。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>開発環境</th><th>選択肢</th></tr></thead><tbody><tr><td>Arduino IDE + Arduino-ESP32</td><td>Preferences</td></tr><tr><td>PlatformIO + Arduino</td><td>Preferences</td></tr><tr><td>ESP-IDF</td><td>NVS API</td></tr><tr><td>ESP-IDF + Arduino Component</td><td>用途に応じて選択</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Arduino Frameworkで小さな設定値を保存するなら、Preferencesは非常に扱いやすい方法です。</p>



<p class="wp-block-paragraph">一方ESP-IDFでは、NVS APIを直接使うことでError処理やPartitionなどを含めて、より細かく制御できます。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>PreferencesとNVSのどちらが高性能か</strong></p>
</blockquote>



<p class="wp-block-paragraph">という比較ではありません。</p>



<p class="wp-block-paragraph">Preferences自体がNVSを利用しているため、<strong>使用しているFrameworkに適したInterfaceを選ぶ</strong>と考える方が自然です。</p>



<p class="wp-block-paragraph">Arduino IDE・PlatformIO・ESP-IDFの違いや、どの開発環境を選べばよいかについては「<a href="https://dlrow-design.net/esp32%e3%81%ae%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83%e3%82%92%e6%af%94%e8%bc%83%ef%bd%9carduino-ide%e3%83%bbplatformio%e3%83%bbesp-idf%e3%81%af%e3%81%a9%e3%82%8c%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/" target="_blank" rel="noopener" title="">ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？</a>」で詳しく解説しています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSとLittleFSはどう使い分ける？</h2>



<p class="wp-block-paragraph">ESP32ではFlashへデータを保存する方法として、NVS以外にLittleFSなどのFile Systemを利用する方法もあります。</p>



<p class="wp-block-paragraph">大まかな使い分けは、</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>データ</th><th>向いている方法</th></tr></thead><tbody><tr><td>設定値</td><td>NVS</td></tr><tr><td>動作モード</td><td>NVS</td></tr><tr><td>Calibration値</td><td>NVS</td></tr><tr><td>Flag</td><td>NVS</td></tr><tr><td>少量の文字列</td><td>NVS</td></tr><tr><td>大きな設定File</td><td>LittleFSなど</td></tr><tr><td>HTML / CSS</td><td>LittleFSなど</td></tr><tr><td>Fileとして扱いたいData</td><td>LittleFSなど</td></tr><tr><td>大量のLog</td><td>用途に適したFile System等を検討</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph">NVSはKeyを指定して、</p>



<pre class="wp-block-code"><code>"temp" → 25</code></pre>



<p class="wp-block-paragraph">のように扱う用途が得意です。</p>



<p class="wp-block-paragraph">一方、</p>



<pre class="wp-block-code"><code>/config/settings.json</code></pre>



<p class="wp-block-paragraph">のようにFileそのものとして管理したければ、File Systemの方が扱いやすい場合があります。</p>



<p class="wp-block-paragraph">EspressifもNVSをConfiguration Dataなどの保存に適した方式として位置付け、大量データについてはFile System等の利用を案内しています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Factory Resetはどう実装する？</h2>



<p class="wp-block-paragraph">製品では、保存した設定を工場出荷状態へ戻したい場合があります。</p>



<p class="wp-block-paragraph">Preferencesでは、</p>



<pre class="wp-block-code"><code>preferences.clear();</code></pre>



<p class="wp-block-paragraph">を使用すると、現在開いているNamespace内のKeyを削除できます。</p>



<p class="wp-block-paragraph">特定のKeyだけ削除するなら、</p>



<pre class="wp-block-code"><code>preferences.remove("temp");</code></pre>



<p class="wp-block-paragraph">も利用できます。</p>



<p class="wp-block-paragraph">ESP-IDFでは、</p>



<pre class="wp-block-code"><code>nvs_erase_key(handle, "temp");</code></pre>



<p class="wp-block-paragraph">で特定Keyを削除できます。</p>



<p class="wp-block-paragraph">Namespace内のすべてのKeyを削除する場合は、</p>



<pre class="wp-block-code"><code>nvs_erase_all(handle);
nvs_commit(handle);</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">これを利用して、</p>



<pre class="wp-block-code"><code>Factory Reset操作
       ↓
設定Namespaceを消去
       ↓
再起動
       ↓
Keyなしを検出
       ↓
Default設定を生成</code></pre>



<p class="wp-block-paragraph">という構成にできます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVS Partition全体を簡単に消さない</h2>



<p class="wp-block-paragraph">ここは製品Firmwareでは注意したいところです。</p>



<p class="wp-block-paragraph">Factory Resetだからといって、</p>



<pre class="wp-block-code"><code>nvs_flash_erase();</code></pre>



<p class="wp-block-paragraph">を安易に呼ぶ設計にはしない方がよいでしょう。</p>



<p class="wp-block-paragraph">NVS PartitionにはApplicationが想定している以外のデータが存在する可能性があります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>user_settings
network
calibration
production</code></pre>



<p class="wp-block-paragraph">のように用途をNamespaceで分けておけば、</p>



<p class="wp-block-paragraph"><strong>ユーザー設定だけ初期化する</strong><br><strong>Calibration値は残す</strong></p>



<p class="wp-block-paragraph">といった制御ができます。</p>



<p class="wp-block-paragraph">Factory Resetで「何を消して、何を残すか」は、製品仕様として決めておくことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Firmwareを更新してもNVSの値は残る？</h2>



<p class="wp-block-paragraph">通常、Firmwareを書き換えただけでNVS Partitionが自動的に消去されるわけではありません。</p>



<p class="wp-block-paragraph">そのためOTAなどでFirmwareを更新した後も、NVSに保存された設定値を引き継ぐ設計ができます。</p>



<p class="wp-block-paragraph">これは便利ですが、別の問題もあります。</p>



<p class="wp-block-paragraph">たとえばVersion 1のFirmwareで、</p>



<pre class="wp-block-code"><code>temp
mode</code></pre>



<p class="wp-block-paragraph">を保存していたとします。</p>



<p class="wp-block-paragraph">Version 2では、</p>



<pre class="wp-block-code"><code>temp
mode
language
sensor_type</code></pre>



<p class="wp-block-paragraph">へ設定項目が増えるかもしれません。</p>



<p class="wp-block-paragraph">さらに将来、</p>



<pre class="wp-block-code"><code>mode : uint8_t</code></pre>



<p class="wp-block-paragraph">だったものを別の形式へ変更する可能性もあります。</p>



<p class="wp-block-paragraph">すると、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>古いFirmwareが保存したデータを、新しいFirmwareがどう解釈するか</strong></p>
</blockquote>



<p class="wp-block-paragraph">を考える必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">設定データにもVersionを持たせる</h2>



<p class="wp-block-paragraph">長期間更新する製品では、設定データにVersion情報を持たせる方法があります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>config_version = 2
temp           = 25
mode           = 1</code></pre>



<p class="wp-block-paragraph">としておきます。</p>



<p class="wp-block-paragraph">起動時に、</p>



<pre class="wp-block-code"><code>NVS読出し
   ↓
config_version確認
   ↓
現在Versionと同じ？
   ├─ YES → そのまま使用
   │
   └─ NO
       ↓
   Migration処理</code></pre>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">これによってFirmware Update後に設定項目が変わっても、古い設定を新しい形式へ変換できます。</p>



<p class="wp-block-paragraph">これはNVS固有の機能というより、<strong>Application側で設計するデータ管理方法</strong>です。</p>



<p class="wp-block-paragraph">しかし製品を長期間Updateするなら非常に重要になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Calibration値とユーザー設定は分ける</h2>



<p class="wp-block-paragraph">もう一つ実務でおすすめしたいのが、保存データを種類ごとに分けることです。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>Namespace : "user"
├─ temp
├─ volume
└─ mode

Namespace : "cal"
├─ offset
└─ gain

Namespace : "system"
├─ config_version
└─ initialized</code></pre>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">こうしておけばFactory Resetするときに、</p>



<pre class="wp-block-code"><code>user → 消す
cal  → 残す</code></pre>



<p class="wp-block-paragraph">といった処理ができます。</p>



<p class="wp-block-paragraph">工場で書き込んだCalibration値までユーザー操作で消えてしまう設計は避けたいところです。</p>



<p class="wp-block-paragraph"><strong>データの用途と寿命を考えてNamespaceを設計する</strong>と、後々のFirmware変更にも対応しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">保存直後に電源を切って大丈夫？</h2>



<p class="wp-block-paragraph">NVS自体には突然のPower Lossを考慮した仕組みがありますが、製品としてはもう一段考えます。</p>



<p class="wp-block-paragraph">たとえばユーザーが設定を変更するたびに、</p>



<pre class="wp-block-code"><code>ボタン操作
 ↓
即Flash Write
 ↓
ボタン操作
 ↓
即Flash Write</code></pre>



<p class="wp-block-paragraph">とすると、操作回数だけ書き込みが発生します。</p>



<p class="wp-block-paragraph">そこで、</p>



<pre class="wp-block-code"><code>設定変更
 ↓
RAM上で更新
 ↓
一定時間変更なし
 ↓
設定確定
 ↓
NVSへ保存</code></pre>



<p class="wp-block-paragraph">という方法も考えられます。</p>



<p class="wp-block-paragraph">ただし保存を遅らせすぎれば、その間に電源が切れたとき変更内容が失われます。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>Flash寿命を優先して保存回数を減らす</strong></p>



<p class="wp-block-paragraph">ことと、</p>



<p class="wp-block-paragraph"><strong>設定変更を確実に残す</strong></p>



<p class="wp-block-paragraph">ことにはTrade-offがあります。</p>



<p class="wp-block-paragraph">製品仕様に応じて保存タイミングを決める必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">毎秒保存するとどうなる？</h2>



<p class="wp-block-paragraph">仮に設定値を毎秒Flashへ書き込むとします。</p>



<p class="wp-block-paragraph">1日では、</p>



<pre class="wp-block-code"><code>60 × 60 × 24
= 86,400回</code></pre>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">1年では約3,150万回の保存要求になります。</p>



<p class="wp-block-paragraph">NVSにはWear Levelingがあるため、「同じFlash Cellを3,150万回直接Eraseする」という単純な話ではありません。</p>



<p class="wp-block-paragraph">しかし、そもそも設定値を毎秒不揮発化する必要がないのであれば、<strong>Firmware側で不要な書き込みを発生させないことが第一</strong>です。</p>



<p class="wp-block-paragraph">たとえば累積稼働時間のような値を保存したい場合にも、毎秒Flashへ保存するのではなく、</p>



<pre class="wp-block-code"><code>RAM上で積算
 ↓
一定間隔
または
正常Shutdown時
 ↓
NVSへ保存</code></pre>



<p class="wp-block-paragraph">など、要求仕様に応じた方法を検討します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NVSへ保存する値・しない値を最初に決める</h2>



<p class="wp-block-paragraph">Firmware設計時には、変数ごとに、</p>



<pre class="wp-block-code"><code>電源OFF後も必要？</code></pre>



<p class="wp-block-paragraph">を考えると整理しやすくなります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>データ</th><th>NVS保存</th></tr></thead><tbody><tr><td>ユーザー設定温度</td><td>○</td></tr><tr><td>Wi-Fi設定</td><td>○</td></tr><tr><td>Calibration値</td><td>○</td></tr><tr><td>初期設定完了Flag</td><td>○</td></tr><tr><td>現在の一時的なADC値</td><td>×</td></tr><tr><td>通信中の一時Buffer</td><td>×</td></tr><tr><td>毎周期更新する内部変数</td><td>×</td></tr><tr><td>大量の連続Log</td><td>△ 別方式を検討</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">「後で必要になるかもしれないから全部保存する」のではなく、<strong>電源断後に復元する必要があるものだけを選ぶ</strong>のが基本です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">製品FirmwareでのNVS設計チェックリスト</h2>



<p class="wp-block-paragraph">最後に、実際にNVSを使うときの確認項目をまとめます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>確認項目</th><th>内容</th></tr></thead><tbody><tr><td>保存対象</td><td>本当に電源OFF後も必要か</td></tr><tr><td>データ量</td><td>NVSに適した小さなデータか</td></tr><tr><td>Namespace</td><td>用途ごとに整理されているか</td></tr><tr><td>Default値</td><td>初回起動時の値を定義したか</td></tr><tr><td>書き込み頻度</td><td>不要なFlash Writeがないか</td></tr><tr><td>保存タイミング</td><td>設定確定時など明確になっているか</td></tr><tr><td>Error処理</td><td>読み書き失敗を考慮しているか</td></tr><tr><td>Factory Reset</td><td>消すデータ・残すデータを決めたか</td></tr><tr><td>Calibration</td><td>ユーザー設定と分離したか</td></tr><tr><td>Version管理</td><td>Firmware更新後の互換性を考えたか</td></tr><tr><td>Migration</td><td>設定形式変更時の処理を考えたか</td></tr><tr><td>電源断</td><td>保存途中・保存前の電源断を考慮したか</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">APIを呼んで値を保存するだけなら簡単です。</p>



<p class="wp-block-paragraph">しかし製品では、<strong>数年後のFirmware Updateまで考えて保存データを設計すること</strong>が重要になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜ESP32の設定保存にはNVSを活用する</h2>



<p class="wp-block-paragraph">ESP32で電源OFF後も設定値を保持したい場合、NVSを利用できます。</p>



<p class="wp-block-paragraph">Arduino-ESP32ではPreferences Libraryを使うことで、NVSを比較的簡単に扱えます。</p>



<p class="wp-block-paragraph">ESP-IDFではNVS APIを直接使用し、</p>



<pre class="wp-block-code"><code>nvs_open()
nvs_get_xxx()
nvs_set_xxx()
nvs_commit()
nvs_close()</code></pre>



<p class="wp-block-paragraph">という流れでデータを管理できます。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Flashに保存できるから、何でも保存する</strong></p>
</blockquote>



<p class="wp-block-paragraph">という考え方にしないことです。</p>



<p class="wp-block-paragraph">NVSは、</p>



<p class="wp-block-paragraph"><strong>設定値</strong><br><strong>Calibration値</strong><br><strong>動作モード</strong><br><strong>初期化Flag</strong></p>



<p class="wp-block-paragraph">など、小さく、頻繁には変更されないデータの保存に適しています。</p>



<p class="wp-block-paragraph">大量のデータや頻繁なLogには、用途に応じてLittleFSなど別の保存方法を検討します。</p>



<p class="wp-block-paragraph">また製品Firmwareでは、</p>



<p class="wp-block-paragraph"><strong>書き込み頻度</strong><br><strong>Factory Reset</strong><br><strong>設定Version</strong><br><strong>Firmware Update時のMigration</strong></p>



<p class="wp-block-paragraph">まで考えておくことで、後からFirmwareを変更したときにも対応しやすくなります。</p>



<p class="wp-block-paragraph">NVSは単なる「電源を切っても値が残る機能」ではありません。</p>



<p class="wp-block-paragraph"><strong>製品の設定データを長期間どう管理するか</strong></p>



<p class="wp-block-paragraph">という視点で使うと、より実用的な仕組みになります。</p>



<p class="wp-block-paragraph">今回の記事からは、既存の**「ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？」**への内部リンクも自然に設定できます。PreferencesとESP-IDF NVS APIの違いを読んで「そもそもどの開発環境を選ぶ？」となった読者をつなげられます。</p>The post <a href="https://dlrow-design.net/esp32%e3%81%aeflash%e3%81%ab%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bd%9cnvs%e3%83%bbpreferences%e3%82%92%e8%a7%a3%e8%aa%ac/">ESP32のFlashにデータを保存する方法｜NVS・Preferencesを解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32でWi-FiとBLEは同時に使える？仕組みと注意点を解説</title>
		<link>https://dlrow-design.net/esp32%e3%81%a7wi-fi%e3%81%a8ble%e3%81%af%e5%90%8c%e6%99%82%e3%81%ab%e4%bd%bf%e3%81%88%e3%82%8b%ef%bc%9f%e4%bb%95%e7%b5%84%e3%81%bf%e3%81%a8%e6%b3%a8%e6%84%8f%e7%82%b9%e3%82%92%e8%a7%a3%e8%aa%ac/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25a7wi-fi%25e3%2581%25a8ble%25e3%2581%25af%25e5%2590%258c%25e6%2599%2582%25e3%2581%25ab%25e4%25bd%25bf%25e3%2581%2588%25e3%2582%258b%25ef%25bc%259f%25e4%25bb%2595%25e7%25b5%2584%25e3%2581%25bf%25e3%2581%25a8%25e6%25b3%25a8%25e6%2584%258f%25e7%2582%25b9%25e3%2582%2592%25e8%25a7%25a3%25e8%25aa%25ac</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sat, 22 Aug 2026 15:38:00 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=834</guid>

					<description><![CDATA[<p>ESP32の大きな特徴の一つが、Wi-FiとBluetoothを1つのデバイスで利用できることです。 たとえば、 「BLEでスマートフォンから初期設定を行い、その後Wi-Fiへ接続する」「BLEでセン ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%a7wi-fi%e3%81%a8ble%e3%81%af%e5%90%8c%e6%99%82%e3%81%ab%e4%bd%bf%e3%81%88%e3%82%8b%ef%bc%9f%e4%bb%95%e7%b5%84%e3%81%bf%e3%81%a8%e6%b3%a8%e6%84%8f%e7%82%b9%e3%82%92%e8%a7%a3%e8%aa%ac/">ESP32でWi-FiとBLEは同時に使える？仕組みと注意点を解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32の大きな特徴の一つが、Wi-FiとBluetoothを1つのデバイスで利用できることです。</p>



<p class="wp-block-paragraph">たとえば、</p>



<p class="wp-block-paragraph">「BLEでスマートフォンから初期設定を行い、その後Wi-Fiへ接続する」<br>「BLEでセンサーと通信しながら、取得したデータをWi-Fiでクラウドへ送信する」<br>「Wi-Fi接続中もBLE Advertisingを続けたい」</p>



<p class="wp-block-paragraph">といった使い方が考えられます。</p>



<p class="wp-block-paragraph">ここで気になるのが、</p>



<p class="wp-block-paragraph"><strong>「ESP32はWi-FiとBLEを本当に同時に使えるのか？」</strong></p>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">結論から言うと、<strong>ESP32ではWi-FiとBLEを同時に使用できます。</strong></p>



<p class="wp-block-paragraph">ただし、「同時使用できる」という言葉には少し注意が必要です。</p>



<p class="wp-block-paragraph">ESP32ではWi-FiとBluetooth/BLEが2.4GHz帯のRFリソースを共有しています。そのため、Wi-FiとBLEが完全に独立した2つの無線回路を持ち、それぞれが同じ瞬間に送受信しているわけではありません。</p>



<p class="wp-block-paragraph">Espressifの公式資料では、RFリソースを共有し、<strong>TDM（Time Division Multiplexing：時分割多重）と優先度制御によってWi-FiとBluetoothを共存させる</strong>仕組みが説明されています。</p>



<p class="wp-block-paragraph">この記事では、ESP32でWi-FiとBLEを同時使用するときの仕組みと、実際の製品開発で注意したいポイントを解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">結論｜ESP32はWi-FiとBLEを同時に使える</h2>



<p class="wp-block-paragraph">最初に結論を整理すると、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wi-FiとBLEを同時に使用することは可能。ただし、RFを時間的に共有している。</strong></p>
</blockquote>



<p class="wp-block-paragraph">という理解が分かりやすいでしょう。</p>



<p class="wp-block-paragraph">たとえばESP32をWi-FiのSTAとしてアクセスポイントへ接続しながら、</p>



<ul class="wp-block-list">
<li>BLE Scan</li>



<li>BLE Advertising</li>



<li>BLE Connection</li>
</ul>



<p class="wp-block-paragraph">を利用する構成は、Espressifの公式Coexistence表でもサポートされています。</p>



<p class="wp-block-paragraph">したがって、</p>



<pre class="wp-block-code"><code>Wi-Fi接続
     ＋
BLE接続</code></pre>



<p class="wp-block-paragraph">というシステムを作ること自体は可能です。</p>



<p class="wp-block-paragraph">ただし、</p>



<pre class="wp-block-code"><code>Wi-Fi専用RF
     ＋
BLE専用RF</code></pre>



<p class="wp-block-paragraph">という2つの独立した無線回路がESP32内部に存在しているわけではありません。</p>



<p class="wp-block-paragraph">この違いが、Wi-FiとBLEを同時使用するときの重要なポイントです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-FiとBLEは同じ2.4GHz RFを共有している</h2>



<p class="wp-block-paragraph">従来ESP32のWi-Fiは2.4GHz帯を使用します。</p>



<p class="wp-block-paragraph">BLEも同じ2.4GHz帯を使用します。</p>



<p class="wp-block-paragraph">ESP32には、この2つがそれぞれ独立して使用できる2系統の2.4GHz RFが搭載されているわけではなく、<strong>1つの2.4GHz ISM帯RFモジュールをWi-FiとBluetoothで共有します。</strong></p>



<p class="wp-block-paragraph">そのため、Wi-FiがRFを使用して送受信している瞬間には、Bluetooth側が同じRFを使って送受信することはできません。</p>



<p class="wp-block-paragraph">そこでESP32では、Wi-FiとBluetoothからのRF使用要求をCoexistence機能が調停します。</p>



<p class="wp-block-paragraph">イメージとしては、</p>



<pre class="wp-block-code"><code>時間 →
┌──────┬──────┬──────┬──────┐
│Wi-Fi │ BLE  │Wi-Fi │ BLE  │
└──────┴──────┴──────┴──────┘
       1つのRFを共有</code></pre>



<p class="wp-block-paragraph">という考え方です。</p>



<p class="wp-block-paragraph">実際の制御はこのような単純な固定交互動作ではありませんが、<strong>非常に短い時間単位でRFを使い分けることで、ユーザーから見るとWi-FiとBLEが並行して動作しているように見える</strong>と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">TDM（時分割多重）でWi-FiとBLEを共存させる</h2>



<p class="wp-block-paragraph">EspressifのCoexistence機能では、Wi-Fi、Bluetooth、BLEにRFを使用するためのTime Sliceが割り当てられます。</p>



<p class="wp-block-paragraph">さらに、それぞれからRF使用要求が発生すると、Coexistence機能が<strong>優先度を基にRFをどちらへ割り当てるか判断</strong>します。</p>



<p class="wp-block-paragraph">この割り当ては常に一定ではありません。</p>



<p class="wp-block-paragraph">Wi-Fi側だけでも、</p>



<ul class="wp-block-list">
<li>IDLE</li>



<li>CONNECTED</li>



<li>SCAN</li>



<li>CONNECTING</li>
</ul>



<p class="wp-block-paragraph">などの状態があり、それに応じてCoexistence PeriodやTime Sliceが調整されます。</p>



<p class="wp-block-paragraph">たとえばWi-Fiがアクセスポイントを検索している最中と、アクセスポイントへ接続済みで待機している状態では、必要になるRF時間が違います。</p>



<p class="wp-block-paragraph">ESP32はその状態に合わせてWi-FiとBluetoothの共存方法を変更します。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wi-Fi 50％、BLE 50％で常に固定されている</strong></p>
</blockquote>



<p class="wp-block-paragraph">わけではありません。</p>



<p class="wp-block-paragraph">使用状況によってRFの割り当て方が変わります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-Fi接続＋BLE接続はできる？</h2>



<p class="wp-block-paragraph">できます。</p>



<p class="wp-block-paragraph">一般的な用途として考えやすいのが、</p>



<pre class="wp-block-code"><code>スマートフォン
     │
    BLE
     │
   ESP32
     │
   Wi-Fi
     │
アクセスポイント
     │
インターネット</code></pre>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">たとえばスマートフォンとはBLEで通信しながら、ESP32はWi-Fi経由でサーバーへデータを送信できます。</p>



<p class="wp-block-paragraph">EspressifのESP32向けCoexistence表でも、Wi-Fi STAについて、</p>



<p class="wp-block-paragraph"><strong>Wi-Fi Scan + BLE</strong><br><strong>Wi-Fi Connecting + BLE</strong><br><strong>Wi-Fi Connected + BLE</strong></p>



<p class="wp-block-paragraph">といった組み合わせがサポートされています。</p>



<p class="wp-block-paragraph">このため、</p>



<p class="wp-block-paragraph"><strong>BLEを使った初期設定</strong><br>↓<br><strong>Wi-Fiへ接続</strong><br>↓<br><strong>BLE接続を維持したままWi-Fi通信</strong></p>



<p class="wp-block-paragraph">という構成も実現できます。</p>



<p class="wp-block-paragraph">IoT機器では使いやすい構成ですね。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「同時使用できる」＝「性能が変わらない」ではない</h2>



<p class="wp-block-paragraph">ここが今回の記事で特に重要なところです。</p>



<p class="wp-block-paragraph">Wi-FiとBLEを同時に使用できるからといって、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wi-Fiだけを使った場合とBLEだけを使った場合の性能を、それぞれ100％同時に得られる</strong></p>
</blockquote>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">1つのRFを共有しているため、一方がRFを使用している間、もう一方は待つ必要があります。</p>



<p class="wp-block-paragraph">そのため通信量が増えるほど、</p>



<ul class="wp-block-list">
<li>Wi-FiのThroughput</li>



<li>BLEの応答時間</li>



<li>BLE Scan</li>



<li>Packet Loss</li>



<li>リアルタイム性</li>
</ul>



<p class="wp-block-paragraph">などへ影響する可能性があります。</p>



<p class="wp-block-paragraph">EspressifもCoexistenceの組み合わせを、単純な「対応／非対応」だけではなく、</p>



<p class="wp-block-paragraph"><strong>Y：Supported and performance is stable</strong><br><strong>C1：Supported but performance is unstable</strong><br><strong>X：Not supported</strong></p>



<p class="wp-block-paragraph">などに分類しています。</p>



<p class="wp-block-paragraph">つまり公式資料の段階でも、</p>



<p class="wp-block-paragraph"><strong>「動作可能」と「安定した性能を期待できる」は別</strong></p>



<p class="wp-block-paragraph">として扱われています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-Fiで大量通信するとBLEへ影響する？</h2>



<p class="wp-block-paragraph">可能性があります。</p>



<p class="wp-block-paragraph">特にWi-Fiで大量のデータを連続転送すると、Wi-Fi側が必要とするRF時間が増えます。</p>



<p class="wp-block-paragraph">同時にBLEでも頻繁な通信を要求すれば、限られたRFリソースを両方で取り合うことになります。</p>



<p class="wp-block-paragraph">EspressifのFAQでも、Wi-FiとBluetoothが大量のデータを同時に扱うと、リアルタイム性の高いBluetoothサービスなどで性能低下が起こり得ることが説明されています。BLE Scanについても、予定されたScan WindowがWi-FiのTime Slotと重なることで中断され、実際のScan時間が設定値より短くなる場合があります。</p>



<p class="wp-block-paragraph">したがって、</p>



<pre class="wp-block-code"><code>BLEで数バイトの設定値を時々送る
       ＋
Wi-Fiで定期的にデータ送信</code></pre>



<p class="wp-block-paragraph">これと</p>



<pre class="wp-block-code"><code>BLEで連続通信
       ＋
Wi-Fiで大量データを連続転送</code></pre>



<p class="wp-block-paragraph">では、同じ「Wi-Fi＋BLE同時使用」でも条件が大きく違います。</p>



<p class="wp-block-paragraph">製品開発では、単に接続できたことだけでなく、<strong>実際の最大通信量で評価することが重要</strong>です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">BLE Advertising中にWi-Fiを使える？</h2>



<p class="wp-block-paragraph">BLE AdvertisingとWi-Fiの併用も可能です。</p>



<p class="wp-block-paragraph">たとえばESP32をWi-Fiへ接続したままBLE Advertisingを行い、スマートフォンなどからESP32を発見できるようにする構成が考えられます。</p>



<p class="wp-block-paragraph">EspressifのCoexistence表でも、Wi-Fi STAとBLE Advertisingの組み合わせはサポートされています。</p>



<p class="wp-block-paragraph">これは、</p>



<p class="wp-block-paragraph"><strong>普段はWi-Fiでクラウド通信</strong><br><strong>設定変更時だけスマートフォンからBLE接続</strong></p>



<p class="wp-block-paragraph">といった製品に使いやすい構成です。</p>



<p class="wp-block-paragraph">BLEを常時接続しておく必要がなければ、</p>



<pre class="wp-block-code"><code>通常時
Wi-Fi通信
＋
BLE Advertising

       ↓

設定時
Wi-Fi通信
＋
BLE Connection</code></pre>



<p class="wp-block-paragraph">という設計もできます。</p>



<p class="wp-block-paragraph">通信量を必要以上に増やさないという意味でも、用途に合わせてBLEの動作状態を設計することが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32が自動で共存制御してくれる？</h2>



<p class="wp-block-paragraph">多くの一般的なCoexistenceケースでは、ESP32側が使用状況に応じて共存状態を切り替えます。</p>



<p class="wp-block-paragraph">ただしESP-IDFでは、Wi-Fi/Bluetooth Coexistenceに関する設定も用意されています。</p>



<p class="wp-block-paragraph">現行のESP-IDF Programming Guideでは、ソフトウェアによるCoexistence機能について<code>CONFIG_ESP_COEX_SW_COEXIST_ENABLE</code>を確認するよう案内されています。</p>



<p class="wp-block-paragraph">また、Dual CoreのESP32では、より良い通信性能を得るため、Wi-Fi Protocol StackとBluetooth Controller / Host StackのTaskを異なるCPU Coreへ配置する方法も公式資料で案内されています。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wi-FiとBLEのAPIを両方呼べば、それで設計検討は終了</strong></p>
</blockquote>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">通信量が多い製品では、Coexistence設定やTask構成も確認する価値があります。</p>



<p class="wp-block-paragraph">ESP-IDFを含め、ESP32で使用する開発環境の違いについては「<a href="https://dlrow-design.net/esp32%e3%81%ae%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83%e3%82%92%e6%af%94%e8%bc%83%ef%bd%9carduino-ide%e3%83%bbplatformio%e3%83%bbesp-idf%e3%81%af%e3%81%a9%e3%82%8c%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/" target="_blank" rel="noopener" title="">ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？</a>」で詳しく解説しています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-Fi＋BLEでメモリ使用量は増える？</h2>



<p class="wp-block-paragraph">Wi-FiとBLEを同時に使用するとき、RFの共存だけでなく注意したいのが<strong>メモリ使用量</strong>です。</p>



<p class="wp-block-paragraph">ESP32ではWi-Fi DriverやTCP/IP Stack、Bluetooth Controller、Bluetooth Host Stackなどがそれぞれメモリを使用します。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>Wi-Fiだけを使用するFirmware</strong></p>



<p class="wp-block-paragraph">と比べると、</p>



<p class="wp-block-paragraph"><strong>Wi-Fi＋BLEを使用するFirmware</strong></p>



<p class="wp-block-paragraph">では、一般に必要なメモリ量が増えます。</p>



<p class="wp-block-paragraph">特にESP32では、無線通信以外にも、</p>



<ul class="wp-block-list">
<li>HTTP / HTTPS</li>



<li>MQTT</li>



<li>TLS</li>



<li>JSON</li>



<li>OTA</li>



<li>センサー処理</li>



<li>Display</li>



<li>File System</li>
</ul>



<p class="wp-block-paragraph">などを同時に使用することがあります。</p>



<p class="wp-block-paragraph">個々の機能では問題がなくても、機能を追加していくうちにHeapの余裕が少なくなることがあります。</p>



<p class="wp-block-paragraph">製品開発では、単にBuildが通るかだけでなく、<strong>実際にWi-FiとBLEを動作させた状態でHeapの残量を確認する</strong>ことをおすすめします。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">NimBLEとBluedroidはどう違う？</h2>



<p class="wp-block-paragraph">ESP-IDFでBLEを使用するときには、Bluetooth Host Stackについても考える必要があります。</p>



<p class="wp-block-paragraph">代表的なのが、</p>



<p class="wp-block-paragraph"><strong>Bluedroid</strong><br><strong>NimBLE</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">BluedroidはBluetooth ClassicとBLEを扱えるHost Stackです。</p>



<p class="wp-block-paragraph">一方、NimBLEはBLE向けのHost Stackで、EspressifはESP-IDFでNimBLEを利用できるよう移植しています。公式Programming Guideでは、NimBLEはBLEのみを必要とする用途に適した、より軽量な選択肢として説明されています。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Bluetooth Classicは不要で、BLEだけ使いたい</strong></p>
</blockquote>



<p class="wp-block-paragraph">という製品では、NimBLEを検討する価値があります。</p>



<p class="wp-block-paragraph">特にWi-Fi、BLE、TLS、Application処理など多くの機能を一つのESP32へ載せる場合、メモリの余裕は重要です。</p>



<p class="wp-block-paragraph">ただし、</p>



<p class="wp-block-paragraph"><strong>NimBLEを使えばWi-Fi＋BLEのRF競合がなくなる</strong></p>



<p class="wp-block-paragraph">わけではありません。</p>



<p class="wp-block-paragraph">Host StackをNimBLEへ変更しても、Wi-FiとBLEがRFリソースを共有する基本構造は変わりません。</p>



<p class="wp-block-paragraph">NimBLEを選択する理由は、RFを分離するためではなく、主に<strong>BLE Host側の機能やメモリ構成を最適化するため</strong>と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32-C3やESP32-C5でもWi-Fi＋BLEは使える？</h2>



<p class="wp-block-paragraph">ここではシリーズの違いにも注意が必要です。</p>



<p class="wp-block-paragraph">従来ESP32はDual Coreですが、ESP32-C3やESP32-C5はSingle Core構成です。</p>



<p class="wp-block-paragraph">それでも、Wi-FiとBLEの共存機能自体は用意されています。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Dual CoreだからWi-Fi＋BLEが使えて、Single Coreだから使えない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という関係ではないことです。</p>



<p class="wp-block-paragraph">Wi-FiとBLEのRF共存と、CPU Core数は別の話です。</p>



<p class="wp-block-paragraph">ただしSingle Coreでは、Application、Wi-Fi、Bluetoothなどの処理が同じCPUリソース上で動作するため、CPU負荷についても意識する必要があります。</p>



<p class="wp-block-paragraph">従来ESP32のように、</p>



<pre class="wp-block-code"><code>Core 0 → Wi-Fi
Core 1 → Bluetooth</code></pre>



<p class="wp-block-paragraph">といった形でTaskを別Coreへ配置する考え方を、そのままSingle Coreデバイスへ適用することはできません。</p>



<p class="wp-block-paragraph">そのためC3やC5では、</p>



<p class="wp-block-paragraph"><strong>RFのCoexistence</strong></p>



<p class="wp-block-paragraph">だけでなく、</p>



<p class="wp-block-paragraph"><strong>CPU使用率</strong><br><strong>Task Priority</strong><br><strong>Stack Size</strong><br><strong>Heap</strong></p>



<p class="wp-block-paragraph">なども確認しておくとよいでしょう。</p>



<p class="wp-block-paragraph">また、シリーズによってサポートされる無線機能やCoexistence条件は異なる可能性があります。</p>



<p class="wp-block-paragraph">実際の製品では、使用するESP32シリーズに対応したESP-IDFのProgramming Guideで最新条件を確認してください。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32-C5の5GHz Wi-FiならBLEと干渉しない？</h2>



<p class="wp-block-paragraph">ESP32-C5では、従来ESP32との大きな違いとして<strong>2.4GHzだけでなく5GHz Wi-Fi 6にも対応</strong>しています。</p>



<p class="wp-block-paragraph">ここで、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「Wi-Fiを5GHzにすれば、2.4GHzのBLEとは完全に別だから共存問題もなくなるのでは？」</p>
</blockquote>



<p class="wp-block-paragraph">と思うかもしれません。</p>



<p class="wp-block-paragraph">周波数帯という意味では、5GHz Wi-Fiと2.4GHz BLEは異なります。</p>



<p class="wp-block-paragraph">しかし、<strong>それだけを理由にWi-Fi＋BLEの共存制御を考えなくてよいとは判断しない方が安全です。</strong></p>



<p class="wp-block-paragraph">ESP32-C5は2.4GHz/5GHz Wi-FiとBluetooth LE、IEEE 802.15.4などの無線機能を一つのSoCへ統合しており、EspressifはC5についてもRF Coexistence機能を提供しています。</p>



<p class="wp-block-paragraph">したがって、C5でも実際に使用するWi-Fi Band、BLEの動作、通信量などを含めて評価することが重要です。</p>



<p class="wp-block-paragraph">特に製品では、</p>



<p class="wp-block-paragraph"><strong>「周波数が違うから問題ないはず」</strong></p>



<p class="wp-block-paragraph">という推測だけで設計を完了せず、実機で確認しましょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-Fi＋BLEが不安定なときに確認すること</h2>



<p class="wp-block-paragraph">Wi-FiとBLEを同時使用して通信が不安定になった場合、すぐにHardware不良と判断するのではなく、まず通信条件を整理します。</p>



<h3 class="wp-block-heading">1．Wi-Fiの通信量を確認する</h3>



<p class="wp-block-paragraph">大量のデータを連続送信していないか確認します。</p>



<p class="wp-block-paragraph">たとえばFirmware Updateや大きなFile Uploadなど、通常時とは大きく異なる通信が発生している場合があります。</p>



<h3 class="wp-block-heading">2．BLEのConnection Intervalを確認する</h3>



<p class="wp-block-paragraph">BLE接続ではConnection IntervalなどのParameterによって、通信頻度が変わります。</p>



<p class="wp-block-paragraph">必要以上に短いIntervalを設定すると、それだけ頻繁に無線通信が必要になります。</p>



<p class="wp-block-paragraph">リアルタイム性が必要ないデータなら、通信頻度を下げられないか検討します。</p>



<h3 class="wp-block-heading">3．BLE Scanを確認する</h3>



<p class="wp-block-paragraph">BLE Scanを常時行っている場合も注意が必要です。</p>



<p class="wp-block-paragraph">Wi-FiとBLE Scanが同時に動作すると、RFリソースを共有する必要があります。</p>



<p class="wp-block-paragraph">前半でも触れたように、EspressifはWi-FiとのCoexistenceによってBLE Scan Windowが中断される場合があることを説明しています。</p>



<p class="wp-block-paragraph">「BLEデバイスを発見できない」という問題でも、必ずしもBLEそのものが停止しているとは限りません。</p>



<h3 class="wp-block-heading">4．Wi-Fiの状態を確認する</h3>



<p class="wp-block-paragraph">Wi-Fiが安定して接続されているときと、</p>



<p class="wp-block-paragraph"><strong>Scan中</strong><br><strong>接続処理中</strong><br><strong>再接続を繰り返している状態</strong></p>



<p class="wp-block-paragraph">ではRFの使用状況が異なります。</p>



<p class="wp-block-paragraph">電波環境が悪くWi-Fiが頻繁に再接続していると、BLE側にも影響が出る可能性があります。</p>



<h3 class="wp-block-heading">5．HeapとStackを確認する</h3>



<p class="wp-block-paragraph">通信問題に見えても、実際にはメモリ不足が原因の場合があります。</p>



<p class="wp-block-paragraph">Wi-FiとBLEを同時に使用すると必要なメモリも増えるため、</p>



<p class="wp-block-paragraph"><strong>Free Heap</strong><br><strong>Minimum Free Heap</strong><br><strong>各TaskのStack余裕</strong></p>



<p class="wp-block-paragraph">などを確認します。</p>



<h3 class="wp-block-heading">6．ESP-IDFのバージョンを確認する</h3>



<p class="wp-block-paragraph">ESP-IDFではWi-FiやBluetooth関連機能も継続的に更新されています。</p>



<p class="wp-block-paragraph">不具合を調査するときは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「ESP32でWi-Fi＋BLEを使っている」</p>
</blockquote>



<p class="wp-block-paragraph">だけでなく、</p>



<p class="wp-block-paragraph"><strong>ESP32の型番</strong><br><strong>ESP-IDFのバージョン</strong><br><strong>Bluetooth Host Stack</strong><br><strong>Wi-Fi Mode</strong><br><strong>BLEの動作状態</strong></p>



<p class="wp-block-paragraph">まで記録しておくと、原因を切り分けやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">製品ではWi-FiとBLEの役割を分ける</h2>



<p class="wp-block-paragraph">Wi-FiとBLEを両方搭載できるからといって、常に両方で大量通信する必要はありません。</p>



<p class="wp-block-paragraph">製品では、それぞれの役割を明確にすると設計しやすくなります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>BLE
 └─ 初期設定
 └─ スマートフォンとの設定通信
 └─ 近距離メンテナンス

Wi-Fi
 └─ クラウド通信
 └─ データUpload
 └─ OTA</code></pre>



<p class="wp-block-paragraph">という分け方です。</p>



<p class="wp-block-paragraph">この構成なら、通常運転ではWi-Fiを中心に使用し、BLEはAdvertisingや低頻度通信に抑えることができます。</p>



<p class="wp-block-paragraph">必要なときだけBLE Connectionを確立する設計も可能です。</p>



<p class="wp-block-paragraph">無線機能を、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>搭載されているから常時使う</strong></p>
</blockquote>



<p class="wp-block-paragraph">のではなく、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>その通信方式が必要な場面だけ使う</strong></p>
</blockquote>



<p class="wp-block-paragraph">と考えると、通信負荷だけでなく消費電力の面でも設計しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「接続できた」だけで評価を終わらせない</h2>



<p class="wp-block-paragraph">試作段階では、</p>



<p class="wp-block-paragraph"><strong>Wi-Fiにつながった</strong><br><strong>BLEでもスマートフォンにつながった</strong></p>



<p class="wp-block-paragraph">ところで動作確認を終えたくなります。</p>



<p class="wp-block-paragraph">しかし製品では、ここからが重要です。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>Wi-Fiで通常通信中
        ↓
BLE接続開始
        ↓
Wi-Fi大量送信
        ↓
BLE設定変更
        ↓
Wi-Fi切断
        ↓
Wi-Fi再接続
        ↓
BLE切断・再接続</code></pre>



<p class="wp-block-paragraph">といった実際に起こり得る状態を試します。</p>



<p class="wp-block-paragraph">さらに、</p>



<ul class="wp-block-list">
<li>Wi-Fi電波が弱い</li>



<li>BLE側が遠い</li>



<li>アクセスポイントが一時的に消える</li>



<li>スマートフォンがBLE圏外へ出る</li>



<li>OTA中にBLE操作される</li>
</ul>



<p class="wp-block-paragraph">などの条件もあります。</p>



<p class="wp-block-paragraph">特に無線通信は周囲の環境によって状態が変化します。</p>



<p class="wp-block-paragraph">そのため、Wi-Fi＋BLE製品では<strong>正常系だけでなく通信状態が悪いときの評価</strong>も重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Wi-Fi＋BLE同時使用チェックリスト</h2>



<p class="wp-block-paragraph">最後に、ESP32でWi-FiとBLEを同時使用するときの確認項目をまとめます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>確認項目</th><th>チェック内容</th></tr></thead><tbody><tr><td>ESP32シリーズ</td><td>使用デバイスのCoexistence仕様を確認したか</td></tr><tr><td>Wi-Fi Mode</td><td>STA / APなど実際の動作Modeを確認したか</td></tr><tr><td>BLE動作</td><td>Scan / Advertising / Connectionを整理したか</td></tr><tr><td>通信量</td><td>Wi-FiとBLEの最大通信量を確認したか</td></tr><tr><td>BLE Interval</td><td>必要以上に短くしていないか</td></tr><tr><td>BLE Scan</td><td>常時Scanが本当に必要か</td></tr><tr><td>Coexistence</td><td>ESP-IDFの設定を確認したか</td></tr><tr><td>CPU負荷</td><td>Applicationを含め余裕があるか</td></tr><tr><td>Heap</td><td>Wi-Fi＋BLE動作時の残量を確認したか</td></tr><tr><td>Stack</td><td>各Taskに十分な余裕があるか</td></tr><tr><td>異常系</td><td>Wi-Fi再接続中なども評価したか</td></tr><tr><td>実機評価</td><td>最大負荷・悪条件でも確認したか</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">この表を設計・評価時のチェックリストとして使うと、単純な接続確認だけで終わることを防げます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜ESP32のWi-FiとBLEは同時使用できる。ただしRFは共有する</h2>



<p class="wp-block-paragraph">ESP32では、Wi-FiとBLEを同時に使用できます。</p>



<p class="wp-block-paragraph">Wi-Fiへ接続しながらBLE Advertisingを行ったり、BLE Connectionを維持しながらWi-Fiでサーバーへデータを送信したりすることも可能です。</p>



<p class="wp-block-paragraph">ただし、重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Wi-FiとBLEが完全に独立した無線回路で同時通信しているわけではない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">ESP32ではRFリソースを共有し、TDMと優先度制御によってWi-FiとBluetoothを共存させています。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>同時使用できる＝それぞれ単独使用時と同じ性能が保証される</strong></p>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">Wi-Fiの通信量、BLEのConnection IntervalやScan、CPU負荷、Heapなどによって、実際の通信性能は変化します。</p>



<p class="wp-block-paragraph">特に製品開発では、</p>



<p class="wp-block-paragraph"><strong>「Wi-FiもBLEも接続できた」</strong></p>



<p class="wp-block-paragraph">だけで評価を終了せず、最大通信量や再接続、電波環境が悪い状態まで確認することが重要です。</p>



<p class="wp-block-paragraph">Wi-FiとBLEそれぞれの役割を整理し、必要なタイミングで必要な通信を行う設計にすることで、ESP32の無線機能をより安定して活用できます。</p>



<p class="wp-block-paragraph"></p>The post <a href="https://dlrow-design.net/esp32%e3%81%a7wi-fi%e3%81%a8ble%e3%81%af%e5%90%8c%e6%99%82%e3%81%ab%e4%bd%bf%e3%81%88%e3%82%8b%ef%bc%9f%e4%bb%95%e7%b5%84%e3%81%bf%e3%81%a8%e6%b3%a8%e6%84%8f%e7%82%b9%e3%82%92%e8%a7%a3%e8%aa%ac/">ESP32でWi-FiとBLEは同時に使える？仕組みと注意点を解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？</title>
		<link>https://dlrow-design.net/esp32%e3%81%ae%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83%e3%82%92%e6%af%94%e8%bc%83%ef%bd%9carduino-ide%e3%83%bbplatformio%e3%83%bbesp-idf%e3%81%af%e3%81%a9%e3%82%8c%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25ae%25e9%2596%258b%25e7%2599%25ba%25e7%2592%25b0%25e5%25a2%2583%25e3%2582%2592%25e6%25af%2594%25e8%25bc%2583%25ef%25bd%259carduino-ide%25e3%2583%25bbplatformio%25e3%2583%25bbesp-idf%25e3%2581%25af%25e3%2581%25a9%25e3%2582%258c%25e3%2582%2592%25e9%2581%25b8%25e3%2581%25b6%25ef%25bc%259f</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Fri, 21 Aug 2026 14:32:32 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=827</guid>

					<description><![CDATA[<p>ESP32を使い始めるとき、最初に迷いやすいのが開発環境です。 ESP32について調べると、 「Arduino IDEが簡単」「PlatformIOの方が本格的」「製品開発ならESP-IDFを使うべき ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%ae%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83%e3%82%92%e6%af%94%e8%bc%83%ef%bd%9carduino-ide%e3%83%bbplatformio%e3%83%bbesp-idf%e3%81%af%e3%81%a9%e3%82%8c%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/">ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32を使い始めるとき、最初に迷いやすいのが<strong>開発環境</strong>です。</p>



<p class="wp-block-paragraph">ESP32について調べると、</p>



<p class="wp-block-paragraph">「Arduino IDEが簡単」<br>「PlatformIOの方が本格的」<br>「製品開発ならESP-IDFを使うべき」</p>



<p class="wp-block-paragraph">といった情報が見つかります。</p>



<p class="wp-block-paragraph">しかし、初めてESP32を使う場合、</p>



<p class="wp-block-paragraph">「結局どれを選べばいい？」<br>「Arduino IDEで作ったプログラムは後から移行できる？」<br>「PlatformIOとESP-IDFは何が違う？」<br>「ESP-IDFはコマンド操作ができないと使えない？」</p>



<p class="wp-block-paragraph">と迷うこともあると思います。</p>



<p class="wp-block-paragraph">結論から言うと、<strong>すべての人にとって最適な開発環境が一つあるわけではありません。</strong></p>



<p class="wp-block-paragraph">試作を素早く動かしたい場合と、長期間保守する製品Firmwareを開発する場合では、求められるものが違います。</p>



<p class="wp-block-paragraph">この記事では、ESP32でよく使われる</p>



<p class="wp-block-paragraph"><strong>Arduino IDE</strong><br><strong>PlatformIO + Visual Studio Code</strong><br><strong>ESP-IDF + Visual Studio Code</strong></p>



<p class="wp-block-paragraph">の3つを比較し、それぞれどのような開発に向いているのかを解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">最初に知っておきたい「IDE」と「Framework」の違い</h2>



<p class="wp-block-paragraph">3つを比較する前に、少し整理しておきたいことがあります。</p>



<p class="wp-block-paragraph">Arduino IDE、PlatformIO、ESP-IDFは、厳密にはすべて同じ種類のものではありません。</p>



<p class="wp-block-paragraph">たとえば、</p>



<p class="wp-block-paragraph"><strong>Arduino IDE</strong>はプログラムを編集・ビルド・書き込みするための統合開発環境です。</p>



<p class="wp-block-paragraph"><strong>PlatformIO</strong>はVS Codeなどと組み合わせて利用できる組み込み開発向けの開発エコシステムで、ESP32ではArduino FrameworkとESP-IDFの両方を扱えます。PlatformIOの公式ドキュメントでも、ESP32向けFrameworkとしてArduinoとEspressif IoT Development Frameworkの両方が用意されています。</p>



<p class="wp-block-paragraph">そして**ESP-IDF（Espressif IoT Development Framework）**は、Espressifが提供するESP32向けの公式開発Frameworkです。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Arduino IDE vs PlatformIO vs ESP-IDF</p>
</blockquote>



<p class="wp-block-paragraph">という比較は、厳密には同じ階層の製品同士を比較しているわけではありません。</p>



<p class="wp-block-paragraph">しかし実際にESP32を開発するときには、この3つが「どの環境で開発するか」という選択肢として比較されることが多いため、この記事でも実際の使い方を基準に比較します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まずは3つの違いを比較</h2>



<p class="wp-block-paragraph">大まかな特徴を整理すると、次のようになります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>Arduino IDE</th><th>PlatformIO + VS Code</th><th>ESP-IDF + VS Code</th></tr></thead><tbody><tr><td>始めやすさ</td><td>◎</td><td>○</td><td>△</td></tr><tr><td>プロジェクト管理</td><td>△</td><td>◎</td><td>◎</td></tr><tr><td>Arduinoライブラリ</td><td>◎</td><td>◎</td><td>△※</td></tr><tr><td>ESP32固有機能</td><td>○</td><td>○～◎</td><td>◎</td></tr><tr><td>複数環境管理</td><td>△</td><td>◎</td><td>○</td></tr><tr><td>本格デバッグ</td><td>△</td><td>○～◎</td><td>◎</td></tr><tr><td>設定自由度</td><td>○</td><td>◎</td><td>◎</td></tr><tr><td>学習コスト</td><td>低</td><td>中</td><td>高</td></tr><tr><td>小規模試作</td><td>◎</td><td>◎</td><td>○</td></tr><tr><td>大規模Firmware</td><td>△</td><td>○～◎</td><td>◎</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">※ArduinoをESP-IDF Componentとして利用する方法もあります。Espressifも公式にこの構成をサポートしています。</p>



<p class="wp-block-paragraph">この表だけを見るとESP-IDFが最も高機能に見えますが、<strong>高機能＝すべての用途で使いやすい、ではありません。</strong></p>



<p class="wp-block-paragraph">LEDを点滅させたり、センサーを一つ接続したりするだけなら、Arduino IDEの手軽さは大きなメリットです。</p>



<p class="wp-block-paragraph">逆に複数人でFirmwareを管理したり、細かなESP32の設定を扱ったりする場合には、ESP-IDFやPlatformIOが便利になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Arduino IDE｜まずESP32を動かしたいなら強い</h2>



<p class="wp-block-paragraph">Arduino IDEの最大のメリットは、<strong>始めるまでのハードルが低いこと</strong>です。</p>



<p class="wp-block-paragraph">ESP32用のArduino Coreを導入すれば、Arduinoと同じような書き方でESP32を開発できます。</p>



<p class="wp-block-paragraph">代表的なのが、</p>



<pre class="wp-block-code"><code>void setup()
{
    Serial.begin(115200);
}

void loop()
{
}</code></pre>



<p class="wp-block-paragraph">というおなじみの構造です。</p>



<p class="wp-block-paragraph">GPIO、UART、I²C、SPI、Wi-FiなどもArduino APIや対応ライブラリを利用して比較的簡単に扱えます。</p>



<h2 class="wp-block-heading">Arduino IDEのメリット</h2>



<p class="wp-block-paragraph">特に大きいのが<strong>情報量とライブラリの多さ</strong>です。</p>



<p class="wp-block-paragraph">ESP32で何かを動かそうとして検索すると、Arduino向けのサンプルコードが大量に見つかります。</p>



<p class="wp-block-paragraph">センサー、LCD、モーター、クラウドサービスなどについても、Arduino対応ライブラリが用意されていることがあります。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>まずESP32を触ってみたい</strong><br><strong>短時間で試作品を作りたい</strong><br><strong>既存ライブラリを利用したい</strong></p>



<p class="wp-block-paragraph">という場合には非常に便利です。</p>



<h2 class="wp-block-heading">Arduino IDEのデメリット</h2>



<p class="wp-block-paragraph">一方、プロジェクトが大きくなると管理面で物足りなさを感じる場合があります。</p>



<p class="wp-block-paragraph">ソースファイルが増えたり、複数のビルド条件を管理したり、ライブラリやFrameworkのバージョンを厳密に固定したりすると、より高度なプロジェクト管理が欲しくなります。</p>



<p class="wp-block-paragraph">また、ESP32固有の細かな設定を扱う場合には、ESP-IDFの方が直接的です。</p>



<p class="wp-block-paragraph">Arduino IDEが「簡易版ESP32開発環境」という意味ではありませんが、<strong>プロジェクトの規模や要求が大きくなるにつれて別の環境を検討する余地が出てくる</strong>と考えると分かりやすいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PlatformIO + VS Code｜Arduinoから一段進んだ開発環境</h2>



<p class="wp-block-paragraph">Arduino Frameworkを使いたいけれど、プロジェクト管理もしっかり行いたい。</p>



<p class="wp-block-paragraph">そんな場合に有力なのが<strong>PlatformIO + Visual Studio Code</strong>です。</p>



<p class="wp-block-paragraph">PlatformIOでは、プロジェクトごとに<code>platformio.ini</code>を持ち、</p>



<pre class="wp-block-code"><code>&#91;env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino</code></pre>



<p class="wp-block-paragraph">のように使用するPlatform、Board、Frameworkなどを設定できます。ESP32ではArduino FrameworkだけでなくESP-IDFも選択できます。</p>



<h2 class="wp-block-heading">PlatformIOのメリット</h2>



<p class="wp-block-paragraph">PlatformIOの大きなメリットは、<strong>開発条件をプロジェクトとして管理しやすいこと</strong>です。</p>



<p class="wp-block-paragraph">たとえば一つのプロジェクトでも、</p>



<ul class="wp-block-list">
<li>使用Board</li>



<li>Framework</li>



<li>Build Option</li>



<li>ライブラリ依存関係</li>



<li>Upload設定</li>



<li>Debug設定</li>
</ul>



<p class="wp-block-paragraph">などを管理できます。</p>



<p class="wp-block-paragraph">さらに複数のEnvironmentを定義すれば、同じソースコードを異なるBoardや設定でビルドするといった使い方もできます。</p>



<p class="wp-block-paragraph">Gitでソースコードを管理する場合にも相性がよく、別のPCへ開発環境を移すときにも構成を再現しやすくなります。</p>



<p class="wp-block-paragraph">PlatformIOにはESP32向けのデバッグやUnit Testingなどの仕組みも用意されています。</p>



<h2 class="wp-block-heading">PlatformIOのデメリット</h2>



<p class="wp-block-paragraph">Arduino IDEと比較すると、最初に覚えることは増えます。</p>



<p class="wp-block-paragraph">特に、</p>



<p class="wp-block-paragraph"><code>platformio.ini</code><br>Environment<br>Build Flags<br>Library Dependency</p>



<p class="wp-block-paragraph">など、PlatformIO独自の仕組みを理解する必要があります。</p>



<p class="wp-block-paragraph">Arduino IDEならメニューからBoardを選択して書き込むだけだったところを、設定ファイルで管理する場面も増えます。</p>



<p class="wp-block-paragraph">また、PlatformIO自身とFrameworkのバージョン関係を意識する必要が出ることもあります。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32を初めて触る人が必ずPlatformIOから始める必要はない</strong></p>
</blockquote>



<p class="wp-block-paragraph">と思います。</p>



<p class="wp-block-paragraph">Arduino IDEでESP32の基本を理解した後、「プロジェクト管理をもっとしっかりしたい」と感じた時点でPlatformIOへ移るのも十分現実的です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PlatformIOはArduino専用ではない</h2>



<p class="wp-block-paragraph">ここは意外と誤解されやすい部分です。</p>



<p class="wp-block-paragraph">PlatformIOは、</p>



<p class="wp-block-paragraph"><strong>ArduinoをVS Codeで使うためだけのツールではありません。</strong></p>



<p class="wp-block-paragraph">ESP32では、</p>



<pre class="wp-block-code"><code>framework = arduino</code></pre>



<p class="wp-block-paragraph">だけでなく、</p>



<pre class="wp-block-code"><code>framework = espidf</code></pre>



<p class="wp-block-paragraph">としてESP-IDFを使用することもできます。PlatformIO公式のEspressif 32 Platformでも両Frameworkがサポートされています。</p>



<p class="wp-block-paragraph">つまり、</p>



<pre class="wp-block-code"><code>VS Code
   │
PlatformIO
   ├── Arduino Framework
   │
   └── ESP-IDF</code></pre>



<p class="wp-block-paragraph">という使い方ができます。</p>



<p class="wp-block-paragraph">この点を理解すると、</p>



<p class="wp-block-paragraph"><strong>Arduino IDE → PlatformIO → ESP-IDF</strong></p>



<p class="wp-block-paragraph">という一直線の「初心者→上級者」の関係ではないことが分かります。</p>



<p class="wp-block-paragraph">PlatformIOを使いながらArduino Frameworkで開発することもできますし、ESP-IDFで開発することもできます。</p>



<p class="wp-block-paragraph">開発環境とFrameworkを分けて考えることが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDF + VS Code｜ESP32を本格的に扱う公式環境</h2>



<p class="wp-block-paragraph">ESP-IDFは、Espressifが提供する<strong>ESP32シリーズの公式開発Framework</strong>です。</p>



<p class="wp-block-paragraph">ESP32の機能をより直接的に扱うことができます。</p>



<p class="wp-block-paragraph">以前は、</p>



<p class="wp-block-paragraph">「ESP-IDFはコマンドライン操作が多くて難しい」</p>



<p class="wp-block-paragraph">というイメージを持っていた人もいるかもしれません。</p>



<p class="wp-block-paragraph">現在はEspressif公式のVS Code Extensionが用意されており、VS Code上からESP-IDFプロジェクトを扱えます。</p>



<p class="wp-block-paragraph">Build、Flash、Monitorだけでなく、GDB/OpenOCDを利用したデバッグも公式Extensionから利用できます。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP-IDF＝ターミナルだけで開発する環境</strong></p>
</blockquote>



<p class="wp-block-paragraph">という理解は現在では正確ではありません。</p>



<p class="wp-block-paragraph">もちろん内部ではCMakeやESP-IDFのBuild Systemが動いているため、それらの知識が必要になる場面はあります。</p>



<p class="wp-block-paragraph">しかし普段のBuild・Flash・MonitorなどはVS Code上から操作できます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDFを使うメリット</h2>



<p class="wp-block-paragraph">ESP-IDFを選ぶ大きな理由は、<strong>ESP32が持っている機能を公式Frameworkから直接利用できること</strong>です。</p>



<p class="wp-block-paragraph">Arduino FrameworkでもESP32の多くの機能を利用できますが、より細かな設定やESP32固有機能を扱うようになると、ESP-IDFの方が分かりやすい場合があります。</p>



<p class="wp-block-paragraph">たとえば、</p>



<ul class="wp-block-list">
<li>FreeRTOS</li>



<li>Wi-Fi / Bluetooth</li>



<li>Partition Table</li>



<li>NVS</li>



<li>OTA</li>



<li>Power Management</li>



<li>Watchdog</li>



<li>Heap管理</li>



<li>Logging</li>



<li>JTAG Debug</li>



<li>Core Dump</li>
</ul>



<p class="wp-block-paragraph">などを本格的に扱う場合です。</p>



<p class="wp-block-paragraph">ESP-IDFでは、これらが公式ドキュメントの中で体系的に整理されています。</p>



<p class="wp-block-paragraph">特に製品開発では、「とりあえず動いた」だけでなく、</p>



<p class="wp-block-paragraph"><strong>なぜ動いているのか</strong><br><strong>異常時に何が起きるのか</strong><br><strong>メモリをどれだけ使用しているのか</strong><br><strong>どのバージョンでビルドしたのか</strong></p>



<p class="wp-block-paragraph">といったところまで管理したくなります。</p>



<p class="wp-block-paragraph">このような開発ではESP-IDFのメリットが大きくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP-IDFのデメリット</h2>



<p class="wp-block-paragraph">一方、ESP-IDFはArduino IDEと比較すると学習する内容が多くなります。</p>



<p class="wp-block-paragraph">たとえばESP-IDFのプロジェクトでは、</p>



<pre class="wp-block-code"><code>project
├── CMakeLists.txt
├── sdkconfig
└── main
    ├── CMakeLists.txt
    └── main.c</code></pre>



<p class="wp-block-paragraph">のような構成を目にします。</p>



<p class="wp-block-paragraph">さらに、</p>



<ul class="wp-block-list">
<li>CMake</li>



<li>Component</li>



<li>menuconfig</li>



<li>sdkconfig</li>



<li>FreeRTOS</li>



<li>Build System</li>
</ul>



<p class="wp-block-paragraph">など、ESP-IDF独自の仕組みを理解する必要があります。</p>



<p class="wp-block-paragraph">最初は、</p>



<p class="wp-block-paragraph">「LEDを点滅させたいだけなのに、覚えることが多い」</p>



<p class="wp-block-paragraph">と感じるかもしれません。</p>



<p class="wp-block-paragraph">これはESP-IDFが難しいというより、<strong>ESP32が持っている機能を細かく扱える分、開発者が理解する範囲も広くなる</strong>と考えるとよいでしょう。</p>



<p class="wp-block-paragraph">そのため、ESP32を初めて使う人が必ずESP-IDFから始める必要はありません。</p>



<p class="wp-block-paragraph">まずArduino IDEでESP32そのものに慣れ、必要になった段階でESP-IDFへ進む方法もあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ArduinoとESP-IDFでコードは流用できる？</h2>



<p class="wp-block-paragraph">ここは開発環境を変更するときに気になるポイントです。</p>



<p class="wp-block-paragraph">結論として、<strong>すべてのコードをそのまま移せるとは限りません。</strong></p>



<p class="wp-block-paragraph">たとえばArduinoでは、</p>



<pre class="wp-block-code"><code>digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);</code></pre>



<p class="wp-block-paragraph">のように記述できます。</p>



<p class="wp-block-paragraph">一方、ESP-IDFではGPIO DriverやFreeRTOSのAPIなどを使用して実装できます。</p>



<p class="wp-block-paragraph">つまり、実現している機能は同じでも、使用するAPIが異なる場合があります。</p>



<p class="wp-block-paragraph">ただし、</p>



<ul class="wp-block-list">
<li>自分で作成した計算処理</li>



<li>通信Protocolの処理</li>



<li>データ変換</li>



<li>状態遷移</li>



<li>デバイスに依存しないC/C++コード</li>
</ul>



<p class="wp-block-paragraph">などは、設計次第で流用しやすくできます。</p>



<p class="wp-block-paragraph">これはESP32に限った話ではありません。</p>



<p class="wp-block-paragraph">Firmwareを作るときに、<strong>Hardware依存部分とApplication部分を分離しておく</strong>と、FrameworkやMCUを変更するときの移植が楽になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ArduinoからESP-IDFへ途中で変更できる？</h2>



<p class="wp-block-paragraph">変更すること自体は可能です。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ArduinoプロジェクトをESP-IDFプロジェクトへ変換するボタンを押せば終わり</strong></p>
</blockquote>



<p class="wp-block-paragraph">というものではありません。</p>



<p class="wp-block-paragraph">Arduino固有APIやArduino向けLibraryを大量に使用している場合は、それらをどう扱うか検討する必要があります。</p>



<p class="wp-block-paragraph">小規模なプログラムならESP-IDFで書き直すこともできますが、ある程度開発が進んだプロジェクトでは移行工数が大きくなる可能性があります。</p>



<p class="wp-block-paragraph">そのため、製品開発では開発初期に、</p>



<p class="wp-block-paragraph"><strong>最終的にどこまでESP32の機能を使うのか</strong></p>



<p class="wp-block-paragraph">をある程度考えておくことをおすすめします。</p>



<p class="wp-block-paragraph">たとえば、</p>



<p class="wp-block-paragraph">「Wi-Fiでデータを送るだけ」</p>



<p class="wp-block-paragraph">という製品と、</p>



<p class="wp-block-paragraph">「Wi-FiとBLEを同時使用し、OTA、NVS、複数Task、Watchdog、低消費電力制御まで行う」</p>



<p class="wp-block-paragraph">という製品では、必要になる開発環境も変わってきます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ArduinoをESP-IDFの中で使う方法もある</h2>



<p class="wp-block-paragraph">ここまで読むと、</p>



<p class="wp-block-paragraph"><strong>ArduinoかESP-IDFのどちらかを選ばなければならない</strong></p>



<p class="wp-block-paragraph">ように見えるかもしれません。</p>



<p class="wp-block-paragraph">実際には、その中間的な方法もあります。</p>



<p class="wp-block-paragraph">Arduino-ESP32は、<strong>ESP-IDFのComponentとして利用することができます。</strong> EspressifのArduino-ESP32公式ドキュメントでも、この構成が案内されています。</p>



<p class="wp-block-paragraph">イメージとしては、</p>



<pre class="wp-block-code"><code>ESP-IDF Project
│
├── ESP-IDF Component
├── 自作Component
│
└── Arduino Component
       └── Arduino API / Library</code></pre>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">これによってESP-IDFをベースにしながら、必要な部分でArduinoのAPIやLibraryを利用できます。</p>



<p class="wp-block-paragraph">ただし、当然ながら構成はArduino IDE単体より複雑になります。</p>



<p class="wp-block-paragraph">また、ESP-IDFとArduino Coreには対応するバージョンの組み合わせがあるため、<strong>好きなバージョン同士を自由に組み合わせられるわけではありません。</strong></p>



<p class="wp-block-paragraph">単純なプロジェクトで無理に採用する必要はありませんが、</p>



<p class="wp-block-paragraph">「ESP-IDFへ移行したいが、既存のArduino資産も利用したい」</p>



<p class="wp-block-paragraph">という場合には選択肢になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PlatformIOとESP-IDF + VS Codeはどちらを選ぶ？</h2>



<p class="wp-block-paragraph">この2つも迷いやすいところです。</p>



<p class="wp-block-paragraph">どちらもVS Codeを使えるため、画面だけを見ると似ています。</p>



<p class="wp-block-paragraph">しかし、考え方には違いがあります。</p>



<p class="wp-block-paragraph"><strong>PlatformIO + ESP-IDF</strong>では、PlatformIOがプロジェクトやToolchainなどを管理し、そのFrameworkとしてESP-IDFを使用します。</p>



<p class="wp-block-paragraph">一方、</p>



<p class="wp-block-paragraph"><strong>ESP-IDF + 公式VS Code Extension</strong>では、Espressif公式のESP-IDF環境をVS Codeから操作します。</p>



<p class="wp-block-paragraph">そのため、ESP-IDFそのものを深く扱いたいのであれば、私は<strong>ESP-IDF + 公式VS Code Extension</strong>を選択肢の中心に置くのが分かりやすいと思います。</p>



<p class="wp-block-paragraph">Espressifの公式Extensionでは、Build・Flash・Monitorだけでなく、Debug、Core Dump、Heap TraceなどESP-IDF向けの機能も提供されています。</p>



<p class="wp-block-paragraph">一方で、</p>



<p class="wp-block-paragraph"><strong>ArduinoとESP-IDFをプロジェクトごとに使い分けたい</strong><br><strong>複数のMCU Platformを同じ開発環境で管理したい</strong></p>



<p class="wp-block-paragraph">という場合にはPlatformIOのメリットがあります。</p>



<p class="wp-block-paragraph">どちらが優れているというより、<strong>何を中心に管理したいかの違い</strong>です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">結局どのESP32開発環境を選べばいい？</h2>



<p class="wp-block-paragraph">ここまでの内容を用途別に整理します。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>用途</th><th>おすすめ</th></tr></thead><tbody><tr><td>ESP32を初めて触る</td><td>Arduino IDE</td></tr><tr><td>LED・センサーなどを試したい</td><td>Arduino IDE</td></tr><tr><td>Arduino資産を活用したい</td><td>Arduino IDE / PlatformIO</td></tr><tr><td>VS CodeでArduino開発したい</td><td>PlatformIO</td></tr><tr><td>複数Board・Build条件を管理したい</td><td>PlatformIO</td></tr><tr><td>ESP32固有機能を深く使いたい</td><td>ESP-IDF</td></tr><tr><td>FreeRTOSを本格的に使いたい</td><td>ESP-IDF</td></tr><tr><td>JTAG Debugなどを活用したい</td><td>ESP-IDF</td></tr><tr><td>長期保守するFirmware</td><td>PlatformIO / ESP-IDF</td></tr><tr><td>ESP32以外のMCUも同じ環境で扱いたい</td><td>PlatformIO</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">ただし、この表は絶対的なものではありません。</p>



<p class="wp-block-paragraph">製品開発でもArduino Frameworkを採用することはできますし、個人の電子工作でESP-IDFを使っても問題ありません。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>開発者のレベルではなく、プロジェクトに必要な機能と管理方法で選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「製品開発ならESP-IDF」は本当？</h2>



<p class="wp-block-paragraph">ESP32について調べていると、</p>



<p class="wp-block-paragraph"><strong>「趣味ならArduino、仕事ならESP-IDF」</strong></p>



<p class="wp-block-paragraph">という説明を見かけることがあります。</p>



<p class="wp-block-paragraph">これは少し単純化しすぎています。</p>



<p class="wp-block-paragraph">製品Firmwareで重要なのは、Frameworkの名前そのものではなく、</p>



<ul class="wp-block-list">
<li>使用バージョンを管理できる</li>



<li>Build環境を再現できる</li>



<li>Source Codeを管理できる</li>



<li>エラー処理が設計されている</li>



<li>Watchdogなど異常時の動作を考慮している</li>



<li>Update方法を管理できる</li>



<li>長期間保守できる</li>
</ul>



<p class="wp-block-paragraph">といった点です。</p>



<p class="wp-block-paragraph">Arduino Frameworkを使っていても、これらを適切に管理できていれば製品開発は可能です。</p>



<p class="wp-block-paragraph">逆にESP-IDFを使っただけで、Firmwareの品質が自動的に上がるわけではありません。</p>



<p class="wp-block-paragraph">ただし、ESP32の機能を深く利用する製品では、ESP-IDFの公式APIやDebug機能、設定機能などが大きなメリットになります。</p>



<p class="wp-block-paragraph">そのため、要求仕様が複雑になるほどESP-IDFを選ぶ理由が増えていく、と考えるのがよいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">迷ったらこの順番でもよい</h2>



<p class="wp-block-paragraph">ESP32を初めて使う場合、最初から将来のすべてを予測する必要はありません。</p>



<p class="wp-block-paragraph">一つの考え方として、</p>



<pre class="wp-block-code"><code>まずESP32を動かしたい
        ↓
    Arduino IDE
        ↓
プロジェクト管理が必要
        ↓
 PlatformIO + Arduino
        ↓
ESP32固有機能を深く扱いたい
        ↓
 ESP-IDF + VS Code</code></pre>



<p class="wp-block-paragraph">という進み方もできます。</p>



<p class="wp-block-paragraph">ただし、これは「レベルアップの順番」という意味ではありません。</p>



<p class="wp-block-paragraph">Arduino IDEで十分なら、そのまま使い続けても問題ありません。</p>



<p class="wp-block-paragraph">PlatformIOが自分の開発方法に合っていれば、ESP-IDFへ移行する必要もありません。</p>



<p class="wp-block-paragraph"><strong>必要になったときに環境を変える。</strong></p>



<p class="wp-block-paragraph">これくらいの考え方でよいと思います。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜ESP32の開発環境は用途で選ぶ</h2>



<p class="wp-block-paragraph">ESP32では、Arduino IDE、PlatformIO、ESP-IDFなど複数の方法でFirmwareを開発できます。</p>



<p class="wp-block-paragraph">それぞれに特徴があります。</p>



<p class="wp-block-paragraph"><strong>Arduino IDE</strong><br>手軽に始められ、Arduinoの豊富なLibraryやサンプルを利用しやすい。</p>



<p class="wp-block-paragraph"><strong>PlatformIO + VS Code</strong><br>プロジェクトや依存関係、複数のBuild環境を管理しやすく、ArduinoとESP-IDFの両方を扱える。</p>



<p class="wp-block-paragraph"><strong>ESP-IDF + VS Code</strong><br>Espressif公式Frameworkを使用し、ESP32固有機能やDebug機能を本格的に扱える。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>「どれが一番高機能か」ではなく、「自分の開発に何が必要か」で選ぶこと</strong></p>
</blockquote>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">ESP32を初めて触るならArduino IDEから始めてもよいでしょう。</p>



<p class="wp-block-paragraph">Arduinoを使いながら開発環境を整理したくなったらPlatformIO、ESP32の機能をより深く扱いたくなったらESP-IDFという選択肢があります。</p>



<p class="wp-block-paragraph">そして製品開発では、開発環境の名前以上に、<strong>バージョン管理・再現性・デバッグ・保守まで含めて開発環境を選定すること</strong>が重要です。</p>



<p class="wp-block-paragraph">ESP32シリーズそのものをまだ決めていない場合は、既存記事の**「ESP32シリーズの選び方」**へつなぎましょう。</p>



<p class="wp-block-paragraph">また、ESP-IDFをこれから使う読者には、既存の**「ESP-IDF初心者がつまずく5つのポイント」**への内部リンクが非常に自然です。</p>



<p class="wp-block-paragraph">今回の記事を間に置くことで、</p>



<p class="wp-block-paragraph"><strong>ESP32シリーズを選ぶ → 開発環境を選ぶ → ESP-IDFを実際に使う</strong></p>



<p class="wp-block-paragraph">という流れができます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">関連記事</h2>



<p class="wp-block-paragraph">ESP32シリーズの選び方</p>



<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="xihBMe1O2X"><a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/">ESP32シリーズの選び方｜用途別におすすめのESP32を現役エンジニアが解説</a></blockquote><iframe title="“ESP32シリーズの選び方｜用途別におすすめのESP32を現役エンジニアが解説” — 江藤良樹の仕事は物づくり" sandbox="allow-scripts" security="restricted" src="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/embed/#?secret=xihBMe1O2X" width="600" height="338" data-secret="xihBMe1O2X" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe><script>/*! This file is auto-generated */!function(d,l){"use strict";l.querySelector&&d.addEventListener&&"undefined"!=typeof URL&&(d.wp=d.wp||{},d.wp.receiveEmbedMessage||(d.wp.receiveEmbedMessage=function(e){var t=e.data;if((t||t.secret||t.message||t.value)&&!/[^a-zA-Z0-9]/.test(t.secret)){for(var s,r,n,a=l.querySelectorAll('iframe[data-secret="'+t.secret+'"]'),o=l.querySelectorAll('blockquote[data-secret="'+t.secret+'"]'),c=new RegExp("^https?:$","i"),i=0;i<o.length;i++)o[i].style.display="none";for(i=0;i<a.length;i++)s=a[i],e.source===s.contentWindow&#038;&#038;(s.removeAttribute("style"),"height"===t.message?(1e3<(r=parseInt(t.value,10))?r=1e3:~~r<200&#038;&#038;(r=200),s.height=r):"link"===t.message&#038;&#038;(r=new URL(s.getAttribute("src")),n=new URL(t.value),c.test(n.protocol))&#038;&#038;n.host===r.host&#038;&#038;l.activeElement===s&#038;&#038;(d.top.location.href=t.value))}},d.addEventListener("message",d.wp.receiveEmbedMessage,!1),l.addEventListener("DOMContentLoaded",function(){for(var e,t,s=l.querySelectorAll("iframe.wp-embedded-content"),r=0;r<s.length;r++)(t=(e=s[r]).getAttribute("data-secret"))||(t=Math.random().toString(36).substring(2,12),e.src+="#?secret="+t,e.setAttribute("data-secret",t)),e.contentWindow.postMessage({message:"ready",secret:t},"*")},!1)))}(window,document);//# sourceURL=https://dlrow-design.net/wp-includes/js/wp-embed.min.js</script>
</div></figure>



<p class="wp-block-paragraph"></p>The post <a href="https://dlrow-design.net/esp32%e3%81%ae%e9%96%8b%e7%99%ba%e7%92%b0%e5%a2%83%e3%82%92%e6%af%94%e8%bc%83%ef%bd%9carduino-ide%e3%83%bbplatformio%e3%83%bbesp-idf%e3%81%af%e3%81%a9%e3%82%8c%e3%82%92%e9%81%b8%e3%81%b6%ef%bc%9f/">ESP32の開発環境を比較｜Arduino IDE・PlatformIO・ESP-IDFはどれを選ぶ？</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32に技適は必要？自作基板・製品化で知っておきたい電波法を解説</title>
		<link>https://dlrow-design.net/esp32%e3%81%ab%e6%8a%80%e9%81%a9%e3%81%af%e5%bf%85%e8%a6%81%ef%bc%9f%e8%87%aa%e4%bd%9c%e5%9f%ba%e6%9d%bf%e3%83%bb%e8%a3%bd%e5%93%81%e5%8c%96%e3%81%a7%e7%9f%a5%e3%81%a3%e3%81%a6%e3%81%8a%e3%81%8d/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25ab%25e6%258a%2580%25e9%2581%25a9%25e3%2581%25af%25e5%25bf%2585%25e8%25a6%2581%25ef%25bc%259f%25e8%2587%25aa%25e4%25bd%259c%25e5%259f%25ba%25e6%259d%25bf%25e3%2583%25bb%25e8%25a3%25bd%25e5%2593%2581%25e5%258c%2596%25e3%2581%25a7%25e7%259f%25a5%25e3%2581%25a3%25e3%2581%25a6%25e3%2581%258a%25e3%2581%258d</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Thu, 20 Aug 2026 15:20:31 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=818</guid>

					<description><![CDATA[<p>ESP32はWi-FiやBluetoothを手軽に利用できるため、電子工作から製品開発まで幅広く使われています。 一方、ESP32を日本国内で使用するときに気になるのが「技適」です。 「ESP32には ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%ab%e6%8a%80%e9%81%a9%e3%81%af%e5%bf%85%e8%a6%81%ef%bc%9f%e8%87%aa%e4%bd%9c%e5%9f%ba%e6%9d%bf%e3%83%bb%e8%a3%bd%e5%93%81%e5%8c%96%e3%81%a7%e7%9f%a5%e3%81%a3%e3%81%a6%e3%81%8a%e3%81%8d/">ESP32に技適は必要？自作基板・製品化で知っておきたい電波法を解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32はWi-FiやBluetoothを手軽に利用できるため、電子工作から製品開発まで幅広く使われています。</p>



<p class="wp-block-paragraph">一方、ESP32を日本国内で使用するときに気になるのが「技適」です。</p>



<p class="wp-block-paragraph">「ESP32には技適が付いているから大丈夫」<br>「技適済みのWROOMモジュールを使えば、自作基板でも問題ない？」<br>「海外から購入したESP32開発ボードは日本で使える？」<br>「外付けアンテナへ変更しても技適はそのまま使える？」</p>



<p class="wp-block-paragraph">ESP32を使っていると、このような疑問が出てきます。</p>



<p class="wp-block-paragraph">結論から言うと、<strong>「ESP32だから技適OK」と一括りに判断することはできません。</strong></p>



<p class="wp-block-paragraph">確認する必要があるのはESP32というシリーズ名だけではなく、実際に使用する無線モジュールの型番、日本向け認証の有無、使用する周波数帯、アンテナなどの条件です。</p>



<p class="wp-block-paragraph">この記事では、ESP32を自作基板へ組み込む場合や製品へ採用する場合を想定して、技適を確認するときの基本的な考え方を解説します。</p>



<p class="wp-block-paragraph">※本記事は回路・基板設計を行う際の確認ポイントを整理したもので、個別製品について法令適合を保証するものではありません。製品化する場合は、使用するモジュールの最新認証資料や関係法令を確認してください。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">そもそも「技適」とは？</h2>



<p class="wp-block-paragraph">一般に「技適」と呼ばれているものには、電波法に基づく<strong>技術基準適合証明</strong>や<strong>工事設計認証</strong>などがあります。</p>



<p class="wp-block-paragraph">Wi-FiやBluetoothのように電波を送信する機器は、日本国内で使用するための技術基準を満たしている必要があります。</p>



<p class="wp-block-paragraph">その適合性を確認する仕組みの一つが技適です。</p>



<p class="wp-block-paragraph">ESP32の場合、Wi-FiやBluetoothを搭載した無線モジュールが多いため、日本国内で無線機能を使用するのであれば技適について確認する必要があります。</p>



<p class="wp-block-paragraph">ここで注意したいのが、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32というCPUそのものに一律で「技適あり」「技適なし」が決まっているわけではない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">実際に確認するのは、採用する無線モジュールや製品です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「ESP32なら技適取得済み」と考えない</h2>



<p class="wp-block-paragraph">ESP32には非常に多くの製品があります。<br>ESP32シリーズごとの機能や用途の違いについては、「<a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/" target="_blank" rel="noopener" title="ESP32シリーズの選び方">ESP32シリーズの選び方</a>」で詳しく解説しています。</p>



<p class="wp-block-paragraph">たとえば、</p>



<ul class="wp-block-list">
<li>ESP32-WROOMシリーズ</li>



<li>ESP32-S3-WROOMシリーズ</li>



<li>ESP32-C3-WROOMシリーズ</li>



<li>ESP32-C5-WROOMシリーズ</li>



<li>アンテナ内蔵型</li>



<li>外部アンテナ接続型</li>
</ul>



<p class="wp-block-paragraph">などがあります。</p>



<p class="wp-block-paragraph">さらに、それらを搭載した各メーカーの開発ボードも存在します。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>「ESP32-C5は技適を取得している」</strong></p>



<p class="wp-block-paragraph">という確認だけでは不十分です。</p>



<p class="wp-block-paragraph">確認するときは、</p>



<p class="wp-block-paragraph"><strong>実際に採用する完全なモジュール型番</strong></p>



<p class="wp-block-paragraph">まで特定します。</p>



<p class="wp-block-paragraph">Espressifは各製品について国・地域ごとの認証資料を公開しています。たとえばESP32-C5-WROOM-1についても、日本向けMIC認証として2.4GHz帯、2484MHz、5GHz帯の認証資料が公開されています。</p>



<p class="wp-block-paragraph"><a target="_blank" rel="noreferrer noopener" href="https://www.espressif.com/ja-jp/support/documents/certificates?utm_source=chatgpt.com">Espressif 認証・コンプライアンス一覧</a></p>



<p class="wp-block-paragraph">設計時には、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">ESP32だから大丈夫<br>↓<br><strong>採用するモジュール型番について、日本向けの認証内容を確認する</strong></p>
</blockquote>



<p class="wp-block-paragraph">という考え方にしておくと安全です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SoC単体と無線モジュールを区別する</h2>



<p class="wp-block-paragraph">ESP32を使った基板を設計するとき、もう一つ区別しておきたいのが<strong>SoC単体と無線モジュール</strong>です。</p>



<p class="wp-block-paragraph">ESP32シリーズのSoCを単体で購入して、自分でRF回路、アンテナ、発振回路などを設計する方法があります。</p>



<p class="wp-block-paragraph">一方、ESP32-WROOMなどのモジュールには、ESP32 SoCだけでなく、</p>



<ul class="wp-block-list">
<li>Flash</li>



<li>水晶発振器</li>



<li>RF回路</li>



<li>アンテナまたはアンテナコネクタ</li>



<li>シールド</li>
</ul>



<p class="wp-block-paragraph">などが一体化されています。</p>



<p class="wp-block-paragraph">そして、モジュール製品について日本向けの認証が取得されているものがあります。</p>



<p class="wp-block-paragraph">この違いは製品開発では非常に重要です。</p>



<p class="wp-block-paragraph">認証済みモジュールを採用する方法と、ESP32 SoCからRF回路まで自社設計する方法では、<strong>無線部分の設計・評価・認証に対する考え方が大きく変わります。</strong></p>



<p class="wp-block-paragraph">そのため、少量生産や初めて無線機能を搭載する製品では、認証状況を確認できるモジュールを採用することが現実的な選択肢になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">技適済みESP32モジュールを自作基板へ載せてもよい？</h2>



<p class="wp-block-paragraph">ここはESP32で自作基板を作るときに、特に気になる部分だと思います。</p>



<p class="wp-block-paragraph">たとえば、</p>



<pre class="wp-block-code"><code>自作基板
   │
   ├─ 電源回路
   ├─ センサー
   ├─ UART / SPI / I²C
   ├─ その他周辺回路
   │
   └─ ESP32-WROOM
        └─ 認証済み無線モジュール</code></pre>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">認証済みモジュールを自作基板へ実装することと、ESP32 SoCからRF回路を自分で設計することは同じではありません。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>「認証済みモジュールを使ったので、その後は何を変更しても技適上問題ない」</strong></p>
</blockquote>



<p class="wp-block-paragraph">と考えるのも危険です。</p>



<p class="wp-block-paragraph">認証されている無線設備には、認証を受けた工事設計があります。</p>



<p class="wp-block-paragraph">したがって、自作基板へ組み込む場合でも、<strong>認証されたモジュールをどのような条件で使用するのか</strong>を確認する必要があります。</p>



<p class="wp-block-paragraph">特にRF部分そのものを改造したり、メーカーが想定していないアンテナ構成へ変更したりする場合は注意が必要です。</p>



<p class="wp-block-paragraph">実際の設計では、</p>



<p class="wp-block-paragraph"><strong>モジュールを改造しない</strong><br><strong>メーカーのHardware Design Guidelinesを確認する</strong><br><strong>アンテナ周辺の実装条件を守る</strong><br><strong>使用するアンテナ条件を確認する</strong><br><strong>採用型番の認証資料を確認する</strong></p>



<p class="wp-block-paragraph">といった確認を行います。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">基板アンテナ型でもレイアウトは重要</h2>



<p class="wp-block-paragraph">ESP32-WROOMには、モジュール上にPCBアンテナを搭載した製品があります。</p>



<p class="wp-block-paragraph">このタイプはアンテナまでモジュール内に含まれているため、自作基板では比較的扱いやすい構成です。</p>



<p class="wp-block-paragraph">しかし、<strong>アンテナ内蔵だから基板上のどこへ配置してもよいわけではありません。</strong></p>



<p class="wp-block-paragraph">EspressifのHardware Design Guidelinesや各モジュールのデータシートには、アンテナ周辺の配置について推奨条件があります。</p>



<p class="wp-block-paragraph">たとえばアンテナ付近に、</p>



<ul class="wp-block-list">
<li>GND Plane</li>



<li>信号配線</li>



<li>電源配線</li>



<li>金属部品</li>



<li>コネクタ</li>



<li>筐体の金属</li>
</ul>



<p class="wp-block-paragraph">などが存在すると、アンテナ性能へ影響する可能性があります。</p>



<p class="wp-block-paragraph">そのため、基板設計ではモジュールを基板端へ配置したり、指定されたアンテナKeepoutを確保したりします。</p>



<p class="wp-block-paragraph">これは技適だけの問題ではなく、<strong>実際の通信距離や安定性にも直接関係する設計条件</strong>です。</p>



<p class="wp-block-paragraph">認証済みモジュールを採用したとしても、メーカーの推奨レイアウトを無視してよいわけではありません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">海外から購入したESP32開発ボードはどう考える？</h2>



<p class="wp-block-paragraph">ESP32の開発ボードは国内だけでなく、海外通販サイトからも簡単に購入できます。</p>



<p class="wp-block-paragraph">ここでも、</p>



<p class="wp-block-paragraph"><strong>「ESP32が載っているから技適あり」</strong></p>



<p class="wp-block-paragraph">とは判断しない方がよいでしょう。</p>



<p class="wp-block-paragraph">確認したいのは、実際に搭載されているモジュールと、その日本向け認証です。</p>



<p class="wp-block-paragraph">同じような外観の開発ボードでも、</p>



<ul class="wp-block-list">
<li>搭載モジュールが異なる</li>



<li>モジュールのメーカーが異なる</li>



<li>アンテナ仕様が異なる</li>



<li>日本向け認証を確認できない</li>
</ul>



<p class="wp-block-paragraph">といった可能性があります。</p>



<p class="wp-block-paragraph">特にESP32互換ボードやノーブランド品では、写真だけを見て判断するのではなく、<strong>実際に搭載されているモジュール型番を確認する</strong>ことが重要です。</p>



<p class="wp-block-paragraph">「ESP32搭載」という商品説明だけでは、日本国内で無線を使用するときの判断材料として十分ではありません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">外付けアンテナ型ESP32は特に注意する</h2>



<p class="wp-block-paragraph">ESP32-WROOMシリーズには、モジュール上にPCBアンテナを搭載したタイプだけでなく、外部アンテナを接続するタイプがあります。</p>



<p class="wp-block-paragraph">たとえばESP32-C5では、</p>



<p class="wp-block-paragraph"><strong>ESP32-C5-WROOM-1：PCBアンテナ型</strong><br><strong>ESP32-C5-WROOM-1U：外部アンテナコネクタ型</strong></p>



<p class="wp-block-paragraph">という違いがあります。</p>



<p class="wp-block-paragraph">外部アンテナ型には、</p>



<ul class="wp-block-list">
<li>筐体外へアンテナを配置できる</li>



<li>金属筐体でもアンテナ位置を調整しやすい</li>



<li>装置に合わせてアンテナ配置を最適化できる</li>
</ul>



<p class="wp-block-paragraph">といったメリットがあります。</p>



<p class="wp-block-paragraph">一方で、技適を考えるうえでは<strong>使用するアンテナについても確認が必要</strong>です。</p>



<p class="wp-block-paragraph">「モジュールが技適取得済みだから、好きなアンテナを接続してよい」と単純に考えることはできません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">アンテナの種類・利得・周波数帯を確認する</h2>



<p class="wp-block-paragraph">外付けアンテナを使用するときは、少なくとも、</p>



<ul class="wp-block-list">
<li>アンテナの種類</li>



<li>対応周波数</li>



<li>アンテナ利得</li>



<li>インピーダンス</li>



<li>コネクタ</li>



<li>ケーブルを含めた接続方法</li>
</ul>



<p class="wp-block-paragraph">を確認します。</p>



<p class="wp-block-paragraph">たとえばESP32-C5-WROOM-1Uのデータシートには、認証試験で使用された外部アンテナや、推奨する外部アンテナの仕様が記載されています。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>コネクタへ物理的に接続できるアンテナ＝そのまま使用条件を満たすアンテナ</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">特に高利得アンテナへ変更すると、無線設備全体としての条件が変わる可能性があります。</p>



<p class="wp-block-paragraph">外部アンテナ型を製品へ採用するときは、モジュールの認証資料だけでなく、<strong>使用予定のアンテナがメーカーの示す条件と整合しているか</strong>まで確認することが重要です。</p>



<p class="wp-block-paragraph">異なるアンテナを使用する場合には、追加評価や認証上の確認が必要になる可能性もあるため、メーカーや認証機関への確認を含めて判断します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32-C5の5GHz Wi-Fiでは何を確認する？</h2>



<p class="wp-block-paragraph">ESP32-C5の大きな特徴の一つが、<strong>2.4GHz帯だけでなく5GHz帯のWi-Fi 6に対応していること</strong>です。</p>



<p class="wp-block-paragraph">従来のESP32で2.4GHz Wi-Fiだけを使っていた場合、</p>



<p class="wp-block-paragraph">「C5なら5GHzも使える」</p>



<p class="wp-block-paragraph">という点は魅力的です。</p>



<p class="wp-block-paragraph">しかし、日本国内で使用する場合は、単にSoCが5GHz対応だから使用できると判断するのではなく、<strong>採用するモジュールについて日本向けの認証内容を確認する</strong>必要があります。</p>



<p class="wp-block-paragraph">EspressifはESP32-C5-WROOM-1について、日本向けMIC認証資料を公開しており、5GHz帯についても認証資料を確認できます。</p>



<p class="wp-block-paragraph">ここでも重要なのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32-C5が5GHz対応していることと、採用する製品を日本国内でどの条件でも5GHz運用できることは同じではない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">5GHz帯には、使用する周波数によって屋内・屋外利用などに条件があります。</p>



<p class="wp-block-paragraph">そのため製品設計では、</p>



<p class="wp-block-paragraph"><strong>どの周波数帯を使用するのか</strong><br><strong>日本向け認証がどうなっているのか</strong><br><strong>製品をどの環境で使用するのか</strong></p>



<p class="wp-block-paragraph">まで確認しておく必要があります。</p>



<p class="wp-block-paragraph">特に海外向けと日本向けで共通のFirmwareを使用する製品では、国・地域に応じた無線設定についても確認しておいた方がよいでしょう。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">技適済みモジュールなら製品として販売できる？</h2>



<p class="wp-block-paragraph">ここも混同しやすいポイントです。</p>



<p class="wp-block-paragraph"><strong>技適と、完成製品として必要になる法令・安全要求は別に考える必要があります。</strong></p>



<p class="wp-block-paragraph">技適済み無線モジュールを適切な条件で組み込んでいたとしても、それだけで完成製品に関係するすべての法令への適合が完了するわけではありません。</p>



<p class="wp-block-paragraph">製品によっては、</p>



<ul class="wp-block-list">
<li>電気用品安全法</li>



<li>EMC関連要求</li>



<li>使用するACアダプタや電源</li>



<li>表示</li>



<li>製品安全</li>
</ul>



<p class="wp-block-paragraph">など、別の確認が必要になる場合があります。</p>



<p class="wp-block-paragraph">したがって、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>「技適済みESP32を使ったから、この製品はそのまま販売できる」</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは判断しません。</p>



<p class="wp-block-paragraph">技適は、製品開発で確認する項目の一つとして扱います。</p>



<p class="wp-block-paragraph">何が必要になるかは製品構成や用途によって異なるため、量産・販売する場合には完成品として適用される法令や規格を別途確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">技適マーク・認証番号はどこで確認する？</h2>



<p class="wp-block-paragraph">ESP32モジュールを選定するときは、販売ページだけで判断せず、メーカーの公式資料を確認することをおすすめします。</p>



<p class="wp-block-paragraph">Espressifでは、各ESP32製品について国・地域別の認証資料を公開しています。</p>



<p class="wp-block-paragraph"><a target="_blank" rel="noreferrer noopener" href="https://www.espressif.com/en/support/documents/certificates?utm_source=chatgpt.com">Espressif Certifications &amp; Compliance</a></p>



<p class="wp-block-paragraph">ここで、</p>



<ol class="wp-block-list">
<li>採用予定の完全なモジュール型番を確認する</li>



<li>Japan / MICの認証資料を探す</li>



<li>使用する無線機能・周波数帯を確認する</li>



<li>外付けアンテナ型ならアンテナ条件も確認する</li>
</ol>



<p class="wp-block-paragraph">という順番で調べると分かりやすいでしょう。</p>



<p class="wp-block-paragraph">また、認証状況は新製品の追加などによって変わる可能性があります。</p>



<p class="wp-block-paragraph">ブログなどに書かれている古い認証番号だけを頼りにするのではなく、<strong>実際に設計・購入する時点の公式資料を確認する</strong>ことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32自作基板の技適チェックリスト</h2>



<p class="wp-block-paragraph">最後に、ESP32を使った自作基板を設計するときの確認項目をまとめます。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>確認項目</th><th>チェック内容</th></tr></thead><tbody><tr><td>モジュール型番</td><td>完全な型番まで特定したか</td></tr><tr><td>日本向け認証</td><td>MIC認証資料を確認したか</td></tr><tr><td>使用周波数</td><td>実際に使用する周波数帯を確認したか</td></tr><tr><td>モジュール改造</td><td>RF部分などを変更していないか</td></tr><tr><td>アンテナ</td><td>認証・メーカー指定条件と整合しているか</td></tr><tr><td>Keepout</td><td>アンテナ周辺の推奨レイアウトを守っているか</td></tr><tr><td>金属部品</td><td>アンテナ付近に影響するものがないか</td></tr><tr><td>5GHz</td><td>使用周波数・使用場所などの条件を確認したか</td></tr><tr><td>Firmware</td><td>使用地域に適した無線設定になっているか</td></tr><tr><td>製品化</td><td>技適以外に必要な法令・規格を確認したか</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">特に、</p>



<p class="wp-block-paragraph"><strong>モジュール型番</strong><br><strong>日本向け認証</strong><br><strong>アンテナ</strong></p>



<p class="wp-block-paragraph">の3項目は、最初の部品選定段階で確認しておくことをおすすめします。</p>



<p class="wp-block-paragraph">基板設計が終わってから使用予定のアンテナが認証条件と合わないことが分かると、アンテナや筐体まで変更することになりかねません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32を選定するときは認証も仕様の一部として考える</h2>



<p class="wp-block-paragraph">ESP32を選ぶときは、</p>



<ul class="wp-block-list">
<li>CPU性能</li>



<li>GPIO数</li>



<li>Wi-Fi</li>



<li>Bluetooth</li>



<li>Flash</li>



<li>PSRAM</li>



<li>USB</li>
</ul>



<p class="wp-block-paragraph">などの機能を比較することが多いと思います。</p>



<p class="wp-block-paragraph">しかし、実際の製品開発では<strong>認証状況もデバイス仕様の一部</strong>として考えた方がよいでしょう。</p>



<p class="wp-block-paragraph">特に新しいESP32シリーズを採用するときは、</p>



<p class="wp-block-paragraph">「性能が良いから採用する」</p>



<p class="wp-block-paragraph">だけでなく、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>使用予定の国・地域で必要な認証を確認できるか</strong></p>
</blockquote>



<p class="wp-block-paragraph">まで部品選定時に確認しておくと、後工程での手戻りを減らせます。</p>



<p class="wp-block-paragraph">これはESP32に限らず、Wi-Fi、Bluetooth、LTEなどの無線モジュールを採用するときにも共通する考え方です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜「ESP32だから技適OK」ではなく型番と使用条件を確認する</h2>



<p class="wp-block-paragraph">ESP32を日本国内で使用するときは、単に「ESP32には技適がある」と判断するのではなく、<strong>実際に採用するモジュールについて確認することが重要</strong>です。</p>



<p class="wp-block-paragraph">確認の基本は、</p>



<p class="wp-block-paragraph"><strong>完全なモジュール型番を確認する</strong><br>↓<br><strong>日本向け認証を確認する</strong><br>↓<br><strong>使用する周波数帯を確認する</strong><br>↓<br><strong>アンテナ条件を確認する</strong><br>↓<br><strong>実際の基板・製品への組み込み条件を確認する</strong></p>



<p class="wp-block-paragraph">という流れです。</p>



<p class="wp-block-paragraph">特に外付けアンテナ型では、モジュールの認証だけを見て終わらず、使用するアンテナの仕様まで確認します。</p>



<p class="wp-block-paragraph">また、技適済みモジュールを採用することと、完成製品として必要なすべての法令・規格へ適合することは別です。</p>



<p class="wp-block-paragraph">ESP32を製品へ採用する場合には、**無線認証も回路や部品と同じ「設計条件の一つ」**として扱うことが大切です。</p>



<p class="wp-block-paragraph">認証や法令は更新される可能性があるため、最終的な製品設計ではメーカーの最新認証資料や公的情報を確認してください。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">関連記事</h2>



<p class="wp-block-paragraph">ESP32シリーズの選び方｜用途別におすすめのESP32を解説</p>



<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="NAESWO65fa"><a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/">ESP32シリーズの選び方｜用途別におすすめのESP32を現役エンジニアが解説</a></blockquote><iframe title="“ESP32シリーズの選び方｜用途別におすすめのESP32を現役エンジニアが解説” — 江藤良樹の仕事は物づくり" sandbox="allow-scripts" security="restricted" src="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e9%81%b8%e3%81%b3%e6%96%b9%ef%bd%9c%e7%94%a8%e9%80%94%e5%88%a5%e3%81%ab%e3%81%8a%e3%81%99%e3%81%99%e3%82%81%e3%81%aeesp32%e3%82%92%e7%8f%be%e5%bd%b9/embed/#?secret=NAESWO65fa" width="600" height="338" data-secret="NAESWO65fa" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe><script>/*! This file is auto-generated */!function(d,l){"use strict";l.querySelector&&d.addEventListener&&"undefined"!=typeof URL&&(d.wp=d.wp||{},d.wp.receiveEmbedMessage||(d.wp.receiveEmbedMessage=function(e){var t=e.data;if((t||t.secret||t.message||t.value)&&!/[^a-zA-Z0-9]/.test(t.secret)){for(var s,r,n,a=l.querySelectorAll('iframe[data-secret="'+t.secret+'"]'),o=l.querySelectorAll('blockquote[data-secret="'+t.secret+'"]'),c=new RegExp("^https?:$","i"),i=0;i<o.length;i++)o[i].style.display="none";for(i=0;i<a.length;i++)s=a[i],e.source===s.contentWindow&#038;&#038;(s.removeAttribute("style"),"height"===t.message?(1e3<(r=parseInt(t.value,10))?r=1e3:~~r<200&#038;&#038;(r=200),s.height=r):"link"===t.message&#038;&#038;(r=new URL(s.getAttribute("src")),n=new URL(t.value),c.test(n.protocol))&#038;&#038;n.host===r.host&#038;&#038;l.activeElement===s&#038;&#038;(d.top.location.href=t.value))}},d.addEventListener("message",d.wp.receiveEmbedMessage,!1),l.addEventListener("DOMContentLoaded",function(){for(var e,t,s=l.querySelectorAll("iframe.wp-embedded-content"),r=0;r<s.length;r++)(t=(e=s[r]).getAttribute("data-secret"))||(t=Math.random().toString(36).substring(2,12),e.src+="#?secret="+t,e.setAttribute("data-secret",t)),e.contentWindow.postMessage({message:"ready",secret:t},"*")},!1)))}(window,document);//# sourceURL=https://dlrow-design.net/wp-includes/js/wp-embed.min.js</script>
</div></figure>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">ESP32シリーズにピン互換性はある？ESP32・S3・C3・C5の置き換えを徹底解説</p>



<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="dZSDvPZeuK"><a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e6%8e%a5%e7%b6%9a%e3%83%94%e3%83%b3%e4%ba%92%e6%8f%9b%e6%80%a7%ef%bd%9cc3%e3%83%bbc5%e3%83%bbs3%e3%81%b8%e7%bd%ae%e3%81%8d%e6%8f%9b%e3%81%88%e3%82%8b/">ESP32シリーズの接続ピン互換性｜C3・C5・S3へ置き換える前に確認したいポイント</a></blockquote><iframe title="“ESP32シリーズの接続ピン互換性｜C3・C5・S3へ置き換える前に確認したいポイント” — 江藤良樹の仕事は物づくり" sandbox="allow-scripts" security="restricted" src="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ae%e6%8e%a5%e7%b6%9a%e3%83%94%e3%83%b3%e4%ba%92%e6%8f%9b%e6%80%a7%ef%bd%9cc3%e3%83%bbc5%e3%83%bbs3%e3%81%b8%e7%bd%ae%e3%81%8d%e6%8f%9b%e3%81%88%e3%82%8b/embed/#?secret=dZSDvPZeuK" width="600" height="338" data-secret="dZSDvPZeuK" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" class="wp-embedded-content"></iframe><script>/*! This file is auto-generated */!function(d,l){"use strict";l.querySelector&&d.addEventListener&&"undefined"!=typeof URL&&(d.wp=d.wp||{},d.wp.receiveEmbedMessage||(d.wp.receiveEmbedMessage=function(e){var t=e.data;if((t||t.secret||t.message||t.value)&&!/[^a-zA-Z0-9]/.test(t.secret)){for(var s,r,n,a=l.querySelectorAll('iframe[data-secret="'+t.secret+'"]'),o=l.querySelectorAll('blockquote[data-secret="'+t.secret+'"]'),c=new RegExp("^https?:$","i"),i=0;i<o.length;i++)o[i].style.display="none";for(i=0;i<a.length;i++)s=a[i],e.source===s.contentWindow&#038;&#038;(s.removeAttribute("style"),"height"===t.message?(1e3<(r=parseInt(t.value,10))?r=1e3:~~r<200&#038;&#038;(r=200),s.height=r):"link"===t.message&#038;&#038;(r=new URL(s.getAttribute("src")),n=new URL(t.value),c.test(n.protocol))&#038;&#038;n.host===r.host&#038;&#038;l.activeElement===s&#038;&#038;(d.top.location.href=t.value))}},d.addEventListener("message",d.wp.receiveEmbedMessage,!1),l.addEventListener("DOMContentLoaded",function(){for(var e,t,s=l.querySelectorAll("iframe.wp-embedded-content"),r=0;r<s.length;r++)(t=(e=s[r]).getAttribute("data-secret"))||(t=Math.random().toString(36).substring(2,12),e.src+="#?secret="+t,e.setAttribute("data-secret",t)),e.contentWindow.postMessage({message:"ready",secret:t},"*")},!1)))}(window,document);//# sourceURL=https://dlrow-design.net/wp-includes/js/wp-embed.min.js</script>
</div></figure>The post <a href="https://dlrow-design.net/esp32%e3%81%ab%e6%8a%80%e9%81%a9%e3%81%af%e5%bf%85%e8%a6%81%ef%bc%9f%e8%87%aa%e4%bd%9c%e5%9f%ba%e6%9d%bf%e3%83%bb%e8%a3%bd%e5%93%81%e5%8c%96%e3%81%a7%e7%9f%a5%e3%81%a3%e3%81%a6%e3%81%8a%e3%81%8d/">ESP32に技適は必要？自作基板・製品化で知っておきたい電波法を解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32シリーズにピン互換性はある？ESP32・S3・C3・C5の置き換えを徹底解説</title>
		<link>https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ab%e3%83%94%e3%83%b3%e4%ba%92%e6%8f%9b%e6%80%a7%e3%81%af%e3%81%82%e3%82%8b%ef%bc%9fesp32%e3%83%bbs3%e3%83%bbc3%e3%83%bbc5%e3%81%ae%e7%bd%ae%e3%81%8d/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2582%25b7%25e3%2583%25aa%25e3%2583%25bc%25e3%2582%25ba%25e3%2581%25ab%25e3%2583%2594%25e3%2583%25b3%25e4%25ba%2592%25e6%258f%259b%25e6%2580%25a7%25e3%2581%25af%25e3%2581%2582%25e3%2582%258b%25ef%25bc%259fesp32%25e3%2583%25bbs3%25e3%2583%25bbc3%25e3%2583%25bbc5%25e3%2581%25ae%25e7%25bd%25ae%25e3%2581%258d</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Tue, 18 Aug 2026 16:14:27 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=815</guid>

					<description><![CDATA[<p>ESP32には、ESP32、ESP32-S3、ESP32-C3、ESP32-C5など、用途や機能の異なるさまざまなシリーズがあります。 新しいESP32が登場すると、 「今使っているESP32から載せ ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ab%e3%83%94%e3%83%b3%e4%ba%92%e6%8f%9b%e6%80%a7%e3%81%af%e3%81%82%e3%82%8b%ef%bc%9fesp32%e3%83%bbs3%e3%83%bbc3%e3%83%bbc5%e3%81%ae%e7%bd%ae%e3%81%8d/">ESP32シリーズにピン互換性はある？ESP32・S3・C3・C5の置き換えを徹底解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32には、ESP32、ESP32-S3、ESP32-C3、ESP32-C5など、用途や機能の異なるさまざまなシリーズがあります。</p>



<p class="wp-block-paragraph">新しいESP32が登場すると、</p>



<p class="wp-block-paragraph">「今使っているESP32から載せ替えられないか？」<br>「同じWROOMシリーズならピン互換なのでは？」<br>「ESP32-C3からESP32-C5へ変更するだけなら、基板はそのまま使える？」</p>



<p class="wp-block-paragraph">と考えることもあると思います。</p>



<p class="wp-block-paragraph">しかし、<strong>同じESP32シリーズだからといって、ピン互換があるとは限りません。</strong></p>



<p class="wp-block-paragraph">外形が似ていても端子配置が異なることがあります。また、同じGPIO番号でも機能や起動時の状態が異なる場合があります。</p>



<p class="wp-block-paragraph">特に基板設計では、単純に「3.3VとGNDの位置が合っている」「必要なGPIOがある」という確認だけでは不十分です。</p>



<p class="wp-block-paragraph">モジュールのLand Pattern、電源、EN、Strapping Pin、UARTやSPIなどの周辺機能、Flash・PSRAM構成、アンテナ領域なども確認する必要があります。</p>



<p class="wp-block-paragraph">この記事では、ESP32・ESP32-S3・ESP32-C3・ESP32-C5を例に、<strong>ESP32シリーズを別のデバイスへ置き換えるとき、何を確認すればよいのか</strong>を基板設計の視点から解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32シリーズは基本的にピン互換ではない</h2>



<p class="wp-block-paragraph">最初に結論を書くと、<strong>ESP32、ESP32-S3、ESP32-C3、ESP32-C5は、基本的にそのまま載せ替えられるピン互換デバイスではありません。</strong></p>



<p class="wp-block-paragraph">「ESP32」という共通した名前が付いていますが、それぞれCPUアーキテクチャや搭載されている周辺機能、GPIO構成などが異なります。</p>



<p class="wp-block-paragraph">モジュールについても同様です。</p>



<p class="wp-block-paragraph">たとえば「WROOM」という名称が付いているからといって、同じLand Patternや端子配列を持っているわけではありません。</p>



<p class="wp-block-paragraph">そのため、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32-WROOMを使っている基板だから、別のESP32-WROOMへそのまま交換できる</strong></p>
</blockquote>



<p class="wp-block-paragraph">とは考えない方が安全です。</p>



<p class="wp-block-paragraph">ESP32シリーズを置き換える場合、少なくとも次の3つの互換性を分けて確認する必要があります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>互換性</th><th>主な確認項目</th></tr></thead><tbody><tr><td>機械的互換性</td><td>モジュール外形、Land Pattern、端子数、端子位置</td></tr><tr><td>電気的互換性</td><td>電源、EN、GPIO、Strapping Pin、起動条件</td></tr><tr><td>機能的互換性</td><td>UART、SPI、I²C、USB、ADCなどの周辺機能</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">さらに、ハードウェアだけでなくFirmware側の対応確認も必要です。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>「基板に物理的に載る」＝「ピン互換」ではありません。</strong></p>



<p class="wp-block-paragraph">ここを最初に理解しておくと、ESP32シリーズを変更するときの設計ミスを減らせます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ピン互換性で確認するべき5つのポイント</h2>



<p class="wp-block-paragraph">では、ESP32シリーズを変更するとき、具体的に何を確認すればよいのでしょうか。</p>



<p class="wp-block-paragraph">ここでは特に重要なポイントを5つに分けて説明します。</p>



<h3 class="wp-block-heading">1．モジュールの外形とLand Pattern</h3>



<p class="wp-block-paragraph">最初に確認するのは、モジュールそのものの物理形状です。</p>



<p class="wp-block-paragraph">同じESP32シリーズやWROOMという名称であっても、</p>



<ul class="wp-block-list">
<li>モジュールの縦横寸法</li>



<li>端子数</li>



<li>端子位置</li>



<li>端子ピッチ</li>



<li>GNDパッド</li>



<li>Land Pattern</li>
</ul>



<p class="wp-block-paragraph">などが同じとは限りません。</p>



<p class="wp-block-paragraph">そのため、データシートの外形寸法だけを比較するのではなく、<strong>推奨Land Patternまで確認することが重要</strong>です。</p>



<p class="wp-block-paragraph">基板上に実装できなければ、その時点で単純な載せ替えはできません。</p>



<p class="wp-block-paragraph">また、モジュールのアンテナ位置にも注意が必要です。</p>



<p class="wp-block-paragraph">アンテナ部分の下や周辺には、銅箔、配線、部品などを配置しないKeepout Areaが指定されています。</p>



<p class="wp-block-paragraph">モジュール変更によってアンテナ位置が変われば、基板外形や部品配置まで見直す必要が出てくることがあります。</p>



<h3 class="wp-block-heading">2．電源・EN・GNDの配置</h3>



<p class="wp-block-paragraph">次に確認するのが電源関係です。</p>



<p class="wp-block-paragraph">ESP32シリーズの多くは3.3V系で動作しますが、</p>



<p class="wp-block-paragraph"><strong>「どれも3.3Vだから交換できる」</strong></p>



<p class="wp-block-paragraph">というわけではありません。</p>



<p class="wp-block-paragraph">3.3V、GND、ENなどの端子位置が違えば、当然そのまま載せ替えることはできません。</p>



<p class="wp-block-paragraph">また、必要な電源容量についても確認が必要です。</p>



<p class="wp-block-paragraph">Wi-FiやBluetoothなどの無線通信を行うESP32では、通信時に消費電流が大きく変動します。</p>



<p class="wp-block-paragraph">既存基板の3.3V電源回路をそのまま流用する場合でも、変更後のESP32に対して十分な電流を供給できるか確認しておく必要があります。</p>



<p class="wp-block-paragraph">単純なピン配置だけでなく、<strong>電源回路そのものが流用できるか</strong>まで含めて判断します。</p>



<h3 class="wp-block-heading">3．GPIO番号だけで判断しない</h3>



<p class="wp-block-paragraph">ESP32はGPIO Matrixによって、多くの周辺機能を比較的自由にGPIOへ割り当てられることが特徴です。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph">「UARTは別のGPIOへ移せばいい」<br>「SPIも空いているGPIOへ割り当てればいい」</p>



<p class="wp-block-paragraph">と考えやすいのですが、すべてのGPIOを自由に使えるわけではありません。</p>



<p class="wp-block-paragraph">シリーズによって、</p>



<ul class="wp-block-list">
<li>入力専用端子</li>



<li>起動時に使用される端子</li>



<li>FlashやPSRAMで使用される端子</li>



<li>USBで使用される端子</li>



<li>使用を避けた方がよい端子</li>
</ul>



<p class="wp-block-paragraph">などが異なります。</p>



<p class="wp-block-paragraph">特に注意したいのが、FlashやPSRAMを内蔵・搭載するモジュールです。</p>



<p class="wp-block-paragraph">同じESP32シリーズでも、FlashやPSRAMの構成によって一部GPIOをユーザーが自由に使用できない場合があります。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>GPIO番号が存在することと、そのGPIOを基板で自由に使えることは別</strong></p>
</blockquote>



<p class="wp-block-paragraph">と考える必要があります。</p>



<h3 class="wp-block-heading">4．Strapping Pinを必ず確認する</h3>



<p class="wp-block-paragraph">ESP32シリーズを使った基板設計で特に注意したいのが、<strong>Strapping Pin</strong>です。</p>



<p class="wp-block-paragraph">Strapping Pinとは、電源投入時やリセット時のGPIO状態によって、ESP32の起動設定などを決定する端子です。</p>



<p class="wp-block-paragraph">通常動作が始まった後はGPIOとして使用できる場合でも、起動時には特別な役割を持っています。</p>



<p class="wp-block-paragraph">そのため、外部回路によってStrapping Pinが意図しないHighまたはLowへ固定されると、</p>



<ul class="wp-block-list">
<li>正常に起動しない</li>



<li>Download Modeへ入ってしまう</li>



<li>書き込みができない</li>



<li>起動設定が変わる</li>
</ul>



<p class="wp-block-paragraph">といった問題につながる可能性があります。</p>



<p class="wp-block-paragraph">そして重要なのは、<strong>Strapping Pinの割り当てがESP32シリーズごとに異なる</strong>ことです。</p>



<p class="wp-block-paragraph">既存ESP32で問題なく使えていたGPIOだからといって、別シリーズでも同じように使えるとは限りません。</p>



<p class="wp-block-paragraph">シリーズ変更時には、データシートのStrapping Pinの項目を必ず確認します。</p>



<h3 class="wp-block-heading">5．UART・SPI・USBなどの周辺機能を確認する</h3>



<p class="wp-block-paragraph">最後に、実際に基板で使用している周辺機能を確認します。</p>



<p class="wp-block-paragraph">代表的なものとして、</p>



<ul class="wp-block-list">
<li>UART</li>



<li>SPI</li>



<li>I²C</li>



<li>ADC</li>



<li>PWM</li>



<li>USB</li>



<li>JTAG</li>
</ul>



<p class="wp-block-paragraph">などがあります。</p>



<p class="wp-block-paragraph">ESP32シリーズによって搭載されている周辺機能やチャンネル数、使用可能なGPIOは異なります。</p>



<p class="wp-block-paragraph">特にUSBはシリーズによる違いが大きい部分です。</p>



<p class="wp-block-paragraph">従来のESP32と、USB機能を持つESP32-S3やESP32-C3などでは、USBを利用した書き込みやデバッグ方法まで変わる可能性があります。</p>



<p class="wp-block-paragraph">既存基板でUART、SPI、I²Cなどを複数使用している場合は、<strong>使用中の機能を一つずつ新しいESP32へ割り当て直せるか確認する</strong>のが確実です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32・S3・C3・C5は何が違う？</h2>



<p class="wp-block-paragraph">ここまでを見ると、ESP32シリーズの変更では単純なピン番号比較だけでは不十分であることが分かります。</p>



<p class="wp-block-paragraph">では、ESP32、ESP32-S3、ESP32-C3、ESP32-C5にはどのような違いがあるのでしょうか。</p>



<p class="wp-block-paragraph">大まかな特徴を比較すると次のようになります。</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>ESP32</th><th>ESP32-S3</th><th>ESP32-C3</th><th>ESP32-C5</th></tr></thead><tbody><tr><td>CPUアーキテクチャ</td><td>Xtensa LX6</td><td>Xtensa LX7</td><td>RISC-V</td><td>RISC-V</td></tr><tr><td>CPU構成</td><td>Dual Core</td><td>Dual Core</td><td>Single Core</td><td>Single Core</td></tr><tr><td>Wi-Fi</td><td>2.4GHz</td><td>2.4GHz</td><td>2.4GHz</td><td>2.4/5GHz</td></tr><tr><td>Wi-Fi世代</td><td>Wi-Fi 4</td><td>Wi-Fi 4</td><td>Wi-Fi 4</td><td>Wi-Fi 6</td></tr><tr><td>Bluetooth</td><td>BR/EDR + BLE</td><td>BLE</td><td>BLE</td><td>BLE</td></tr><tr><td>802.15.4</td><td>―</td><td>―</td><td>―</td><td>対応</td></tr><tr><td>USB</td><td>―※</td><td>USB OTG / Serial-JTAG</td><td>USB Serial-JTAG</td><td>USB Serial-JTAG</td></tr><tr><td>CPU系統</td><td>Xtensa</td><td>Xtensa</td><td>RISC-V</td><td>RISC-V</td></tr><tr><td>単純な載せ替え</td><td>×</td><td>×</td><td>×</td><td>×</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">※従来ESP32自体にESP32-S3のようなネイティブUSB OTG機能があるという意味ではありません。</p>



<p class="wp-block-paragraph">ここで重要なのは、性能の優劣ではありません。</p>



<p class="wp-block-paragraph">たとえばESP32-C5は2.4GHz/5GHz Wi-Fi 6に対応するなど、従来シリーズから無線機能が大きく強化されています。</p>



<p class="wp-block-paragraph">一方で、</p>



<p class="wp-block-paragraph"><strong>「C5の方が新しくて高機能だから、C3をC5へ交換すればよい」</strong></p>



<p class="wp-block-paragraph">とはなりません。</p>



<p class="wp-block-paragraph">CPUアーキテクチャが同じRISC-Vであっても、GPIO、周辺機能、Strapping Pin、モジュール端子配置などは別に確認する必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32からESP32-S3へ置き換えできる？</h2>



<p class="wp-block-paragraph">ESP32-S3は、従来のESP32と同じXtensa系CPUを採用しています。</p>



<p class="wp-block-paragraph">そのため、一見すると比較的移行しやすそうに見えます。</p>



<p class="wp-block-paragraph">しかし、<strong>ESP32からESP32-S3への変更を単純な載せ替えとして考えることはできません。</strong></p>



<p class="wp-block-paragraph">ESP32-S3ではCPUコアがXtensa LX7へ変更されているほか、GPIO構成や周辺機能も異なります。</p>



<p class="wp-block-paragraph">特に大きな違いの一つがUSBです。</p>



<p class="wp-block-paragraph">ESP32-S3にはUSB OTGやUSB Serial/JTAGが搭載されているため、従来ESP32ではUSB-UART変換ICを使用していた構成でも、S3ではUSBを直接利用する設計が可能です。</p>



<p class="wp-block-paragraph">これは機能面ではメリットですが、既存基板から変更する場合には、</p>



<ul class="wp-block-list">
<li>USB端子を使用するか</li>



<li>USB-UART変換ICを残すか</li>



<li>書き込み方法をどうするか</li>



<li>JTAGをどう利用するか</li>
</ul>



<p class="wp-block-paragraph">といった基板全体の構成を改めて検討する必要があります。</p>



<p class="wp-block-paragraph">また、Strapping PinやGPIOの用途も同じではありません。</p>



<p class="wp-block-paragraph">したがって、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>ESP32-S3への変更は「ESP32を高性能版へ交換する」のではなく、新しいMCUを使って基板を再設計する</strong></p>
</blockquote>



<p class="wp-block-paragraph">と考えた方が安全です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32からESP32-C3へ置き換えできる？</h2>



<p class="wp-block-paragraph">ESP32-C3では、CPUアーキテクチャそのものが変わります。</p>



<p class="wp-block-paragraph">従来ESP32がXtensa LX6を採用しているのに対して、ESP32-C3はRISC-Vベースです。</p>



<p class="wp-block-paragraph">さらにCPU構成、GPIO、周辺機能、Bluetooth機能などにも違いがあります。</p>



<p class="wp-block-paragraph">そのため、ESP32からESP32-C3へ変更する場合も、単純な載せ替えは基本的にできません。</p>



<p class="wp-block-paragraph">ただし、ESP-IDFやArduinoなどの開発環境では複数のESP32シリーズがサポートされているため、アプリケーションコードの一部を流用できる場合はあります。</p>



<p class="wp-block-paragraph">ここで注意したいのが、</p>



<p class="wp-block-paragraph"><strong>「ソースコードが流用できる」ことと「基板が流用できる」ことは別</strong></p>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">たとえばUART通信を行うプログラムそのものは移植できても、実際にUARTへ使用するGPIOが変われば基板配線は変更しなければなりません。</p>



<p class="wp-block-paragraph">また、特定のESP32向けライブラリや、CPU固有機能へ直接アクセスしているプログラムでは、Firmware側にも修正が必要になる可能性があります。</p>



<p class="wp-block-paragraph">ESP32-C3への変更では、ハードウェアとFirmwareを別々に確認する必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32-C3からESP32-C5へ置き換えできる？</h2>



<p class="wp-block-paragraph">ESP32-C3とESP32-C5は、どちらもRISC-VベースのESP32です。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph">「C3からC5なら比較的簡単に変更できるのでは？」</p>



<p class="wp-block-paragraph">と思うかもしれません。</p>



<p class="wp-block-paragraph">しかし、<strong>C3とC5もピン互換デバイスとして考えるべきではありません。</strong></p>



<p class="wp-block-paragraph">ESP32-C5では2.4GHzだけでなく5GHz帯にも対応したWi-Fi 6を利用でき、IEEE 802.15.4にも対応するなど、無線機能が大きく拡張されています。</p>



<p class="wp-block-paragraph">一方で、GPIO構成やStrapping PinなどはC3と同じではありません。</p>



<p class="wp-block-paragraph">たとえばESP32-C5では、Boot Modeに関係するGPIOやUSB Serial/JTAGで使用されるGPIOなどを確認したうえで回路を設計する必要があります。</p>



<p class="wp-block-paragraph">さらに、モジュールのメモリ構成にも注意が必要です。</p>



<p class="wp-block-paragraph">ESP32-C5-WROOM-1では、PSRAM搭載品を選択すると、一部端子がPSRAMとの接続に使用されます。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>同じESP32-C5-WROOM-1でも、選択するメモリ構成によって自由に使用できるGPIOが変わる場合がある</strong></p>
</blockquote>



<p class="wp-block-paragraph">ということです。</p>



<p class="wp-block-paragraph">これはシリーズ変更だけでなく、<strong>同一シリーズ内でモジュール型番を変更するときにもデータシートを確認する必要がある</strong>ことを意味します。</p>



<p class="wp-block-paragraph">CPUアーキテクチャが同じだからといって、基板まで互換になるわけではありません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「同じWROOMなら互換」は間違い</h2>



<p class="wp-block-paragraph">ESP32を選定していると、</p>



<ul class="wp-block-list">
<li>ESP32-WROOM</li>



<li>ESP32-S3-WROOM</li>



<li>ESP32-C5-WROOM</li>
</ul>



<p class="wp-block-paragraph">のように「WROOM」という名称を目にします。</p>



<p class="wp-block-paragraph">ここで注意したいのが、</p>



<p class="wp-block-paragraph"><strong>WROOMという名称＝共通のピン配置</strong></p>



<p class="wp-block-paragraph">ではないことです。</p>



<p class="wp-block-paragraph">WROOMは、ESP32シリーズのモジュール製品で使用されている名称ですが、シリーズをまたいで共通のLand Patternを保証するものではありません。</p>



<p class="wp-block-paragraph">そのため、部品表に「ESP32-WROOM」とだけ記載して互換品を選定するような運用は避けた方が安全です。</p>



<p class="wp-block-paragraph">基板設計では必ず、</p>



<p class="wp-block-paragraph"><strong>完全なモジュール型番 → データシート → 推奨Land Pattern → Pin Definitions</strong></p>



<p class="wp-block-paragraph">まで確認します。</p>



<p class="wp-block-paragraph">特に量産製品では、部品供給の都合から別のESP32へ変更したくなる場合があります。</p>



<p class="wp-block-paragraph">その場合も「同じWROOMだから代替品」と判断するのではなく、<strong>設計変更として扱う</strong>ことをおすすめします。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32を別シリーズへ変更するときの確認手順</h2>



<p class="wp-block-paragraph">では、実際に既存基板のESP32を変更するとき、どのような順番で確認すればよいのでしょうか。</p>



<p class="wp-block-paragraph">私は次の順番で確認することをおすすめします。</p>



<h3 class="wp-block-heading">1．モジュール型番を確定する</h3>



<p class="wp-block-paragraph">最初に変更先の完全な型番を決めます。</p>



<p class="wp-block-paragraph">「ESP32-C5」だけでは不十分です。</p>



<p class="wp-block-paragraph">Flash容量、PSRAMの有無、アンテナ仕様などによってモジュール型番や使用条件が変わるためです。</p>



<h3 class="wp-block-heading">2．Land Patternを比較する</h3>



<p class="wp-block-paragraph">既存モジュールと変更先モジュールの推奨Land Patternを比較します。</p>



<p class="wp-block-paragraph">端子数や端子位置が違えば、基本的に基板変更が必要です。</p>



<h3 class="wp-block-heading">3．電源仕様を確認する</h3>



<p class="wp-block-paragraph">動作電圧だけでなく、必要な電流や電源投入条件なども確認します。</p>



<p class="wp-block-paragraph">既存の3.3V電源を流用できるかも、この段階で確認します。</p>



<h3 class="wp-block-heading">4．使用しているGPIOを一覧化する</h3>



<p class="wp-block-paragraph">既存基板で使用しているGPIOと用途を一覧にします。</p>



<p class="wp-block-paragraph">たとえば、</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>信号</th><th>用途</th></tr></thead><tbody><tr><td>GPIO-A</td><td>UART TX</td></tr><tr><td>GPIO-B</td><td>UART RX</td></tr><tr><td>GPIO-C</td><td>SPI CLK</td></tr><tr><td>GPIO-D</td><td>LED</td></tr><tr><td>GPIO-E</td><td>外部割り込み</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">のように整理します。</p>



<p class="wp-block-paragraph">この表を変更先ESP32のGPIOへ一つずつ割り当て直します。</p>



<h3 class="wp-block-heading">5．Strapping Pinを確認する</h3>



<p class="wp-block-paragraph">割り当てたGPIOがStrapping Pinと衝突していないか確認します。</p>



<p class="wp-block-paragraph">通常動作だけでなく、電源投入時・リセット時に外部回路がどのような状態になるかまで確認します。</p>



<h3 class="wp-block-heading">6．Flash・PSRAM関連端子を確認する</h3>



<p class="wp-block-paragraph">モジュール構成によって内部FlashやPSRAMで使用される端子がないか確認します。</p>



<p class="wp-block-paragraph">データシート上にGPIO番号が存在していても、採用するモジュールでは使用できない場合があります。</p>



<h3 class="wp-block-heading">7．USB・UART・JTAGを確認する</h3>



<p class="wp-block-paragraph">書き込みやデバッグ方法も確認します。</p>



<p class="wp-block-paragraph">ESP32シリーズによってUSB Serial/JTAGなどの利用可否が異なるため、MCU変更を機会に書き込み回路を簡略化できる場合もあります。</p>



<h3 class="wp-block-heading">8．アンテナ領域を確認する</h3>



<p class="wp-block-paragraph">モジュールのアンテナ位置とKeepout Areaを確認します。</p>



<p class="wp-block-paragraph">ここを見落とすと、基板上には実装できても無線性能へ影響する可能性があります。</p>



<h3 class="wp-block-heading">9．Firmwareを確認する</h3>



<p class="wp-block-paragraph">最後にFirmware側を確認します。</p>



<p class="wp-block-paragraph">使用しているESP-IDFやArduino Coreなどが変更先デバイスに対応しているか、使用中のライブラリにデバイス依存部分がないか確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ピン互換にこだわらず基板を再設計した方がよい場合</h2>



<p class="wp-block-paragraph">既存基板をできるだけ変更したくない場合、変換基板やGPIOの割り当て変更によって対応したくなることがあります。</p>



<p class="wp-block-paragraph">試作や評価用途であれば、それも一つの方法です。</p>



<p class="wp-block-paragraph">しかし量産基板の場合は、無理に互換性を持たせることで、</p>



<ul class="wp-block-list">
<li>配線が複雑になる</li>



<li>不要な0Ω抵抗やジャンパが増える</li>



<li>Strapping Pinの制約を受ける</li>



<li>本来使いやすいGPIOを使えない</li>



<li>新しいESP32の機能を活かせない</li>
</ul>



<p class="wp-block-paragraph">といった問題が発生することがあります。</p>



<p class="wp-block-paragraph">特にESP32からESP32-C5のように世代や機能が大きく異なる場合は、既存回路への適合を優先するよりも、<strong>新しいデバイスに合わせて基板を再設計した方が結果的にシンプルになる</strong>ことがあります。</p>



<p class="wp-block-paragraph">基板変更には工数が必要ですが、製品を長期間使用するのであれば、無理な互換設計を残すより保守もしやすくなります。</p>



<p class="wp-block-paragraph">ESP32モジュールを変更する場合は、ピン配置や機能だけでなく、日本国内で使用するための認証状況も確認しておきましょう。ESP32の技適については「<a href="https://dlrow-design.net/esp32%e3%81%ab%e6%8a%80%e9%81%a9%e3%81%af%e5%bf%85%e8%a6%81%ef%bc%9f%e8%87%aa%e4%bd%9c%e5%9f%ba%e6%9d%bf%e3%83%bb%e8%a3%bd%e5%93%81%e5%8c%96%e3%81%a7%e7%9f%a5%e3%81%a3%e3%81%a6%e3%81%8a%e3%81%8d/" target="_blank" rel="noopener" title="">ESP32に技適は必要？自作基板・製品化で知っておきたい電波法を解説</a>」で詳しく解説しています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ｜ESP32の型番変更は「載せ替え」ではなく再設計として考える</h2>



<p class="wp-block-paragraph">ESP32、ESP32-S3、ESP32-C3、ESP32-C5は同じESP32ファミリですが、基本的に単純なピン互換デバイスではありません。</p>



<p class="wp-block-paragraph">ESP32シリーズを変更するときは、</p>



<p class="wp-block-paragraph"><strong>機械的互換性</strong><br><strong>電気的互換性</strong><br><strong>機能的互換性</strong></p>



<p class="wp-block-paragraph">の3つを確認する必要があります。</p>



<p class="wp-block-paragraph">さらに、実際の製品ではFirmware、Flash・PSRAM構成、アンテナ領域、書き込み・デバッグ方法まで確認します。</p>



<p class="wp-block-paragraph">特に覚えておきたいのは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>「同じESP32」「同じRISC-V」「同じWROOM」だから互換とは限らない</strong></p>
</blockquote>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">ESP32シリーズを変更するときは、単なる部品置換ではなく、<strong>別のMCUへ変更するつもりでデータシートを確認する</strong>のが安全です。</p>



<p class="wp-block-paragraph">その結果、基板変更が必要になったとしても、新しいESP32に合わせて回路を最適化した方がシンプルで扱いやすい設計になることがあります。</p>



<p class="wp-block-paragraph">ESP32シリーズそのものの選び方で迷っている場合は、既存の**「ESP32シリーズの選び方｜用途別におすすめのESP32を現役エンジニアが解説」**も関連記事としてつなげましょう。逆側の記事から今回の記事への内部リンクも追加すると、かなり相性のよい2記事になります。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>技術は、経験から価値になる。</strong></p>



<p class="wp-block-paragraph"><strong>DLROW Design | 現場エンジニア</strong></p>



<p class="wp-block-paragraph"></p>The post <a href="https://dlrow-design.net/esp32%e3%82%b7%e3%83%aa%e3%83%bc%e3%82%ba%e3%81%ab%e3%83%94%e3%83%b3%e4%ba%92%e6%8f%9b%e6%80%a7%e3%81%af%e3%81%82%e3%82%8b%ef%bc%9fesp32%e3%83%bbs3%e3%83%bbc3%e3%83%bbc5%e3%81%ae%e7%bd%ae%e3%81%8d/">ESP32シリーズにピン互換性はある？ESP32・S3・C3・C5の置き換えを徹底解説</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32の起動時にGPIOが勝手に動く？｜初期状態・Pull-up・Pull-downで誤動作を防ぐ方法</title>
		<link>https://dlrow-design.net/esp32%e3%81%ae%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%abgpio%e3%81%8c%e5%8b%9d%e6%89%8b%e3%81%ab%e5%8b%95%e3%81%8f%ef%bc%9f%ef%bd%9c%e5%88%9d%e6%9c%9f%e7%8a%b6%e6%85%8b%e3%83%bbpull-up%e3%83%bbpull-down/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25ae%25e8%25b5%25b7%25e5%258b%2595%25e6%2599%2582%25e3%2581%25abgpio%25e3%2581%258c%25e5%258b%259d%25e6%2589%258b%25e3%2581%25ab%25e5%258b%2595%25e3%2581%258f%25ef%25bc%259f%25ef%25bd%259c%25e5%2588%259d%25e6%259c%259f%25e7%258a%25b6%25e6%2585%258b%25e3%2583%25bbpull-up%25e3%2583%25bbpull-down</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Sat, 15 Aug 2026 15:10:25 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=811</guid>

					<description><![CDATA[<p>ESP32でリレーやMOSFETなどを制御していると、 「電源を入れた瞬間だけリレーがONする」 「ResetするとLEDが一瞬光る」 「プログラムではLOWにしているのに、起動時だけ負荷が動く」 と ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%ae%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%abgpio%e3%81%8c%e5%8b%9d%e6%89%8b%e3%81%ab%e5%8b%95%e3%81%8f%ef%bc%9f%ef%bd%9c%e5%88%9d%e6%9c%9f%e7%8a%b6%e6%85%8b%e3%83%bbpull-up%e3%83%bbpull-down/">ESP32の起動時にGPIOが勝手に動く？｜初期状態・Pull-up・Pull-downで誤動作を防ぐ方法</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32でリレーやMOSFETなどを制御していると、</p>



<p class="wp-block-paragraph">「電源を入れた瞬間だけリレーがONする」</p>



<p class="wp-block-paragraph">「ResetするとLEDが一瞬光る」</p>



<p class="wp-block-paragraph">「プログラムではLOWにしているのに、起動時だけ負荷が動く」</p>



<p class="wp-block-paragraph">といった現象が発生することがあります。</p>



<p class="wp-block-paragraph">プログラムを見ると、最初にGPIOをLOWへ設定している。</p>



<p class="wp-block-paragraph">それなのに、なぜ負荷が動くのでしょうか。</p>



<p class="wp-block-paragraph">原因を調べるときに重要なのが、</p>



<p class="wp-block-paragraph"><strong>ESP32は電源投入直後から自分のプログラムを実行しているわけではない</strong></p>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">今回はESP32-C5とESP-IDFを例に、起動時のGPIO状態と、外部回路で誤動作を防ぐ考え方を整理します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">app_main()より前にも時間がある</h2>



<p class="wp-block-paragraph">ESP-IDFでプログラムを作成すると、アプリケーションでは<code>app_main()</code>から処理を書き始めます。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph">「app_main()の最初でGPIOをLOWにすれば、起動時からLOWになる」</p>



<p class="wp-block-paragraph">と思いたくなります。</p>



<p class="wp-block-paragraph">しかし実際には、</p>



<p class="wp-block-paragraph">電源投入<br>↓<br>Reset<br>↓<br>ROM Boot処理<br>↓<br>Bootloader<br>↓<br>Application起動<br>↓<br>app_main()</p>



<p class="wp-block-paragraph">という流れがあります。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>電源投入からapp_main()がGPIOを初期化するまでには時間があります。</strong></p>



<p class="wp-block-paragraph">その期間のGPIO状態を考えずに外部回路を設計すると、起動時だけ負荷が意図しない状態になる可能性があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOを設定するまでは出力とは限らない</h2>



<p class="wp-block-paragraph">アプリケーションでGPIOをOutputに設定するまでは、</p>



<p class="wp-block-paragraph">「必ずLOW」</p>



<p class="wp-block-paragraph">「必ずHIGH」</p>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">Pinによっては内部Pull-up/Pull-down、Boot時の機能、Strapping用途なども関係します。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>起動直後の状態をアプリケーションだけで保証しようとしない</strong></p>



<p class="wp-block-paragraph">ことが重要です。</p>



<p class="wp-block-paragraph">特に、</p>



<ul class="wp-block-list">
<li>MOSFET Gate</li>



<li>Transistor Base</li>



<li>Relay Driver</li>



<li>Motor Driver Enable</li>



<li>Heater Enable</li>



<li>その他、起動時にONしてほしくない信号</li>
</ul>



<p class="wp-block-paragraph">では外部回路側でもDefault状態を決めておく方が安全です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">MOSFET Gateが浮くとどうなる？</h2>



<p class="wp-block-paragraph">例えばN-channel MOSFETをLow Side Switchとして使用するとします。</p>



<p class="wp-block-paragraph">ESP32 GPIO<br>↓<br>Gate抵抗<br>↓<br>MOSFET Gate</p>



<p class="wp-block-paragraph">という接続だけにした場合、ESP32がまだGPIOを制御していない期間にGate電圧が不定になる可能性があります。</p>



<p class="wp-block-paragraph">MOSFETのGateは容量性の入力なので、周囲のノイズや残留電荷などによって電位が決まってしまうことがあります。</p>



<p class="wp-block-paragraph">その結果、</p>



<p class="wp-block-paragraph"><strong>電源投入時にMOSFETが一瞬ONする</strong></p>



<p class="wp-block-paragraph">可能性があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Pull-down抵抗でOFF状態を作る</h2>



<p class="wp-block-paragraph">N-channel MOSFETを、</p>



<p class="wp-block-paragraph"><strong>GPIO HIGH → ON</strong></p>



<p class="wp-block-paragraph">として使用するなら、GateとGNDの間にPull-down抵抗を入れる方法があります。</p>



<p class="wp-block-paragraph">ESP32がまだGPIOを制御していなくても、</p>



<p class="wp-block-paragraph">Gate<br>↓<br>Pull-down抵抗<br>↓<br>GND</p>



<p class="wp-block-paragraph">によってGateをLOW側へ保持できます。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<p class="wp-block-paragraph"><strong>Softwareが動く前からHardwareで安全状態を作る</strong></p>



<p class="wp-block-paragraph">という考え方です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">サンプルコード</h2>



<p class="wp-block-paragraph">今回はGPIO10を出力として使用し、起動直後にLOWへ設定したあと、1秒周期でHIGH/LOWを切り替えるサンプルを使用します。</p>



<p class="wp-block-paragraph">ここで重要なのは、</p>



<p class="wp-block-paragraph"><strong>このコードだけでは電源投入直後からGPIO10がLOWであることを保証できない</strong></p>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">以下が今回使用するサンプルコード全文です。</p>



<pre class="wp-block-code"><code>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "driver/gpio.h"
#include "esp_log.h"

#define OUTPUT_GPIO GPIO_NUM_10

static const char *TAG = "BOOT_GPIO";

void app_main(void)
{
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL &lt;&lt; OUTPUT_GPIO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };

    ESP_ERROR_CHECK(gpio_config(&amp;io_conf));

    ESP_ERROR_CHECK(
        gpio_set_level(OUTPUT_GPIO, 0));

    ESP_LOGI(
        TAG,
        "GPIO initialized LOW");

    while (1)
    {
        ESP_ERROR_CHECK(
            gpio_set_level(OUTPUT_GPIO, 1));

        ESP_LOGI(
            TAG,
            "GPIO HIGH");

        vTaskDelay(
            pdMS_TO_TICKS(1000));

        ESP_ERROR_CHECK(
            gpio_set_level(OUTPUT_GPIO, 0));

        ESP_LOGI(
            TAG,
            "GPIO LOW");

        vTaskDelay(
            pdMS_TO_TICKS(1000));
    }
}</code></pre>



<p class="wp-block-paragraph">このサンプルでは、GPIO10をOutputへ設定した直後にLOWを出力しています。</p>



<p class="wp-block-paragraph">しかし、ここで確認したいのは、</p>



<p class="wp-block-paragraph"><strong>LOWへ設定したタイミング</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">LOWにしているのはapp_main()実行後</h2>



<p class="wp-block-paragraph">サンプルコードでは次の部分でGPIOを初期化しています。</p>



<pre class="wp-block-code"><code>gpio_config_t io_conf = {
    .pin_bit_mask = (1ULL &lt;&lt; OUTPUT_GPIO),
    .mode = GPIO_MODE_OUTPUT,
    .pull_up_en = GPIO_PULLUP_DISABLE,
    .pull_down_en = GPIO_PULLDOWN_DISABLE,
    .intr_type = GPIO_INTR_DISABLE
};

ESP_ERROR_CHECK(gpio_config(&amp;io_conf));

ESP_ERROR_CHECK(
    gpio_set_level(OUTPUT_GPIO, 0));</code></pre>



<p class="wp-block-paragraph">確かに、この処理が実行されたあとはGPIO10をLOWへ制御できます。</p>



<p class="wp-block-paragraph">しかし、</p>



<p class="wp-block-paragraph">電源投入<br>↓<br>ESP32起動処理<br>↓<br>このコードを実行</p>



<p class="wp-block-paragraph">という順番です。</p>



<p class="wp-block-paragraph">つまり、このコードが実行されるより前の状態については、この<code>gpio_set_level()</code>では制御できません。</p>



<p class="wp-block-paragraph">ここが起動時誤動作を考えるうえで重要なポイントです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">内部Pull-downを使えば解決する？</h2>



<p class="wp-block-paragraph">ESP32にはGPIOの内部Pull-up/Pull-down機能があります。</p>



<p class="wp-block-paragraph">例えば今回の設定を、</p>



<p class="wp-block-paragraph"><code>GPIO_PULLDOWN_ENABLE</code></p>



<p class="wp-block-paragraph">へ変更すればよいのではないか、と考えることもできます。</p>



<p class="wp-block-paragraph">ただし、それだけに依存するのは避けたい場合があります。</p>



<p class="wp-block-paragraph">内部Pull-up/Pull-downもESP32内部の機能です。</p>



<p class="wp-block-paragraph">製品として、</p>



<p class="wp-block-paragraph"><strong>Reset中や起動途中を含めて確実に負荷をOFFへしたい</strong></p>



<p class="wp-block-paragraph">のであれば、外部抵抗でDefault状態を決める方が回路として分かりやすくなります。</p>



<p class="wp-block-paragraph">特にリレー、モーター、ヒーターなど、安全性や機械動作に関係する出力では重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Softwareより先にHardwareで状態を決める</h2>



<p class="wp-block-paragraph">例えばMOSFET Gateなら、</p>



<p class="wp-block-paragraph">ESP32 GPIO<br>↓<br>Gate抵抗<br>↓<br>MOSFET Gate<br>↓<br>10kΩ～100kΩ程度<br>↓<br>GND</p>



<p class="wp-block-paragraph">という構成を検討できます。</p>



<p class="wp-block-paragraph">このPull-down抵抗があれば、ESP32 GPIOがHi-ZでもGateをLOW側へ保持できます。</p>



<p class="wp-block-paragraph">そしてESP32が起動してGPIOをHIGHにすれば、Pull-down抵抗に逆らってGate電圧が上がり、MOSFETをONできます。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>HardwareでDefault OFF</strong></p>



<p class="wp-block-paragraph"><strong>Softwareで必要なときだけON</strong></p>



<p class="wp-block-paragraph">という役割分担です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Pull-down抵抗は何Ωにする？</h2>



<p class="wp-block-paragraph">よく使用される値としては、10kΩ～100kΩ程度があります。</p>



<p class="wp-block-paragraph">ただし、</p>



<p class="wp-block-paragraph">「MOSFET Gateには必ず10kΩ」</p>



<p class="wp-block-paragraph">という決まりではありません。</p>



<p class="wp-block-paragraph">抵抗値を小さくするとGateをより強くLOWへ保持できますが、GPIOがHIGHの間はPull-down抵抗へ電流が流れ続けます。</p>



<p class="wp-block-paragraph">逆に抵抗値を大きくすると消費電流は減りますが、外来ノイズなどに対する保持は弱くなります。</p>



<p class="wp-block-paragraph">回路条件に合わせて決めます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Active Lowなら考え方が逆になる</h2>



<p class="wp-block-paragraph">すべての回路が、</p>



<p class="wp-block-paragraph">HIGH → ON</p>



<p class="wp-block-paragraph">とは限りません。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">LOW → Enable</p>



<p class="wp-block-paragraph">となる外部ICもあります。</p>



<p class="wp-block-paragraph">この場合、起動時にOFFへしたければ、Pull-downではなくPull-upが必要になる可能性があります。</p>



<p class="wp-block-paragraph">つまり重要なのは、</p>



<p class="wp-block-paragraph"><strong>Pull-upかPull-downかを先に決めることではありません。</strong></p>



<p class="wp-block-paragraph">まず、</p>



<p class="wp-block-paragraph"><strong>負荷を安全な状態にする論理レベルはHIGHなのかLOWなのか</strong></p>



<p class="wp-block-paragraph">を決めます。</p>



<p class="wp-block-paragraph">その後、その状態へ保持する抵抗を選びます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Strapping Pinにも注意する</h2>



<p class="wp-block-paragraph">ESP32シリーズには、起動時に特定の状態を参照してBoot動作などを決めるPinがあります。</p>



<p class="wp-block-paragraph">こうしたPinへ外部Pull-up/Pull-downや負荷を接続すると、意図しないBoot Modeになる可能性があります。</p>



<p class="wp-block-paragraph">そのためGPIOを割り当てるときは、</p>



<p class="wp-block-paragraph"><strong>「空いているGPIOだから使う」</strong></p>



<p class="wp-block-paragraph">だけで決めず、そのPinが起動時にどのような役割を持つか確認します。</p>



<p class="wp-block-paragraph">特に自作基板では、この確認を回路設計段階で行うことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">起動時だけでなくReset時も考える</h2>



<p class="wp-block-paragraph">もう一つ忘れやすいのがResetです。</p>



<p class="wp-block-paragraph">製品は電源投入時だけResetするとは限りません。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>Watchdog Reset</li>



<li>Software Reset</li>



<li>Brownout</li>



<li>ENによるReset</li>



<li>Firmware Update後のReset</li>
</ul>



<p class="wp-block-paragraph">などがあります。</p>



<p class="wp-block-paragraph">Resetが発生すれば、再びApplicationがGPIOを初期化するまでの期間が生まれます。</p>



<p class="wp-block-paragraph">したがって、</p>



<p class="wp-block-paragraph"><strong>「電源投入時に一瞬だけだから問題ない」</strong></p>



<p class="wp-block-paragraph">ではなく、</p>



<p class="wp-block-paragraph"><strong>運転中にResetしても外部回路が安全状態を維持できるか</strong></p>



<p class="wp-block-paragraph">まで確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Strapping Pinは回路設計の最初に確認する</h2>



<p class="wp-block-paragraph">ESP32シリーズでは、起動時に特定のGPIO状態を参照してBoot Modeなどを決めるPinがあります。</p>



<p class="wp-block-paragraph">こうしたPinへ外部回路を接続する場合、</p>



<ul class="wp-block-list">
<li>強いPull-up</li>



<li>強いPull-down</li>



<li>外部ICの出力</li>



<li>MOSFET Gate回路</li>



<li>LED</li>



<li>Driver Enable</li>
</ul>



<p class="wp-block-paragraph">などが起動条件へ影響する可能性があります。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>空いているGPIOを見つけてから用途を割り当てる</strong></p>



<p class="wp-block-paragraph">のではなく、</p>



<p class="wp-block-paragraph"><strong>そのGPIOが起動時に何をするPinなのかを確認してから割り当てる</strong></p>



<p class="wp-block-paragraph">方が安全です。</p>



<p class="wp-block-paragraph">特に製品基板では、Boot Modeに関係するPinへ不用意に外部回路を接続すると、</p>



<p class="wp-block-paragraph">「通常は動くのに、特定条件だけ起動しない」</p>



<p class="wp-block-paragraph">という分かりにくいトラブルにつながります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">起動時の波形はオシロスコープで確認する</h2>



<p class="wp-block-paragraph">起動時だけ一瞬負荷が動く場合は、GPIO波形を実際に測定すると状況が分かりやすくなります。</p>



<p class="wp-block-paragraph">確認したいのは、</p>



<p class="wp-block-paragraph"><strong>電源投入直後からApplicationがGPIOを初期化するまで</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">例えばGPIOをLowにしたい場合でも、波形が、</p>



<pre class="wp-block-code"><code>電源ON
  ↓
Hi-Z
  ↓
一瞬HIGH
  ↓
LOW</code></pre>



<p class="wp-block-paragraph">のようになっているかもしれません。</p>



<p class="wp-block-paragraph">目視では分からない短いパルスでも、MOSFETやDriver Enableには十分な場合があります。</p>



<p class="wp-block-paragraph">そのため、起動時誤動作が疑われる場合は、</p>



<ul class="wp-block-list">
<li>GPIO</li>



<li>Enable信号</li>



<li>MOSFET Gate</li>



<li>負荷側電圧</li>
</ul>



<p class="wp-block-paragraph">をオシロスコープで確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">MOSFET GateはHardwareでOFFを作る</h2>



<p class="wp-block-paragraph">N-channel MOSFETをLow Side Switchとして使用し、</p>



<p class="wp-block-paragraph"><strong>HIGHでON</strong></p>



<p class="wp-block-paragraph">とする場合は、GateへPull-down抵抗を入れるのが基本的な考え方です。</p>



<pre class="wp-block-code"><code>ESP32 GPIO
    │
  Gate抵抗
    │
    ├──── MOSFET Gate
    │
 Pull-down
    │
   GND</code></pre>



<p class="wp-block-paragraph">ESP32がまだGPIOを出力していない状態でも、GateはGND側へ引かれます。</p>



<p class="wp-block-paragraph">これにより、</p>



<p class="wp-block-paragraph"><strong>Default OFF</strong></p>



<p class="wp-block-paragraph">をHardware側で作れます。</p>



<p class="wp-block-paragraph">一方で、Pull-down抵抗値を小さくしすぎるとGPIO HIGH時に無駄な電流が増えます。</p>



<p class="wp-block-paragraph">逆に大きすぎるとノイズに弱くなる可能性があります。</p>



<p class="wp-block-paragraph">そのため回路条件に合わせて選びます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Relay Driverでも同じ考え方</h2>



<p class="wp-block-paragraph">リレーをトランジスタやMOSFETで駆動する場合も、起動時にDriverが勝手にONしない状態を作る必要があります。</p>



<p class="wp-block-paragraph">例えばNPNトランジスタを使う場合、</p>



<p class="wp-block-paragraph"><strong>Baseが浮かないようにする</strong></p>



<p class="wp-block-paragraph">ことが重要です。</p>



<p class="wp-block-paragraph">MOSFETならGate Pull-down。</p>



<p class="wp-block-paragraph">NPNならBase-Emitter間の抵抗。</p>



<p class="wp-block-paragraph">このように、CPUが動いていなくてもDriverがOFFになるようにします。</p>



<p class="wp-block-paragraph">特にリレーは一瞬ONするだけでも、</p>



<ul class="wp-block-list">
<li>接点が切り替わる</li>



<li>機械が動く</li>



<li>電源が投入される</li>
</ul>



<p class="wp-block-paragraph">可能性があります。</p>



<p class="wp-block-paragraph">そのためLEDよりも起動時状態の重要度は高くなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Enable信号は安全側へ倒す</h2>



<p class="wp-block-paragraph">Motor Driver、Power IC、外部ModuleなどにはEnable端子があることがあります。</p>



<p class="wp-block-paragraph">このEnable信号は、</p>



<p class="wp-block-paragraph"><strong>CPU Reset中にどちらの論理へ倒すべきか</strong></p>



<p class="wp-block-paragraph">を先に決めます。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">HIGH = Enable</p>



<p class="wp-block-paragraph">ならPull-down。</p>



<p class="wp-block-paragraph">LOW = Enable</p>



<p class="wp-block-paragraph">ならPull-up。</p>



<p class="wp-block-paragraph">というように、</p>



<p class="wp-block-paragraph"><strong>安全状態をHardwareで固定</strong></p>



<p class="wp-block-paragraph">します。</p>



<p class="wp-block-paragraph">ここで重要なのは、</p>



<p class="wp-block-paragraph">「CPUが起動したら正しく制御できる」</p>



<p class="wp-block-paragraph">ではなく、</p>



<p class="wp-block-paragraph"><strong>CPUが起動していないときでも安全である</strong></p>



<p class="wp-block-paragraph">ことです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Software初期化もできるだけ早く行う</h2>



<p class="wp-block-paragraph">Hardware側でDefault状態を決めたうえで、Software側でもApplication開始後にできるだけ早くGPIOを初期化します。</p>



<p class="wp-block-paragraph">サンプルコードでは、<code>app_main()</code>の最初でGPIO設定を行っています。</p>



<pre class="wp-block-code"><code>gpio_config_t io_conf = {
    .pin_bit_mask = (1ULL &lt;&lt; OUTPUT_GPIO),
    .mode = GPIO_MODE_OUTPUT,
    .pull_up_en = GPIO_PULLUP_DISABLE,
    .pull_down_en = GPIO_PULLDOWN_DISABLE,
    .intr_type = GPIO_INTR_DISABLE
};

ESP_ERROR_CHECK(gpio_config(&amp;io_conf));

ESP_ERROR_CHECK(
    gpio_set_level(OUTPUT_GPIO, 0));</code></pre>



<p class="wp-block-paragraph">この順番なら、Applicationが開始したあと早い段階でGPIOをLOWへ確定できます。</p>



<p class="wp-block-paragraph">ただし、繰り返しになりますが、</p>



<p class="wp-block-paragraph"><strong>このコードが動く前の状態はHardware側で担保する</strong></p>



<p class="wp-block-paragraph">という役割分担が重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIO初期値と出力切替順序にも注意する</h2>



<p class="wp-block-paragraph">回路によっては、GPIOをOutputに切り替えた瞬間の状態も気になる場合があります。</p>



<p class="wp-block-paragraph">例えば、</p>



<ol start="1" class="wp-block-list">
<li>GPIOをOutputへ設定</li>



<li>その後LOWへ設定</li>
</ol>



<p class="wp-block-paragraph">という順序で、ごく短時間だけ意図しない状態になる可能性がないか確認します。</p>



<p class="wp-block-paragraph">必要に応じて、使用するESP-IDF APIやGPIOの初期値設定方法を確認し、</p>



<p class="wp-block-paragraph"><strong>Outputとして有効になる瞬間から安全な論理になるようにする</strong></p>



<p class="wp-block-paragraph">ことも重要です。</p>



<p class="wp-block-paragraph">特に高速なDriver EnableやPower Controlでは、この短い時間も無視できない場合があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Reset中にも同じことが起きる</h2>



<p class="wp-block-paragraph">起動時対策は、電源投入時だけの話ではありません。</p>



<p class="wp-block-paragraph">ESP32がResetすると、再びApplicationがGPIOを制御するまでの期間が発生します。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>Watchdog Reset</li>



<li>Software Reset</li>



<li>Brownout</li>



<li>EN Reset</li>



<li>Firmware更新後のReset</li>
</ul>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>Reset = GPIO制御が一時的に解除される可能性がある</strong></p>



<p class="wp-block-paragraph">と考えます。</p>



<p class="wp-block-paragraph">製品が運転中にResetしても、外部回路が勝手にONしないようにしておく必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Brownout時も安全状態を維持する</h2>



<p class="wp-block-paragraph">Brownoutも注意したいケースです。</p>



<p class="wp-block-paragraph">電源電圧が低下すると、ESP32が正常に制御できなくなる前後で外部回路の状態が変化する可能性があります。</p>



<p class="wp-block-paragraph">そのため重要なEnable信号では、</p>



<p class="wp-block-paragraph"><strong>電源が不安定になっても外部回路が安全側へ倒れる</strong></p>



<p class="wp-block-paragraph">ようにします。</p>



<p class="wp-block-paragraph">ここでもPull-up/Pull-downやDriver回路のDefault状態が効いてきます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">外部ICの内部Pull-up/Pull-downも確認する</h2>



<p class="wp-block-paragraph">ESP32側だけを見ていると見落としやすいのが、接続先ICの内部抵抗です。</p>



<p class="wp-block-paragraph">例えばDriver ICのEnable端子に、</p>



<p class="wp-block-paragraph"><strong>内部Pull-up</strong></p>



<p class="wp-block-paragraph">が入っている場合があります。</p>



<p class="wp-block-paragraph">ESP32側で何も接続しなければ、自動的にEnableになる可能性があります。</p>



<p class="wp-block-paragraph">逆に内部Pull-downがある場合もあります。</p>



<p class="wp-block-paragraph">そのため外部ICのデータシートで、</p>



<ul class="wp-block-list">
<li>Internal Pull-up</li>



<li>Internal Pull-down</li>



<li>Input Leakage</li>



<li>Default State</li>
</ul>



<p class="wp-block-paragraph">を確認します。</p>



<p class="wp-block-paragraph">外付け抵抗と内部抵抗が並列になることも考慮します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Active High / Active Lowを回路図で明確にする</h2>



<p class="wp-block-paragraph">製品設計では、信号名にもDefault状態を反映すると分かりやすくなります。</p>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>MOTOR_EN</code></pre>



<p class="wp-block-paragraph">だけではなく、</p>



<pre class="wp-block-code"><code>MOTOR_EN</code></pre>



<p class="wp-block-paragraph">がHIGH Activeなのか、</p>



<pre class="wp-block-code"><code>/MOTOR_EN</code></pre>



<p class="wp-block-paragraph">のようなLOW Activeなのかを明確にします。</p>



<p class="wp-block-paragraph">回路図上でActive Levelが分かると、</p>



<p class="wp-block-paragraph">「起動時にPull-upなのかPull-downなのか」</p>



<p class="wp-block-paragraph">も判断しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">安全が必要な負荷はSoftwareだけに任せない</h2>



<p class="wp-block-paragraph">特に、</p>



<ul class="wp-block-list">
<li>ヒーター</li>



<li>モーター</li>



<li>ソレノイド</li>



<li>電磁弁</li>



<li>リレー</li>



<li>高出力LED</li>



<li>電源制御</li>
</ul>



<p class="wp-block-paragraph">のような負荷では、</p>



<p class="wp-block-paragraph"><strong>Applicationが正常に起動してからOFFにする</strong></p>



<p class="wp-block-paragraph">という設計だけでは不十分な場合があります。</p>



<p class="wp-block-paragraph">Hardware側でDefault OFFを作り、</p>



<p class="wp-block-paragraph">Softwareはその状態を必要なときだけ変更する。</p>



<p class="wp-block-paragraph">この構成なら、</p>



<p class="wp-block-paragraph">CPUがResetしても、</p>



<p class="wp-block-paragraph">Firmwareが起動しなくても、</p>



<p class="wp-block-paragraph">Debug中でも、</p>



<p class="wp-block-paragraph">Default状態を維持しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">起動時誤動作の切り分け方法</h2>



<p class="wp-block-paragraph">起動時だけ負荷が動く場合は、次の順序で確認すると整理しやすくなります。</p>



<p class="wp-block-paragraph"><strong>1. GPIOの起動時波形を見る</strong></p>



<p class="wp-block-paragraph">電源投入からApplication起動までを確認します。</p>



<p class="wp-block-paragraph"><strong>2. 外部回路のDefault状態を見る</strong></p>



<p class="wp-block-paragraph">Pull-up/Pull-downがあるか確認します。</p>



<p class="wp-block-paragraph"><strong>3. Strapping Pinか確認する</strong></p>



<p class="wp-block-paragraph">Boot動作に関係するGPIOではないか確認します。</p>



<p class="wp-block-paragraph"><strong>4. 外部ICの内部Pullを確認する</strong></p>



<p class="wp-block-paragraph">DriverやEnable端子側の仕様を確認します。</p>



<p class="wp-block-paragraph"><strong>5. Reset時にも同じ現象が起きるか確認する</strong></p>



<p class="wp-block-paragraph">電源投入だけでなくSoftware Resetなどでも確認します。</p>



<p class="wp-block-paragraph"><strong>6. Hardwareで安全状態を作る</strong></p>



<p class="wp-block-paragraph">必要に応じて外付けPull-up/Pull-downを追加します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SoftwareとHardwareの役割を分ける</h2>



<p class="wp-block-paragraph">起動時GPIO対策では、SoftwareとHardwareのどちらか一方だけで解決しようとしない方が分かりやすくなります。</p>



<p class="wp-block-paragraph">Hardware：</p>



<p class="wp-block-paragraph"><strong>CPUが制御していない状態でも安全なDefaultを作る</strong></p>



<p class="wp-block-paragraph">Software：</p>



<p class="wp-block-paragraph"><strong>起動後に必要な状態へ正しく制御する</strong></p>



<p class="wp-block-paragraph">という役割分担です。</p>



<p class="wp-block-paragraph">例えばMotor Enableなら、</p>



<pre class="wp-block-code"><code>電源投入
↓
Hardware Pull-down
↓
Motor OFF
↓
ESP32起動
↓
GPIO初期化
↓
必要な条件が成立
↓
SoftwareでMotor ON</code></pre>



<p class="wp-block-paragraph">という流れにできます。</p>



<p class="wp-block-paragraph">これなら起動時にMotorが勝手に回る可能性を減らせます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">設計時チェックリスト</h2>



<p class="wp-block-paragraph">ESP32のGPIOで外部回路を制御するときは、次の項目を確認しておくと安心です。</p>



<ul class="wp-block-list">
<li>そのGPIOはStrapping Pinではないか</li>



<li>Reset中の状態はどうなるか</li>



<li>Application起動前の状態を考えたか</li>



<li>外部回路の安全状態はHIGHかLOWか</li>



<li>外付けPull-up/Pull-downは必要か</li>



<li>外部ICに内部Pullがないか</li>



<li>Reset時にも負荷が安全か</li>



<li>Brownout時にも安全か</li>



<li>GPIO波形を実測したか</li>



<li>Software初期化をできるだけ早く行っているか</li>



<li>安全に関係する負荷をSoftwareだけに依存していないか</li>
</ul>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">ESP32で、</p>



<p class="wp-block-paragraph">「起動時だけGPIOが勝手に動く」</p>



<p class="wp-block-paragraph">ように見える現象は、Applicationだけを見ていると分かりにくいことがあります。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<p class="wp-block-paragraph"><strong>ESP32がGPIOを制御できない時間も存在する</strong></p>



<p class="wp-block-paragraph">ということです。</p>



<p class="wp-block-paragraph">電源投入直後。</p>



<p class="wp-block-paragraph">Reset中。</p>



<p class="wp-block-paragraph">Boot処理中。</p>



<p class="wp-block-paragraph">Application初期化前。</p>



<p class="wp-block-paragraph">こうした期間でも外部回路を安全な状態へ保つには、Hardware側のDefault設計が重要になります。</p>



<p class="wp-block-paragraph">MOSFET GateならPull-down。</p>



<p class="wp-block-paragraph">Active Low EnableならPull-up。</p>



<p class="wp-block-paragraph">Driver回路ならDefault OFF。</p>



<p class="wp-block-paragraph">そしてApplicationが起動したあと、Softwareで必要な状態へ切り替えます。</p>



<p class="wp-block-paragraph"><strong>Hardwareで安全状態を作り、Softwareで制御する。</strong></p>



<p class="wp-block-paragraph">この役割分担を決めておけば、起動時やReset時の意図しない動作を防ぎやすくなります。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>技術は、経験から価値になる。</strong></p>



<p class="wp-block-paragraph"><strong>DLROW Design | 現場エンジニア</strong></p>The post <a href="https://dlrow-design.net/esp32%e3%81%ae%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%abgpio%e3%81%8c%e5%8b%9d%e6%89%8b%e3%81%ab%e5%8b%95%e3%81%8f%ef%bc%9f%ef%bd%9c%e5%88%9d%e6%9c%9f%e7%8a%b6%e6%85%8b%e3%83%bbpull-up%e3%83%bbpull-down/">ESP32の起動時にGPIOが勝手に動く？｜初期状態・Pull-up・Pull-downで誤動作を防ぐ方法</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32のGPIOは何mAまで流せる？｜出力電流と直接駆動してはいけない負荷</title>
		<link>https://dlrow-design.net/esp32%e3%81%aegpio%e3%81%af%e4%bd%95ma%e3%81%be%e3%81%a7%e6%b5%81%e3%81%9b%e3%82%8b%ef%bc%9f%ef%bd%9c%e5%87%ba%e5%8a%9b%e9%9b%bb%e6%b5%81%e3%81%a8%e7%9b%b4%e6%8e%a5%e9%a7%86%e5%8b%95%e3%81%97%e3%81%a6/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25aegpio%25e3%2581%25af%25e4%25bd%2595ma%25e3%2581%25be%25e3%2581%25a7%25e6%25b5%2581%25e3%2581%259b%25e3%2582%258b%25ef%25bc%259f%25ef%25bd%259c%25e5%2587%25ba%25e5%258a%259b%25e9%259b%25bb%25e6%25b5%2581%25e3%2581%25a8%25e7%259b%25b4%25e6%258e%25a5%25e9%25a7%2586%25e5%258b%2595%25e3%2581%2597%25e3%2581%25a6</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Fri, 14 Aug 2026 08:38:06 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=808</guid>

					<description><![CDATA[<p>ESP32でLEDやリレーなどを制御するとき、 「GPIOから何mAまで流していいのか？」 と迷うことがあります。 例えばLEDなら、GPIOへ抵抗を接続して直接点灯させる回路をよく見かけます。 では ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%aegpio%e3%81%af%e4%bd%95ma%e3%81%be%e3%81%a7%e6%b5%81%e3%81%9b%e3%82%8b%ef%bc%9f%ef%bd%9c%e5%87%ba%e5%8a%9b%e9%9b%bb%e6%b5%81%e3%81%a8%e7%9b%b4%e6%8e%a5%e9%a7%86%e5%8b%95%e3%81%97%e3%81%a6/">ESP32のGPIOは何mAまで流せる？｜出力電流と直接駆動してはいけない負荷</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32でLEDやリレーなどを制御するとき、</p>



<p class="wp-block-paragraph">「GPIOから何mAまで流していいのか？」</p>



<p class="wp-block-paragraph">と迷うことがあります。</p>



<p class="wp-block-paragraph">例えばLEDなら、GPIOへ抵抗を接続して直接点灯させる回路をよく見かけます。</p>



<p class="wp-block-paragraph">では、</p>



<p class="wp-block-paragraph">10mAなら大丈夫なのか。</p>



<p class="wp-block-paragraph">20mAならどうなのか。</p>



<p class="wp-block-paragraph">40mAまで流せるのか。</p>



<p class="wp-block-paragraph">そしてリレーやモーターもGPIOから直接動かしてよいのか。</p>



<p class="wp-block-paragraph">今回はESP32-C5を例に、GPIOの出力電流と、実際の回路設計でどう考えるべきかを整理します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「最大何mA？」だけで考えない</h2>



<p class="wp-block-paragraph">ESP32-C5-WROOM-1のデータシートには、GPIO出力について電流と出力電圧の関係が記載されています。</p>



<p class="wp-block-paragraph">最も強いDrive設定では、High側について、</p>



<p class="wp-block-paragraph"><strong>40mAをSourceした条件で、VOHが2.64V以上</strong></p>



<p class="wp-block-paragraph">という特性が示されています。</p>



<p class="wp-block-paragraph">Low側では、</p>



<p class="wp-block-paragraph"><strong>28mAをSinkした条件で、VOLが0.495V</strong></p>



<p class="wp-block-paragraph">という特性があります。</p>



<p class="wp-block-paragraph">ここで注意したいのが、</p>



<p class="wp-block-paragraph"><strong>40mAという数字だけを取り出さないこと</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">GPIOは理想的な3.3V電源ではありません。</p>



<p class="wp-block-paragraph">流す電流が大きくなれば、High出力の電圧は低下します。</p>



<p class="wp-block-paragraph">同じようにLow側へ大きな電流を流せば、出力電圧は0Vから上昇します。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>「GPIOから何mA取り出せるか」と「回路として何mA流す設計にするか」は別の話</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Drive Strengthも設定できる</h2>



<p class="wp-block-paragraph">ESP32-C5のGPIOにはDrive Capabilityの設定があります。</p>



<p class="wp-block-paragraph">ESP-IDFでは、</p>



<p class="wp-block-paragraph"><code>gpio_set_drive_capability()</code></p>



<p class="wp-block-paragraph">を使ってGPIO PadのDrive Capabilityを変更できます。</p>



<p class="wp-block-paragraph">ただし、Drive Strengthを強く設定したからといって、</p>



<p class="wp-block-paragraph"><strong>外部負荷へ大電流を供給するための電源出力になるわけではありません。</strong></p>



<p class="wp-block-paragraph">Drive Strengthはデジタル信号を駆動する能力の設定です。</p>



<p class="wp-block-paragraph">LEDをより明るくするために最大設定へする、リレーを動かすために最大設定へする、といった使い方を基本に考えるものではありません。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">LEDなら直接駆動できる場合がある</h2>



<p class="wp-block-paragraph">LED程度の小さな負荷なら、GPIOから直接駆動できる場合があります。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">3.3V GPIO<br>↓<br>電流制限抵抗<br>↓<br>LED<br>↓<br>GND</p>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">重要なのは、必ず電流制限抵抗を入れることです。</p>



<p class="wp-block-paragraph">LEDの順方向電圧を2.0V、GPIO出力を3.3V、抵抗を330Ωと仮定すると、</p>



<p class="wp-block-paragraph">(3.3V &#8211; 2.0V) / 330Ω</p>



<p class="wp-block-paragraph">なので、理想的には約4mAです。</p>



<p class="wp-block-paragraph">実際にはGPIOの出力特性やLEDのVfによって変わりますが、この程度ならインジケータLEDとして十分な場合も多いでしょう。</p>



<p class="wp-block-paragraph">「GPIOから20mA取れるから20mA流す」</p>



<p class="wp-block-paragraph">ではなく、</p>



<p class="wp-block-paragraph"><strong>必要な明るさを得られる範囲で電流を小さくする</strong></p>



<p class="wp-block-paragraph">方が扱いやすい設計です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">サンプルコード</h2>



<pre class="wp-block-code"><code>#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "driver/gpio.h"
#include "esp_log.h"

#define LED_GPIO GPIO_NUM_10

static const char *TAG = "GPIO_CURRENT";

void app_main(void)
{
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL &lt;&lt; LED_GPIO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };

    ESP_ERROR_CHECK(gpio_config(&amp;io_conf));

    ESP_LOGI(TAG, "GPIO LED test start");

    while (1)
    {
        gpio_set_level(LED_GPIO, 1);
        ESP_LOGI(TAG, "LED ON");

        vTaskDelay(pdMS_TO_TICKS(500));

        gpio_set_level(LED_GPIO, 0);
        ESP_LOGI(TAG, "LED OFF");

        vTaskDelay(pdMS_TO_TICKS(500));
    }
}</code></pre>



<p class="wp-block-paragraph">今回はGPIOを出力に設定し、LEDを500ms周期でON/OFFする簡単なコードを使用します。</p>



<p class="wp-block-paragraph">このコード自体が電流を制限するわけではありません。</p>



<p class="wp-block-paragraph"><strong>LED電流は外付け抵抗で制限します。</strong></p>



<p class="wp-block-paragraph">例えばGPIO10にLEDと電流制限抵抗を接続した場合を想定します。</p>



<p class="wp-block-paragraph">以下が今回使用するサンプルコード全文です。</p>



<p class="wp-block-paragraph">のサンプルではGPIO10をOutputとして使用しています。</p>



<p class="wp-block-paragraph">ここで、</p>



<p class="wp-block-paragraph"><code>gpio_set_level()</code>で1を出したから3.3V・何mAという電源が保証される、</p>



<p class="wp-block-paragraph">という考え方はしません。</p>



<p class="wp-block-paragraph">接続する負荷によってGPIOの電圧・電流条件は変化します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOをOutputに設定する</h2>



<p class="wp-block-paragraph">サンプルコードでは、次の部分でGPIO10を出力として設定しています。</p>



<pre class="wp-block-code"><code>gpio_config_t io_conf = {
    .pin_bit_mask = (1ULL &lt;&lt; LED_GPIO),
    .mode = GPIO_MODE_OUTPUT,
    .pull_up_en = GPIO_PULLUP_DISABLE,
    .pull_down_en = GPIO_PULLDOWN_DISABLE,
    .intr_type = GPIO_INTR_DISABLE
};

ESP_ERROR_CHECK(gpio_config(&amp;io_conf));</code></pre>



<p class="wp-block-paragraph">ここではGPIOをOutputとして設定しているだけです。</p>



<p class="wp-block-paragraph"><strong>接続する負荷の電流までESP-IDFが管理してくれるわけではありません。</strong></p>



<p class="wp-block-paragraph">例えばGPIOに低い抵抗値を接続すれば、GPIOはその負荷を駆動しようとします。</p>



<p class="wp-block-paragraph">そのため回路側で、</p>



<ul class="wp-block-list">
<li>負荷に必要な電流</li>



<li>GPIOの出力特性</li>



<li>電流制限抵抗</li>



<li>外部ドライバが必要か</li>
</ul>



<p class="wp-block-paragraph">を判断します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOのON/OFFは信号として考える</h2>



<p class="wp-block-paragraph">LEDのON/OFFは次の部分で行っています。</p>



<pre class="wp-block-code"><code>gpio_set_level(LED_GPIO, 1);
ESP_LOGI(TAG, "LED ON");

vTaskDelay(pdMS_TO_TICKS(500));

gpio_set_level(LED_GPIO, 0);
ESP_LOGI(TAG, "LED OFF");</code></pre>



<p class="wp-block-paragraph">ここで考えておきたいのが、</p>



<p class="wp-block-paragraph"><strong>GPIOは基本的に「電力を供給する端子」ではなく「信号を出力する端子」として扱う</strong></p>



<p class="wp-block-paragraph">という考え方です。</p>



<p class="wp-block-paragraph">LEDのように数mA程度で目的を達成できる負荷なら直接駆動できることがあります。</p>



<p class="wp-block-paragraph">しかし負荷電流が大きくなってくると、</p>



<p class="wp-block-paragraph">GPIO<br>↓<br>トランジスタ / MOSFET<br>↓<br>負荷</p>



<p class="wp-block-paragraph">という構成にします。</p>



<p class="wp-block-paragraph">GPIOはトランジスタやMOSFETへON/OFFの指示を出し、実際の負荷電流は外部電源から供給します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">リレーをGPIOから直接駆動しない</h2>



<p class="wp-block-paragraph">例えばコイル電流が50mA必要なリレーがあったとします。</p>



<p class="wp-block-paragraph">「GPIOは40mA程度まで出せるらしいから、少しだけ足りない」</p>



<p class="wp-block-paragraph">という問題ではありません。</p>



<p class="wp-block-paragraph">そもそもGPIOへリレーコイルを直接接続する設計を避けます。</p>



<p class="wp-block-paragraph">一般的には、</p>



<p class="wp-block-paragraph">ESP32 GPIO<br>↓<br>抵抗<br>↓<br>トランジスタ / MOSFET<br>↓<br>リレーコイル<br>↓<br>電源</p>



<p class="wp-block-paragraph">とします。</p>



<p class="wp-block-paragraph">さらにリレーコイルのような誘導性負荷では、OFF時に発生する逆起電力への対策も必要です。</p>



<p class="wp-block-paragraph">GPIOの電流能力だけを見て、</p>



<p class="wp-block-paragraph"><strong>「数字上流せそうだから接続する」</strong></p>



<p class="wp-block-paragraph">という判断をしないことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">モーターも直接駆動しない</h2>



<p class="wp-block-paragraph">DCモーターなどはさらに明確です。</p>



<p class="wp-block-paragraph">起動時には定常運転時より大きな電流が流れることがあります。</p>



<p class="wp-block-paragraph">またモーターは誘導性負荷であり、ノイズ源にもなります。</p>



<p class="wp-block-paragraph">そのためESP32のGPIOから直接駆動するのではなく、</p>



<ul class="wp-block-list">
<li>MOSFET</li>



<li>Motor Driver IC</li>



<li>H-Bridge</li>
</ul>



<p class="wp-block-paragraph">などを使用します。</p>



<p class="wp-block-paragraph">ESP32の役割は、</p>



<p class="wp-block-paragraph"><strong>モーターへ電力を供給することではなく、Driverへ制御信号を送ること</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">MOSFETなら何でもよいわけではない</h2>



<p class="wp-block-paragraph">GPIOからMOSFETを駆動する場合も注意が必要です。</p>



<p class="wp-block-paragraph">ESP32-C5のGPIOは3.3V系です。</p>



<p class="wp-block-paragraph">そのためMOSFETを選定するときは、</p>



<p class="wp-block-paragraph"><strong>VGS = 3.3V付近で十分にONできるか</strong></p>



<p class="wp-block-paragraph">を確認します。</p>



<p class="wp-block-paragraph">MOSFETのデータシートに記載されたThreshold Voltageだけを見て、</p>



<p class="wp-block-paragraph">「VGS(th)が2Vだから3.3Vで使える」</p>



<p class="wp-block-paragraph">と判断するのは危険です。</p>



<p class="wp-block-paragraph">VGS(th)は、一般にMOSFETが大電流を十分低いON抵抗で流せることを保証する値ではありません。</p>



<p class="wp-block-paragraph">実際に使用するGate VoltageでのRDS(on)などを確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">複数GPIOならさらに注意する</h2>



<p class="wp-block-paragraph">もう一つ忘れやすいのが、</p>



<p class="wp-block-paragraph"><strong>GPIOを1本だけ使用する場合と、多数を同時使用する場合は同じではない</strong></p>



<p class="wp-block-paragraph">ということです。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">「1pinである程度流せる」</p>



<p class="wp-block-paragraph">という情報だけを見て、</p>



<p class="wp-block-paragraph">多数のGPIOすべてへ同じ電流を流してよいとは限りません。</p>



<p class="wp-block-paragraph">実際の設計ではGPIO単体だけでなく、デバイス全体の電源条件、同時駆動するI/O数、発熱、電圧降下なども考える必要があります。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>1pinの最大値 × GPIO本数</strong></p>



<p class="wp-block-paragraph">という計算だけで設計するのは避けます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SourceとSinkの違い</h2>



<p class="wp-block-paragraph">GPIOから電流を扱うときは、SourceとSinkを分けて考えます。</p>



<p class="wp-block-paragraph"><strong>Source</strong>はGPIOから外部へ電流を流す状態です。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">ESP32 GPIO → 抵抗 → LED → GND</p>



<p class="wp-block-paragraph">という回路でGPIOをHIGHにすると、GPIOからLEDへ電流が流れます。</p>



<p class="wp-block-paragraph">一方、<strong>Sink</strong>は外部からGPIOへ電流を流し込む状態です。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">3.3V → 抵抗 → LED → ESP32 GPIO</p>



<p class="wp-block-paragraph">としてGPIOをLOWにすると、GPIO側へ電流が流れます。</p>



<p class="wp-block-paragraph">同じLEDを点灯させる場合でも、GPIOが担う役割は異なります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SourceとSinkで特性は同じではない</h2>



<p class="wp-block-paragraph">ESP32-C5のデータシートでは、High出力側とLow出力側で別々にDC特性が示されています。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>「GPIOは何mAまで流せるか」</strong></p>



<p class="wp-block-paragraph">を一つの数字だけで表現するのは適切ではありません。</p>



<p class="wp-block-paragraph">High出力時にはVOHがどこまで維持されるか。</p>



<p class="wp-block-paragraph">Low出力時にはVOLがどこまで上昇するか。</p>



<p class="wp-block-paragraph">このように、出力電圧と電流の関係で考えます。</p>



<p class="wp-block-paragraph">回路側が3.3V近いHighを必要としているのに、大きな電流をSourceした結果としてGPIO電圧が大きく低下すれば、論理信号としても問題になる可能性があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Drive Capabilityとは？</h2>



<p class="wp-block-paragraph">ESP32-C5ではGPIOのDrive Capabilityを設定できます。</p>



<p class="wp-block-paragraph">ESP-IDFでは<code>gpio_set_drive_capability()</code>を使用します。</p>



<p class="wp-block-paragraph">Drive Capabilityは、GPIO出力の駆動能力を変更するための設定です。</p>



<p class="wp-block-paragraph">ただし、</p>



<p class="wp-block-paragraph"><strong>Drive Capabilityを最大にすれば、大電流負荷を直接駆動できる</strong></p>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">Drive Strengthを強くすると、配線容量などに対して信号をより強く駆動できます。</p>



<p class="wp-block-paragraph">一方で、立ち上がり・立ち下がりが速くなることで、基板条件によってはリンギングやEMIなどの影響も考慮する必要があります。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>必要以上に強く設定することが常に正解ではありません。</strong></p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">LEDを複数同時に点灯する場合</h2>



<p class="wp-block-paragraph">1個のLEDを数mAで点灯する回路なら問題がなくても、LEDを多数同時にGPIOから駆動する場合は話が変わります。</p>



<p class="wp-block-paragraph">例えば10個のLEDへそれぞれ5mA流すと、</p>



<p class="wp-block-paragraph">合計では50mAです。</p>



<p class="wp-block-paragraph">ここで、</p>



<p class="wp-block-paragraph">「1GPIOあたり5mAだから問題ない」</p>



<p class="wp-block-paragraph">だけで判断してはいけません。</p>



<p class="wp-block-paragraph">確認したいのは、</p>



<ul class="wp-block-list">
<li>同時にONするGPIO数</li>



<li>デバイス全体の電源条件</li>



<li>GPIOのSource/Sink状態</li>



<li>3.3V電源への負荷</li>



<li>発熱</li>



<li>GPIO電圧の変化</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">多数のLEDを点灯する場合は、LED Driver ICやトランジスタアレイを使った方が合理的なこともあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOの最大値を合計しない</h2>



<p class="wp-block-paragraph">特に避けたいのが、</p>



<p class="wp-block-paragraph"><strong>1pinの数字 × GPIO本数</strong></p>



<p class="wp-block-paragraph">という考え方です。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">40mA × 10pin = 400mA</p>



<p class="wp-block-paragraph">だからESP32から400mA取り出せる、</p>



<p class="wp-block-paragraph">という計算にはなりません。</p>



<p class="wp-block-paragraph">GPIO単体の出力特性と、デバイス全体の電源・内部回路の制約は別に考える必要があります。</p>



<p class="wp-block-paragraph">多数のGPIOから比較的大きな電流を同時に取る設計は避け、外部ドライバを使う方が安全です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">MOSFETを使う判断</h2>



<p class="wp-block-paragraph">負荷電流がGPIO直接駆動には大きい場合、MOSFETを使う方法があります。</p>



<p class="wp-block-paragraph">基本構成は、</p>



<p class="wp-block-paragraph">ESP32 GPIO<br>↓<br>Gate抵抗<br>↓<br>MOSFET Gate</p>



<p class="wp-block-paragraph">そして負荷側は、</p>



<p class="wp-block-paragraph">電源<br>↓<br>負荷<br>↓<br>MOSFET<br>↓<br>GND</p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">この場合、GPIOはMOSFETのGateを制御するだけなので、負荷電流そのものはGPIOへ流れません。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>リレー</li>



<li>ソレノイド</li>



<li>小型DCモーター</li>



<li>LED Strip</li>



<li>ヒーター制御信号</li>
</ul>



<p class="wp-block-paragraph">などでは、このような構成が有効です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Logic Level MOSFETを選ぶ</h2>



<p class="wp-block-paragraph">ESP32-C5は3.3V GPIOです。</p>



<p class="wp-block-paragraph">そのためMOSFETを選定するときは、</p>



<p class="wp-block-paragraph"><strong>VGS = 2.5Vや3.3V付近でRDS(on)が規定されているもの</strong></p>



<p class="wp-block-paragraph">を選ぶと判断しやすくなります。</p>



<p class="wp-block-paragraph">注意したいのが<code>VGS(th)</code>です。</p>



<p class="wp-block-paragraph"><code>VGS(th)</code>はMOSFETが十分低いON抵抗になるGate電圧ではありません。</p>



<p class="wp-block-paragraph">一般に、非常に小さなDrain電流が流れ始める条件として規定されています。</p>



<p class="wp-block-paragraph">したがって、</p>



<p class="wp-block-paragraph"><code>VGS(th) = 1.5V</code></p>



<p class="wp-block-paragraph">だから、</p>



<p class="wp-block-paragraph">3.3V GPIOなら完全にONできる、</p>



<p class="wp-block-paragraph">とは判断しません。</p>



<p class="wp-block-paragraph">実際に使用するGate電圧での<code>RDS(on)</code>を確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Gate抵抗は何のため？</h2>



<p class="wp-block-paragraph">MOSFET GateはDC的にはほとんど電流を消費しません。</p>



<p class="wp-block-paragraph">ただしGateには容量があります。</p>



<p class="wp-block-paragraph">ON/OFF時にはこの容量を充放電するため、一時的にGPIOから電流が流れます。</p>



<p class="wp-block-paragraph">そこでGPIOとMOSFET Gateの間に、数十Ω〜数百Ω程度の抵抗を入れることがあります。</p>



<p class="wp-block-paragraph">目的は、</p>



<ul class="wp-block-list">
<li>Gate充放電電流のピークを抑える</li>



<li>リンギングを抑える</li>



<li>GPIOへの負担を軽減する</li>



<li>スイッチング速度を調整する</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">最適値はMOSFET、周波数、負荷条件によって変わります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Gate Pull-downも検討する</h2>



<p class="wp-block-paragraph">MOSFETをLow Side Switchとして使用する場合、</p>



<p class="wp-block-paragraph">ESP32がReset中、</p>



<p class="wp-block-paragraph">起動途中、</p>



<p class="wp-block-paragraph">GPIOがHi-Zの期間、</p>



<p class="wp-block-paragraph">などにGateが浮く可能性があります。</p>



<p class="wp-block-paragraph">そこで、</p>



<p class="wp-block-paragraph">Gate → GND</p>



<p class="wp-block-paragraph">へPull-down抵抗を設け、ESP32が制御していない状態ではMOSFETをOFFへ保つ設計がよく使われます。</p>



<p class="wp-block-paragraph">例えば10kΩ〜100kΩ程度を検討します。</p>



<p class="wp-block-paragraph">重要なのは抵抗値そのものより、</p>



<p class="wp-block-paragraph"><strong>起動時に負荷が勝手にONしない構成にすること</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">リレーやモーターでは逆起電力対策も必要</h2>



<p class="wp-block-paragraph">リレーコイルやDCモーターのような誘導性負荷では、電流を急に遮断すると大きな電圧が発生します。</p>



<p class="wp-block-paragraph">そのため、</p>



<ul class="wp-block-list">
<li>Flyback Diode</li>



<li>TVS</li>



<li>Snubber</li>
</ul>



<p class="wp-block-paragraph">などを負荷条件に応じて検討します。</p>



<p class="wp-block-paragraph">MOSFETを使えばGPIOから大電流を切り離せますが、</p>



<p class="wp-block-paragraph"><strong>MOSFETを追加しただけで回路が完成するわけではありません。</strong></p>



<p class="wp-block-paragraph">負荷の性質も考える必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">トランジスタを使う場合</h2>



<p class="wp-block-paragraph">小型リレーなどでは、NPNトランジスタを使うこともできます。</p>



<p class="wp-block-paragraph">ESP32 GPIO<br>↓<br>Base抵抗<br>↓<br>NPN transistor<br>↓<br>Relay</p>



<p class="wp-block-paragraph">という構成です。</p>



<p class="wp-block-paragraph">この場合はMOSFETとは異なり、Base電流を流す必要があります。</p>



<p class="wp-block-paragraph">そのため、</p>



<ul class="wp-block-list">
<li>必要なCollector電流</li>



<li>トランジスタの増幅率</li>



<li>Base電流</li>



<li>GPIOから流す電流</li>



<li>Base抵抗</li>
</ul>



<p class="wp-block-paragraph">を設計します。</p>



<p class="wp-block-paragraph">負荷電流が大きくなるほど、MOSFETの方が扱いやすい場合も多いです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「直接駆動するか」の判断基準</h2>



<p class="wp-block-paragraph">実際の設計では、私は次のように考えると整理しやすいと思います。</p>



<p class="wp-block-paragraph"><strong>数mA程度の表示LED</strong></p>



<p class="wp-block-paragraph">→ GPIO直接駆動を検討できる</p>



<p class="wp-block-paragraph"><strong>外部ICのDigital Input</strong></p>



<p class="wp-block-paragraph">→ 基本的にGPIOから直接接続できる<br>ただし電圧レベルや入力条件を確認</p>



<p class="wp-block-paragraph"><strong>トランジスタ/MOSFET Gate</strong></p>



<p class="wp-block-paragraph">→ GPIOで制御可能<br>Gate条件・抵抗・起動時状態を確認</p>



<p class="wp-block-paragraph"><strong>数十mA以上必要な負荷</strong></p>



<p class="wp-block-paragraph">→ 外部Driverを検討</p>



<p class="wp-block-paragraph"><strong>誘導性負荷</strong></p>



<p class="wp-block-paragraph">→ Driver＋逆起電力対策</p>



<p class="wp-block-paragraph"><strong>モーターや大電力負荷</strong></p>



<p class="wp-block-paragraph">→ 専用DriverやMOSFET回路を使用</p>



<p class="wp-block-paragraph">このように、GPIOの限界値から逆算するより、</p>



<p class="wp-block-paragraph"><strong>負荷の種類から駆動方法を決める</strong></p>



<p class="wp-block-paragraph">方が設計しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOが壊れる前に起こること</h2>



<p class="wp-block-paragraph">GPIOに過大な負荷を接続した場合、</p>



<p class="wp-block-paragraph">いきなり完全故障するとは限りません。</p>



<p class="wp-block-paragraph">その前に、</p>



<ul class="wp-block-list">
<li>High電圧が下がる</li>



<li>Low電圧が上がる</li>



<li>通信が不安定になる</li>



<li>GPIO出力が期待通りにならない</li>



<li>ESP32全体の電源が不安定になる</li>



<li>Resetが発生する</li>
</ul>



<p class="wp-block-paragraph">といった症状として現れる可能性があります。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>動いているから安全とは限りません。</strong></p>



<p class="wp-block-paragraph">長時間運転や温度条件、複数GPIO同時動作なども含めて確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOトラブルの切り分け</h2>



<p class="wp-block-paragraph">GPIOに接続した負荷が正常に動かない場合は、次の順番で確認すると整理しやすくなります。</p>



<p class="wp-block-paragraph"><strong>1. GPIO単体の電圧を確認する</strong></p>



<p class="wp-block-paragraph">負荷を外した状態でHIGH/LOWが正常か確認します。</p>



<p class="wp-block-paragraph"><strong>2. 負荷接続後の電圧を見る</strong></p>



<p class="wp-block-paragraph">負荷を接続した瞬間にHigh電圧が大きく下がっていないか確認します。</p>



<p class="wp-block-paragraph"><strong>3. 負荷電流を確認する</strong></p>



<p class="wp-block-paragraph">必要な電流が想定通りか確認します。</p>



<p class="wp-block-paragraph"><strong>4. 外部Driverを入れて確認する</strong></p>



<p class="wp-block-paragraph">Driver経由で正常になるなら、GPIO直接駆動が原因候補になります。</p>



<p class="wp-block-paragraph"><strong>5. 電源全体を見る</strong></p>



<p class="wp-block-paragraph">負荷切替によって3.3V自体が低下していないか確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GPIOを使うときの設計チェック</h2>



<p class="wp-block-paragraph">最後に、実際の回路設計で確認したいポイントをまとめます。</p>



<ul class="wp-block-list">
<li>GPIOは信号出力として使う</li>



<li>データシートの電流値だけを見ない</li>



<li>Source/Sinkを区別する</li>



<li>VOH/VOL条件を見る</li>



<li>LEDは必要最小限の電流で使う</li>



<li>数十mA級の負荷は直接駆動しない</li>



<li>モーターやリレーは外部Driverを使用する</li>



<li>MOSFETは3.3VでのRDS(on)を確認する</li>



<li>誘導性負荷には逆起電力対策を入れる</li>



<li>多数GPIOの同時駆動にも注意する</li>



<li>起動時のGPIO状態も確認する</li>
</ul>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">ESP32-C5のGPIOには数十mAクラスの出力特性が記載されています。</p>



<p class="wp-block-paragraph">しかし、それは、</p>



<p class="wp-block-paragraph"><strong>「その電流を積極的に取り出して負荷を駆動するための電源端子」</strong></p>



<p class="wp-block-paragraph">という意味ではありません。</p>



<p class="wp-block-paragraph">GPIOは基本的に、</p>



<p class="wp-block-paragraph"><strong>外部回路へHIGH/LOWを伝える信号端子</strong></p>



<p class="wp-block-paragraph">として考えます。</p>



<p class="wp-block-paragraph">小電流のLEDなどは直接駆動できる場合がありますが、</p>



<ul class="wp-block-list">
<li>リレー</li>



<li>モーター</li>



<li>ソレノイド</li>



<li>大電流LED</li>
</ul>



<p class="wp-block-paragraph">などはMOSFETやトランジスタ、専用Driverを使用します。</p>



<p class="wp-block-paragraph">そして重要なのは、</p>



<p class="wp-block-paragraph"><strong>最大何mA流せるかではなく、必要な機能をどれだけ余裕を持って実現できるか</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">データシートの最大付近を目標にするのではなく、GPIOに必要以上の負担をかけない回路を作る。</p>



<p class="wp-block-paragraph">その方が、長時間安定して動作する製品へつながります。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>技術は、経験から価値になる。</strong></p>



<p class="wp-block-paragraph"><strong>DLROW Design | 現場エンジニア</strong></p>The post <a href="https://dlrow-design.net/esp32%e3%81%aegpio%e3%81%af%e4%bd%95ma%e3%81%be%e3%81%a7%e6%b5%81%e3%81%9b%e3%82%8b%ef%bc%9f%ef%bd%9c%e5%87%ba%e5%8a%9b%e9%9b%bb%e6%b5%81%e3%81%a8%e7%9b%b4%e6%8e%a5%e9%a7%86%e5%8b%95%e3%81%97%e3%81%a6/">ESP32のGPIOは何mAまで流せる？｜出力電流と直接駆動してはいけない負荷</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32が突然再起動する原因｜リセット理由からBrownout・Watchdogを切り分ける方法</title>
		<link>https://dlrow-design.net/esp32%e3%81%8c%e7%aa%81%e7%84%b6%e5%86%8d%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%83%aa%e3%82%bb%e3%83%83%e3%83%88%e7%90%86%e7%94%b1%e3%81%8b%e3%82%89brownout%e3%83%bbwatchdo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%258c%25e7%25aa%2581%25e7%2584%25b6%25e5%2586%258d%25e8%25b5%25b7%25e5%258b%2595%25e3%2581%2599%25e3%2582%258b%25e5%258e%259f%25e5%259b%25a0%25ef%25bd%259c%25e3%2583%25aa%25e3%2582%25bb%25e3%2583%2583%25e3%2583%2588%25e7%2590%2586%25e7%2594%25b1%25e3%2581%258b%25e3%2582%2589brownout%25e3%2583%25bbwatchdo</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 14:16:11 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=804</guid>

					<description><![CDATA[<p>ESP32でプログラムを動かしていると、 「しばらく動かしていると突然再起動する」 「Wi-Fi通信を始めた瞬間にリセットする」 「処理を追加したら、ときどき最初から起動し直すようになった」 といった ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%8c%e7%aa%81%e7%84%b6%e5%86%8d%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%83%aa%e3%82%bb%e3%83%83%e3%83%88%e7%90%86%e7%94%b1%e3%81%8b%e3%82%89brownout%e3%83%bbwatchdo/">ESP32が突然再起動する原因｜リセット理由からBrownout・Watchdogを切り分ける方法</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32でプログラムを動かしていると、</p>



<p class="wp-block-paragraph">「しばらく動かしていると突然再起動する」</p>



<p class="wp-block-paragraph">「Wi-Fi通信を始めた瞬間にリセットする」</p>



<p class="wp-block-paragraph">「処理を追加したら、ときどき最初から起動し直すようになった」</p>



<p class="wp-block-paragraph">といった現象に遭遇することがあります。</p>



<p class="wp-block-paragraph">突然再起動すると、つい直前に追加したプログラムを疑いたくなります。</p>



<p class="wp-block-paragraph">しかしESP32が再起動する原因は、プログラムだけとは限りません。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>電源電圧の低下</li>



<li>Watchdog</li>



<li>CPU例外</li>



<li>Stack関連の異常</li>



<li>Heap破損</li>



<li>ソフトウェアからの再起動</li>
</ul>



<p class="wp-block-paragraph">などでも再起動します。</p>



<p class="wp-block-paragraph">そこで重要なのが、</p>



<p class="wp-block-paragraph"><strong>「なぜ再起動したのか」を最初に確認すること</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">今回はESP32-C5とESP-IDFを例に、リセット理由を取得しながら原因を切り分ける方法を紹介します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">最初にリセット理由を確認する</h2>



<p class="wp-block-paragraph">ESP-IDFには、直前のリセット理由を取得するための</p>



<p class="wp-block-paragraph"><code>esp_reset_reason()</code></p>



<p class="wp-block-paragraph">が用意されています。</p>



<p class="wp-block-paragraph">突然再起動する現象が発生したら、まずこの情報を確認します。</p>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>ESP_RST_BROWNOUT</code></pre>



<p class="wp-block-paragraph">なら電源側を疑う。</p>



<pre class="wp-block-code"><code>ESP_RST_TASK_WDT</code></pre>



<p class="wp-block-paragraph">ならTask Watchdogを疑う。</p>



<pre class="wp-block-code"><code>ESP_RST_PANIC</code></pre>



<p class="wp-block-paragraph">なら例外やPanic発生時のログを確認する。</p>



<p class="wp-block-paragraph">このように、リセット理由が分かるだけでも調査範囲をかなり狭められます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">サンプルコード</h2>



<p class="wp-block-paragraph">今回は起動時に直前のリセット理由を取得し、ログへ表示するサンプルを使用します。</p>



<p class="wp-block-paragraph">さらに現在のFree Heapと、起動後に記録されたMinimum Free Heapも定期的に表示します。</p>



<p class="wp-block-paragraph"><strong>以下が今回使用するサンプルコード全文です。</strong></p>



<pre class="wp-block-code"><code>#include &lt;stdio.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_system.h"
#include "esp_log.h"

static const char *TAG = "RESET_CHECK";

static const char *reset_reason_to_string(
    esp_reset_reason_t reason)
{
    switch (reason)
    {
        case ESP_RST_POWERON:
            return "POWERON";

        case ESP_RST_SW:
            return "SOFTWARE";

        case ESP_RST_PANIC:
            return "PANIC";

        case ESP_RST_INT_WDT:
            return "INTERRUPT_WDT";

        case ESP_RST_TASK_WDT:
            return "TASK_WDT";

        case ESP_RST_WDT:
            return "OTHER_WDT";

        case ESP_RST_DEEPSLEEP:
            return "DEEPSLEEP";

        case ESP_RST_BROWNOUT:
            return "BROWNOUT";

        case ESP_RST_USB:
            return "USB";

        case ESP_RST_JTAG:
            return "JTAG";

        case ESP_RST_EFUSE:
            return "EFUSE_ERROR";

        case ESP_RST_PWR_GLITCH:
            return "POWER_GLITCH";

        case ESP_RST_CPU_LOCKUP:
            return "CPU_LOCKUP";

        case ESP_RST_UNKNOWN:
        default:
            return "UNKNOWN";
    }
}

static void print_reset_reason(void)
{
    esp_reset_reason_t reason;

    reason = esp_reset_reason();

    ESP_LOGI(
        TAG,
        "Reset reason: %s (%d)",
        reset_reason_to_string(reason),
        (int)reason);
}

static void print_memory_status(void)
{
    ESP_LOGI(
        TAG,
        "Free heap: %lu bytes",
        (unsigned long)esp_get_free_heap_size());

    ESP_LOGI(
        TAG,
        "Minimum free heap: %lu bytes",
        (unsigned long)esp_get_minimum_free_heap_size());
}

void app_main(void)
{
    ESP_LOGI(
        TAG,
        "ESP32 reset check start");

    print_reset_reason();

    while (1)
    {
        print_memory_status();

        vTaskDelay(pdMS_TO_TICKS(5000));
    }
}</code></pre>



<p class="wp-block-paragraph">このサンプルを実行すると、起動時に直前のリセット理由を表示します。</p>



<p class="wp-block-paragraph">その後は5秒ごとにHeapの状態を表示します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">esp_reset_reason()で原因候補を絞る</h2>



<p class="wp-block-paragraph">先ほどのサンプルコードでは、<code>print_reset_reason()</code>内でリセット理由を取得しています。</p>



<pre class="wp-block-code"><code>static void print_reset_reason(void)
{
    esp_reset_reason_t reason;

    reason = esp_reset_reason();

    ESP_LOGI(
        TAG,
        "Reset reason: %s (%d)",
        reset_reason_to_string(reason),
        (int)reason);
}</code></pre>



<p class="wp-block-paragraph"><code>esp_reset_reason()</code>の戻り値は<code>esp_reset_reason_t</code>です。</p>



<p class="wp-block-paragraph">代表的なリセット理由には、</p>



<ul class="wp-block-list">
<li><code>ESP_RST_POWERON</code></li>



<li><code>ESP_RST_SW</code></li>



<li><code>ESP_RST_PANIC</code></li>



<li><code>ESP_RST_INT_WDT</code></li>



<li><code>ESP_RST_TASK_WDT</code></li>



<li><code>ESP_RST_WDT</code></li>



<li><code>ESP_RST_BROWNOUT</code></li>



<li><code>ESP_RST_PWR_GLITCH</code></li>



<li><code>ESP_RST_CPU_LOCKUP</code></li>
</ul>



<p class="wp-block-paragraph">などがあります。</p>



<p class="wp-block-paragraph">ここで大切なのは、</p>



<p class="wp-block-paragraph"><strong>リセット理由そのものが原因箇所を完全に教えてくれるわけではない</strong></p>



<p class="wp-block-paragraph">という点です。</p>



<p class="wp-block-paragraph">例えば<code>ESP_RST_TASK_WDT</code>なら「Task Watchdogによってリセットされた」ことは分かります。</p>



<p class="wp-block-paragraph">しかし、どの処理がCPUを長時間占有したのかまでは、別途ログやTaskの処理内容を調べる必要があります。</p>



<p class="wp-block-paragraph">リセット理由は原因を特定する答えというより、</p>



<p class="wp-block-paragraph"><strong>次にどこを調べるべきかを決める情報</strong></p>



<p class="wp-block-paragraph">として使います。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Brownoutなら、まず電源を疑う</h2>



<p class="wp-block-paragraph">リセット理由が<code>ESP_RST_BROWNOUT</code>だった場合は、プログラムを変更する前に電源を確認します。</p>



<p class="wp-block-paragraph">ESP32-C5にはBrownout Detectorがあり、電源電圧が安全なレベルを下回るとリセットする仕組みがあります。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>Wi-Fi送信開始時</li>



<li>BLE動作開始時</li>



<li>外部回路をONした瞬間</li>



<li>LEDやリレーなどの負荷を切り替えた瞬間</li>
</ul>



<p class="wp-block-paragraph">だけ再起動するのであれば、電源電圧の瞬間的な低下も疑います。</p>



<p class="wp-block-paragraph">ここで、</p>



<p class="wp-block-paragraph">「Wi-Fi処理を追加したら再起動した」</p>



<p class="wp-block-paragraph">という理由だけで、</p>



<p class="wp-block-paragraph"><strong>Wi-Fiプログラムにバグがある</strong></p>



<p class="wp-block-paragraph">と判断してはいけません。</p>



<p class="wp-block-paragraph">Wi-Fiを動かした結果、消費電流が変化し、電源側の問題が表面化した可能性もあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Brownout発生時は電源波形を見る</h2>



<p class="wp-block-paragraph">Brownoutが疑われる場合は、3.3V電源をテスターだけで確認して終わらせない方がよい場合があります。</p>



<p class="wp-block-paragraph">テスターで3.30Vと表示されていても、非常に短い時間だけ電圧が低下している可能性があります。</p>



<p class="wp-block-paragraph">このような瞬間的な電圧変動は、テスターでは確認できない場合があります。</p>



<p class="wp-block-paragraph">そのためBrownoutが発生しているなら、</p>



<p class="wp-block-paragraph"><strong>オシロスコープでESP32直近の3.3V電源を確認する</strong></p>



<p class="wp-block-paragraph">のが有効です。</p>



<p class="wp-block-paragraph">確認したいポイントは、</p>



<ul class="wp-block-list">
<li>電源ICの供給能力</li>



<li>3.3Vラインの電圧低下</li>



<li>デカップリングコンデンサ</li>



<li>電源配線</li>



<li>GND</li>



<li>負荷切替時の電圧変動</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Watchdogによるリセット</h2>



<p class="wp-block-paragraph">リセット理由が<code>ESP_RST_TASK_WDT</code>や<code>ESP_RST_INT_WDT</code>の場合はWatchdogを疑います。</p>



<p class="wp-block-paragraph">Watchdogは、プログラムが正常に処理を続けられなくなったときに、システムが永久に停止してしまうことを防ぐための仕組みです。</p>



<p class="wp-block-paragraph">例えばTask内で長時間処理を続け、他のTaskへ実行権を渡せない状態になると、Task Watchdogが発生する可能性があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">while(1)そのものが悪いわけではない</h2>



<p class="wp-block-paragraph">ESP32のプログラムでは<code>while (1)</code>という構造をよく使用します。</p>



<p class="wp-block-paragraph">重要なのは<code>while (1)</code>があることではなく、</p>



<p class="wp-block-paragraph"><strong>ループ内部でどのような処理をしているか</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">今回のサンプルコードでは次のようになっています。</p>



<pre class="wp-block-code"><code>while (1)
{
    print_memory_status();

    vTaskDelay(pdMS_TO_TICKS(5000));
}</code></pre>



<p class="wp-block-paragraph"><code>vTaskDelay()</code>によってTaskをBlock状態へ移しているため、CPUを永久に占有するループにはなっていません。</p>



<p class="wp-block-paragraph">一方、長時間CPUを占有し続ける処理では、Task構成やWatchdog設定によって問題になる可能性があります。</p>



<p class="wp-block-paragraph">したがってWatchdogが発生した場合は、</p>



<p class="wp-block-paragraph"><strong>「どのTaskが、どれくらい長く処理を続けているのか」</strong></p>



<p class="wp-block-paragraph">を確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Panicの場合は再起動前のログを見る</h2>



<p class="wp-block-paragraph">リセット理由が<code>ESP_RST_PANIC</code>だった場合は、再起動後の理由だけを見るのではなく、</p>



<p class="wp-block-paragraph"><strong>再起動する直前に出力されたログ</strong></p>



<p class="wp-block-paragraph">が非常に重要です。</p>



<p class="wp-block-paragraph">ESP-IDFではCPU例外などが発生すると、<code>Guru Meditation Error</code>とともに原因やBacktraceなどが出力される場合があります。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>Illegal Instruction</li>



<li>Load/Store Prohibited</li>



<li>Load/Store Alignment Error</li>



<li>Stack Overflow</li>



<li>Heap Corruption</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">この場合、「ESP32が勝手に再起動した」のではなく、</p>



<p class="wp-block-paragraph"><strong>Panic Handlerが異常を検出し、その結果として再起動した</strong></p>



<p class="wp-block-paragraph">と考えます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Heapの状態も一緒に確認する</h2>



<p class="wp-block-paragraph">今回のサンプルでは、Free Heapも定期的に表示しています。</p>



<pre class="wp-block-code"><code>static void print_memory_status(void)
{
    ESP_LOGI(
        TAG,
        "Free heap: %lu bytes",
        (unsigned long)esp_get_free_heap_size());

    ESP_LOGI(
        TAG,
        "Minimum free heap: %lu bytes",
        (unsigned long)esp_get_minimum_free_heap_size());
}</code></pre>



<p class="wp-block-paragraph"><code>esp_get_free_heap_size()</code>では現在利用可能なHeap量を確認できます。</p>



<p class="wp-block-paragraph">また、<code>esp_get_minimum_free_heap_size()</code>では、起動してから現在までで最も少なかったFree Heap量を確認できます。</p>



<p class="wp-block-paragraph">例えば長時間運転してFree Heapが継続的に減少しているのであれば、Memory Leakなどを疑う材料になります。</p>



<p class="wp-block-paragraph">ただし、Free Heapが減っただけでMemory Leakと断定してはいけません。</p>



<p class="wp-block-paragraph">システムや各Componentが必要に応じてMemoryを確保している場合もあります。</p>



<p class="wp-block-paragraph">ここでも重要なのは、</p>



<p class="wp-block-paragraph"><strong>時間とともにどのように変化しているかを見ること</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">再起動したら、まず分類する</h2>



<p class="wp-block-paragraph">突然再起動したときは、最初からすべてを疑うのではなく、まず大きく分類します。</p>



<p class="wp-block-paragraph"><strong>Brownout → 電源を確認</strong></p>



<p class="wp-block-paragraph"><strong>Watchdog → Task・割り込み・長時間処理を確認</strong></p>



<p class="wp-block-paragraph"><strong>Panic → 再起動直前のログとBacktraceを確認</strong></p>



<p class="wp-block-paragraph"><strong>その他 → 発生条件とReset Reasonを確認</strong></p>



<p class="wp-block-paragraph">BrownoutなのにTask処理を延々と調べても、なかなか原因にはたどり着けません。</p>



<p class="wp-block-paragraph">逆にTask Watchdogなのに電源回路だけを調べても同じです。</p>



<p class="wp-block-paragraph"><strong>最初に現象を分類する。</strong></p>



<p class="wp-block-paragraph">これが突然再起動する問題を切り分ける第一歩です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Task Watchdogが出たら何を見るか</h2>



<p class="wp-block-paragraph">前半では、<code>esp_reset_reason()</code>を使って再起動の原因を大きく分類しました。</p>



<p class="wp-block-paragraph">ここからは、それぞれのリセット理由が確認できたあと、具体的に何を調べればよいのかを見ていきます。</p>



<p class="wp-block-paragraph">まずはTask Watchdogです。</p>



<p class="wp-block-paragraph"><code>ESP_RST_TASK_WDT</code>が確認できた場合、</p>



<p class="wp-block-paragraph"><strong>「Watchdogを無効にすれば直る」</strong></p>



<p class="wp-block-paragraph">と考えるのはおすすめできません。</p>



<p class="wp-block-paragraph">Watchdogは問題そのものではなく、プログラムが正常に処理を継続できていないことを知らせている可能性があるからです。</p>



<p class="wp-block-paragraph">最初に確認したいのは、</p>



<ul class="wp-block-list">
<li>長時間終了しない処理</li>



<li>Blockしないループ</li>



<li>Task優先度</li>



<li>他Taskへ実行機会を与えているか</li>



<li>MutexやSemaphoreの待ち状態</li>



<li>処理時間が想定以上に長くなっていないか</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">vTaskDelay()の意味を確認する</h2>



<p class="wp-block-paragraph">前半で掲載したサンプルコードでは、メインループを次のようにしています。</p>



<pre class="wp-block-code"><code>while (1)
{
    print_memory_status();

    vTaskDelay(pdMS_TO_TICKS(5000));
}</code></pre>



<p class="wp-block-paragraph">ここで重要なのは、単に5秒待っていることではありません。</p>



<p class="wp-block-paragraph"><code>vTaskDelay()</code>を実行すると、そのTaskは指定時間だけBlock状態になります。</p>



<p class="wp-block-paragraph">その間、Schedulerは他の実行可能なTaskへCPU時間を割り当てられます。</p>



<p class="wp-block-paragraph">一方、</p>



<p class="wp-block-paragraph"><code>while (1)</code>の中で重い計算を延々と実行する、</p>



<p class="wp-block-paragraph">非常に長い処理から戻ってこない、</p>



<p class="wp-block-paragraph">高優先度TaskがCPUを占有し続ける、</p>



<p class="wp-block-paragraph">といった構造では、他のTaskやIdle Taskが十分に実行されない可能性があります。</p>



<p class="wp-block-paragraph">Watchdogが発生した場合は、</p>



<p class="wp-block-paragraph"><strong>Watchdogの時間を長くする前に、CPUを占有している処理がないか確認する</strong></p>



<p class="wp-block-paragraph">ことを優先します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Interrupt WatchdogはTask Watchdogと分けて考える</h2>



<p class="wp-block-paragraph"><code>ESP_RST_INT_WDT</code>と<code>ESP_RST_TASK_WDT</code>は、同じWatchdogでも調査対象が異なります。</p>



<p class="wp-block-paragraph">Task WatchdogならTask処理を中心に確認します。</p>



<p class="wp-block-paragraph">一方、Interrupt Watchdogが発生している場合は、</p>



<ul class="wp-block-list">
<li>Interruptを長時間Disableしていないか</li>



<li>Critical Sectionが長すぎないか</li>



<li>ISR内で時間のかかる処理をしていないか</li>
</ul>



<p class="wp-block-paragraph">などを確認します。</p>



<p class="wp-block-paragraph">割り込み処理では、</p>



<p class="wp-block-paragraph"><strong>「ISRの中ですべてを処理する」</strong></p>



<p class="wp-block-paragraph">のではなく、</p>



<p class="wp-block-paragraph"><strong>「ISRでは必要最低限の処理だけ行い、重い処理はTask側へ渡す」</strong></p>



<p class="wp-block-paragraph">という構成が基本になります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">PanicではReset Reasonだけで終わらない</h2>



<p class="wp-block-paragraph">次に<code>ESP_RST_PANIC</code>だった場合です。</p>



<p class="wp-block-paragraph">この場合、Reset Reasonから分かるのは、</p>



<p class="wp-block-paragraph"><strong>Panicによって再起動した</strong></p>



<p class="wp-block-paragraph">というところまでです。</p>



<p class="wp-block-paragraph">本当に欲しい情報は、再起動する直前のログにあります。</p>



<p class="wp-block-paragraph">ESP-IDFでは異常発生時に、例外の種類やRegister Dump、Backtraceなどが出力される場合があります。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph"><code>LoadProhibited</code></p>



<p class="wp-block-paragraph">が表示されていた場合は、不正なMemory AddressへのReadを疑います。</p>



<p class="wp-block-paragraph"><code>StoreProhibited</code></p>



<p class="wp-block-paragraph">なら、不正なMemory AddressへのWriteを疑います。</p>



<p class="wp-block-paragraph">このように、Panicの種類によって確認すべきコードが変わります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Backtraceを見る</h2>



<p class="wp-block-paragraph">Panic発生時にはBacktraceが表示されることがあります。</p>



<p class="wp-block-paragraph">Backtraceから、</p>



<p class="wp-block-paragraph"><strong>「どの関数を通って異常箇所へ到達したのか」</strong></p>



<p class="wp-block-paragraph">を追える場合があります。</p>



<p class="wp-block-paragraph">ESP-IDF Monitorを使用している環境では、BacktraceのAddressからソースコード上の関数名や行番号へ変換された情報を確認できる場合があります。</p>



<p class="wp-block-paragraph">ここで大切なのは、</p>



<p class="wp-block-paragraph"><strong>最後に表示された関数だけを原因と決めつけないこと</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">例えば不正なPointerを別の関数で生成し、そのPointerを後から使用した場所で例外が発生するケースがあります。</p>



<p class="wp-block-paragraph">つまり、</p>



<p class="wp-block-paragraph"><strong>異常が発生した場所と、異常を作り込んだ場所が同じとは限りません。</strong></p>



<p class="wp-block-paragraph">Backtraceを手掛かりに、その少し前の処理まで確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Brownoutなら「発生する瞬間」を探す</h2>



<p class="wp-block-paragraph">Brownoutの場合は、電源電圧だけを見るのではなく、</p>



<p class="wp-block-paragraph"><strong>何をした瞬間にBrownoutが発生するのか</strong></p>



<p class="wp-block-paragraph">を確認すると原因を絞りやすくなります。</p>



<p class="wp-block-paragraph">例えば、</p>



<ul class="wp-block-list">
<li>Wi-Fi送信開始</li>



<li>BLE通信開始</li>



<li>外部回路ON</li>



<li>モーター駆動開始</li>



<li>リレー切替</li>



<li>LED点灯</li>



<li>USB接続状態の変化</li>
</ul>



<p class="wp-block-paragraph">などです。</p>



<p class="wp-block-paragraph">「30分に1回再起動する」</p>



<p class="wp-block-paragraph">という情報だけより、</p>



<p class="wp-block-paragraph"><strong>「Wi-Fi送信開始直後に再起動する」</strong></p>



<p class="wp-block-paragraph">という情報の方が、はるかに原因を探しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32直近で3.3Vを測る</h2>



<p class="wp-block-paragraph">電源波形を測定するときは、できるだけESP32の電源端子に近い場所で確認します。</p>



<p class="wp-block-paragraph">電源ICの出力が正常でも、</p>



<p class="wp-block-paragraph">配線抵抗、</p>



<p class="wp-block-paragraph">パターンインピーダンス、</p>



<p class="wp-block-paragraph">コネクタ、</p>



<p class="wp-block-paragraph">GND、</p>



<p class="wp-block-paragraph">負荷変動、</p>



<p class="wp-block-paragraph">などによってESP32側の電圧が変動する可能性があります。</p>



<p class="wp-block-paragraph">特に自作基板では、</p>



<p class="wp-block-paragraph"><strong>「電源ICの出力は3.3Vだった」</strong></p>



<p class="wp-block-paragraph">だけで判断せず、</p>



<p class="wp-block-paragraph"><strong>「ESP32が実際に受け取っている3.3Vはどうなっているか」</strong></p>



<p class="wp-block-paragraph">を見ることが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">Heapは「現在値」だけでは判断しない</h2>



<pre class="wp-block-code"><code>ESP_LOGI(
    TAG,
    "Free heap: %lu bytes",
    (unsigned long)esp_get_free_heap_size());

ESP_LOGI(
    TAG,
    "Minimum free heap: %lu bytes",
    (unsigned long)esp_get_minimum_free_heap_size());</code></pre>



<p class="wp-block-paragraph">ここで注目したいのは、単純なFree Heapの大きさだけではありません。</p>



<p class="wp-block-paragraph">例えば起動直後に100kBあり、しばらくして80kBになったとしても、それだけでMemory Leakとは判断できません。</p>



<p class="wp-block-paragraph">一方、</p>



<p class="wp-block-paragraph">100kB<br>95kB<br>90kB<br>85kB<br>80kB<br>75kB</p>



<p class="wp-block-paragraph">のように、特定操作を繰り返すたびに戻らず減少しているのであれば、調査する価値があります。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">接続する<br>→ Memory確保</p>



<p class="wp-block-paragraph">切断する<br>→ Memory解放</p>



<p class="wp-block-paragraph">という処理を繰り返したとき、確保したMemoryが適切に解放されているか確認します。</p>



<p class="wp-block-paragraph"><strong>「何MB残っているか」ではなく「同じ操作を繰り返したときどう変化するか」</strong></p>



<p class="wp-block-paragraph">を見るのがポイントです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">HeapとStackを混同しない</h2>



<p class="wp-block-paragraph">ESP32のMemory問題を調査するときに注意したいのが、HeapとTask Stackは同じものではないという点です。</p>



<p class="wp-block-paragraph">Free Heapに余裕があっても、特定Taskへ割り当てたStackが不足する可能性があります。</p>



<p class="wp-block-paragraph">逆にTask Stackに余裕があっても、動的Memory確保を繰り返してHeap側で問題が発生することがあります。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>Free Heapが十分あるからMemory問題ではない</strong></p>



<p class="wp-block-paragraph">とは断定できません。</p>



<p class="wp-block-paragraph">Task Stackが疑わしい場合は、FreeRTOSのStack High Water Markなども使って確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ソフトウェアResetも確認する</h2>



<p class="wp-block-paragraph">再起動が発生した場合、ハードウェア異常とは限りません。</p>



<p class="wp-block-paragraph">前半のサンプルコードでは<code>esp_reset_reason()</code>の結果を文字列へ変換しています。</p>



<pre class="wp-block-code"><code>case ESP_RST_SW:
    return "SOFTWARE";</code></pre>



<p class="wp-block-paragraph"><code>ESP_RST_SW</code>が確認できた場合は、ソフトウェアからResetされた可能性を確認します。</p>



<p class="wp-block-paragraph">例えばアプリケーション側で異常を検出した際に、意図的に再起動する設計になっている場合があります。</p>



<p class="wp-block-paragraph">この場合、</p>



<p class="wp-block-paragraph">「なぜESP32がResetしたのか」</p>



<p class="wp-block-paragraph">ではなく、</p>



<p class="wp-block-paragraph"><strong>「なぜプログラムがResetを要求したのか」</strong></p>



<p class="wp-block-paragraph">を追います。</p>



<p class="wp-block-paragraph">ここでもReset Reasonを最初に確認していれば、電源やWatchdogを必要以上に調査せずに済みます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">再現条件を作る</h2>



<p class="wp-block-paragraph">原因調査で非常に重要なのが、再現条件です。</p>



<p class="wp-block-paragraph">例えば、</p>



<p class="wp-block-paragraph">「たまに再起動する」</p>



<p class="wp-block-paragraph">だけでは調査が難しくなります。</p>



<p class="wp-block-paragraph">そこで条件を変えてみます。</p>



<ul class="wp-block-list">
<li>Wi-Fiを使用すると発生するか</li>



<li>Wi-Fiを停止すると発生しないか</li>



<li>外部負荷を外すとどうなるか</li>



<li>通信周期を変更するとどうなるか</li>



<li>特定処理を繰り返すと発生するか</li>



<li>数分なのか数時間なのか</li>



<li>電源投入直後なのか長時間運転後なのか</li>
</ul>



<p class="wp-block-paragraph">こうして、</p>



<p class="wp-block-paragraph"><strong>「何をすると発生し、何をすると発生しないのか」</strong></p>



<p class="wp-block-paragraph">を探します。</p>



<p class="wp-block-paragraph">原因そのものがまだ分からなくても、再現条件が分かれば調査はかなり進みます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">一度に複数の条件を変えない</h2>



<p class="wp-block-paragraph">原因調査中に、</p>



<p class="wp-block-paragraph">電源を変更する。</p>



<p class="wp-block-paragraph">プログラムも変更する。</p>



<p class="wp-block-paragraph">通信速度も変更する。</p>



<p class="wp-block-paragraph">Task構成も変更する。</p>



<p class="wp-block-paragraph">これを一度に行うと、問題が解消しても、</p>



<p class="wp-block-paragraph"><strong>何が原因だったのか分からなくなります。</strong></p>



<p class="wp-block-paragraph">基本的には、一度に変更する条件をできるだけ少なくします。</p>



<p class="wp-block-paragraph">例えばBrownoutが疑わしいなら、</p>



<p class="wp-block-paragraph">まず電源波形を測定する。</p>



<p class="wp-block-paragraph">次に電源条件を変更する。</p>



<p class="wp-block-paragraph">それでも発生するなら次の条件を見る。</p>



<p class="wp-block-paragraph">というように進めます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">現場では「再起動した」より前の情報が重要</h2>



<p class="wp-block-paragraph">突然再起動するトラブルでは、Reset後のESP32だけを見ても情報が少ないことがあります。</p>



<p class="wp-block-paragraph">重要なのは、</p>



<p class="wp-block-paragraph"><strong>再起動する直前に何が起きていたのか</strong></p>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">そのため開発中は、最低限でも、</p>



<ul class="wp-block-list">
<li>起動ログ</li>



<li>Reset Reason</li>



<li>主要処理の開始・終了</li>



<li>Error</li>



<li>通信状態</li>



<li>Memory状態</li>
</ul>



<p class="wp-block-paragraph">などをログとして残しておくと、後から原因を追いやすくなります。</p>



<p class="wp-block-paragraph">特に再現頻度が低い問題では、</p>



<p class="wp-block-paragraph"><strong>問題が起きてからログを追加するのでは遅い</strong></p>



<p class="wp-block-paragraph">ことがあります。</p>



<p class="wp-block-paragraph">製品開発では、正常時には邪魔にならず、異常時には調査材料になるログ設計も重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ESP32が突然再起動したときの切り分け手順</h2>



<p class="wp-block-paragraph">ここまでを実際の調査順にすると、次のようになります。</p>



<p class="wp-block-paragraph"><strong>1. Reset Reasonを確認する</strong></p>



<p class="wp-block-paragraph">まず<code>esp_reset_reason()</code>で大分類します。</p>



<p class="wp-block-paragraph"><strong>2. 再起動直前のログを保存する</strong></p>



<p class="wp-block-paragraph">PanicやWatchdogの情報が残っていないか確認します。</p>



<p class="wp-block-paragraph"><strong>3. 発生条件を整理する</strong></p>



<p class="wp-block-paragraph">通信開始時、負荷切替時、長時間運転後など、再現条件を探します。</p>



<p class="wp-block-paragraph"><strong>4. Brownoutなら電源波形を確認する</strong></p>



<p class="wp-block-paragraph">ESP32直近の3.3Vをオシロスコープで確認します。</p>



<p class="wp-block-paragraph"><strong>5. WatchdogならTask・ISRを確認する</strong></p>



<p class="wp-block-paragraph">長時間処理、CPU占有、Critical Sectionなどを確認します。</p>



<p class="wp-block-paragraph"><strong>6. PanicならBacktraceを確認する</strong></p>



<p class="wp-block-paragraph">異常発生箇所だけでなく、そこへ至った処理も追います。</p>



<p class="wp-block-paragraph"><strong>7. Memoryを疑う場合は時間変化を見る</strong></p>



<p class="wp-block-paragraph">HeapやStackの余裕を継続的に確認します。</p>



<p class="wp-block-paragraph"><strong>8. 一つずつ条件を変更する</strong></p>



<p class="wp-block-paragraph">変更結果から原因候補を減らします。</p>



<p class="wp-block-paragraph">この順序なら、</p>



<p class="wp-block-paragraph"><strong>「とりあえずコードを書き換えてみる」</strong></p>



<p class="wp-block-paragraph">よりも、原因を残しながら調査できます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">ESP32が突然再起動すると、ソフトウェアのバグを最初に疑いたくなります。</p>



<p class="wp-block-paragraph">しかし実際には、</p>



<p class="wp-block-paragraph"><strong>Brownout<br>Watchdog<br>Panic<br>Memory<br>Software Reset</strong></p>



<p class="wp-block-paragraph">など、さまざまな原因があります。</p>



<p class="wp-block-paragraph">そこで最初に行うのが、</p>



<p class="wp-block-paragraph"><strong>Reset Reasonの確認です。</strong></p>



<p class="wp-block-paragraph">原因を推測して修正するのではなく、</p>



<p class="wp-block-paragraph"><strong>観測する<br>→ 分類する<br>→ 再現する<br>→ 一つずつ切り分ける</strong></p>



<p class="wp-block-paragraph">という順序で調査します。</p>



<p class="wp-block-paragraph">特に自作基板では、プログラムだけでなく電源やGND、負荷変動まで含めて考える必要があります。</p>



<p class="wp-block-paragraph">ESP32が再起動したという結果だけを見るのではなく、</p>



<p class="wp-block-paragraph"><strong>「再起動する直前に何が起きたのか」</strong></p>



<p class="wp-block-paragraph">を残しておくことが、原因特定への近道です。</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><strong>技術は、経験から価値になる。</strong></p>



<p class="wp-block-paragraph"><strong>DLROW Design | 現場エンジニア</strong></p>



<p class="wp-block-paragraph"></p>The post <a href="https://dlrow-design.net/esp32%e3%81%8c%e7%aa%81%e7%84%b6%e5%86%8d%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%83%aa%e3%82%bb%e3%83%83%e3%83%88%e7%90%86%e7%94%b1%e3%81%8b%e3%82%89brownout%e3%83%bbwatchdo/">ESP32が突然再起動する原因｜リセット理由からBrownout・Watchdogを切り分ける方法</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32のSPI通信が不安定になる原因｜クロック・配線・信号品質の対策</title>
		<link>https://dlrow-design.net/esp32%e3%81%aespi%e9%80%9a%e4%bf%a1%e3%81%8c%e4%b8%8d%e5%ae%89%e5%ae%9a%e3%81%ab%e3%81%aa%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%82%af%e3%83%ad%e3%83%83%e3%82%af%e3%83%bb%e9%85%8d%e7%b7%9a%e3%83%bb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32%25e3%2581%25aespi%25e9%2580%259a%25e4%25bf%25a1%25e3%2581%258c%25e4%25b8%258d%25e5%25ae%2589%25e5%25ae%259a%25e3%2581%25ab%25e3%2581%25aa%25e3%2582%258b%25e5%258e%259f%25e5%259b%25a0%25ef%25bd%259c%25e3%2582%25af%25e3%2583%25ad%25e3%2583%2583%25e3%2582%25af%25e3%2583%25bb%25e9%2585%258d%25e7%25b7%259a%25e3%2583%25bb</link>
		
		<dc:creator><![CDATA[管理者]]></dc:creator>
		<pubDate>Mon, 10 Aug 2026 13:16:39 +0000</pubDate>
				<category><![CDATA[ESP32]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[回路設計]]></category>
		<guid isPermaLink="false">https://dlrow-design.net/?p=801</guid>

					<description><![CDATA[<p>ESP32でSPI通信を実装して、 「低速なら動くのに、クロックを上げると通信エラーになる」 「机の上では動いていたのに、基板にしたら不安定になった」 「同じプログラムなのに、ときどき受信データが化け ...</p>
The post <a href="https://dlrow-design.net/esp32%e3%81%aespi%e9%80%9a%e4%bf%a1%e3%81%8c%e4%b8%8d%e5%ae%89%e5%ae%9a%e3%81%ab%e3%81%aa%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%82%af%e3%83%ad%e3%83%83%e3%82%af%e3%83%bb%e9%85%8d%e7%b7%9a%e3%83%bb/">ESP32のSPI通信が不安定になる原因｜クロック・配線・信号品質の対策</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">ESP32でSPI通信を実装して、</p>



<p class="wp-block-paragraph">「低速なら動くのに、クロックを上げると通信エラーになる」</p>



<p class="wp-block-paragraph">「机の上では動いていたのに、基板にしたら不安定になった」</p>



<p class="wp-block-paragraph">「同じプログラムなのに、ときどき受信データが化ける」</p>



<p class="wp-block-paragraph">といった現象に遭遇することがあります。</p>



<p class="wp-block-paragraph">SPI通信が一応動いているため、プログラムの問題なのか、配線なのか、クロックなのか判断しにくいトラブルです。</p>



<p class="wp-block-paragraph">特にSPIは通信速度を上げるほど、単純な「HIGHとLOW」だけでは説明できない<strong>信号品質</strong>の影響が大きくなります。</p>



<p class="wp-block-paragraph">今回はESP32-C5とESP-IDFを例に、</p>



<p class="wp-block-paragraph"><strong>SPI通信が不安定になるとき、どこから確認すればよいのか</strong></p>



<p class="wp-block-paragraph">を実際の切り分け方法と合わせて解説します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SPIクロックを下げて確認する</h2>



<p class="wp-block-paragraph">SPI通信が不安定な場合、最初に試したいのが<strong>クロック周波数を下げること</strong>です。</p>



<p class="wp-block-paragraph">例えば現在20MHzで通信しているのであれば、</p>



<pre class="wp-block-code"><code>20MHz
 ↓
10MHz
 ↓
5MHz
 ↓
1MHz</code></pre>



<p class="wp-block-paragraph">のように下げて確認します。</p>



<p class="wp-block-paragraph">ここで1MHzなら安定して通信できるのであれば、</p>



<ul class="wp-block-list">
<li>SPI Modeが完全に間違っている</li>



<li>MOSI/MISOを逆接続している</li>



<li>CSがまったく動いていない</li>
</ul>



<p class="wp-block-paragraph">といった根本的な問題である可能性は低くなります。</p>



<p class="wp-block-paragraph">一方、1MHzなら安定するが20MHzではエラーになる</p>



<p class="wp-block-paragraph">のであれば、クロック速度によって顕在化する問題を疑えます。</p>



<p class="wp-block-paragraph">このように、<strong>条件を一つずつ変えて原因候補を減らしていく</strong>ことが重要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">今回使用するサンプルコード</h2>



<p class="wp-block-paragraph">今回はSPI Deviceへ8byteを送信し、同時に8byteを受信する簡単なテストコードを使用します。</p>



<p class="wp-block-paragraph">実際のセンサーなどに依存しないよう、SPI通信部分そのものを確認する構成です。</p>



<p class="wp-block-paragraph">※実際に受信値を検証する場合は、接続するSPI Deviceの仕様に合わせて送信コマンドを変更してください。</p>



<pre class="wp-block-code"><code>#include &lt;stdio.h>
#include &lt;string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "driver/spi_master.h"

#include "esp_err.h"
#include "esp_log.h"

#define SPI_HOST        SPI2_HOST

#define PIN_NUM_MOSI    GPIO_NUM_4
#define PIN_NUM_MISO    GPIO_NUM_5
#define PIN_NUM_CLK     GPIO_NUM_6
#define PIN_NUM_CS      GPIO_NUM_7

#define SPI_CLOCK_HZ    (1 * 1000 * 1000)

static const char *TAG = "SPI_TEST";

static spi_device_handle_t spi_handle;

static void spi_test_transfer(void)
{
    uint8_t tx_data&#91;8] = {
        0x10, 0x20, 0x30, 0x40,
        0x50, 0x60, 0x70, 0x80
    };

    uint8_t rx_data&#91;8] = {0};

    spi_transaction_t transaction = {
        .length = sizeof(tx_data) * 8,
        .tx_buffer = tx_data,
        .rx_buffer = rx_data,
    };

    esp_err_t ret = spi_device_transmit(
        spi_handle,
        &amp;transaction);

    if (ret != ESP_OK)
    {
        ESP_LOGE(
            TAG,
            "SPI transmit failed: %s",
            esp_err_to_name(ret));

        return;
    }

    ESP_LOGI(
        TAG,
        "RX: %02X %02X %02X %02X %02X %02X %02X %02X",
        rx_data&#91;0],
        rx_data&#91;1],
        rx_data&#91;2],
        rx_data&#91;3],
        rx_data&#91;4],
        rx_data&#91;5],
        rx_data&#91;6],
        rx_data&#91;7]);
}

void app_main(void)
{
    spi_bus_config_t bus_config = {
        .mosi_io_num = PIN_NUM_MOSI,
        .miso_io_num = PIN_NUM_MISO,
        .sclk_io_num = PIN_NUM_CLK,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
    };

    ESP_ERROR_CHECK(
        spi_bus_initialize(
            SPI_HOST,
            &amp;bus_config,
            SPI_DMA_CH_AUTO));

    spi_device_interface_config_t device_config = {
        .clock_speed_hz = SPI_CLOCK_HZ,
        .mode = 0,
        .spics_io_num = PIN_NUM_CS,
        .queue_size = 1,
    };

    ESP_ERROR_CHECK(
        spi_bus_add_device(
            SPI_HOST,
            &amp;device_config,
            &amp;spi_handle));

    ESP_LOGI(
        TAG,
        "SPI initialized: %d Hz",
        SPI_CLOCK_HZ);

    while (1)
    {
        spi_test_transfer();

        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}</code></pre>



<p class="wp-block-paragraph">このコードではSPIクロックを、</p>



<pre class="wp-block-code"><code>#define SPI_CLOCK_HZ    (1 * 1000 * 1000)</code></pre>



<p class="wp-block-paragraph">としているため、<strong>1MHz</strong>で通信します。</p>



<p class="wp-block-paragraph">まずこの状態で安定して通信できることを確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">クロック周波数を変更する</h2>



<p class="wp-block-paragraph">先ほどのサンプルコードでは、SPIクロックをマクロで定義しています。</p>



<pre class="wp-block-code"><code>#define SPI_CLOCK_HZ    (1 * 1000 * 1000)</code></pre>



<p class="wp-block-paragraph">そしてDevice登録時に、その値を使用しています。</p>



<h2 class="wp-block-heading">抜粋コード</h2>



<p class="wp-block-paragraph">spi_device_interface_config_t device_config = {<br>.clock_speed_hz = SPI_CLOCK_HZ,<br>.mode = 0,<br>.spics_io_num = PIN_NUM_CS,<br>.queue_size = 1,<br>};</p>



<p class="wp-block-paragraph">例えば5MHzで確認する場合は、</p>



<pre class="wp-block-code"><code>#define SPI_CLOCK_HZ    (5 * 1000 * 1000)</code></pre>



<p class="wp-block-paragraph">へ変更します。</p>



<p class="wp-block-paragraph">ただし、この5MHzのコードは上記サンプルコードそのものではなく<strong>変更例</strong>です。</p>



<p class="wp-block-paragraph">サンプルコードとして掲載している完成版では、最初の動作確認を目的として1MHzにしています。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">「最大クロック」と「安定して使えるクロック」は別</h2>



<p class="wp-block-paragraph">SPI Deviceのデータシートを見ると、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Maximum SCLK Frequency：20MHz</p>
</blockquote>



<p class="wp-block-paragraph">などと記載されていることがあります。</p>



<p class="wp-block-paragraph">ここで注意したいのは、</p>



<p class="wp-block-paragraph"><strong>20MHzまで対応していることと、現在の基板・配線条件で20MHzが安定することは同じではない</strong></p>



<p class="wp-block-paragraph">ということです。</p>



<p class="wp-block-paragraph">通信品質には、</p>



<ul class="wp-block-list">
<li>ESP32側の信号</li>



<li>Device側の入力特性</li>



<li>PCBパターン</li>



<li>ジャンパ線</li>



<li>コネクタ</li>



<li>配線長</li>



<li>負荷容量</li>



<li>GND</li>



<li>電源品質</li>
</ul>



<p class="wp-block-paragraph">なども関係します。</p>



<p class="wp-block-paragraph">そのため開発初期では、まず低速で通信を成立させ、その後クロックを上げていく方が原因を切り分けやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SPI Modeを確認する</h2>



<p class="wp-block-paragraph">クロックを十分下げても通信内容がおかしい場合は、SPI Modeも確認します。</p>



<p class="wp-block-paragraph">今回のサンプルコードでは、</p>



<pre class="wp-block-code"><code>spi_device_interface_config_t device_config = {
    .clock_speed_hz = SPI_CLOCK_HZ,
    .mode = 0,
    .spics_io_num = PIN_NUM_CS,
    .queue_size = 1,
};</code></pre>



<p class="wp-block-paragraph">としているため、SPI Mode 0です。</p>



<p class="wp-block-paragraph">接続するDeviceがMode 3を要求しているのであれば、この設定では正常に通信できません。</p>



<p class="wp-block-paragraph">SPI Modeは、</p>



<ul class="wp-block-list">
<li>CPOL</li>



<li>CPHA</li>
</ul>



<p class="wp-block-paragraph">によって決まり、Deviceのデータシートに指定されています。</p>



<p class="wp-block-paragraph">通信速度を下げても改善しない場合には、<strong>クロック周波数だけを疑い続けず、Mode設定も再確認</strong>します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">エラーと「データ化け」は分けて考える</h2>



<p class="wp-block-paragraph">SPI通信のトラブルでは、</p>



<p class="wp-block-paragraph"><strong>ESP-IDFがエラーを返す場合</strong></p>



<p class="wp-block-paragraph">と、</p>



<p class="wp-block-paragraph"><strong>APIとしては成功しているのに受信値がおかしい場合</strong></p>



<p class="wp-block-paragraph">を分けて考える必要があります。</p>



<p class="wp-block-paragraph">今回のサンプルコードでは、</p>



<pre class="wp-block-code"><code>esp_err_t ret = spi_device_transmit(
    spi_handle,
    &amp;transaction);

if (ret != ESP_OK)
{
    ESP_LOGE(
        TAG,
        "SPI transmit failed: %s",
        esp_err_to_name(ret));

    return;
}</code></pre>



<p class="wp-block-paragraph">として、<code>spi_device_transmit()</code>の戻り値を確認しています。</p>



<p class="wp-block-paragraph">ここで<code>ESP_OK</code>が返ったからといって、</p>



<p class="wp-block-paragraph"><strong>接続先Deviceから正しいデータが返ってきたことまで保証されるわけではありません。</strong></p>



<p class="wp-block-paragraph">SPI Master Driverから見ればトランザクション処理が正常に完了していても、</p>



<ul class="wp-block-list">
<li>Deviceがコマンドを正しく認識していない</li>



<li>SPI Modeが違う</li>



<li>信号品質が悪い</li>



<li>読み出すレジスタを間違えている</li>
</ul>



<p class="wp-block-paragraph">などによって受信値がおかしくなることがあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">受信値をログで確認する</h2>



<p class="wp-block-paragraph">そこで今回のサンプルでは、受信した8byteをログへ出しています。</p>



<pre class="wp-block-code"><code>ESP_LOGI(
    TAG,
    "RX: %02X %02X %02X %02X %02X %02X %02X %02X",
    rx_data&#91;0],
    rx_data&#91;1],
    rx_data&#91;2],
    rx_data&#91;3],
    rx_data&#91;4],
    rx_data&#91;5],
    rx_data&#91;6],
    rx_data&#91;7]);</code></pre>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>1MHz  → 毎回同じ正常値
5MHz  → 毎回同じ正常値
10MHz → ときどき異常値
20MHz → 頻繁に異常値</code></pre>



<p class="wp-block-paragraph">という結果になった場合、</p>



<p class="wp-block-paragraph">通信速度と異常発生に相関があることが分かります。</p>



<p class="wp-block-paragraph">この情報が得られれば、ソフトウェアのロジックだけでなく、<strong>信号品質やタイミングを確認する段階</strong>へ進めます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ジャンパ線では動作条件が変わる</h2>



<p class="wp-block-paragraph">ブレッドボードやジャンパ線でSPI通信を確認する場合は、特に高速通信へ注意が必要です。</p>



<p class="wp-block-paragraph">SPIクロックを高速化すると、ジャンパ線も単なる「導線」としてだけでは扱えなくなってきます。</p>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>ESP32
 │
 │ 長いジャンパ線
 │
 ├──────── SCLK
 ├──────── MOSI
 ├──────── MISO
 └──────── CS
                    │
                 SPI Device</code></pre>



<p class="wp-block-paragraph">のような構成では、配線長やGNDの取り方によって波形が悪化することがあります。</p>



<p class="wp-block-paragraph">低速では問題が見えなくても、高速化したときに初めて問題が現れるケースがあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">確認したい切り分け順序</h2>



<p class="wp-block-paragraph">SPI通信が不安定なとき、私は次のように原因候補を減らしていくのが良いと考えています。</p>



<pre class="wp-block-code"><code>① SPIクロックを下げる
        ↓
② SPI Modeを確認
        ↓
③ CS動作を確認
        ↓
④ MOSI / MISO / SCLKを確認
        ↓
⑤ GND・電源を確認
        ↓
⑥ オシロスコープで波形確認
        ↓
⑦ 信号品質対策を検討</code></pre>



<p class="wp-block-paragraph">重要なのは、最初からすべてを変更しないことです。</p>



<p class="wp-block-paragraph">クロック、Mode、配線、抵抗値を同時に変更してしまうと、</p>



<p class="wp-block-paragraph"><strong>何を変更したことで改善したのか分からなくなります。</strong></p>



<p class="wp-block-paragraph">一つ変更して、一つ結果を見る。</p>



<p class="wp-block-paragraph">これはSPIに限らず、組み込み開発のデバッグ全般で有効な考え方です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SCLK波形を確認する</h2>



<p class="wp-block-paragraph">SPI通信が低速では安定しているのに、高速化すると不安定になる場合は、まずSCLK波形を確認したいところです。</p>



<p class="wp-block-paragraph">デジタル信号は、論理的にはHIGHとLOWの2値ですが、実際の配線上では立ち上がり時間、立ち下がり時間、オーバーシュート、リンギングなどの影響を受けます。</p>



<p class="wp-block-paragraph">特にSCLKは一定周期で繰り返し変化するため、信号品質の問題が顕在化しやすい信号です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">立ち上がり・立ち下がりが遅い場合</h2>



<p class="wp-block-paragraph">SCLKのエッジが鈍っていると、Device側でしきい値を跨ぐタイミングが曖昧になります。</p>



<pre class="wp-block-code"><code>理想波形

┌─────┐      ┌─────┐
│          │      │          │
│          │      │          │
┘          └───┘          └─────


立ち上がりが遅い波形

   ／─────
 ／
┘</code></pre>



<p class="wp-block-paragraph">のような違いです。</p>



<p class="wp-block-paragraph">クロック周波数が低いと多少エッジが遅くても余裕がありますが、高速化するとセットアップ時間やホールド時間に対する余裕が減ります。</p>



<p class="wp-block-paragraph">その結果、同じ回路でも1MHzでは正常、20MHzでは不安定という現象が起こります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">オーバーシュートとリンギング</h2>



<p class="wp-block-paragraph">高速なデジタル信号では、配線長やドライバの立ち上がり速度によって、波形が一度大きく振れてから振動することがあります。</p>



<p class="wp-block-paragraph">これがオーバーシュートやリンギングです。</p>



<pre class="wp-block-code"><code>理想

──────┐
            │
            └──────

リンギングあり

─────╮╲╱╲╱────────</code></pre>



<p class="wp-block-paragraph">この振動が入力しきい値を何度も跨ぐと、Device側が余分なクロックエッジとして認識する可能性があります。</p>



<p class="wp-block-paragraph">特にSCLKで発生すると、1bit余計に読み込む、ビット位置がずれる、といった問題につながることがあります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">シリーズ抵抗を検討する</h2>



<p class="wp-block-paragraph">リンギングが確認された場合、SCLKやMOSIへシリーズ抵抗を追加すると改善することがあります。</p>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>ESP32 GPIO ──&#91;22Ω〜47Ω]── SCLK ── SPI Device</code></pre>



<p class="wp-block-paragraph">のように、信号源の近くへ抵抗を配置します。</p>



<p class="wp-block-paragraph">シリーズ抵抗は信号の立ち上がりを少し緩やかにし、反射やリンギングを抑える目的で使用します。</p>



<p class="wp-block-paragraph">ただし、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">とりあえず抵抗を入れればよい</p>
</blockquote>



<p class="wp-block-paragraph">というものではありません。</p>



<p class="wp-block-paragraph">抵抗値が大きすぎると立ち上がり・立ち下がりが遅くなり、高速通信では逆にタイミング余裕を減らす可能性があります。</p>



<p class="wp-block-paragraph">そのため実際には、オシロスコープで波形を確認しながら調整するのが理想です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">SCLKだけでなくMOSIも確認する</h2>



<p class="wp-block-paragraph">クロックだけ正常でも、MOSI側のデータ波形が崩れていれば通信は不安定になります。</p>



<p class="wp-block-paragraph">確認したいのは、</p>



<ul class="wp-block-list">
<li>SCLK</li>



<li>MOSI</li>



<li>MISO</li>



<li>CS</li>
</ul>



<p class="wp-block-paragraph">の4信号です。</p>



<p class="wp-block-paragraph">特に、SCLKとMOSIを同時に観測すると、</p>



<p class="wp-block-paragraph"><strong>データがクロックエッジに対して十分早く確定しているか</strong></p>



<p class="wp-block-paragraph">を確認しやすくなります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">CSのタイミングを確認する</h2>



<p class="wp-block-paragraph">通信開始直前や終了直後のCSタイミングも重要です。</p>



<p class="wp-block-paragraph">今回のサンプルコードでは、Device登録時にCSをESP-IDFへ任せています。</p>



<pre class="wp-block-code"><code>spi_device_interface_config_t device_config = {
    .clock_speed_hz = SPI_CLOCK_HZ,
    .mode = 0,
    .spics_io_num = PIN_NUM_CS,
    .queue_size = 1,
};</code></pre>



<p class="wp-block-paragraph">この場合、<code>spi_device_transmit()</code>に合わせてSPI Master DriverがCSを制御します。</p>



<pre class="wp-block-code"><code>esp_err_t ret = spi_device_transmit(
    spi_handle,
    &amp;transaction);</code></pre>



<p class="wp-block-paragraph">それでも接続するDeviceによっては、</p>



<ul class="wp-block-list">
<li>CSを下げてから最初のクロックまでの待ち時間</li>



<li>最後のクロックからCSを上げるまでの待ち時間</li>



<li>トランザクション間の待ち時間</li>
</ul>



<p class="wp-block-paragraph">などに条件がある場合があります。</p>



<p class="wp-block-paragraph">そのため、DeviceのデータシートにあるCS timingも確認します。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">GNDリターンパスを確認する</h2>



<p class="wp-block-paragraph">SPI信号はGPIOからDeviceへ流れて終わりではありません。</p>



<p class="wp-block-paragraph">電流はGND側を通って戻ります。</p>



<p class="wp-block-paragraph">つまり、信号線だけでなく<strong>リターンパス</strong>も重要です。</p>



<p class="wp-block-paragraph">例えばPCB上でSCLKの直下に連続したGNDプレーンがあれば、比較的きれいなリターンパスを確保できます。</p>



<p class="wp-block-paragraph">一方、</p>



<ul class="wp-block-list">
<li>GNDプレーンが途中で分断されている</li>



<li>スリットを跨いでいる</li>



<li>コネクタ経由で遠回りしている</li>
</ul>



<p class="wp-block-paragraph">といった状態では、信号品質が悪化する可能性があります。</p>



<p class="wp-block-paragraph">高速SPIでは、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">信号線だけを見るのではなく、戻り電流がどこを流れるか</p>
</blockquote>



<p class="wp-block-paragraph">まで考える必要があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">配線の分岐を短くする</h2>



<p class="wp-block-paragraph">複数DeviceへSPIを分岐する場合、前回の記事で紹介したようにSCLK・MOSI・MISOを共有できます。</p>



<p class="wp-block-paragraph">ただし、ハードウェア的には分岐が増えるほど信号品質は厳しくなります。</p>



<p class="wp-block-paragraph">例えば、</p>



<pre class="wp-block-code"><code>ESP32
  │
  ├──────────── Device A
  │
  └──────────── Device B</code></pre>



<p class="wp-block-paragraph">よりも、</p>



<pre class="wp-block-code"><code>ESP32 ──────────┬── Device A
                          └── Device B</code></pre>



<p class="wp-block-paragraph">のように、長いスタブができる構成では反射の影響が出やすくなります。</p>



<p class="wp-block-paragraph">特にSCLKは、不要に長い分岐を避けた方が安全です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ブレッドボードと製品基板は同じではない</h2>



<p class="wp-block-paragraph">開発初期にブレッドボードやジャンパ線で動作確認できたとしても、製品基板で必ず同じ結果になるとは限りません。</p>



<p class="wp-block-paragraph">逆に、ブレッドボードでは10MHzが不安定でも、PCBでは問題なく20MHzで動作することもあります。</p>



<p class="wp-block-paragraph">これは、</p>



<ul class="wp-block-list">
<li>配線長</li>



<li>配線インピーダンス</li>



<li>GND</li>



<li>コネクタ</li>



<li>Device配置</li>
</ul>



<p class="wp-block-paragraph">などの条件が異なるためです。</p>



<p class="wp-block-paragraph">そのため、</p>



<p class="wp-block-paragraph"><strong>試作環境で確認できた最大クロック = 製品での最終クロック</strong></p>



<p class="wp-block-paragraph">とは考えない方がよいです。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">ロジックアナライザとオシロスコープの使い分け</h2>



<p class="wp-block-paragraph">SPIデバッグでは、ロジックアナライザとオシロスコープの両方が役立ちます。</p>



<h3 class="wp-block-heading">ロジックアナライザ</h3>



<p class="wp-block-paragraph">向いている確認項目は、</p>



<ul class="wp-block-list">
<li>MOSIデータ</li>



<li>MISOデータ</li>



<li>CS</li>



<li>SPI Mode</li>



<li>コマンド内容</li>



<li>通信順序</li>
</ul>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">プロトコルデコーダを使えば、送受信データをHEX表示できるため非常に便利です。</p>



<h3 class="wp-block-heading">オシロスコープ</h3>



<p class="wp-block-paragraph">向いているのは、</p>



<ul class="wp-block-list">
<li>立ち上がり時間</li>



<li>立ち下がり時間</li>



<li>オーバーシュート</li>



<li>リンギング</li>



<li>ノイズ</li>



<li>電圧レベル</li>



<li>クロックとデータのタイミング関係</li>
</ul>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">通信内容を見る → ロジックアナライザ<br>波形品質を見る → オシロスコープ</p>
</blockquote>



<p class="wp-block-paragraph">という使い分けが基本です。</p>



<h2 class="wp-block-heading">「ロジアナで正常」は信号品質が正常とは限らない</h2>



<p class="wp-block-paragraph">ここは注意したいポイントです。</p>



<p class="wp-block-paragraph">ロジックアナライザは入力信号をHIGH / LOWとして判定します。</p>



<p class="wp-block-paragraph">そのため、多少波形が崩れていても、しきい値を正しく跨いでいれば正常に見えることがあります。</p>



<p class="wp-block-paragraph">一方、実際のSPI Deviceでは入力条件が異なり、同じ波形でも誤動作する可能性があります。</p>



<p class="wp-block-paragraph">つまり、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">ロジックアナライザで正しくデコードできた</p>
</blockquote>



<p class="wp-block-paragraph">だけで、信号品質まで保証されたわけではありません。</p>



<p class="wp-block-paragraph">不安定現象がある場合は、オシロスコープでも確認する価値があります。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">電源品質も確認する</h2>



<p class="wp-block-paragraph">SPI通信が高速化すると、Device側の内部回路も高速に動作します。</p>



<p class="wp-block-paragraph">そのため、電源が不安定な場合は通信エラーとして現れることがあります。</p>



<p class="wp-block-paragraph">確認したいのは、</p>



<ul class="wp-block-list">
<li>3.3V電源</li>



<li>デカップリングコンデンサ</li>



<li>GND</li>



<li>Device直近の電源波形</li>
</ul>



<p class="wp-block-paragraph">です。</p>



<p class="wp-block-paragraph">特にDeviceの近くにデカップリングコンデンサがない場合や、長い配線で電源を供給している場合は注意が必要です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">不安定な通信を切り分ける実践フロー</h2>



<p class="wp-block-paragraph">今回の記事の内容を実際の切り分け順にまとめると、次のようになります。</p>



<pre class="wp-block-code"><code>       SPI通信が不安定
               ↓
       クロックを下げる
               ↓
           安定する？
 ┌──────┴──────┐
YES               NO
 ↓               ↓
信号品質を疑う   Mode・配線・CS確認
 ↓
SCLK/MOSI観測
 ↓
リンギング確認
 ↓
配線・GND確認
 ↓
必要ならシリーズ抵抗
 ↓
徐々にクロックUP</code></pre>



<p class="wp-block-paragraph">この順番なら、無闇に条件を変更せずに原因を絞り込めます。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">実務で大切なのは「最大速度」ではない</h2>



<p class="wp-block-paragraph">SPI通信では高速化に目が向きがちですが、製品設計では必ずしも最大クロックで使う必要はありません。</p>



<p class="wp-block-paragraph">例えば20MHzまで対応しているDeviceでも、5MHzで必要な処理が十分間に合うなら、あえて5MHzで使う判断もあります。</p>



<p class="wp-block-paragraph">通信速度を上げれば、</p>



<ul class="wp-block-list">
<li>信号品質</li>



<li>EMI</li>



<li>クロストーク</li>



<li>タイミング余裕</li>
</ul>



<p class="wp-block-paragraph">は厳しくなります。</p>



<p class="wp-block-paragraph">必要な性能を満たしているなら、</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>余裕を持った通信速度を選ぶ</strong></p>
</blockquote>



<p class="wp-block-paragraph">ことも立派な設計判断です。</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">ESP32のSPI通信が不安定な場合、プログラムだけを疑うのではなく、クロック・配線・GND・信号品質まで含めて確認する必要があります。</p>



<p class="wp-block-paragraph">特に、</p>



<ul class="wp-block-list">
<li>低速では安定する</li>



<li>高速化するとエラーが増える</li>
</ul>



<p class="wp-block-paragraph">という現象は、重要な手掛かりです。</p>



<p class="wp-block-paragraph">まずクロックを下げ、</p>



<p class="wp-block-paragraph">次にSPI ModeやCSを確認し、</p>



<p class="wp-block-paragraph">それでも高速化時だけ問題が出るのであれば、オシロスコープで信号品質を確認します。</p>



<p class="wp-block-paragraph">必要に応じて、</p>



<ul class="wp-block-list">
<li>配線の短縮</li>



<li>GNDリターンパス改善</li>



<li>シリーズ抵抗</li>



<li>クロック周波数の見直し</li>
</ul>



<p class="wp-block-paragraph">などを検討します。</p>



<p class="wp-block-paragraph">SPI通信では、</p>



<p class="wp-block-paragraph"><strong>「最大何MHzまで出せるか」より、「必要な性能を安定して満たせるか」</strong></p>



<p class="wp-block-paragraph">の方が重要です。</p>



<p class="wp-block-paragraph">安定した条件を一つずつ確認しながら、必要な性能へ近づけていく。</p>



<p class="wp-block-paragraph">この進め方が、結果的に最短のデバッグになることがあります。</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><strong>技術は、経験から価値になる。</strong></p>



<p class="wp-block-paragraph"><strong>DLROW Design｜現場エンジニア</strong></p>



<p class="wp-block-paragraph"></p>The post <a href="https://dlrow-design.net/esp32%e3%81%aespi%e9%80%9a%e4%bf%a1%e3%81%8c%e4%b8%8d%e5%ae%89%e5%ae%9a%e3%81%ab%e3%81%aa%e3%82%8b%e5%8e%9f%e5%9b%a0%ef%bd%9c%e3%82%af%e3%83%ad%e3%83%83%e3%82%af%e3%83%bb%e9%85%8d%e7%b7%9a%e3%83%bb/">ESP32のSPI通信が不安定になる原因｜クロック・配線・信号品質の対策</a> first appeared on <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a>.<p>Copyright &copy; 2026 <a href="https://dlrow-design.net">江藤良樹の仕事は物づくり</a> All Rights Reserved.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
