Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

BLE対応のESP32のRSSIをRaspberry Piで検出する

今回はBLEに対応したESP32のRSSIをRaspberry Piで検出してみたいと思います

開発環境

ESP32

  • micropython
  • WSL(Windows Subsystem for Linux)
  • ESP32開発ボード
  • ESP-idf
  • ampy (書き込みツール)

Raspberry Pi Zero WH(Bluetooth 対応)

  • Raspbian
  • Python3.7
  • pip3

ESP32の設定

今回はWSL内でファイルを書き込みますが,好きな書き込みツールを使用して構いません

対話モードでubluetoothモジュールがあるか確認する

ESP32でBLEを使用するにはubluetoothが必要です.モジュールの有無はhelp('modules')で確認ができます

>>> help('modules')
__main__          framebuf          uasyncio/funcs    upip
_boot             gc                uasyncio/lock     upip_utarfile
_onewire          inisetup          uasyncio/stream   urandom
_thread           machine           ubinascii         ure
_uasyncio         math              ubluetooth        uselect
_webrepl          micropython       ucollections      usocket
apa106            neopixel          ucryptolib        ussl
btree             network           uctypes           ustruct
builtins          ntptime           uerrno            utime
cmath             onewire           uhashlib          utimeq
dht               sys               uhashlib          uwebsocket
ds18x20           uarray            uheapq            uzlib
esp               uasyncio/__init__ uio               webrepl
esp32             uasyncio/core     ujson             webrepl_setup
flashbdev         uasyncio/event    uos               websocket_helper
Plus any modules on the filesystem

もしなければ各自の使用している書き込みツールの方法でubluetoothモジュールをインストールしてください

bluetoothのサンプルプログラムをインストール

''
今回はここからgitにあるmicropythonのソースコードを拝借

git clone  https://github.com/micropython/micropython

などでインストール

Bluetoothのサンプルプログラムは/micropython/examples/bluetooth/ にあります.

今回使用するのはble_advertising.pyble_temperature.pyです
これらをESP32に書き込みます

次にble_temperature.pyを編集します

ble_temperature.py
import bluetooth
import random
import struct
import time
from ble_advertising import advertising_payload

from micropython import const

_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)

# org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
# org.bluetooth.characteristic.temperature
_TEMP_CHAR = (
    bluetooth.UUID(0x2A6E),
    bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,
)
_ENV_SENSE_SERVICE = (
    _ENV_SENSE_UUID,
    (_TEMP_CHAR,),
)

# org.bluetooth.characteristic.gap.appearance.xml
_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)


class BLETemperature:
    def __init__(self, ble, name="beacon1"):
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(handler=self._irq)
        ((self._handle,),) = self._ble.gatts_register_services((_ENV_SENSE_SERVICE,))
        self._connections = set()
        self._payload = advertising_payload(
            name=name, services=[_ENV_SENSE_UUID], appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER
        )
        self._advertise()

    def _irq(self, event, data):
        # Track connections so we can send notifications.
        if event == _IRQ_CENTRAL_CONNECT:
            conn_handle, _, _, = data
            self._connections.add(conn_handle)
        elif event == _IRQ_CENTRAL_DISCONNECT:
            conn_handle, _, _, = data
            self._connections.remove(conn_handle)
            # Start advertising again to allow a new connection.
            self._advertise()

    def set_temperature(self, temp_deg_c, notify=False):
        # Data is sint16 in degrees Celsius with a resolution of 0.01 degrees Celsius.
        # Write the local value, ready for a central to read.

BLETemperatureクラスのdef _init(self, ble, name="mpy-temp")のmpy-tempをbeacon1など分かりやすい名前に変更します
UUIDの指定もこのファイル内でできます

main.pyの編集

ESP32は特に指定のない限り,電源が入るとmain.pyが実行されます
ここにBluetoothの発信し続けるように指定します

main.py
import ble_temperature
ble_temperature.demo()

これをESP32に書き込んだら準備完了です

Raspberry Piの設定

bluepyなどの必要なツールを次のコマンドでインストールします

$ sudo apt install libbluetooth3-dev libglib2.0 libboost-python-dev libboost-thread-dev
$ sudo apt install python3-pip
$ cd /usr/lib/arm-linux-gnueabihf/
$ sudo ln libboost_python-py37.so libboost_python-py34.so
$ sudo pip3 install gattlib
$ sudo pip3 install bluepy
$ sudo systemctl daemon-reload
$ sudo service bluetooth restart

3行目のlibboost_python-py37.soは自身のデバイス内のPython3のバージョンにより異なります

gatlibのインストールが出来ない場合

Rasberry Pi Zeroの低スペックのRasberry Piではgattlibのインストールがスワップファイルが原因で出来ない場合がある(自分がそうでした)ので対処

free -mでスワップファイルの容量を確認すると100MBしかないのでスワップファイルを編集します

$ free -m 
              total        used        free      shared  buff/cache   available
Mem:            875         115         523           8         236         695
Swap:            99           3          96
$ sudo nano /etc/dphys-swapfile

dphys-swapfileCONF_SWAPSIZEを100から800に変更します
次のコマンドでスワップファイルを停止して開始するとスワップファイルが800MBに変更されると思います

$ sudo /etc/init.d/dphys-swapfile stop
$ sudo /etc/init.d/dphys-swapfile start
$ sudo free -m
 total        used        free      shared  buff/cache   available
Mem:            432          37         222           4         172         323
Swap:           799          67         732

これでgatlibのインストールが可能になると思います.

スキャンプログラムでESP32のRSSIの検出

Python3でble_scan.pyを管理者権限で実行

ble_scan.py
import bluepy

scanner = bluepy.btle.Scanner(0)
device = scanner.scan(5)  #5秒間スキャン

for device in device:
  print('======================================================')
  print('address : %s' % device.addr)
  print('addrType: %s' % device.addrType)
  print('RSSI    : %s' % device.rssi)
  print('Adv data:')
  for (adtype, desc, value) in device.getScanData():
    print(' (%3s) %s : %s ' % (adtype, desc, value))

実行結果

======================================================
address : fc:f5:c4:29:05:4e
addrType: public
RSSI    : -60
Adv data:
 (  1) Flags : 06
 (  9) Complete Local Name : beacon1
 (  3) Complete 16b Services : 0000181a-0000-1000-8000-00805f9b34fb
 ( 25) Appearance : 0003
======================================================

↓以下に他のBluetoothデバイス情報をが表示される

先ほど設定したESP32の情報とRSSIデータなどが表示されていると思います.

おわりに

次はRasberryPiとESP32と距離をメートル表記にして表示できるようにしたいですね

参考サイト

Raspberry Pi で bluepy を使ってmicro:bitをコントロール(https://qiita.com/FiveOne/items/ea04b74271da0f382ed6)
BLE対応のESP32用MicroPythonのビルドと書き込み - Ubuntu (Windows Subsystem for Linux)(https://qiita.com/jp-96/items/f5a18e2d10591849bd3d)

cdsl
東京工科大学コンピュータサイエンス学部クラウド・分散システム研究室
https://www.tak-cslab.org/
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