概要
M5Stack UIFlow (最新版は 1.7.2) で BLE を使っての、いろいろ接続確認。今回は 新型コロナウイルス接触確認アプリ COCOA を検出します。いくつかあるArduinoでの実装例を参考にしながら、MicroPython での実装です。
- BLE のスキャンを行って COCOA のサービスUUID(0xfd6f) を持つデバイスのアドレスおよび rssi(電波強度) を取得
- rssi の値の降順で表示
- 上記処理を繰り返す
環境
- M5Stack Core2 (UIFlow 1.7.2)
実行結果
プログラム
プログラムの bluetooth 関連の実装は、公式 MicroPython の例 examples/bluetooth を参考にしています。
表示は M5Label を使ってみましたが、プロポーショナルフォントしかないので、今回のような表示には不向きかも。
lcd.print() を使った方が見やすい表示になる気がします。
from micropython import const
from ble.ble_advertising import decode_services
import bluetooth
import ubinascii
import struct
import time
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_ADV_NONCONN_IND = const(0x03)
_COCOA_UUID = bluetooth.UUID(0xfd6f)
class BLECentral:
def __init__(self, ble):
self._ble = ble
self._cocoa_list = {}
self._scanning = False
self._ble.active(True)
self._ble.irq(self._irq)
def _irq(self, event, data):
if event == _IRQ_SCAN_RESULT:
addr_type, addr, adv_type, rssi, adv_data = data
if adv_type == _ADV_NONCONN_IND and _COCOA_UUID in decode_services(adv_data):
self._cocoa_list[ubinascii.hexlify(addr).decode()] = rssi
elif event == _IRQ_SCAN_DONE:
self._scanning = False
def scan(self, duration=2000):
self._cocoa_list = {}
self._scanning = True
self._ble.gap_scan(duration, 30000, 30000)
def cocoa_list(self):
return self._cocoa_list
def is_scanning(self):
return self._scanning
from m5stack import *
from m5stack_ui import *
from uiflow import *
screen = M5Screen()
screen.clean_screen()
screen.set_screen_bg_color(0xFFFFFF)
count_label = M5Label('COCOA Count: ', x=20, y=10, font=FONT_MONT_24, color=0x000, parent=None)
cocoa_count = M5Label('0', x=240, y=10, font=FONT_MONT_24, color=0x000, parent=None)
cocoa_addr = []
cocoa_rssi = []
for i in range(5):
cocoa_addr.append(M5Label('------------', x=20, y=50+35*i, font=FONT_MONT_24, color=0x000, parent=None))
cocoa_rssi.append(M5Label('---', x=240, y=50+35*i, font=FONT_MONT_24, color=0x000, parent=None))
ble = bluetooth.BLE()
central = BLECentral(ble)
for n in range(20):
print('===== scan begin =====', n)
central.scan(3000)
while central.is_scanning():
time.sleep_ms(100)
cocoa_count.set_text(str(len(central.cocoa_list())))
cocoa_list = sorted(central.cocoa_list().items(), key=lambda x:x[1], reverse=True)[:len(cocoa_addr)]
for i, cocoa in enumerate(cocoa_list):
print(i, cocoa[0], cocoa[1])
cocoa_addr[i].set_text(cocoa[0])
cocoa_rssi[i].set_text(str(cocoa[1]))
for i in range(len(cocoa_list), len(cocoa_addr)):
print(i, '------------', '---')
cocoa_addr[i].set_text('------------')
cocoa_rssi[i].set_text('---')
time.sleep_ms(2000)