AWS IoT ExpressLinkとは
簡単にいうと、クラウド接続ができないようなマイコンと繋げることで、簡単にコネクテッドなデバイスが作れる仕様と、その仕様に対応したデバイスを指す。
詳しくはJAWSUG IoT専門支部のこの動画が参考になります。
マイコンとの接続はUARTを利用し、ATコマンドを使ってExpressLinkモジュールを操作することで、データの送受信などを行ことができるのが特徴となっている。
この記事ではUSB-NORA-W2を使って、クラウド接続を試してみます。
まずは繋げてみる
User Guideに手順が書かれているので、それを参考にセットアップしてみます。
試している環境は、
- MacBook Pro(2023 M2), macOS Sonoma 14.6.1
USB-NORA-W2はUSB端子がついたボードなので、Type-Cの変換アダプタとか使って、そのままMacに繋ぐことができます。ターミナルで確認したら以下のように認識されました。
ls -l /dev/tty.*
crw-rw-rw- 1 root wheel 0x9000000 8 16 10:48 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw- 1 root wheel 0x9000002 9 1 10:43 /dev/tty.usbserial-DP05GXGX
screenコマンドで繋ぎます
screen /dev/tty.usbserial-DP05GXGX 115200
iTermだとlocal echoの設定ができないため、入力したコマンドが確認できませんが、以降の例では入力したコマンドとその結果を示しています。
AT
OK
ExpressLinkを操作する際には基本的に AT+コマンド
のような方法で指定します。利用可能なコマンドはドキュメントで確認することができます。
まず最初にExpressLinkのバージョンを確認したいので、設定情報などを確認することができるコマンドを実行します。
データの読み取りでは AT+CONG? 対象のキー
というフォーマットで入力すると、対象のキーの値を確認することができます。
AT+CONF? Version
OK 1.1.14 - 001
2024/8現在だとExpressLinkの最新バージョンは1.2ですので、少し古いのが入っています。u-bloxのドキュメントでは1.2にバージョンアップ可能とあります。
ExpressLink Evaluation Kits Quick Connect
ExpressLinkは初期状態でモジュールにThing名、証明書などがプロビジョニングされています。証明書などはセキュアエレメントに保存されており、安全に管理されています。
Thing名の確認
AT+CONF? ThingName
OK 長いユニークな文字列
証明書を確認
AT+CONF? Certificate
OK -----BEGIN CERTIFICATE-----\AMIIDRswfQ\A-----END CERTIFICATE-----\A
AWS IoT Coreのエンドポイントを確認
AT+CONF? Endpoint
OK
最初は設定されていないようです。
お試し用にQuick Connectのアプリが用意されているので、これを使って接続を試してみます。ダウンロードしたファイルを展開するとconfig.txt
というファイルがあるので、必要な情報を設定します。
Serial_port:/dev/tty.usbserial-DP05GXGX
SSID:
Passphrase:
ファイルに実行権限をつけて、実行します。screenコマンドを実行したままだったので、途中でBoard not found
となりました。実行する前に停止しておきましょう。
chmod +x Start_Quick_Connect
Macだとセキュリティーのエラーが出るので、Finderでファイルを選んで右クリックから実行しました。
11:42:10 - This program will configure your Expresslink board to connect to the
internet using Wi-Fi, and then to AWS. You will be asked to enter
your Wi-Fi network credentials so that the device can connect. This
information will be written to the device to allow it to connect to
the internet. The information will not be transmitted to the internet
or AWS.
11:42:10 - ---------------------------------------------------------------------
11:42:10 - Provisioning device to connect. This may take several minutes.
11:42:10 - Board not found. Please connect the board to your computer.
11:42:10 - Try again?
1 - [Y/N]: y
11:43:44 - Provisioning device to connect. This may take several minutes.
11:43:45 - Configuring SSID by sending AT+CONF SSID = hogehoge
11:43:46 - Configuring Passphrase by sending AT+CONF Passphrase = fugafuga
11:43:46 - Provisioning complete. Retrieving thing name from the device.
11:43:46 - Fetching ThingName from the device
11:43:46 - Sending serial command: AT+CONF? ThingName to the device
11:43:46 - Device thingName is hogehoge
11:43:46 - ---------------------------------------------------------------------
11:43:46 - Starting AWS Session
11:43:49 - AWS Session Initialized
11:43:56 - Something went wrong while processing the request. Response:
{"message":"Thing doesn't exist"}, Status code: 400
Saving session...completed.
Deleting expired sessions... 4 completed.
このQuick Startはデバイスベンダーが用意したアカウントに接続するのですが、何か問題が起きているみたいです。
接続先の設定を確認すると設定されていたので、問題はなさそうですが、ちょっとわからず。
AT+CONF? Endpoint
OK u-bloxのAWS IoT Core エンドポイントっぽい値
一旦無視して、自分のアカウントに繋いでみます。
Thing,証明書,IoTPolicyの登録
実際の製品に組み込む場合に取れるプロビジョニング方法は複数あります。
https://docs.aws.amazon.com/iot-expresslink/v1.2/programmersguide/elpg-provisioning.html#elpg-provisioning-onboarding
今回は手動で登録します。
必要になるのは、以下の情報です
- Thing名
- 証明書
- IoT Policy
- AWS IoT Coreのエンドポイント名
順に作業していきます。
AWS CLIを使うには権限を持ったクレデンシャルが事前に必要となります。 AWS Cloud Shellを使うとサインインしている人の権限が利用できるので、私はAWS Cloud Shell上で作業しました。
Thingの登録
AT+CONF? ThingName
で確認した値をAWS CLIで登録します。
aws iot create-thing \
--thing-name 確認した値 \
--attribute-payload attributes={ExpressLink="u-blox_USB-NORA-W2"}
{
"thingName": "確認した値",
"thingArn": "arn:aws:iot:ap-northeast-1:1234567890:thing/確認した値",
"thingId": "ユニークな値"
}
証明書の登録
証明書は AT+CONF? Certificate
で確認した長い文字列です。証明書は以下のように決められたフォーマットである必要がありますが、取得できた文字列は \A
で区切られてました。そのまま登録できませんでしたので、以下のコマンドで改行コードに置き換えます。
CERT=$(echo "-----BEGIN CERTIFICATE-----\AMIIDRzC〜〜〜EQBxwBswfQ\A-----END CERTIFICATE-----" | sed 's/\\A/\n/g')
そして、以下のコマンドで登録します。今回はCA証明書が無いので、CA lessの方法で登録です。
aws iot register-certificate-without-ca \
--status ACTIVE \
--certificate-pem "$CERT"
{
"certificateArn": "arn:aws:iot:ap-northeast-1:1234567890:cert/長いID",
"certificateId": "長いID"
}
IoT Policyの登録
テスト用ですので、ガバガバなPolicyですが、実際に利用する際には正しく制限しましょう。
POLICY=$(cat << EOS
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "*"
}
]
}
EOS
)
aws iot create-policy \
--policy-name expresslink-policy \
--policy-document "$POLICY"
{
"policyName": "expresslink-policy",
"policyArn": "arn:aws:iot:ap-northeast-1:1234567890:policy/expresslink-policy",
"policyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"iot:*\",\n \"Resource\": \"*\"\n }\n ]\n}",
"policyVersionId": "1"
}
Thing,証明書,IoT Policyを紐付け
登録したそれぞれの情報を紐付けます
aws iot attach-policy \
--target "登録した証明書のARN" \
--policy-name "expresslink-policy"
aws iot attach-thing-principal \
--thing-name 確認したThingName \
--principal "登録した証明書のARN"
これでAWS IoT Core側の準備ができました。最後に、デバイスが接続するためのエンドポイントを調べます。この値をExpressLinkのデバイスに登録します。
aws iot describe-endpoint \
--endpoint-type iot:Data-ATS
{
"endpointAddress": "xxxxxxx-ats.iot.ap-northeast-1.amazonaws.com"
}
ExpressLinkモジュールを接続
ここからのコマンドはscreenコマンドで繋いでいるターミナルで実行します。接続先のエンドポイントを登録します。
AT+CONF Endpoint=xxxxxxx-ats.iot.ap-northeast-1.amazonaws.com
OK
Wi-Fiの設定
AT+CONF SSID=<your router SSID>
AT+CONF Passphrase=<your router passphrase>
AWS IoT Coreのテストクライアントで、 $aws/events/#
トピックにサブスクライブ。やり方はこちらのページを参照
AWS IoT Coreに接続
AT+CONNECT
OK 1 CONNECTED
AWS IoT Coreのテストクライアントに、以下のようなメッセージが出力されました。
{
"clientId": "Thing名",
"timestamp": 1725162234536,
"eventType": "connected",
"sessionIdentifier": "2e10e9ba-3446-41d6-b10f-a5d72fe62547",
"principalIdentifier": "証明書のID",
"ipAddress": "123.123.123.123",
"versionNumber": 0
}
{
"clientId": "Thing名",
"timestamp": 1725162234612,
"eventType": "subscribed",
"sessionIdentifier": "2e10e9ba-3446-41d6-b10f-a5d72fe62547",
"principalIdentifier": "証明書のID",
"topics": [
"$aws/things/Thing名/jobs/notify-next"
]
}
うまくいきました。
ExpressLinkのモジュールはOTA用のtopicにもsubscribeしているのが確認できますね。
次に、テストクライアントで ublox/data
トピックにsubscribeします。
メッセージを送りましょう
AT+CONF Topic1=ublox/data
OK
AT+SEND1 Hello World
OK
メッセージを受信してみます
AT+CONF Topic2=ublox/recieve
OK
AT+SUBSCRIBE2
OK
AWS IoT Coreのテストクライアントから ublox/recieve
にメッセージを送ります。そして以下のコマンドで、受信したデータを取得します。
AT+GET
OK1 ublox/recieve
{\A "message": "Hello from AWS IoT console"\A}
無事に受け取れました。
Topicはリストで管理されており、ATコマンド経由でtopicを操作する際には、AT+CONF Topic{番号}=Topic名
コマンドで指定した数字を SEND{数字}
や SUBSCRIBE{数字}
で指定することでどのTopicを使うかを指定しています。この数字が利用できるTopic数の数に依存しており、モジュールによって異なります。
NORA-W2だと試した感じでは、16個まで利用可能なようです。
AT+CONF Topic16=aa
OK
AT+CONF Topic17=aa
ERR7 OUT OF RANGE
以上で基本的な動きが確認できました。既存のマイコン側でATコマンドを使って操作することで、コネクテッドに必要な複雑な処理や、証明書などのクレデンシャルをセキュアに保つための仕組みを丸投げできるのはかなり便利ですね。
次の記事ではホストマイコンとしてRaspberry Pi picoを使って試してみています。
https://qiita.com/sparkgene/items/c2c4086ae4d098153f25