Raspberry PiからのデータをMicrosoft Azure IoT HubとMicrosoft Azure App Serviceでリアルタイム可視化 2

本記事シリーズでは、Raspberry Piに繋がっているセンサーから取得したデータをAzure IoT Hubに送信し、Azure App Serviceを使ってリアルタイムで可視化する方法について紹介します。

この記事シリーズでできることは以下の通りです。

  • 記事1:Azure IoT Hubの作成やデバイス登録 
    • Azure Iot Hubの紹介、Azure IoT Hubの作成、デバイス登録について
  • 記事2:Raspberry Piでデータを読み鋳込んでIoT Hubに送信 (本記事) 
    • Raspberry Piとセンサーの紹介、センサー連結、Azure IoT Hubにメッセージ送信について
  • 記事3:IoT Hubで受信したデータを可視化するWeb AppをAzure App Serviceでリリース
    • リアルタイム可視化、Azure App ServiceのWeb Appでリリスについて

準備物

Raspberry Pi

  • イギリスのラズベリーパイ財団によって開発された、ARMプロセッサを搭載したシングルボードコンピュータ。
  • GPIOピンやポート(USB, シリアル, HDMI, LANなど)を使って様々な装置の連結ができます。
  • 現時点(2024/3/4)での最新のバージョンはRaspberry Pi 5ですが、本記事ではRaspberry Pi 4 Model Bを使用しました。
  • Raspberry PiのOSのインストールのため、SDカードが必要です。

センサー

以下の3つのセンサーをRaspberry Piに連結します。

HC-SR501 人体赤外線感応センサー

服屋の試着室などにある、人がいるかを感応するセンサーです。

下にあるオレンジ色のスクリューで、センサーの感度や感知距離を調節できます。

DHT20 温湿度センサー

温度と湿度を測定するセンサーです。

測定間隔 2秒毎
湿度分解能 0.024%RH
湿度精度 ±3%RH
温度測定範囲 -40~80℃
温度分解能 0.01℃
温度精度 ±0.5℃
I2Cアドレス 0x38
照度センサー(CDSセンサー)

光の強さによってセンサーの抵抗が変わることを使って、光の強さを測定します。

Raspberry Piの構築

OSインストール

  1. Raspberry Pi本体、SDカードを準備します。

    Raspberry PiはSDカードにOSをインストールして、SDカードから起動します。

    SDカードの容量については、8GB以上の容量のSDカードを使うと問題ありません。ただ、読み書きスピードが早いものを使うほうがおすすめです。

  2. SDカードにOSをインストールするため、以下のサイトから「Raspberry Pi Imager」をダウンロードし、インストールします。

    https://www.raspberrypi.com/software/

  3. 「CHOOSE OS」をクリックし、「Raspberry Pi OS」を選択します。

  4. 「CHOOSE SD CARD」をクリックし、インストールするSD Cardを選択します。

  5. 「WRITE」をクリックして、インストールを開始します。

    10~20分くらいで終わるので、少々お待ちください。

初期設定

  1. Raspberry Pi OSがインストールされているSDカードをRaspberry Piに入れ、電源を繋ぎます。

  2. 最初の画面から「Next」をクリックして、設定を始めます。

  3. 地域の基本設定を行います。

    • Country : Japan
    • Language : Japanese
    • Timezone : Tokyo
    • Use English language:チェックを入れる
    • Use US keyboard:チェックを入れる
  4. Raspberry Piのアカウント名と暗号を設定します。

  5. Wi-Fiに接続します。

  6. アップデートがある場合はアップデートを行います。

  7. Setup Complete画面で「Done」をクリックして、初期設定を終了します。

SPI/I2C設定

シリアル通信の設定を行います。

  1. メイン画面の左上にあるRaspberry Piマークをクリックして、Preferences – Raspberry Pi Configurationをクリックします。

  2. Interfacesタブにある「SPI」と「I2C」をクリックして、ONにします。

Raspberry Piとセンサーの連結

Raspberry Piとセンサーを連結します。配線は上の画像を参照してください。

GPIO設定

GPIOとは?

https://www.raspberrypi.com/documentation/computers/os.html#gpio-and-the-40-pin-header

Raspberry PiにはUSBやRJ45、HDMI以外にもデータ通信のため、GPIOピンが用意されています。このGPIOピンを使って、センサーなどからデータの送受信を行います。

GPIOピンを使うにはソースコードでBCMまたはBOARDのモードを設定する必要があります。

BCMは上のGPIO XXなどの番号(XX)で、BOARDは実際のピンの番号です。

例えば、GPIO 27ピンを使うにはBCMモードでは27、BOARDモードでは13を指定する必要があります。

Rpi.GPIOのインストール

Raspberry PiでGPIOピンを使用するために、ライブラリをインストールします。

sudo apt-get update

sudo apt-get install –y python-pip

sudo pip install Rpi.GPIO

もしインストールできなかった場合は以下のようにpip3で試してみてください。

sudo apt install python3-pip

sudo pip3 install rpi.gpio

Python開発環境の準備(ライブラリインストール)

  1. ライブラリをインストールするため、メイン画面の左上の「Terminal」をクリックして、ターミナルを開きます。
  2. 下のコマンドを入力して、「Azure IoT Device SDK」をインストールします。

    sudo pip install azure-iot-device

  3. 下のコマンドを入力して、「Azure IoTHub Service SDK」をインストールします。

    sudo pip install azure-iot-hub

参照サイト

GitHub - Azure/azure-iot-sdk-python: A Python SDK for connecting devices to Microsoft Azure IoT services

