はじめに
ESP32で、AWS IoTと通信するesp-aws-iotというライブラリがあります。同リポジトリのexamplesに、ESP32ボードからAWS IoTに対してMQTT通信を行うサンプルが用意されています。
サンプルは、ESP-IDFを使うとすぐに試せますが、自分のプロジェクトに組み込む且つ、PlatformIOを使う想定の場合、設定ファイルを修正する必要があり、備忘のため記事にしました。
リポジトリ
手順を省略出来るようにshuntaka9576/esp-aws-iot-subscribe-publish-sampleを用意しています。リポジトリを使う場合は、モノと証明書の作成から手順を進められます。
shuntaka9576/esp-aws-iot-subscribe-publish-sampleを利用する場合、submoduleを再起的に取得するコマンドを実行してください。
$ git clone https://github.com/shuntaka9576/esp-aws-iot-subscribe-publish-sample.git
$ cd esp-aws-iot-subscribe-publish-sample
$ git submodule update --init --recursive
プロジェクトの作成
プロジェクトの初期化
pio init --board=m5stack-core2 --project-option="framework=espidf"
esp-aws-iotライブラリの追加
git submodule add https://github.com/espressif/esp-aws-iot.git components/esp-aws-iot
esp-aws-iotは、aws-iot-device-sdk-embedded-Cをsubmoduleとしている。上記のコマンドだけでは、aws-iot-device-sdk-embedded-Cはクローンされないため、下記のコマンドで再起的にgit submoduleをクローンする
git submodule update --init --recursive
platformio.iniの修正
[env:m5stack-core2]
platform = espressif32
board = m5stack-core2
framework = espidf
+monitor_speed = 115200
+
+board_build.embed_txtfiles =
+ src/certs/aws-root-ca.pem
+ src/certs/certificate.pem.crt
+ src/certs/private.pem.key
examples/subscribe_publishを参考にファイルを移植
# This file was automatically generated for projects
# without default 'CMakeLists.txt' file.
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
set(COMPONENT_SRCS "main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()
if(CONFIG_EXAMPLE_EMBEDDED_CERTS)
target_add_binary_data(${COMPONENT_TARGET} "certs/aws-root-ca.pem" TEXT)
target_add_binary_data(${COMPONENT_TARGET} "certs/certificate.pem.crt" TEXT)
target_add_binary_data(${COMPONENT_TARGET} "certs/private.pem.key" TEXT)
endif()
src/Kconfig.projbuildは、Kconfig.projbuildの内容をそのまま利用src/component.mkは、component.mkの内容をそのまま利用src/main.cは、subscribe_publish_sample.cの内容をそのまま利用
src/Kconfig.projbuildはコミットされるファイルです。デフォルト値に秘匿したい値は設定しないでください。
pio run -t menuconfig経由で設定し、sdkconfigとして最終的に設定が出力されます。sdkconfigはgitginoreします。
モノと証明書の作成
モノを作成



ポリシーは後ほど作成します


ポリシーを作成します。名前は、esp32-test-policyとします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "*"
}
]
}

作成できたら、証明書にポリシーをアタッチします。


ダウンロードした秘密鍵や証明書を、./src/certs配下にリネームしつつ、配置します。
| 名称 | ファイル名 | リネームして配置する場所 |
|---|---|---|
| デバイス証明書 | xxxx-certificate.pem.crt | ./src/certs/certificate.pem.crt |
| デバイス証明書秘密鍵 | xxxx-private.pem.key | ./src/certs/private.pem.key |
| デバイス証明書公開鍵 | xxxx-public.pem.key | 利用しない |
| AmazonルートCA証明書 | AmazonRootCA1.pem | ./src/certs/aws-root-ca.pem |
最終的にsrc配下は、下記となります。
src
├── CMakeLists.txt
├── Kconfig.projbuild
├── certs
│ ├── aws-root-ca.pem
│ ├── certificate.pem.crt
│ └── private.pem.key
├── component.mk
└── main.c
sdkconfigの生成
コマンドを実行すると、TUIが起動します
pio run -t menuconfig
Example Configureationを選択します。補足ですが、本設定の枠組みはsrc/Kconfig.projbuildに記述されています。

wifiのSSIDを入力後、Enterを押下

wifiのパスワードを入力後、Enterを押下

入力完了したら、ESCを1回押下し、1つ前の選択画面に戻り、Component configを選択します

下の方にAmaozn Web Services IoT Platformがあるので、選択します

急に画面が変わりますが、AWSマネジメントコンソール > AWS IoT > 設定 からエンドポイントをクリップボードに保存します

TUIの画面に戻ります。

先ほどコピーしたエンドポイントを、そのまま貼り付けて、Enterを押下

完了したら、sを押してsdkconfigに保存します

ESCを数回(3回)押して、TUIから抜ければsdkconfigの設定は完了です。本項の設定で、新しく下記のファイルが生成されます。sdkconfigはwifiのパスワードや環境のエンドポイントが入っています。かならずgitignoreするようにしましょう。
- CMakeLists.txt
- sdkconfig
ファームの書き込みと実行
pio run --upload-port /dev/cu.SLAB_USBtoUART -t upload
pio device monitor -p /dev/cu.SLAB_USBtoUART
AWS IoTのMQTTテストクライアントを使ってtest_topic/esp32をサブスクライブしてみると、M5Stack Core2から定期的に電文がpublishされていることが確認できます。

シリアルモニターの出力の␛[0;32mIが気になる場合、--rawオプションをつける解決します
pio device monitor -p /dev/cu.SLAB_USBtoUART --raw
補足
ccls定義の出力
Neovimとcoc.nvimで開発しているため、補完や定義ジャンプをするには、.ccls定義が必要となります。下記の手順で出力することが出来ます。
target_add_binary_data の箇所をコメントアウト
# This file was automatically generated for projects
# without default 'CMakeLists.txt' file.
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
set(COMPONENT_SRCS "main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()
if(CONFIG_EXAMPLE_EMBEDDED_CERTS)
# target_add_binary_data(${COMPONENT_TARGET} "certs/aws-root-ca.pem" TEXT)
# target_add_binary_data(${COMPONENT_TARGET} "certs/certificate.pem.crt" TEXT)
# target_add_binary_data(${COMPONENT_TARGET} "certs/private.pem.key" TEXT)
endif()
下記のコマンドを実行すると.ccls定義が出力されます。
pio init --board=m5stack-core2 --project-option="framework=espidf" --ide vim
最後に
ESP32環境で、比較的ミニマムなコードでMQTT通信を行うサンプルを試しました。esp-aws-iotの魅力は、Using an ATECC608A with the ESP-AWS-IoTにあるように、secure elementをサポートしている点です。Edukitだとソースが膨大すぎて、追うのが大変でした。今回のようにミニマムな実装を繰り返していくことで、secure elemetnサポート周りの理解が進められたらなぁと思います。
今回サンプルのCコードはまだ1ミリも理解していないので、まずはそれが先ですね...