SORACOM Air と Raspberry Pi を使って簡易地震計を作ってみた

このエントリーは[ソラコム](https://soracom.jp/)のSoftware Design 誌 [巻頭特集記念リレーブログ](https://blog.soracom.jp/relay-blog/2016-04/)4/29分です。

ソラコムインターンエンジニアの岩瀬です。
熊本地震が記憶に新しいですが、連日のニュース報道で改めて地震の恐ろしさを思い知らされました。
防災という用途においてIoT普及の足がかりになればと考え、今回はSORACOM Air と Raspberry Pi を使った簡易地震計を作成していきます。

## アーキテクチャ

SORACOM Air
--> SORACOM Funnel
--> AWS Kinesis Firehose
--> AWS Elasticsearch Service (Kibanaで可視化)

SORACOM Funnelを利用して、Elasticsearch Service にデータを送り、Kibanaを使ってグラフを描画していきます。

## 準備するもの
* Raspberry Pi B+ (OSインストール済み、SORACOM Airセットアップ済みのもの)
* SORACOM Air 標準サイズ(USBドングルに合わせたサイズを使用)
* USBドングル(FS01BU)
* [加速度センサモジュール　ＬＩＳ３ＤＨ](http://akizukidenshi.com/catalog/g/gK-06791/)
* ジャンパー線(メス4本)、ブレッドボード
* はんだごて、はんだ

完成イメージ：
![asset.JPG](https://qiita-image-store.s3.amazonaws.com/0/47744/42842f54-4cb0-940f-5ec0-de7195cc27a1.jpeg)


SORACOM Airの接続方法に関しては、

* [簡単にRaspberry PiでSORACOM Airを使う(FS01BU USBモデムを用いて自動接続)](http://qiita.com/dietposter/items/068019ee53252206a6bf)
* [Raspberry PiでSORACOM SIMを使う(ZTE MF120, MF112)](http://qiita.com/dietposter/items/068019ee53252206a6bf)

を参考にしてください。

本制作で利用する加速度センサモジュールはI2Cインタフェースに対応しているので、I2C通信を用いてRaspberry Piとのデータのやりとりを行っていきます。

## 加速度センサの取り付け
1.裏面の半田ジャンパーA,B,C と加速度センサモジュールに付属するピンヘッダをそれぞれハンダ付けします。

2.加速度センサを下図のように配線します。

| Raspberry Pi (ピン番号) | 加速度センサー (ピン番号)
|:-----------|:------------|
| Pin01       | PIN01
| Pin03       | PIN04
| Pin05       | PIN03
| Pin09       | PIN10

参考：[３軸加速度センサモジュール　ＬＩＳ３ＤＨ 説明書](http://akizukidenshi.com/download/ds/akizuki/AE-LIS3DH.pdf)

![asset (1).JPG](https://qiita-image-store.s3.amazonaws.com/0/47744/9f97c821-4fa6-f7e5-95bb-8bf5c920ba3b.jpeg)

![asset (2).JPG](https://qiita-image-store.s3.amazonaws.com/0/47744/e94950e9-9461-8cad-ce6f-3241a9b71cac.jpeg)


## I2Cインタフェースからのデータ読み取り
1.I2Cを有効にする
下記のコマンドを実行すると設定画面が表示されるので、

```
$ sudo raspi-config
"8 Advanced Options" -> "A7 I2C" と選択
```

2.i2c-toolsをインストールし、I2Cデバイスが接続されているか確認します。
(この場合は0x18がデバイスアドレス)

```
$ sudo apt-get install i2c-tools
$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --  
```

3.I2C接続の確認をしたあとに、加速度センサをアクティベートします

```
$ sudo /usr/sbin/i2cget -y 1 0x18(デバイスアドレス) 0x0F b
-> 0x33
上記で0x33が返却されれば正しく接続されています。
$ sudo /usr/sbin/i2cset -y 1 0x18(デバイスアドレス) 0x20 0x27 b
```

4.Pythonで加速度データを取得します

```test.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
  
import smbus
import time
import math
  
i2c = smbus.SMBus(1)
address = 0x18

# 平常時のX軸、Y軸の値が0になるように下記の値を修正してください
default_x_a = 25.0
default_y_a = 8.0

def s18(value):
    return -(value & 0b100000000000) | (value & 0b011111111111)

while True:

    x_l = i2c.read_byte_data(address, 0x28)
    x_h = i2c.read_byte_data(address, 0x29)
    x_a = (x_h << 8 | x_l) >> 4
    x_a = s18(x_a)/1024.0*980.0 - default_x_a
    print("X-Value:%6.2f" % (x_a))

    y_l = i2c.read_byte_data(address, 0x2A)
    y_h = i2c.read_byte_data(address, 0x2B)
    y_a = (y_h << 8 | y_l) >> 4
    y_a = s18(y_a)/1024.0*980.0 - default_y_a
    print("Y-Value:%6.2f" % (y_a))

    z_l = i2c.read_byte_data(address, 0x2C)
    z_h = i2c.read_byte_data(address, 0x2D)
    z_a = (z_h << 8 | z_l) >> 4
    z_a = s18(z_a)/1024.0*980.0
    print("Z-Value:%6.2f" % (z_a))

    gal = math.hypot(x_a, y_a)
    print("Gal:%6.2f" % (gal))

    time.sleep(1)
```

```
$ sudo python test.py
Z-Value:980.00
Y-Value: -0.34
X-Value: -0.86
Gal:  0.93
※ 地震の震度を測定するときの目安として使用されるGalという単位を用いています。
```

## SORACOM Funnel のセットアップ
1.AWSコンソールにログインをして、Elasticsearch Service のドメインを作成します。

Amazon Kinesis Firehose が東京リージョンでサポートされていないため、米国(オレゴン)リージョンで作成します。
この際、利用するIAMユーザにAmazonESFullAccessポリシーをアタッチするのを忘れないようにしましょう。

クラメソさんの記事がとてもわかりやすいのでぜひ参考にしてください。
[[新機能]Amazon Elasticsearch Serviceがリリースされました！](http://dev.classmethod.jp/cloud/aws/amazon-elasticsearch-service-released/)

2.Amazon Kinesis Firehose の設定
前述したように、Amazon Kinesis Firehose が東京リージョンでサポートされていないため、米国(オレゴン)リージョンで作成します。

下記の写真のように、設定を行います。
Delivery stream name, Elasticsearch domain は先ほど設定したものを選択してください。
<img width="645" alt="スクリーンショット 2016-04-29 20.20.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/47744/b3288a00-2a05-e328-a18b-ed3e4a186fa9.png">


3.SORACOM Funnelの設定をします
ユーザーコンソールのグループから下記のように、SORACOM Funnelの設定を行います。
<img width="1079" alt="スクリーンショット 2016-04-29 20.37.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/47744/cdb000ad-9f4b-7a39-237f-22c589042700.png">
 
参考：[SORACOM Funnel の Kinesis Firehoseアダプターを使用してクラウドにデータを収集する](https://dev.soracom.io/jp/start/funnel/)

## SORACOM Funnel 経由でデータを送信する

下記のスクリプトを実行することで、SORACOM Funnel 経由で Elasticsearch Service までデータが送信されます。

```send.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import smbus
import time
import datetime
import math
import requests
import json

i2c = smbus.SMBus(1)
address = 0x18
funnel_url = 'http://funnel.soracom.io'

# 平常時のX軸、Y軸の値が0になるように下記の値を修正してください
default_x_a = 25.0
default_y_a = 8.0

def s18(value):
    return -(value & 0b100000000000) | (value & 0b011111111111)

while True:
    x_l = i2c.read_byte_data(address, 0x28)
    x_h = i2c.read_byte_data(address, 0x29)
    x_a = (x_h << 8 | x_l) >> 4
    x_a = s18(x_a)/1024.0*980.0 - default_x_a
    print("X-Value:%6.2f" % (x_a))

    y_l = i2c.read_byte_data(address, 0x2A)
    y_h = i2c.read_byte_data(address, 0x2B)
    y_a = (y_h << 8 | y_l) >> 4
    y_a = s18(y_a)/1024.0*980.0 - default_y_a
    print("Y-Value:%6.2f" % (y_a))

    z_l = i2c.read_byte_data(address, 0x2C)
    z_h = i2c.read_byte_data(address, 0x2D)
    z_a = (z_h << 8 | z_l) >> 4
    z_a = s18(z_a)/1024.0*980.0
    print("Z-Value:%6.2f" % (z_a))

    gal = math.hypot(x_a, y_a)
    print("Gal:%6.2f" % (gal))

    current_time = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    headers = {"Content-Type" :"application/json"}
    body = {
      "x_a": x_a,
      "y_a": y_a,
      "z_a": z_a,
      "xy_gal": gal,
      "created_time": current_time
    }
    r = requests.post(funnel_url, headers=headers, data=json.dumps(body))
    print("StatusCode is:%i" % (r.status_code))

    time.sleep(5)
```

```
$ sudo python send.py
```

Elasticsearch ServiceのメニューからKibanaを開きます。

![スクリーンショット 2016-04-29 20.44.23.jpg](https://qiita-image-store.s3.amazonaws.com/0/47744/d55a2e39-92f4-d121-edcd-7087caa7ca39.jpeg)

データがすでに溜まっているはずなので、VizualizationでGalを試しに表示してみると下記のようなグラフがリアルタイムで表示されます。

![galgal.gif](https://qiita-image-store.s3.amazonaws.com/0/47744/ea3ac348-47c2-155e-6d87-7659058b51aa.gif)

以上で本制作は終了です。

## まとめ
SORACOM Air および SORACOM Funnel を使って地震計のデータ収集から可視化までのプロセスを簡単に解説させていただきました。

今回はRaspberry Pi1台のみで実装しましたが、このようなデバイスを全国各地に置くことで、地震の予知・経過観察などを定量的に行うことができるのではないかと考えています。

また、SORACOM Funnelを使うことで、

* Raspberry PiでSDKをインストールするなどの余計な手間を一切かけずに簡単にデータを可視化することが可能
* AWSの認証情報などもデバイス側で保つ必要がないので、簡単にセキュアな実装ができる

ということがわかっていただけと思います。

今回作った簡易地震計は2,3時間程度で製作することができると思うので、是非興味を持たれた方はチャレンジしてみてください。

質問等あれば気軽にコメントしていただけると嬉しいです！

## 参考にさせていただいたサイト
* [3軸加速度センサーLIS3DHで傾斜を計測記事をクリップする](http://blogs.yahoo.co.jp/jf1vrr_station/26573399.html)
* [【新機能】Amazon Kinesis Firehoseの出力先にAmazon Elasticsearch Serviceが追加されました](http://dev.classmethod.jp/cloud/aws/kinesis-firehose-integration-amazon-es/)
* [Arduino ３軸加速度センサーのI2C接続うまく行きましたー　[Arduino]
](http://makers-with-myson.blog.so-net.ne.jp/2014-03-16)