Help us understand the problem. What is going on with this article?

PythonとSensorTag, Kafka, Spark Streamingのストリーム処理 - Part 1: Raspberry Pi 3

More than 3 years have passed since last update.

 このシリーズではRaspberry Pi 3からSensorTagの環境データを取得します。その後にKafkaを経由したSpark Streamingでウィンド分析するPythonのコードを書いてみます。
 
 Raspberry Pi 3のセットアップ方法は多くのサンプルがあります。ここでは簡単にSensorTagの環境データを取得するための準備をします。

用意するもの

 Raspberry Pi 3はWi-FiとBluetoothを内蔵しています。ドングルが不要になり用意するものが減りました。この例ではUSB-A端子がある古いMacBook Pro (macOS Sierra 10.12.6)を開発用端末に使っています。Raspberry Pi 3とEthernet接続する周辺機器を用意します。
 
* USB2.0 有線LANアダプタ
* Ethernetケーブル

 テキサスインスツルメンツのSensorTagはRaspberry Pi 3とBluetooth接続して温度や湿度といった環境データを簡単に取得することができます。
 
* CC2650

macOSでRaspbian Liteイメージを焼く

 オフィシャルのInstalling operating system images on Mac OSの手順に従います。SDカードのデバイス名を確認してunmountします。この例では/dev/disk2です。

$ diskutil list
...
/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.6 GB    disk2
   1:             Windows_FAT_32 NO NAME                 15.6 GB    disk2s1

$ diskutil unmountDisk /dev/disk2

 Raspbian Jessie LiteをダウンロードしてSDカードに焼きます。SSHの有効化も忘れずに行います。

$ cd ~/Downloads
$ wget http://director.downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-07-05/2017-07-05-raspbian-jessie-lite.zip
$ unzip 2017-07-05-raspbian-jessie-lite.zip
$ sudo dd bs=1m if=2017-07-05-raspbian-jessie-lite.img of=/dev/rdisk2
$ touch /Volumes/boot/ssh
$ diskutil unmountDisk /dev/disk2

mDNSでSSH接続する

 macOSはRaspberry Pi 3とEthernetケーブル接続をして簡単にSSHできます。デフォルトでは以下のユーザーが設定されています。

  • username: pi
  • password: raspberry
