この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Raspberry Pi(ラズベリーパイ)とAWS IoTでLチカしてみたいと思います。AWS IoTでシャドウ(Thing Shadow)を更新すると、MQTTで接続しているRaspberry Piが差分を受け取り、LEDをON/OFFする仕組みを構築します。
環境情報
次のようなMacbookとRaspberry Piの環境で開発しています。また、Raspberry Piをリモートから操作するため、MacbookからRaspberry PiにVNCとSSHで接続できるようにしています。
Macbook
項目 | 内容 |
---|---|
モデル | MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports) |
OS | macOS Catalina 10.15.4(19E287) |
プロセッサ | 2.3 GHz クアッドコアIntel Core i5 |
メモリ | 16 GB 2133 MHz LPDDR3 |
Raspberry Pi
項目 | 内容 |
---|---|
モデル | Raspberry Pi 4 Model B |
OS | Raspbian 10 (Raspbian GNU/Linux 10 buster) |
SDカード | SanDisk Ultra microSDHC 32GB SDSQUAR-032G-GN6MN |
電源 | 電源アダプター USB Type-C 5.1V/3A |
その他(部品)
- ブレッドボード ×1
- ジャンパーワイヤー(オス-メス) ×2
- LED ×1
- 抵抗器 1KΩ ×1
Raspberry PiだけでLチカ
まずは、Raspberry PiだけでLチカできることを確認します。後ほど「AWS IoT Device SDK for JavaScript」を使用したいので、Node.jsで開発することにします。
配線
次の画像のようにRaspberry Piからブレッドボードへ配線します。
Node.jsをインストール
Raspberry Piに最新のNode.jsとnpmをインストールします。Raspberry Piのターミナルを使用するかSSHで接続して作業します。
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
Nodeとnpmをインストールします。
sudo apt-get install -y nodejs
インストールされたNodeとnpmのバージョンを確認します。
node -v # v12.16.2
npm -v # 6.14.4
Lチカ用のコードを実装
プロジェクト用のディレクトリを用意して、GPIOの操作で使用するライブラリをインストールします。
mkdir raspberry-pi-sample
cd raspberry-pi-sample
npm init
npm install rpi-gpio --save
1秒毎に8番ピンをON/OFFするコードを実装します。
main.js
const gpio = require("rpi-gpio");
const PIN = 8; // 8番ピン(GPIO14)
let LED = true;
gpio.setup(PIN, gpio.DIR_OUT, () => {
setInterval(() => {
if (LED) {
gpio.write(PIN, false);
LED = false;
} else {
gpio.write(PIN, true);
LED = true;
}
}, 1000);
});
Lチカしてみる
Raspberry Pi上でコードを実行します。
node main.js
LEDが1秒毎に点灯と消灯を繰り返します。
Raspberry PiとAWS IoTでLチカ
今度はRaspberry PiとAWS IoTをMQTTで接続して、サブスクリプション要求により受け取る差分を処理して、LEDをON/OFFしてみます。まずは、AWS IoTに接続するための準備から始めます。
AWS IoTでポリシーを作成
AWS IoT Coreのマネジメントコーンソールからポリシーを作成します。
適当なポリシー名を入力します。アクションにiot:*
リソースに*
に入力、効果は許可
にチェックをしてポリシー作成します。
AWS IoTでモノを作成
AWS IoT Coreのマネジメントコーンソールから単一のモノを作成します。
適当なモノの名前を入力して次へ進みます。
AWS IoTで証明書を作成
モノに証明書を追加します。次の画面が表示されるので「1-Click 証明書作成 (推奨)」で証明書を作成します。
証明書の作成が完了したら、次の画面で証明書や秘密鍵をダウンロードします。また、証明書を有効化して先ほど作成したポリシーをアタッチしておきます。
AWS IoTのエンドポイントを取得
AWS IoT CoreのマネジメントコンソールからAWS IoT Coreへ接続するためのエンドポイントを取得します。
AWS IoT Device SDK for JavaScriptをインストール
npmでAWS IoT Device SDK for JavaScriptをインストールします。
npm install aws-iot-device-sdk --save
Lチカ用のコードを実装
サブスクリプション要求により受け取る差分を処理して、LEDをON/OFFするコードを実装します。秘密鍵や証明書のパスはあらかじめダウンロードしたファイルのパスを設定します。raspberry-pi-sample
はモノを作成した際の名前に変更してください。
main.js
const awsIot = require("aws-iot-device-sdk");
const gpio = require("rpi-gpio");
const PIN = 8; // 8番ピン(GPIO14)
const device = awsIot.device({
keyPath: "xxxxxxxxx-private.pem.key", // 秘密鍵
certPath: "xxxxxxxxx-certificate.pem.crt", // 証明書
caPath: "amazon-root-ca1.pem", // CA証明書
clientId: "raspberry-pi-sample", // ClientID
host: "xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com", // エンドポイント
});
device.on("connect", function () {
console.log("connect");
device.subscribe("$aws/things/raspberry-pi-sample/shadow/update/delta");
device.publish(
"$aws/things/raspberry-pi-sample/shadow/update",
JSON.stringify({
state: {
reported: {
led: "off",
},
},
})
);
gpio.setup(PIN, gpio.DIR_OUT, () => {
gpio.write(PIN, true); // true=消灯
});
});
device.on("message", function (topic, payload) {
console.log("message", topic, payload.toString());
const shadow = JSON.parse(payload.toString());
if (shadow.state && shadow.state.led) {
console.log("led", shadow.state.led);
const led = shadow.state.led !== "on";
gpio.setup(PIN, gpio.DIR_OUT, () => {
gpio.write(PIN, led);
});
device.publish(
"$aws/things/raspberry-pi-sample/shadow/update",
JSON.stringify({
state: {
reported: {
led: shadow.state.led,
},
},
})
);
}
});
MQTTのトピックはAWS IoTの予約されたトピックを使用しています。
Lチカしてみる
Raspberry Pi上でコードを実行します。
node main.js
AWS IoTでシャドウを確認します。
desired
に"led": "on"
を書き込んで保存します。
{
"desired": {
"led": "on"
},
"reported": {
"led": "off"
}
}
保存するとdelta
に差分が追加されます。
{
"desired": {
"led": "on"
},
"reported": {
"led": "off"
},
"delta": {
"led": "on"
}
}
Raspberry Piで差分を処理してreported
が更新されます。
{
"desired": {
"led": "on"
},
"reported": {
"led": "on"
}
}
処理が終わるとLEDが点灯します。
desired
に"led": "off"
を書き込んで保存します。
{
"desired": {
"led": "off"
},
"reported": {
"led": "on"
}
}
LEDが消灯します。
まとめ
Raspberry PiとAWS IoTでLチカすることができました。API Gatewayから実行するLambdaでシャドウのdesired
を更新することで、WEBアプリからLEDをON/OFFすることもできそうです。他にもRaspberry Piにスイッチを接続して、LEDのON/OFFを制御するケースも考えられると思います。