2019年1月10日にスイッチサイエンスで購入できるようになった、地震の大きさを表す震度階級とも相関性の高いSI値を採用することで、より高精度な地震の強さを判定できるオムロン感震センサD7S-A0001を搭載した評価用モジュール(Groveコネクタ付き)を、RaspberryPiに接続して地震データの可視化をやってみます。

なお、D7S-A0001の詳細な仕様はオムロン公式のD7S 感震センサ ユーザーズマニュアル(PDF)をご確認ください。

事前準備

必要なモノ

  • Raspberry Pi 3B/3B+
  • microSDカード
  • GrovePi+
  • DD7S-A0001(感震センサ、Groveコネクタ付き)

だいたい1万5000円くらいで揃えることができます。

※ isaax勉強会では必要なライブラリのインストール時間を節約するためにあらかじめ用意したSDカードを使用します。公式のRaspbianを使って1からセットアップする場合はこの記事の最後にある付録をご覧ください。

必要なアカウント

ハンズオンを行う前に以下のアカウントを取得してください。アカウント登録が出来た方から先に進んでください。

  • GitHub – ソースコード管理
  • isaax – アプリケーション配信
  • Ambient – グラフ化

必要な知識

  • CUIの操作の基礎知識
  • プログラミングの基礎知識
  • Git / GitHubの基本的な操作
  • Linuxシステムの基礎知識

Pythonの知識があるとより深く内容を理解できます。

ハードウェアの組み立て

勉強会では席についた方から、以下の手順でハードの組み立てを行って、電源を入れ、IPアドレスを確認するところまでやってください。

※IPアドレスの確認方法は、isaax勉強会オリジナルです。自宅で試す場合はこちらの記事をご確認ください。

microSDカードスロットにmicroSDカードを挿し込む

GrovePi+とRaspberry PiのUSBが直接触れてしまうと、漏電・故障の原因になりますのでマスキングテープを貼ります。セロテープや付箋でも代用可。

完成形

Raspberry PiにLANケーブルを接続しUSB電源ケーブルを挿してください。特に電源ボタンは無いので、USBケーブルを接続するとRasppberry Piは起動します。

IPアドレスを確認します

勉強会に参加している方は、スタッフが渡した小型のLCDディスプレイを、画像の6本のピンに挿してください。ネットワークに接続できていれば、ディスプレイにIPアドレスが表示されます。

Raspberry Piにログインするのに必要なので、IPアドレスをメモしておいてください。

IPアドレスの確認が終わったら、同じテーブルの人にディスプレイを渡してください。

ハードウェアの動作確認

感震センサの接続確認

Raspberry Pi –> GrovePi+ –> センサーと接続するものが多いので、先にハードウェアの問題がないか確認します。

SSHでRaspberry Piにログインする

ターミナルを開いてssh pi@xx.xx.xx.xx(xx.xx.xx.xxの部分はRaspberryPiのIPアドレス)を実行し、Raspberry Piにログインします。

Windowsの場合はGoogle Chrome拡張機能のSecure Shell Appを使うことをおすすめします。

