はじめに
IoT の案件をいくつか担当させていただいたことがありますが、開発時にセンサーからデータを取得する際はいつも擬似データを使っていました。
しかし、本当にやりたかったのは、物理的な世界とデータの橋渡しとなる「実機からのデータ収集」を自分の手で体験することでした。
そこで、今回は手軽に始められるESP32を使って、その第一歩として開発環境の構築と定番のLチカに挑戦しました。 最終的には AWS IoT Core へデータを送信することを目標にしています。
前提
Apple シリコン搭載の Mac で動作確認しています。 また、Python 3系が動作する前提で進めます。
必要なもの
今回は以下のボードを使用します。 Freenove ESP32-WROVER CAM
選定理由は公式のリポジトリにサンプルプロジェクトが公開されており、初心者でも手軽に試せる点が決め手となりました。 安価なのに、 Wi-Fi や Bluetooth に加え、カメラモジュールが標準で搭載されています。
また、参考にしたこちらの記事が分かりやすく、 その手順を踏襲することで、本記事を読んだ方もスムーズに学習を進められるよう配慮しました。
開発環境のセットアップ
公式ドキュメントを参考に、進めていきます。
# 必要なソフトのインストール # cmake: ビルド設定ファイルを生成するツール # ninja: cmakeが生成した設定ファイルを使って、高速にプロジェクトをビルドするツール # dfu-util: USB経由でデバイスにファームウェアを書き込むためのツール brew install cmake ninja dfu-util # ESP-IDFインストール cd ~ git clone -b release/v5.0 --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh # 環境にパスを通す(idf.py が使用できるようになります) . $HOME/esp-idf/export.sh
これで、プロジェクトをビルドなどすることができる状態になりました。
Lチカしてみる
ポート番号を調べる
ESP32 をパソコンに接続した状態で以下のコマンドを実行します。
ls /dev/cu.*
そうすると、 /dev/cu.usbserial-1110
のような項目が出てくると思うので、メモしておきます。
プロジェクトでビルドしたプログラムを書き込むために使用します。
サンプルプロジェクトの実行
先ほど Clone したリポジトリの中に Lチカのサンプルプロジェクトが用意されているので、それを利用します。
# サンプルプロジェクトへ移動 cd ~/esp-idf/examples/get-started/blink/ # 設定を行う # Example Configuration->Blink GPIO number を 2 に設定する idf.py menuconfig # プログラムをビルドし、書き込む idf.py -p /dev/cu.usbserial-1110 build flash # 実行の様子を確認する(終了したい場合、 control + `]`) idf.py -p /dev/cu.usbserial-1110 monitor

実行ログが以下のように出ていれば成功です。
I (303) example: Turning the LED OFF! I (1303) example: Turning the LED ON! I (2303) example: Turning the LED OFF! I (3303) example: Turning the LED ON! I (4303) example: Turning the LED OFF! I (5303) example: Turning the LED ON! I (6303) example: Turning the LED OFF!
実機 IO2 の LED がチカチカしているのが確認できました。

プログラムの削除
monitor を終了しても、ESP32のフラッシュメモリにはLチカプログラムが書き込まれたままになるため、電源を再投入すると再びLチカを開始します。]
そのため、次に別のプログラムを書き込んだり、予期せぬ動作を防ぐためにも、書き込んだプログラムを消去しておくことをお勧めします。
erase_flash でフラッシュメモリを消去することができます。
idf.py -p /dev/cu.usbserial-1110 erase_flash
Lチカプログラムの中身確認
最後にサンプルプログラムを見ていきます。
Main 関数(app_main)
ESP32の組み込みプログラムでは、app_main 関数がプログラムの開始点となり、一般的なPCアプリケーションの main 関数に相当します。 この関数が、Lチカのすべての動きを制御しています。
void app_main(void) { /* LED を光らせるピンを確定し、初期設定を行います。(menuconfig で設定した値を参照します。) */ configure_led(); /* 永遠にループさせる。 */ while (1) { /* 現在の LED の状態をログに出力します。これで動作を確認できる。 */ ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF"); /* gpio_set_level を使って、LED の状態を変化させる。 */ blink_led(); /* 次の点滅のために、LED の状態を反転させる。(ON なら OFF に、OFF なら ON に) */ s_led_state = !s_led_state; /* スリープさせる。(menuconfig で点滅間隔を設定することができる。) */ vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS); } }
環境変数の読み込み
ESP-IDFの大きな特徴の一つが、menuconfig を使ってプログラムの挙動を柔軟に設定できる点です。その設定値がどのようにプログラムに反映されるかを見てみましょう。
#define BLINK_GPIO CONFIG_BLINK_GPIO
この一行は、「BLINK_GPIO と書かれた場所はすべて、menuconfig で設定した CONFIG_BLINK_GPIO の値に置き換えなさい」というコンパイル時の指示です。
今回、 GPIO ピンを 2 に設定したため、プログラム上の BLINK_GPIO は 2 として定義されます。 これにより、コードを直接書き換えることなく、対象の LED ピンを切り替えることができます。
詰まった点
バージョンによる差異
開発環境のセットアップの際に、バージョンを4.4で進めていました。ドキュメント
すると、以下のようなエラーが出て、進みませんでした。
Compatibility with CMake < 3.5 has been removed from CMake ModuleNotFoundError: No module named 'click'
5系のドキュメントには、Apple M1 Users の項目があるため、 おそらく、4.4 だと Apple シリコンに対応していないのかと思います。
バージョン 5.0 を使用することで、今回は回避することができました。
モジュールが存在しない
build しようとすると、以下のモジュールが存在しないエラーで実行できませんでした。 esp-aws-iot/libraries/backoffAlgorithm/backoffAlgorithm/backoffAlgorithmFilePaths.cmake
git clone する際に、 recursive
オプションを有効にしていないからのようです。
以下のコマンドで無事成功するようになりました。
git submodule update --init --recursive
idf.py コマンドが見つからない (command not found)
ターミナルを再起動した後に、コマンドが見つからないことがあります。
ターミナルを起動した都度、 . $HOME/esp-idf/export.sh
を実行する必要があります。
.zshrc に登録することも考えましたが、関係ない時も数秒待たされるようになったので、 ESP32 の開発を行うときに、エクスポートコマンドを都度実行しています。
まとめ
今回は、ESP32を動かすためのPC環境構築と、Lチカプログラムの書き込みを行いました。
C 言語の経験はほとんどありませんでしたが、ESP-IDFの公式ドキュメントや豊富なサンプルプログラムのおかげで、スムーズに実行ができました。
開発環境のセットアップがとても大変で、実際に LED が点滅した時は感動しました。
次は、今回の環境を活かして、 AWS IoT Core へデータを送信する 記事を書こうと思います。