Azure IoT Hubにメッセージ送信

ソースコード(python)

今回のソースコードでは以下の機能を実装します。

  1. IoT Hubに接続
  2. 赤外線センサーで部屋に誰か動いているかをチェックして、その結果を読み込む
  3. 照度センサーで部屋の明るさをチェックして、その結果を読み込む
  4. 温湿度センサーで温度と湿度を読み込む
  5. 読み込んだデータを1つのメッセージにする
  6. メッセージをAzure IoT Hubに送信する
import os
import asyncio
import random
import time
import sys
import smbus
import RPi.GPIO as GPIO

from azure.iot.device.aio import IoTHubDeviceClient

#Azure Connection setting
CONNECTION_STRING = "{自分のConnection String}"

#Azure message form
MSG_TXT = "{\"deviceId\":\"raspberry\",\"temperature\": %f,\"humidity\": %f,\"light\": %f}"

#SR501 setting
PIN_SR501 = 7

#Light sensor setting
PIN_LIGHT = 11

#DHT20 setting
i2c = smbus.SMBus(1)
address = 0x38
trigger = [0xAC, 0x33, 0x00]
dat = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

GPIO.cleanup()
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN_SR501, GPIO.IN)

async def main():
    # Create instance of the device client using the connection string
    device_client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    # Connect the device client.
    await device_client.connect()
    print("Connection Success")
    
    status_person = 0
    status_light = 0
    
    try:
        while True:
            if(GPIO.input(PIN_SR501) == GPIO.HIGH):
                status_person = 1
            else:
                status_person = 0

            light1 = light(PIN_LIGHT)
            time.sleep(1)
            light2 = light(PIN_LIGHT)
            time.sleep(1)
            light3 = light(PIN_LIGHT)
            lightavg = (light1 + light2 + light3)/3
            if(lightavg < 300):
                status_light = 1
            else:
                status_light = 0

            #DHT20
            i2c.write_i2c_block_data(address, 0x00, trigger)
            time.sleep(0.1)
            dat = i2c.read_i2c_block_data(address, 0x00, 7)
            hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
            tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
            hum = hum / 2**20 * 100
            tmp = tmp / 2**20 * 200 - 50
            print("Humidity: " + str(hum) + "%")
            print("Temperature: " + str(tmp) + "C")
            print("Sending message : {\"deviceId\":\"raspberry\",\"temperature\": %f,\"humidity\": %f,\"person\": %f,\"light\": %f}" %(tmp, hum, status_person, lightavg))
            await device_client.send_message("{\"deviceId\":\"raspberry\",\"temperature\": %f,\"humidity\": %f,\"person\": %f,\"light\": %f}" %(tmp, hum, status_person, lightavg))
                    
            print("Message successfully sent!")
                
            sleep(5)
    
    except KeyboardInterrupt:
        # Finally, shut down the client
        await device_client.shutdown()
        print("Stop")

    return


def light(PIN_LIGHT):
    count = 0
  
    #Output on the pin for 
    GPIO.setup(PIN_LIGHT, GPIO.OUT)
    GPIO.output(PIN_LIGHT, GPIO.LOW)
    time.sleep(1)

    #Change the pin back to input
    GPIO.setup(PIN_LIGHT, GPIO.IN)
  
    #Count until the pin goes high
    while (GPIO.input(PIN_LIGHT) == GPIO.LOW):
        count += 1
    return count

if __name__ == "__main__":
    asyncio.run(main())
  

ソースコード説明

変数設定
  • CONNECTION_STRING : 現在のデバイスのプライマリ接続文字列
  • PIN_SR501、PIN_LIGHT : GPIOピン設定
Azure IoT Hub接続

接続文字列を作成し、connect()でAzure IotHubに接続します。

センサー
  • 人環センサー:PIN_SR501からの信号で判定します。
    • HIGH : 人がいる
    • その他 : 人がいない

  • 照度の測定:センサーから数値で測定します。

  • DHT20温湿度センサー

    センサーからのデータを変換する必要があります。

    # データ変換
    hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
    tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
    # 物理量変換
    hum = hum / 2**20 * 100
    tmp = tmp / 2**20 * 200 - 50

    詳細は以下のサイトを参照してください。

    温湿度センサーDHT20AHT25の使い方 Raspberry Pi

メッセージの形式

プロトコル間のシームレスな相互運用性をサポートするために、Azure IoT Hub では、すべてのデバイスに接続するプロトコルで使用できる一般的なメッセージング機能のセットを定義しています。

Azure IoT Hub メッセージの形式について | Microsoft Docs

今回のメッセージの例

{“deviceId”:”raspberry”, “temperature”: 28.349686, “humidity”: 64.481926,“person”: 1.000000, “light”: 1.000000}

実行結果

おわりに

今回の記事ではRaspberry Piからセンサーの値を取得し、Azure IoT Hubにメッセージを送信する方法について紹介しました。

今回はRaspberry Piの実機を使いましたが、Raspberry Piがない場合はMicrosoftが提供しているシミュレーターからAzure IoT Hubに仮想のデータを送信することも可能です。

Raspberry Pi Azure IoT Web Simulator (azure-samples.github.io)

次回の記事ではAzure IoT HubがRaspberry Piから受け取ったセンサーの値をAzure App Serviceを使ってウェブページで可視化する方法について紹介します。

執筆担当者プロフィール
Lee Byungju

Lee Byungju(日本ビジネスシステムズ株式会社)

Microsoft Azure関係の開発, Power Platformが担当領域。

担当記事一覧