パスワードを聞かれるので、Raspberry Piのパスワードを入力します。(デフォルトではraspberry

以下は、IPアドレスが192.168.1.37の場合の例です。

$ ssh pi@192.168.1.37
pi@192.168.1.37's password: 
Linux raspberrypi 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Feb  5 16:23:48 2019 from 10.0.1.11
pi@raspberrypi:~ $

Secure Shell Appの場合は、sshコマンドを入力する代わりにこのようになります。

GrovePi+と感震センサの接続を確認する

Raspberry PiとGrovePi+、感震センサはI2C(アイ・スクエア・シー)という方式でシリアル通信をしています。i2cdetectコマンドでセンサが認識できているかを確認できます。RaspberryPi 3を使っている場合のコマンドと実行結果は以下のようになります。

pi@raspberrypi:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- 04 -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- 55 -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

04がGrovePi+、55が感震センサのアドレスです。この2つが表示されなかった場合、ハードの接続が正しくできていないのでスタッフのサポートを受けてください。

サンプルプログラムを動かす

続いて、isaax UGのスタッフが用意したサンプルプログラムを動かしてみましょう。

https://github.com/isaaxug/d7s-with-isaax – GitHub

大まかな手順は、以下のとおりです。

  1. GitHubのリポジトリをフォークする
  2. isaaxプロジェクトの作成
  3. isaaxdをRaspberry Piにインストール

isaaxdをRaspberry Piにインストールすると、自動的にアプリケーションが起動し、isaaxのダッシュボード上で動作確認ができます。(そういうサンプルコードを用意しました)

サンプルプログラムのフォーク

Gitリポジトリ(以下、リポジトリ)で管理したプログラムは、isaaxを使ってデバイスに配信されます。今回はあらかじめ用意したサンプルコードをフォークして使います。

リポジトリとは、ファイルやディレクトリの変更履歴を保持したプログラムファイルの集合です。Gitを使って開発する場合、大抵は1つのアプリケーションごとに1リポジトリ作成します(もちろん例外もあります)。

isaaxプロジェクトの作成

前節で自分のGitHubアカウントにフォークしたリポジトリを使ってisaaxにプロジェクトを作成します。isaaxアカウントをまだ作成していない場合はこのタイミングで登録しましょう(GitHubアカウントを使って登録すると便利です)。

isaax ダッシュボード

新規プロジェクト追加 をクリックし新しいプロジェクトを作成します。

isaax 新規プロジェクト追加リポジトリ名のyutashi/envsensor-ambientは、{あなたの名前}/d7s-with-isaaxに書き換えてください

プラットフォームは GitHubを選択し、上図のように設定し保存ボタンをクリックします。

isaaxdのインストール

作成したプロジェクトにデバイスを登録します。Raspberry Pi側にisaaxdというエージェントをインストールすことで、デバイス登録が完了します。

isaaxdはRaspberry Piなどのデバイス上で動作するソフトウェアです。isaaxクラウドとの通信とユーザーアプリケーションの管理を担っています。
isaaxdとはより引用

プロジェクトの作成後、このような画面が表示されます。

プロジェクトトークンはデバイスの認証を行うのに必要となります。インストールスクリプトはそのトークンを引数としてisaaxdのインストールをワンコマンド実行するためのスクリプトです。下側のインストールスクリプトの文字列をコピーしてください。

コピーしたコマンドはラズベリーパイ上で実行します。WindowsならSecure Shell App、macやLinuxならTerminalを使ってラズパイにSSH接続しましょう。

ユーザー名はpi、初期パスワードはraspberryです。

Raspberry Piのログ

上図のようにisaaxd installation completeが表示されればインストール成功です。

先ほどフォークしたリポジトリのコードがRaspberry Piに配信され、自動的にアプリケーションを起動してデータの収集をはじめます。

動作の確認

サンプルコードは、感震センサからデータを取得し、その値を標準出力するシンプルなスクリプトです。isaaxdはこのアプリケーションの標準出力と、標準エラー出力を監視してクラウドにログデータとして送信します。

isaaxのダッシュボードに戻り、登録したデバイスの状態を確認しましょう。

isaax クラスター

プロジェクトトークンのモーダルを閉じ、DEFAULTクラスターをクリックします。

クラスターはIsaaxにおいてデバイスをグルーピングします。1つのプロジェクトに対して複数のクラスターを作成でき、それぞれのクラスターは料金プランに応じたデバイスを登録できます。ただし、1つのデバイスが登録できるクラスターは1つまでです。
プロジェクトとクラスターより

isaax クラスターページ

クラスターページを開くと「最近のデバイス」に先ほど登録したデバイスが表示されます。「バージョン」はインストールされているisaaxdのバージョンを、「リビジョン」はインストールされているアプリケーションのコミットID(Gitで作成した履歴ごとに付与されるID)をそれぞれ示しています。

デバイスをクリックしましょう。

感震センサのデータがログとして表示されました

画面左側には、デバイスに割り当てられているローカルIPアドレスの確認やアプリケーションの起動・停止などの機能を備えています。

画面右側で、インストールしたアプリケーションのログを確認できます。ラズベリーパイが期待する動作をしないときなどはこちらにエラーログが上がっている可能性が高いので確認しましょう。

うまく動いている場合は、SI値(Kine)とPGA値(gal)、地震かどうかのフラグが表示されています。

センサーを手で揺らして変化が起きるか確認してみましょう。

参考:SI値とPGA値について

詳しい解説はアズビル株式会社のウェブサイトやWikipediaの表面最大加速度を見てください。

それぞれのサイトから引用:

SI値とは

地震によって一般的な建物にどの程度被害が生じるかを数値化したものです。 地振動による構造物の破壊等の被害は、地震発生時の構造物の振動エネルギーが寄与し、地振動の最大加速度が同じでも地震の継続時間が長いほど構造物の被害が大きくなる

PGA値とは

震度と同様、ある場所においてどれだけ強く地面が揺れたかを表すものである。

プログラムが起動する仕組み

デバイスにisaaxdをインストールするとセンシングした値が、isaaxのダッシュボードに表示されました。

これはisaaxが皆さんのGitHubのリポジトリから最新のソースコードを取得し、Raspberry Piにインストールしたisaaxdへアップデートの命令を出し、isaaxdが最新のソフトウェアをRaspberry Pi内に展開しsystemdのプロセスとして登録するという一連の作業をすべて自動で行ったために実現しました。

展開されたされたソフトウェアは/var/isaax/projectディレクトリ配下にあります。

リポジトリルートにあるisaax.jsonがアプリケーションの起動を管理している設定ファイルです。

{
    "name": "D7S sample",
    "license": "MIT",
    "author": "tomotomo",
    "scripts": {
        "start": "python3 -u sample_d7s.py"
    }
}

scripts->startのセクションで、アプリケーションの起動方法を記述します。

また、/var/isaax/log/project.out.logに標準出力が、/var/isaax/log/project.err.logに標準エラー出力のログが記録されます。isaaxdはこのログを監視し、自動でisaaxのダッシューボードに表示しています。

 

プログラムを変更してデータを可視化する

続いて、アプリケーションの更新方法について説明します。本日の勉強会はこの節をクリアすることが目標です。

Raspberry Piからログアウトし、PC上で先ほどフォークしたリポジトリのisaax.jsonを編集します。

編集方法は主に2つあります。

  • GitHubのリポジトリをローカルPCにクローンし、編集してPushする
  • GitHubのウェブサイト上で直接編集する(参考記事)

どちらでも良いので慣れた方法で編集してください。説明は割愛するので、わからない方はスタッフに聞くかググってください。

main.pyの追加

プログラムの概要

  • オムロン公式のPythonライブラリgrove_d7sとAmbientのPythonライブラリambientを使います
  • Linuxの環境変数からAmbient認証に必要なキーAMBIENT_CHANNEL_ID, AMBIENT_WRITE_KEYを取得しAmbientインスタンスを作成します
  • センサーからデータを取得しペイロードを作成します
  • Ambientに送信します

以下のプログラムをコピペしていただくことで使えます。

# coding: utf-8
from __future__ import print_function

import os
import time
import datetime

import grove_d7s
import ambient

# sensor instance
sensor = grove_d7s.GroveD7s()

# ambient instance
try:
    AMBIENT_CHANNEL_ID = int(os.environ['AMBIENT_CHANNEL_ID'])
    AMBIENT_WRITE_KEY = os.environ['AMBIENT_WRITE_KEY']
    am = ambient.Ambient(AMBIENT_CHANNEL_ID, AMBIENT_WRITE_KEY)
except KeyError:
    print("isaaxの環境変数サービスを使って AMBIENT_CHANNEL_ID と AMBIENT_WRITE_KEY を設定してください")
    exit(1)


def main():
    while sensor.isReady() == False:
        print('.')
        time.sleep(1.0)

    print("start")

    while True:
        # 10秒のインターバルを設定
        time.sleep(10)
        # センサーデータの取得
        si = sensor.getInstantaneusSI()
        pga = sensor.getInstantaneusPGA()
        now = datetime.datetime.today()
        eq = sensor.isEarthquakeOccuring()

        # センサーの初期化中は値がNoneになるので処理をスキップ
        if si == None and pga == None:
            continue

        # Ambientに送信するペイロードを作成
        payload = {
            "d5": int(eq),
            "d1": si,
            "d2": pga,
            "created": now.strftime("%Y/%m/%d %H:%M:%S")
            }
        try:
            am.send(payload)
        except Exception as e:
            print(e)

        # デバッグ用に送信したデータを標準出力(本当は不要)
        print(now.strftime("[%Y/%m/%d %H:%M:%S]"),
            "SI={}[Kine]".format(si), 
            "PGA={}[gal]".format(pga),
            "EQ=%s" % eq)


if __name__ == '__main__':
    main()

完成形はGitHubに公開してありますので、うまく動かない方は参考にしてください。

 

isaax.jsonの修正

isaax.jsonを編集しましょう。

鉛筆アイコンをクリックすると編集可能な状態になるので、isaax.jsonの9行目、startスクリプトの内容を以下のように変更します。

{
    "name": "2SMPB02E with isaax",
    "version": "0.0.1",
    "description": "",
    "author": "tomotomo",
    "license": "MIT Lisence",
    "language": "Python",
    "scripts": {
        "start": "python3 -u main.py"
    }
}

変更したら先ほどのmain.pyと合わせてコミットし、GitHubにプッシュします。

$ git add .
$ git commit -m "ambient sample"
$ git push origin master

GitHubのサイト上で編集している方は、画面下方の「Commit changes」ボタンをクリックして保存ます。

Ambientの設定

勉強会の冒頭で登録したAmbientから登録確認メールが届いているはずなので、メールをクリックして登録を完了してください。

Ambientにログインしたらチャネルを作ってください。

Ambientにデータを送信するにはチャネルIDとライトキーが必要なのでメモをしておいてください。

環境変数の設定

再びisaaxのダッシュボードに戻ります。

isaaxはクラスター単位でデバイスの環境変数を設定することが出来ます。この機能を使って、Ambientにアクセスするための「チャネルID」と「ライトキー」をデバイスに受け渡します。

クラスター画面を開きCluster Settingsをクリックして開きます。

「isaaxd設定」の右に「ユーザー変数」タブがあるのでクリックして、「+環境変数追加」をクリックします。

スクリーンショットを参考にAMBIENT_CHANNEL_IDAMBIENT_WRITE_KEYを設定してください。

しばらくすると、アンビエントのチャネルにグラフが表示されます。

センシングの頻度を上げる

データをプログラム側でバッファーしてAmbientに送信することで、短い間隔でセンシングした値を可視化することが出来ます。

ambientモジュールをラップしてバッファーと送信を担うAmbientConnectorクラスを新しく作ります。

ambient_connector.pyを追加

# coding: utf-8
import os
from datetime import datetime
import time
import ambient
import requests

class AmbientConnector():
    def __init__(self):
        '''
        Ambientに接続するためのキーが環境変数にセットされているかの確認
        該当する環境変数がない場合は強制終了
        '''
        try:
            CHANNEL_ID = int(os.environ['AMBIENT_CHANNEL_ID'])
            WRITE_KEY = os.environ['AMBIENT_WRITE_KEY']
        except KeyError:
            print(KeyError)
            exit(1)
        # Ambientインスタンスの作成
        self.am = ambient.Ambient(CHANNEL_ID, WRITE_KEY)
        # バッファー用のデータを初期化
        self.datas = []
        # 最終送信時刻
        self.last_posted_at = datetime.now()

    # データをバッファーする
    def buffer(self, payload):
        self.datas.append(payload)

        # 前回の送信から10秒間隔が空いていればバッファーした直後に自動的に送信する
        if (datetime.now() - self.last_posted_at).seconds > 10:
            self.__send()
        return payload
    
    # バッファーデータを送信する(private method)
    def __send(self):
        r = self.am.send(self.datas)
        if (r.status_code == 200):
            self.datas = []
            self.last_posted_at = datetime.now()
            print('Ambient send successful')
        else:
            print('Ambient send error')

main.pyを修正

# coding: utf-8
# Sample that outputs the value acquired by D7S.

from __future__ import print_function

import os
import time
import datetime

import grove_d7s
from ambient_connector import AmbientConnector

# sensor instance
sensor = grove_d7s.GroveD7s()

# ambientをラップしたAmbientConnectorを使います
am = AmbientConnector()


def main():
    while sensor.isReady() == False:
        print('.')
        time.sleep(1.0)

    print("start")

    while True:
        # 1秒間隔でデータを取得する
        time.sleep(1.0)
        
        # センサーデータの取得
        si = sensor.getInstantaneusSI()
        pga = sensor.getInstantaneusPGA()
        now = datetime.datetime.today()
        eq = sensor.isEarthquakeOccuring()

        # デバッグ用にデータを標準出力(本当は不要)
        print(now.strftime("[%Y/%m/%d %H:%M:%S]"),
            "SI={}[Kine]".format(si), 
            "PGA={}[gal]".format(pga),
            "EQ=%s" % eq)

        # センサーの初期化中は値がNoneになるので処理をスキップ
        if si == None and pga == None:
            continue

        # Ambientに送信するペイロードを作成
        payload = {
            "d5": int(eq),
            "d1": si,
            "d2": pga,
            "created": now.strftime("%Y/%m/%d %H:%M:%S")
            }
        # データをバッファーする
        am.buffer(payload)


if __name__ == '__main__':
    main()

Ambientへの送信処理をAmbientConnectorに任せたことで最初のmain.pyよりもコードの見通しが良くなりました。

この変更をGitHubにプッシュすれば、しばらくしてRaspberry Piにプログラムが配信されて1秒毎のデータを確認できるようになります。

時間に余裕がある方は…

勉強会の内容は以上ですが、時間がある方は下記課題に取り組んでみましょう。

課題1. 地図を表示してみよう

Ambientのドキュメント「データーに位置情報を付加する」を参考に、座標データを送って地図に表示してみましょう。

課題2. 感震センサにリセット信号を送る

実は今回使った感震センサは一定期間(約2分)の間の最大の揺れを保持する仕組みになっています。揺れが大きくなっていく様子はわかるのですが、小さくなっていく様子がわかりません。

そこで、センサーにリセット信号を送って、揺れを感知して何度かセンシングした後に値をゼロに戻してみましょう。

grove_d7s.pyを読み解いた結果、以下の命令でリセットコマンドを送れることが分かりました。

sensor.writeByte(sensor.REG_MODE, 0x02)

課題3. 震度を計算してみる

先ほど紹介したアズビル株式会社のウェブサイトにSI値と震度の関係性をまとめた表があります。

課題4. 地震速報を作ってみる

地震を検知したら震度を計算し、通知をする仕組みを作ってみましょう。

SlackのAPIを使える方は、過去のisaax勉強会の資料(AIカメラを使ってカウントした人数をSlackに通知しよう)を参考にしてください。

 

付録. SDカードのセットアップ

勉強会で使用したOSはRaspbian Stretch Liteをベースに作成しました。下記ページよりダウンロードしてください。

Raspbian – ダウンロードページ

サンプルコードを動作させるには下記の手順に習ってRaspberry Piの設定をしてください。

GrovePi+の設定

$ sudo curl -kL dexterindustries.com/update_grovepi | bash
$ sudo raspi-config
I2CとSPIを有効にする
$ sudo reboot

Pythonライブラリのインストール

matplotlibsmbus2をインストールします。

$ pip3 install matplotlib
$ pip3 install smbus2

matplotlibモジュールは今回の勉強会では使用しませんでしたが、sample_gui_2smpb_02e.pyのサンプルを実行するのに必要です。

Ambientを使う場合にはambientモジュールもインストールします。

$ pip install git+https://github.com/AmbientDataInc/ambient-python-lib.git

事後学習のために

isaaxについてより深く知るためには、公式のドキュメントを読んだり、コミュニティで質問してみましょう。

無料の勉強会も開催しているので、ハンズオンしたい方はこちらにもご参加ください。

本格的にIoTの開発を学びたい場合は、有料の講座もご利用ください。

SNSでもIoTに関する情報を発信しています。フォローお願いします。


Tomoyuki Sugita

Chief Product Officer of XSHELL Inc.

1 Comment

デバイスのステータスをisaaxのログに出す – Isaax Camp · 2019-03-11 at 11:44

[…] 今回のコードはgoofmint/isaax-status-update(GitHub)にアップロードしてあります。実装時の参考にしてください。 […]

Leave a Reply to デバイスのステータスをisaaxのログに出す – Isaax Camp Cancel reply

Your email address will not be published. Required fields are marked *