こんにちは、ヨシケンです!
自宅を快適に、在宅仕事を効率的にするデバイス作りの第2回です。前回は制作の概要と必要な部品を紹介しました。今回は実際にBluetoothセンサとラズパイをつないでいきます。ローム・センサメダルがあればとても簡単に、リモートでもセンサの値をラズパイに連携することができますよ!
今回の記事で必要な物一覧
Raspberry Pi 3 B+ または Raspberry Pi 4 Model B
ローム・センサメダル(SensorMedal-EVK-002)
モバイルバッテリ
USB機器
100均などで買えるUSBミニライトや扇風機などを使用
今回の記事の流れ
- ローム・センサメダルとラズパイのBLE接続
- ラズパイUSBのコントロール
- センサ値を使ってハードウェアを動かすプログラム
- まとめ
1. ローム・センサメダルとラズパイのBLE接続
前回はローム・センサメダルをとりあえずスマホにつないで、その結果を表示してみました。ここではデータを受信する母艦としてラズパイを使いますので、ラズパイのBluetoothとセンサメダルを接続してみます。
まず、ラズパイのBluetooth接続のためのPythonプログラムbluepyをインストールします。
pi@raspberrypi:~ $ sudo pip3 install bluepy Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting bluepy Downloading https://www.piwheels.org/simple/bluepy/bluepy-1.3.0-cp37-cp37m-linux_armv7l.whl (560kB) 100% |████████████████████████████████| 563kB 608kB/s Installing collected packages: bluepy Successfully installed bluepy-1.3.0
次に、センサメダルとラズパイに電源を入れ、近くに置きます。
センサメダルをBluetooth経由でラズパイにつなぎます。センサメダルからの数値を表示する便利なプログラムがあるので、それをダウンロードします(こちらのGithubを使用させてもらっています)。
pi@raspberrypi:~ $ sudo mkdir Programs pi@raspberrypi:~ $ cd Programs pi@raspberrypi:~ $ sudo git clone http://github.com/bokunimowakaru/SensorMedal2
ダウンロードしたSensorMedal2フォルダに移り、以下のサンプルプログラムを実行します。こちらはPython3でsudo権限を付けて実行する必要があります。
pi@raspberrypi:~ $ cd SensorMedal2 pi@raspberrypi:~ $ sudo python3 ble_logger_SensorMedal2.py
いかがでしょうか?以下のように、とても簡単にセンサメダルからの計測数値をラズパイから見ることができたと思います。
センサメダルには全部で6個のセンサが内蔵されています。それぞれの意味はこのようになっており、様々な数値を計測、取得することができます。
- Temperature: 温度(℃)
- Humidity: 湿度(%)
- Pressure: 気圧(hPa)
- Illuminance: 明るさ(lx)
- Accelerometer: 加速度(x軸、y軸、z軸)(g)
- Geomagnetic: ジャイロセンサ値(x軸、y軸、z軸)(uT)
- Magnetic: ホールセンサ値(もし磁石が近くを通ったら1、そうでない場合0)
- Steps: 歩数(歩)
- Battery Level: バッテリの残量
2. ラズパイUSBのコントロール
とても簡単にセンサの値を取得できたので、これを使ってラズパイにつないだハードウェアをコントロールしてみましょう。
前回記載した「このような機能があったらいいな」から以下を実装してみます。
番号 | 計測機能 | 計測後にあったらいい機能 |
1 | 部屋の温度を測る | 室温に合わせて、扇風機などをコントロール |
2 | 手元の明るさを測る | 暗かったらライトを点ける |
天気の変化や部屋の状況により、明るさが変化します。暗くなってもそのまま作業を続けると目が疲れるので、先ほどのセンサメダルの数値のうち、明るさのIlliminance (lx)を使います。明るさはルクスという単位で表示されます。昼間の部屋の明るさで200〜300ルクスくらいです。
明るさを測定後、手元が暗かったら電気を点けるように、USBで使えるミニライトを使います。このようにラズパイのUSB端子にミニライトを挿します。
明るさに応じてこのライトを点けたり消したりするように、USBをコントロールするライブラリをインストールします。以下のようにライブラリをダウンロード、インストールをおこないます。
pi@raspberrypi:~ $ wget https://www.gniibe.org/oitoite/ac-power-control-by-USB-hub/hub-ctrl.c pi@raspberrypi:~ $ sudo apt-get install libusb-dev pi@raspberrypi:~ $ gcc -o hub-ctrl hub-ctrl.c -lusb
さあ、これでコマンドからUSBに挿したデバイスのON、OFFができるようになりました。このhub-ctrlの使い方は、hub-ctrl -b [Bus Num] -d [Device Num] -P [Port Num] -p [On:1 / Off:0] のようになります。lsusb -tコマンドでデバイス接続情報を取得します。ここでは、Bus num: 1, Device num: 2, USBポートのPort numは2になります。
pi@raspberrypi:~ $ hub-ctrl Hub #0 at 001:002 INFO: individual power switching. WARN: Port indicators are NOT supported. Hub #1 at 001:001 INFO: ganged switching. WARN: Port indicators are NOT supported. pi@raspberrypi:~ $ lsusb -t /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M |__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
以下のように、-pに0を入れると電源オフ、1を入れると電源オンになります。
pi@raspberrypi:~ $ sudo hub-ctrl -b 1 -d 2 -P 2 -p 0 pi@raspberrypi:~ $ sudo hub-ctrl -b 1 -d 2 -P 2 -p 1
3. センサ値からハードウェアを動かすプログラム
それではセンサメダルからの数値とUSBコントロールを紐付けたプログラムを作ります。
基本は先ほどダウンロードしたSensorMedal2プログラムを使います。
pi@raspberrypi:~ $ sudo cp ble_logger_SensorMedal2.py ble_illum.py
元々のプログラムに以下の9行目、78〜85行目の部分を追加します。明るさが300lxを下回ったらライト点灯。それ以上ならライトは消しておきます。
#!/usr/bin/env python3 # coding: utf-8 from __future__ import (division, absolute_import, print_function, unicode_literals) import fcntl import socket import struct import os def get_addr(ifname): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa( fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15].encode('utf-8')))[20:24]) except IOError: return 'Not Found!' interval = 10 # 動作間隔 from bluepy import btle from sys import argv import getpass from time import sleep def payval(num, bytes=1, sign=False): global val a = 0 for i in range(0, bytes): a += (256 ** i) * int(val[(num - 2 + i) * 2 : (num - 1 + i) * 2],16) if sign: if a >= 2 ** (bytes * 8 - 1): a -= 2 ** (bytes * 8) return a scanner = btle.Scanner() while True: try: devices = scanner.scan(interval) except Exception as e: print("ERROR",e) if getpass.getuser() != 'root': print('使用方法: sudo', argv[0]) exit() sleep(interval) continue for dev in devices: print("\nDevice %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)) isRohmMedal = False sensors = dict() for (adtype, desc, val) in dev.getScanData(): print(" %s = %s" % (desc, val)) if desc == 'Short Local Name' and val[0:10] == 'ROHMMedal2': isRohmMedal = True if isRohmMedal and desc == 'Manufacturer': # センサ値を辞書型変数sensorsへ代入 sensors['ID'] = hex(payval(2,2)) sensors['Illuminance'] = payval(25,2) / 1.2 sensors['Battery Level'] = payval(30) sensors['RSSI'] = dev.rssi # 画面へ表示 print(' ID =',sensors['ID']) print(' Illuminance =',round(sensors['Illuminance'],1),'lx') print(' Battery Level =',sensors['Battery Level'],'%') print(' RSSI =',sensors['RSSI'],'dB') ''' for key, value in sorted(sensors.items(), key=lambda x:x[0]): print(' ',key,'=',value) ''' illum = sensors['Illuminance'] if illum < 300: illum_msg = "Dark!" os.system(“sudo hub-ctrl -b 1 -d 2 -P 2 -p 1”) else: illum_msg = "Bright" os.system(“sudo hub-ctrl -b 1 -d 2 -P 2 -p 0”) print(illum_msg) sleep(interval)
このプログラムをsudo python3 ble_illum.pyと流します。
センサの値を取得し、右側の写真のようにセンサメダルを覆って暗くなると、見事ライトが点きました。
4. まとめ
今回は、ローム・センサメダルとラズパイをBLE接続してみました。とても簡単に、離れたところから様々なセンサ値を取得できるのがご理解頂けたのではないかと思います。
6つのセンサにより、明るさだけでなく、温湿度や、気圧、加速度なども分かります。デスクや部屋の中の数値を色々測っても面白いかもしれませんね。
次回は、人感センサなども付けてさらに家でのリモートワークを快適にするような工夫をしていきたいと思います。
お楽しみに!
今回の連載の流れ
第1回:ラズパイとセンサで作る「快適空間自動生成装置」
第2回:ラズパイとセンサで作る「快適空間自動生成装置」(今回)
第3回:ラズパイとセンサで作る「快適空間自動生成装置」
第4回:ラズパイとセンサで作る「快適空間自動生成装置」