ESP-IDFでESP32の開発をはじめよう!
この記事では、ESP-IDFを使ってESP32を開発する方法を解説します。
ESP-IDFとは、ESP32の製造会社であるEspressif Systems社がリリースしている、ESP32向けの開発フレームワークです。 ESP-IDFでは、C/C++のプログラミング言語を使って、より高度でネイティブなESP32のアプリケーション開発を行うことができます。
本記事が、みなさんのESP32開発の第2のステップアップになれば幸いです。
なお、この記事で解説する内容は、すべてmacOS上で操作したものになります。WindowsやLinuxをお使いの場合は、こちらの公式ページをご参照ください。 Get Started - ESP32 - — ESP-IDF Programming Guide v4.3.1 documentation
はじめてのESP-IDF
ESP-IDFは、ESP32やESP32-S、ESP32-CシリーズといったSoCに対応してます。 ここでは一般的なESP32-DevKitCのボードを想定に進めていきます。
▲ ESP32はこちらの製品を使いました。商品タイトルが「ESP-32S NodeMCU」ですが、実際はESP32 DevKit V1です。この記事で説明する手順で、問題なくESP-IDFからプログラムを書き込むことができました。
CMakeのインストール
ESP-IDFはESP32アプリケーションをCMakeを使ってビルドするため、あらかじめbrewでCMakeをインストールします。
$ brew install cmake
ESP-IDFのインストール
現在最新バージョンのESP-IDF v4.1.2をGitで入手します。ホームディレクトリへ移動してespディレクトリを作り、その中でesp-idfをcloneしました。
$ mkdir esp
$ cd ~/esp
$ git clone https://github.com/espressif/esp-idf.git
ESP-IDFのツールのセットアップ
cloneして作成されたesp-idfディレクトリにinstall.shというシェルスクリプトがあります。スクリプトを実行してツールのセットアップを行います。
$ cd ~/esp/esp-idf
$ ./install.sh
しばらくすると次のようにしてセットアップが完了しました。
Installing collected packages: six, MarkupSafe, Werkzeug, urllib3, python-engineio, Jinja2, itsdangerous, idna, click, charset-normalizer, certifi, requests, python-socketio, pycparser, greenlet, Flask, contextlib2, brotli, tqdm, semantic-version, schema, requests-toolbelt, pyyaml, Pygments, pygdbmi, gevent, future, Flask-SocketIO, Flask-Compress, cffi, reedsolo, pyserial, pyparsing, pyelftools, kconfiglib, idf-component-manager, gdbgui, ecdsa, cryptography, construct, bitstring
Successfully installed Flask-0.12.5 Flask-Compress-1.10.1 Flask-SocketIO-2.9.6 Jinja2-3.0.1 MarkupSafe-2.0.1 Pygments-2.10.0 Werkzeug-0.16.1 bitstring-3.1.9 brotli-1.0.9 certifi-2021.5.30 cffi-1.14.6 charset-normalizer-2.0.4 click-8.0.1 construct-2.10.54 contextlib2-21.6.0 cryptography-3.4.8 ecdsa-0.17.0 future-0.18.2 gdbgui-0.13.2.0 gevent-1.5.0 greenlet-1.1.1 idf-component-manager-0.2.100b0 idna-3.2 itsdangerous-2.0.1 kconfiglib-13.7.1 pycparser-2.20 pyelftools-0.27 pygdbmi-0.9.0.2 pyparsing-2.3.1 pyserial-3.5 python-engineio-3.14.2 python-socketio-4.6.1 pyyaml-5.4.1 reedsolo-1.5.4 requests-2.26.0 requests-toolbelt-0.9.1 schema-0.7.4 semantic-version-2.8.5 six-1.16.0 tqdm-4.62.2 urllib3-1.26.6
All done! You can now run:
. ./export.sh
環境変数PATHの設定
次にインストールしたツール群を、環境変数PATHに追加する必要があります。ESP-IDFに付属のスクリプトを使って設定します。先ほどのインストール完了メッセージの最後の文章の通り、次のシェルを実行します。
$ . ./export.sh
Setting IDF_PATH to '/Users/xxxxx/esp/esp-idf'
Detecting the Python interpreter
Checking "python" ...
Checking "python3" ...
Python 3.9.4
"python3" has been detected
Adding ESP-IDF tools to PATH...
Using Python interpreter in /Users/xxxxx/.espressif/python_env/idf4.4_py3.9_env/bin/python
Checking if Python packages are up to date...
Python requirements from /Users/xxxxx/esp/esp-idf/requirements.txt are satisfied.
Updated PATH variable:
...
Done! You can now compile ESP-IDF projects.
Go to the project directory and run:
idf.py build
以上で環境変数PATHの設定が完了しました。また、ESP-IDFもインストール完了です。 さて、~/esp/esp-idf/examples/ディレクトリにいくつかサンプルプロジェクトが入ってます。ここからは、サンプルプロジェクト使って、実際にESP32へプログラムを書き込んでみます。
ESP-IDFのサンプルプロジェクト
ここでは、サンプルプロジェクト~/esp/esp-idf/examples/get-started/の中にあるhello_worldプロジェクトを使用します。あらかじめ、hello_worldプロジェクトを作業しやすい場所へコピーします。
$ cd ~/esp
$ cp -r $IDF_PATH/examples/get-started/hello_world .
これで、~/espディレクトリにhello_worldプロジェクトを配置できました。
ちなみに、hello_worldプロジェクト内のmain/hello_world_main.cに次のようなプログラム内容が書かれているので確認しておきましょう。使われているチップの情報などを出力し、再起動するプログラムです。このプログラムをビルドしESP32へ書き込んでいきます。
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
void app_main(void)
{
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
printf("silicon revision %d, ", chip_info.revision);
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}
ESP32デバイスの接続
ESP32デバイスをMacに接続して、シリアルポートのパスを確認します。ESP32では/dev/cu.から始まるデバイス名前になるため、次のコマンドでパスを確認します。
$ ls /dev/cu.*
私の環境では、/dev/cu.usbserial-0001がESP32のシリアルポートのパスである事が分かりました。後に、ポートの指定で必要となるのでメモしておきましょう。
プロジェクトの設定
次にプロジェクトの設定を行います。hello_worldプロジェクトへ移動し、ESP32をターゲットとして次のように設定コマンドを実行します。
$ cd ~/esp/hello_world
$ idf.py set-target esp32
設定が完了するまで数分ほどかかりますが、気長に待ちましょう。
プロジェクトのビルド
いよいよプロジェクトをビルドします。それほど時間はかからずビルドできます。
$ idf.py build
ESP32へプロジェクトを書き込む
最後に、-pオプションにポート番号を指定し、flashを実行してプロジェクトをESP32へ書き込みます。
$ idf.py -p /dev/cu.usbserial-0001 flash
ESP-IDFのシリアルモニター
ESP32へプロジェクトが書き込まれると、main/hello_world_main.cにかかれていた内容のプログラムが実行されます。ESP32の標準出力を確認するため、次のモニターコマンドを実行します。
$ idf.py -p /dev/cu.usbserial-0001 monitor
すると、次のようなESP32の標準出力結果を得ることができました。
Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision 1, 2MB external flash
Minimum free heap size: 294448 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
モニターを終了するためにはCtrl+]を押してください。
さいごに
ここまでで、とくに大きなトラブルはなく、はじめてESP-IDFでESP32にプログラムを書き込むことができました。プログラム内容を書き換えた場合は、プロジェクトのビルドからやり直せば大丈夫なようです。 ESP-IDFにはまだまだ機能がありますので、詳しくは公式ガイドをご覧ください。 Get Started - ESP32 - — ESP-IDF Programming Guide v4.3.1 documentation