Espressif ESP32-DevKitCでAWS IoT Coreとの通信を行ってみた(Dockerでの開発環境構築)

## はじめに
Espressif ESP32-DevKitCを入手しましたので、開発環境構築及び、Amazon FreeRTOSを利用したAWS IoT CoreサービスとのMQTT通信をおこなってみました。
本記事は、以下の環境にて実施しています。

- ホストOS：Ubuntu18.04(LTS)

更新日：2019.09.24

## Espressif ESP32-DevKitCとは
上海にある、Espressif社が開発した評価ボードです。
AWS Partner Deviceに認定されており、対応するAmazonFreeRTOSを使用して、容易にAWS IoT Coreとの通信が行なえます。
また、比較的安価に手に入り、IoT入門機として最適ではないかと思います。

## 開発環境構築
ESP32用開発環境は、Dockerを利用して構築しています。
まずはじめに、Dockerインストール及びコンテナの起動を行った後、コンテナ環境にて、開発環境の構築を行います。
本手順を実施する前に、ESP32-DevKitCをPCとUSB接続しておいてください。

本手順は、[Espressif ESP32-DevKitC と ESP-WROVER-KIT の開始方法](https://docs.aws.amazon.com/ja_jp/freertos/latest/userguide/getting_started_espressif.html)及び、[ESP32 Setup of toolchain for Linux](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/linux-setup.html)の内容を参考にしていますが、今後変更になる可能性もありますので、うまく行かなかった場合は、上記サイトの内容を確認して、適時読み替えて実施ください。

---
- **Dockerの準備**

1.　Dockerインストール
[公式ページ](https://docs.docker.com/install/linux/docker-ce/ubuntu/)の手順を参考に実施します。

2.　Dockerコンテナの起動

```console:コマンド
$ sudo docker pull ubuntu:latest 
$ sudo docker run -it --name <コンテナ名> --device=/dev/ttyUSB0 ubuntu:latest bash 
```

---
- **ESP32用ツールチェーンの準備**

ここからは、先程起動したDockerコンテナにログインして作業を実施します。
Dockerの準備手順が完了した段階で、コンテナにログインした状態になっています。

1.　事前にパッケージをインストール

```docker:docker内コマンド
root@<コンテナID>:<Dir># apt-get update
root@<コンテナID>:<Dir># apt-get install git wget curl libncurses-dev flex bison gperf python python-pip python-setuptools python-serial python-click python-cryptography python-future python-pyparsing python-pyelftools cmake ninja-build ccache
```

 2.　ESP32 toolchain for Linuxのセットアップ

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd
root@<コンテナID>:<Dir># wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz --no-check-certificate
root@<コンテナID>:<Dir># mkdir -p ~/esp 
root@<コンテナID>:<Dir># cd ~/esp 
root@<コンテナID>:<Dir># tar -xzf ~/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz 
```

　これで、ツールチェーンが「~/esp/xtensa-esp32-elf/」に展開されます。

 3.　ツールチェーンのパスを環境変数に追加
　.bashrcファイルの末尾に、次の1行を追加します。

```shell:.bashrc
 　export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"
```
　追加したら、以下のコマンドを実行します。

```docker:docker内コマンド
root@<コンテナID>:<Dir># source ~/.bashrc
```

---
- **CMakeを更新**

1.　バージョンの確認
以下のコマンドを実行し、CMakeのバージョンを確認します。Amazon FreeRTOS を使用するには、バージョン 3.13 以降が必要です。

```docker:docker内コマンド
root@<コンテナID>:<Dir># cmake -version
cmake version 3.15.3 　⬅バージョンを確認

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

2.　CMakeの更新
バージョンが3.12以前の場合は、最新バージョンに更新します。

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd
root@<コンテナID>:<Dir># wget https://github.com/Kitware/CMake/releases/download/v3.15.3/cmake-3.15.3-Linux-x86_64.tar.gz
root@<コンテナID>:<Dir># tar xvfz cmake-3.15.3-Linux-x86_64.tar.gz 
root@<コンテナID>:<Dir># cd cmake-3.15.3-Linux-x86_64
root@<コンテナID>:<Dir># cp -r bin/* /usr/bin/
root@<コンテナID>:<Dir># cp -r doc/* /usr/share/doc/
root@<コンテナID>:<Dir># cp -r man/* /usr/share/man/
root@<コンテナID>:<Dir># cp -r share/* /usr/share/
```

---
- **Amazon FreeRTOSのダウンロード＆設定**

Amazon FreeRTOSをダウンロードし、ESP32への書き込み・AWS IoTとの通信を行うための準備を行います。

1.　ツールのバージョン確認

Pythonのバージョンが2.7.10以降であるか確認します。

```docker:docker内コマンド
root@<コンテナID>:<Dir># python --version
Python 2.7.15+　⬅バージョンを確認
```

2.　AWS CLIのインストール

```docker:docker内コマンド
root@<コンテナID>:<Dir># pip install awscli
```

3.　AWS SDK for Python (boto3) をインストール

```docker:docker内コマンド
root@<コンテナID>:<Dir># pip install tornado nose --user
root@<コンテナID>:<Dir># pip install boto3 --user
```

4.　Amazon FreeRTOSのダウンロード

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd
root@<コンテナID>:<Dir># git clone https://github.com/aws/amazon-freertos
```

## Amazon FreeRTOSのビルドと実行

上記手順で構築した開発環境を使用して、Amazon FreeRTOSのビルドと、ESP32への書き込みを実施します。この手順を実施することで、Amazon FreeRTOSのデモプロジェクトが自動的に実行され、AWS IoT Coreとの通信が行われます。

---
- **AWSCLI/AmazonFreeRTOS/AWSIoTの設定**

1.　AWS CLIの設定
aws configure を実行し、AWS アクセスキー ID、シークレットアクセスキー、およびデフォルトのリージョン名を使用して AWS CLI を設定します。 
アクセスキー ID、シークレットアクセスキーは、ここでは、AWSIoTサービスにフルアクセスできるIAMユーザーのID及びキーを使用してください。

```docker:docker内コマンド
root@<コンテナID>:<Dir># aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: 
```

2.　Amazon FreeRTOSの設定
~/amazon-freertos/tools/aws_config_quick_start配下にある、configure.jsonファイルの内容を書き換えます。

```json:configure.json
{
    "afr_source_dir":"../..",
    "thing_name":"$thing_name",
    "wifi_ssid":"$wifi_ssid",
    "wifi_password":"$wifi_password",
    "wifi_security":"$wifi_security"
}
```

<dl>
<dt>afr_source_dir</dt>
<dd>コンピュータ上の amazon-freertos ディレクトリへの完全なパスを記載します。ここでは、"/root/amazon-freertos"と記載してください。</dd>
<dt>thing_name</dt>
<dd>ボードを表す AWS IoT モノに割り当てる名前。好きな名前を記載してください。</dd>
<dt>wifi_ssid</dt>
<dd>Wi-Fi ネットワークの SSID。使用するWi-Fiに合わせてください。</dd>
<dt>wifi_password</dt>
<dd>Wi-Fi ネットワークのパスワード。 使用するWi-Fiに合わせてください。</dd>
<dt>wifi_security</dt>
<dd>Wi-Fi ネットワークのセキュリティタイプ。 有効なセキュリティタイプは以下の通り。使用するWi-Fiに合わせてください。</dd>
    <dd>・eWiFiSecurityOpen (オープン、セキュリティなし)</dd>
    <dd>・eWiFiSecurityWEP (WEP セキュリティ)</dd>
    <dd>・eWiFiSecurityWPA (WPA セキュリティ)</dd>
    <dd>・eWiFiSecurityWPA2 (WPA2 セキュリティ)</dd> 
</dl>

3.　AWS IoTの設定
設定スクリプトを実行して、AWS IoTの設定を行います。

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd ~/amazon-freertos/tools/aws_config_quick_start
root@<コンテナID>:<Dir># python SetupAWS.py setup
```

スクリプトでは次のことが実行されます。
　IoT のモノ、証明書およびポリシーを作成します。
　証明書に IoT ポリシーを、AWS IoT のモノに証明書をアタッチします。
　AWS IoT エンドポイント、Wi-Fi SSID、および認証情報を aws_clientcredential.h ファイルに追加します。
　証明書とプライベートキーをフォーマットして aws_clientcredential.h ヘッダーファイルに書き込みます。

---
- **Amazon FreeRTOS デモプロジェクトをビルド、フラッシュ、および実行**

1.　Amazon FreeRTOS のビルド

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd ~/amazon-freertos/
root@<コンテナID>:<Dir># cmake -DVENDOR=espressif -DBOARD=esp32_wrover_kit -DCOMPILER=xtensa-esp32 -S . -B ~/esp/build
root@<コンテナID>:<Dir># cd ~/esp/build/
root@<コンテナID>:<Dir># make all -j4
```

2.　Amazon FreeRTOS のフラッシュおよび実行

```docker:docker内コマンド
root@<コンテナID>:<Dir># cd ~/esp
root@<コンテナID>:<Dir># ~/amazon-freertos/vendors/espressif/esp-idf/tools/idf.py erase_flash -B build
root@<コンテナID>:<Dir># cd ~/esp/build/
root@<コンテナID>:<Dir># make flash
```
ESP32への書き込みが終わると、自動的に再起動して書き込んだプログラムが実行されます。

3.　クラウド上の MQTT メッセージのモニタリング
デバイスが AWS クラウドに送信するメッセージをモニタリングするには、AWS IoT コンソールで MQTT クライアントを使用します。 

AWS IoT MQTT クライアントで MQTT トピックをサブスクライブするには
 1. AWS IoT コンソールにサインインします。
 2. ナビゲーションペインで、[Test (テスト)] を選択して MQTT クライアントを開きます。
 3.[Subscription topic (トピックのサブスクリプション)] で「iotdemo/#」と入力し、[Subscribe to topic (トピックへのサブスクライブ)] を選択します。

![Screenshot from 2019-09-25 00-47-16_small.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307872/426d4f8d-c328-e5e5-217b-24b48d75e349.png)