[初心者向け] 温度湿度気圧センサーのデータをRaspberry PiからAWS IoT Coreに送ってみた

2022.03.04

どうも、ラズパイ初心者のアベシです! BME280というセンサーで取得した温度、湿度、気圧のデータをRaspberry PiからIoT Coreに送ってみましたので、その際の手順が誰かの参考になればと思いブログに残しました。

ハード側の紹介と準備

今回使用したハード関係は以下の通りです。

  1. ラズパイ:Raspberry Pi 3 Model B+
  2. センサー:BME280使用の温湿度気圧センサー


ラズパイとセンサー間の配線接続は以下の通りです。

ラズパイ側GPIOピン センサー側 備考
1pin(3.3V) 1pin(VDD) ----
6pin(GND) 2pin(GND) ----
17pin(3.3V) 3pin(CSB) 3.3vに繋ぐことでI2C通信モードになる
3pin(SDA) 4pin(SDI) ----
9pin(GND) 5pin(SDO) GNDに接続するとI2Cアドレスは0×76となる
5pin(SCL) 6pin(SCK) ----

↓センサーのピン配置(センサーに同梱の説明書に記載されております。) ↓ラズパイのGPIOピン配置 <引用:https://pinout.xyz/>

Raspberry Pi側のセットアップ

I2C通信をするための設定

以下のコマンドで設定画面を開きます。 sudo raspi-config 3番のInterface Optionsを選択 5番のI2Cを選択 Would you like the ARM I2C interface to be enabled?という問いかけが出てくるのではいを選択 最後にThe ARM I2C interface is enabled と表示されれば設定完了

I2C通信をするためのツールの導入

以下のコマンドで必要なツール類を導入して行きます。

$ sudo apt-get update               // インストール可能なパッケージの一覧を更新する
$ sudo apt-get upgrade              // インストール済みのパッケージ更新
$ sudo apt-get install i2c-tools    // I2Cの接続テストをするツール
$ sudo apt-get install python-smbus // pythonでのI2Cの制御に使用

i2c-toolsの機能を使って以下のコマンドでI2Cとの接続テストができます。 今回はI2Cのアドレスを0×76に設定していますので、76と表示されれば問題なく接続できていることになります。

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- 76 --

センサーのデータ取得用のサンプルプログラムの入手

今回スイッチサイエンスさんが提供しているプログラムを使用しました。 これをgit cloneで入手します。

$ git clone https://github.com/SWITCHSCIENCE/BME280.git

使用したプログラムはuser/BME280/Python27/内のbme280_sample.py です。

注意点

  1. プログラムの変更の影響でsmbus2というモジュールも必要になり、こちらのブログの(5)項目を参考に導入しました。
  2. プログラム内の計測結果表示のprint文にカッコ抜けがあり、そのままでは構文エラーとなり修正しました。

一度動かしてみます 以下のように計測結果が取れました。

$ python bme280_sample.py
temp : 24.35  ℃
pressure : 1007.07 hPa
hum :  52.74 %

このプログラムは後ほどIoT Coreに送れるように修正します。

AWS IoT Core の設定

次にIoT Coreの設定入ります。

モノの作成と設定

AWS IoTのトップページの管理タブ内のモノのページに行き、モノを作成をクリックして作成開始します。 1つのモノを作成を選択して次に行きます。 モノの名前の記載と、Device Shadowの項目で今回はシャドウがありませんを選択して次に進みます。 デバイス証明書は推奨の自動生成を選択しました。 ポリシーのアタッチは一旦スキップでモノを作成をクリックします。 証明書とキーのダウンロード画面が立ち上がりますので、全て項目をダウンロードします。ここを逃すと証明書をダウンロードできなくなるのでご注意ください。 モノができました。

ポリシーの作成

まず証明書にアタッチするポリシーを作ります。 安全性の項目のプルダウンメニュー内のポリシーをクリックして作成画面に行きます。
今回トライアル用に全アクションと全リソースを許可する設定で作ります。ポリシー、アクションともにを選択してします。

下のようなポリシーが出来上がりました。ちゃんとリソースとポリシーがになってますね。

証明書にポリシーをアタッチ

先程モノを作った際に一緒に作られた証明書を選択します。

ポリシーをアタッチというボタンをクリックして先程作ったポリシーをアタッチします。

証明書にモノをアタッチ

今度は証明書をモノにアタッチします。モノというタブを開き、モノにアタッチするボタンを押して先程作ったモノの名前を選択します。

サンプルプログラムの入手

AWSが提供してるデータ転送用のプログラムをgit cloneで入手します。

$ git clone https://github.com/aws/aws-iot-device-sdk-python.git