$ ssh pi@raspberrypi.local

 macOSの公開鍵をRaspberry Pi 3の`~/.ssh/authorized_keys'にコピーします。

$ mkdir -p -m 700 ~/.ssh
$ cat << EOF > ~/.ssh/authorized_keys
ssh-rsa AAAA...
EOF
$ chmod 600 ~/.ssh/authorized_keys

 ログインし直します。

$ exit

無線LAN

 無線LANのアクセスポイント(ESSID)を設定してネットワークを再起動します。pingからインターネット接続を確認します。

$ sudo sh -c 'wpa_passphrase [ESSID] [パスワード] >> /etc/wpa_supplicant/wpa_supplicant.conf'
$ sudo ifdown wlan0
$ sudo ifup wlan0
$ ping -c 1 www.yahoo.co.jp

raspi-config

 raspi-configでパスワードとタイムゾーンを変更します。

$ sudo raspi-config
  • 1 Change User Password
  • 4 Localisation Options
    • I2 Change Timezone
    • Asia > Tokyo

apt-get

 日本のミラーサイトに変更してパッケージを最新にします。ファイルを編集するためにvimをインストールします。

$ sudo sed -i".bak" -e "s/mirrordirector.raspbian.org/ftp.jaist.ac.jp/g" /etc/apt/sources.list
$ sudo apt-get update && sudo apt-get dist-upgrade -y
$ sudo apt-get install vim -y

BluetoothとSensorTag

 SensorTagの電源を入れてRaspberry Pi 3からスキャンします。BDアドレスを確認します。

$ sudo hcitool lescan
...
B0:B4:48:BE:5E:00 CC2650 SensorTag
...

gatttool

 gatttoolコマンドのインタラクティブモードで確認したBDアドレスのSensorTagに接続します。

$ gatttool -b B0:B4:48:BE:5E:00 --interactive
[B0:B4:48:BE:5E:00][LE]> connect
Attempting to connect to B0:B4:48:BE:5E:00
Connection successful
[B0:B4:48:BE:5E:00][LE]>

 Raspberry PiでTI製センサータグ(CC2650)の値を取得してみるを参考にしてセンサーの値を取得します。

  • 0x24(config)に01を書いて有効にする
  • 0x21からバイトを取得する
[B0:B4:48:BE:5E:00][LE]> char-write-cmd 0x24 01
[B0:B4:48:BE:5E:00][LE]> char-read-hnd 0x21
Characteristic value/descriptor: 94 0b f0 0d

 4バイトの値が得られます。SensorTag User Guideによると順番に以下のデータになります。

ObjLSB ObjMSB AmbLSB AmbMSB

 Python REPLから取得した4バイトを摂氏に変換して周辺温度と物体温度を出力します。

>>> raw_data = '94 0b f0 0d'
>>> rval = raw_data.split()
>>> obj_temp = int(rval[1] + rval[0], 16) / 4
>>> amb_temp = int(rval[3] + rval[2], 16) / 4
>>> obj_temp_celcius = obj_temp * 0.03125
>>> amb_temp_celcius = amb_temp * 0.03125
>>> print("周囲温度 : {:.2f} ℃".format(amb_temp_celcius))
周囲温度 : 27.88 
>>> print("物体温度 : {:.2f} ℃".format(obj_temp_celcius))
物体温度 : 23.16 

bluepyのsensortagコマンド

 PythonからBluetooth LEのデバイスを操作するためにbluepyをインストールします。

$ sudo apt-get install python-pip libglib2.0-dev -y
$ sudo pip install bluepy

 sensortagコマンドが使えるようになります。-Tフラグを付けBDアドレスを引数に実行します。

$ sensortag -T B0:B4:48:BE:5E:00

 -Tフラグを指定すると周囲温度、物体温度の順番に取得できます。

Connecting to B0:B4:48:BE:5E:00
('Temp: ', (28.34375, 24.25))
('Temp: ', (28.375, 23.28125))
...

SensorTag

 周囲温度(ambient)と物体温度(object)、湿度(humidy)を取得するPythonのスクリプトを書きます。

~/python_apps/temp.py
# -*- coding: utf-8 -*-
from bluepy.sensortag import SensorTag
import sys
import time

def main():
    argvs = sys.argv
    argc = len(argvs)
    if (argc != 2):
        print 'Usage: # python {0} bd_address'.format(argvs[0])
        quit()
    host = argvs[1]
    print('Connecting to ' + host)

    timeout = 5.0
    count = 3

    tag = SensorTag(host)

    tag.IRtemperature.enable()
    tag.humidity.enable()

    time.sleep(1.0)

    counter = 0
    while True:
        counter += 1
        tAmb, tObj = tag.IRtemperature.read()

        print("温度: 周囲: {0:.2f}, 物体: {1:.2f}".format(tAmb, tObj) )
        humidy, RH = tag.humidity.read()
        print("湿度: humidy: {0:.2f}, RH: {1:.2f}".format(humidy, RH))

        if counter >= count:
           break

        tag.waitForNotifications(timeout)

    tag.disconnect()
    del tag

if __name__ == '__main__':
    main()

 SensorTagのBDアドレスを引数にスクリプトを実行します。

$ python temp.py B0:B4:48:BE:5E:00

 5秒間隔で3回計測した結果を出力します。エアコンが効いてきたので快適になりました。

Connecting to B0:B4:48:BE:5E:00
温度: 周囲: 25.03, 物体: 19.94
湿度: humidy: 25.25, RH: 69.47
温度: 周囲: 25.06, 物体: 20.69
湿度: humidy: 25.25, RH: 69.37
温度: 周囲: 25.06, 物体: 20.69
湿度: humidy: 25.25, RH: 69.37
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away