今回使用するプログラムは~/aws-iot-device-sdk-python/samples/basicPubSub内のbasicPubSub.pyです。内容は"Hello World!"というメッセージをIoT Coreに送るシンプルなものです。

その他の準備

  • IoT Coreの設定からエンドポイントを調べることができます。調べたら控えておいて下さい。 IoT Coreにメッセージを送る際に必要になります。
  • 予めダウンロードしていたデバイス証明書キーファイルルートCA証明書をラズパイのディレクトリに格納します。 自分の場合、サンプルコードを格納しているディレクトリ内にcertsというディレクトリを作り、上記を格納しました。

IoTCoreへのデータ送付トライ

サンプルコードを格納したディレクトリに移動し、以下のコマンドでIoT Coreにメッセージデータを送ってみます。

pi@hogehoge:~/BME280/Python27 $ python3 basicPubSub.py \
--endpoint *********.iot.ap-northeast-1.amazonaws.com \   // エンドポイント
--rootCA ./certs/AmazonRootCA1.pem \                      // ルートCA証明書
--cert ./certs/*********-certificate.pem.crt \            // デバイス証明書
--key ./certs/*********-private.pem.key                   // プライベートキー

以下のようにsdk/test/PythonというトピックにHello World!というメッセージが送られました。

2022-03-04 11:17:04,431 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2022-03-04 11:17:05,385 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
2022-03-04 11:17:05,386 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback...
2022-03-04 11:17:05,425 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event
2022-03-04 11:17:05,425 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event
2022-03-04 11:17:05,426 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2022-03-04 11:17:05,426 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation...
2022-03-04 11:17:05,451 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2022-03-04 11:17:05,451 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message: 
b'{"message": "Hello World!", "sequence": 3}'
from topic: 
sdk/test/Python
--------------

IoT Core側でもメッセージの受信結果を確認してみます。 IoT Coreのページに行って、左側のペインからMQTTテストクライアントを選択します。 トピックのフィルターという欄にトピック名sdk/test/Pythonを記載してサブスクライブボタンを押すとサブスクリプションされたトピックが下の方に現れます。 ここでもう一度python3 mybasicPubSub.pyを実行してみます。 "message": "Hello World!", "sequence": 2というメッセージがちゃんと受け取れています。

センサーで取得したデータをIoT Coreに送付

センサー取得用プログラムの修正

こちらで取得したプログラムを以下のように修正します。 以下の4つの関数を修正

def readData():

//元々のコード↓
compensate_T(temp_raw)
compensate_P(pres_raw)
compensate_H(hum_raw)

//以下のように修正
temperature = compensate_T(temp_raw)
pressure    = compensate_P(pres_raw)
humidity    = compensate_H(hum_raw)
return temperature, pressure, humidity

def compensate_P(adc_P):

//以下を追加
return pressure

def compensate_T(adc_T):

//以下を追加
return pressure

def compensate_H(adc_H):

//以下を追加
return var_h

(修正後のファイル名:my_bme280.py)

IoT Coreへのデータパブリッシュ用のプログラム修正

以下のようにコードを5箇所追加しております。既に修正したmy_bme280.pyimportで呼び出し、readData()関数を使用する形です。

my_basicPubSub.py

import my_bme280                                                 //追加

while True:
    if args.mode == 'both' or args.mode == 'publish':
        temperature, pressure, humidity = my_bme280.readData()  //追加
        message = {}
        message['message'] = args.message
        message['sequence'] = loopCount
        message['temperature'] = round(temperature, 2)          //追加
        message['pressure'] = round(pressure/100, 2)              //追加
        message['humidity'] = round(humidity, 2)                //追加          
        messageJson = json.dumps(message)
        myAWSIoTMQTTClient.publish(topic, messageJson, 1)
        if args.mode == 'publish':
            print('Published topic %s: %s\n' % (topic, messageJson))
        loopCount += 1
    time.sleep(1)

(修正後のファイル名:my_basicPubSub.py)

センサーデータをIoT Coreへ送付

my_basicPubSub.pyを実行してみます。 以下のように温度、湿度、気圧のデータがIoT Coreへ送付できました!\(^o^)/

終わりに

実際にセンサーで取得したデータをラズパイからIoT Coreへ送ってみました。 ラズパイとAWSの連携は初めてということも有り、実際にセンサーのデータがAWSに送られているところ見た時に、モノとインターネットを繋がってる!と改めて思ってちょっと感動しました。 今後はIoT Coreとその他のAWSリソースを連携させてみようと考えてます。 その手順もまたブログにできればと思っております。 それでは、また!