ubluetooth --- 低レベル Bluetooth¶
このモジュールは、ボード上の Bluetooth コントローラーへのインターフェースを提供します。現在、これは、セントラル、プリフェラル、ブロードキャスター、オブザーバーのロールで Bluetooth Low Energy(BLE)をサポートしており、デバイスは複数のロールで同時に動作できます。
このAPIは、低レベルの Bluetooth プロトコルに相当するもので、特定のデバイスタイプなどの高レベルの抽象化のビルディングブロックを提供します。
注釈
このモジュールはまだ開発中であり、そのクラス、関数、メソッド、定数は変更される可能性があります。
クラス BLE¶
設定¶
-
BLE.active([active])¶ オプションでBLE無線のアクティブ状態を変更し、現在の状態を返します。
このクラスの他のメソッドを使用する前には、BLE無線をアクティブにする必要があります。
-
BLE.config('param')¶ -
BLE.config(param=value, ...) BLE インターフェイスの設定値を取得または設定します。値を取得するには、パラメーター名を文字列として一度に1つだけ指定します。値を設定する場合には、キーワード構文を使って、一度に1つ以上のパラメーターを設定できます。
現在サポートされている値は次のとおりです:
'mac': Returns the device MAC address. If a device has a fixed address (e.g. PYBD) then it will be returned. Otherwise (e.g. ESP32) a random address will be generated when the BLE interface is made active.注記: ポートによっては、この値にアクセスするのに、(コントローラから MAC アドレスを取得できるように)インタフェースをアクティブにして"おく必要があります
'gap_name': サービス 0x1800、キャラクタリスティック(Characteristic) 0x2a00 で利用する GAP デバイス名を取得/設定します。これはいつでも設定でき、何度も変更できます。'rxbuf': 着信イベントの保存に使用される内部バッファーのサイズをバイト単位で取得/設定します。このバッファは BLE ドライバー全体に対してグローバルであるため、すべてのキャラクタリスティック(Characteristic)を含むすべてのイベントの着信データを処理します。これを増やすと、バーストな受信データ(スキャン結果など)の処理が改善され、セントラル(Central)なロール(Role)がより大きなキャラクタリスティック値を受信できるようになります。
イベント処理¶
-
BLE.irq(handler)¶ BLE スタックからのイベントのコールバックを登録します。 handler に指定するコールバックは二つの引数
event(後述するイベントコードのいずれか)とdata(イベント固有の値のタプル)をとります注記: タプルの
addr,adv_data,char_data,notify_data,uuid項目は、ubluetoothモジュールによって管理されるデータへの参照です(つまり、複数のイベントハンドラー呼び出しで同じインスタンスが再利用されます)。プログラムがハンドラの外部でこのデータを使う場合、まずbytes(addr)またはbluetooth.UUID(uuid)などを使ってこれらのデータをコピーする必要があります。すべてのイベントを処理するイベントハンドラーの例を示します:
def bt_irq(event, data): if event == _IRQ_CENTRAL_CONNECT: # A central has connected to this peripheral. conn_handle, addr_type, addr = data elif event == _IRQ_CENTRAL_DISCONNECT: # A central has disconnected from this peripheral. conn_handle, addr_type, addr = data elif event == _IRQ_GATTS_WRITE: # A central has written to this characteristic or descriptor. conn_handle, attr_handle = data elif event == _IRQ_GATTS_READ_REQUEST: # A central has issued a read. Note: this is a hard IRQ. # Return None to deny the read. # Note: This event is not supported on ESP32. conn_handle, attr_handle = data elif event == _IRQ_SCAN_RESULT: # A single scan result. addr_type, addr, adv_type, rssi, adv_data = data elif event == _IRQ_SCAN_DONE: # Scan duration finished or manually stopped. pass elif event == _IRQ_PERIPHERAL_CONNECT: # A successful gap_connect(). conn_handle, addr_type, addr = data elif event == _IRQ_PERIPHERAL_DISCONNECT: # Connected peripheral has disconnected. conn_handle, addr_type, addr = data elif event == _IRQ_GATTC_SERVICE_RESULT: # Called for each service found by gattc_discover_services(). conn_handle, start_handle, end_handle, uuid = data elif event == _IRQ_GATTC_SERVICE_DONE: # Called once service discovery is complete. # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, status = data elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT: # Called for each characteristic found by gattc_discover_services(). conn_handle, def_handle, value_handle, properties, uuid = data elif event == _IRQ_GATTC_CHARACTERISTIC_DONE: # Called once service discovery is complete. # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, status = data elif event == _IRQ_GATTC_DESCRIPTOR_RESULT: # Called for each descriptor found by gattc_discover_descriptors(). conn_handle, dsc_handle, uuid = data elif event == _IRQ_GATTC_DESCRIPTOR_DONE: # Called once service discovery is complete. # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, status = data elif event == _IRQ_GATTC_READ_RESULT: # A gattc_read() has completed. conn_handle, value_handle, char_data = data elif event == _IRQ_GATTC_READ_DONE: # A gattc_read() has completed. # Note: The value_handle will be zero on btstack (but present on NimBLE). # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, value_handle, status = data elif event == _IRQ_GATTC_WRITE_DONE: # A gattc_write() has completed. # Note: The value_handle will be zero on btstack (but present on NimBLE). # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, value_handle, status = data elif event == _IRQ_GATTC_NOTIFY: # A peripheral has sent a notify request. conn_handle, value_handle, notify_data = data elif event == _IRQ_GATTC_INDICATE: # A peripheral has sent an indicate request. conn_handle, value_handle, notify_data = data elif event == _IRQ_GATTS_INDICATE_DONE: # A central has acknowledged the indication. # Note: Status will be zero on successful acknowledgment, implementation-specific value otherwise. conn_handle, value_handle, status = data
イベントコードには次のものがあります:
from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)
ファームウェアのスペースを節約するために、これらの定数は ubluetooth モジュールには含まれていません 。上記のリストから必要なものをプログラムに追加してください。
ブロードキャスターロール(アドバタイザー)¶
-
BLE.gap_advertise(interval_us, adv_data=None, resp_data=None, connectable=True)¶ 指定された間隔(マイクロ秒単位)でアドバタイジング(Advertising)を開始します。この間隔は、625us に最も近いところで切り捨てられます。アドバタイジングを停止するには interval_us を
Noneに設定します。adv_data と resp_data はバッファプロトコルを実装する任意のタイプにできます(
bytes,bytearray,strなど)。 adv_data はすべてのブロードキャストに含まれ、 resp_data はアクティブスキャンへの返信として送信されます。注記: adv_data (または resp_data)が
Noneの場合、前のgap_advertise呼び出しに渡されたデータが再利用されます。これによりgap_advertise(interval_us)だけで、ブロードキャスターはアドバタイジングを再開できます。アドバタイジングペイロードをクリアするには、空のbytes、すなわちb''を渡します。
オブザーバーロール(スキャナー)¶
-
BLE.gap_scan(duration_ms[, interval_us][, window_us][, active])¶ 指定された期間(ミリ 秒単位)持続するスキャン操作を実行します。
無期限にスキャンするには duration_ms を
0に設定します。スキャンを停止するには duration_ms を
Noneに設定します。オプションでデューティサイクル(duty cycle)を設定するには interval_us と window_us を使います。スキャナは全体の duration_ms ミリ秒の間の interval_us マイクロ秒毎に window_us マイクロ秒間実行します。 interval_us と window_us のデフォルト値はそれぞれ 1.28 と 11.25 です(バックグラウンドスキャン)。
スキャン結果ごとに、
_IRQ_SCAN_RESULTイベントが発生します。イベントデータは(addr_type, addr, adv_type, rssi, adv_data)です。adv_typeの値は次の Bluetooth 仕様に対応しています:- 0x00 - ADV_IND - 接続/スキャン可能な無向アドバタイジング
- 0x01 - ADV_DIRECT_IND - 接続可能な有向アドバタイジング
- 0x02 - ADV_SCAN_IND - スキャン可能な無向アドバタイジング
- "0x03 - ADV_NONCONN_IND - 接続不可能な無向アドバタイジング
- 0x04 - SCAN_RSP - スキャン応答
スキャンの応答を結果として受け取りたい場合は、
activeをTrueにします。スキャンが終了すると(終了時間になったか、明示的に停止した場合)、
_IRQ_SCAN_DONEイベントが発生します。
ペリフェラルロール(GATT サーバー)¶
BLE ペリフェラルには登録されたサービスのセットがあります。各サービスにはキャラクタリスティック(Characteristic)が含まれていることがあり、各キャラクタリスティックは値を持ちます。キャラクタリスティックには、それ自体に値を持つディスクリプタを含めることもできます。
これらの値はローカルに保存され、サービス登録中に生成される「値ハンドル(value handle)」によってアクセスされます。また、リモートのセントラルデバイスから読み書きすることもできます。さらに、プリフェラルは接続ハンドルを介して接続されたセントラルにキャラクタリスティックを「通知(notify)」できます。
キャラクタリスティックとディスクリプタのデフォルト最大サイズは 20 バイトです。セントラルによってそれらに書き込まれたものはすべて、この長さに切り捨てられます。ただし、セントラルから特定のキャラクタリスティックへのより大きな書き込みを許可したくて、ローカル書き込みの最大サイズを大きくするには、登録後に gatts_write を使います。たとえば gatts_write(char_handle, bytes(100)) のようにします。
-
BLE.gatts_register_services(services_definition)¶ 指定したサービスでプリフェラルを構成し、既存のサービスを置換します。
services_definition は サービス のリストであり、各 サービス は UUID と キャラクタリスティック のリストを含む2項目のタプルです。
各 キャラクタリスティック は、UUID、 フラグ 値、およびオプションの ディスクリプタ のリストを含む2または3項目のタプルです。
各 ディスクリプタ は UUID と フラグ 値を含む2項目のタプルです。
フラグ は、後述する値
ubluetooth.FLAG_READ,ubluetooth.FLAG_WRITE,ubluetooth.FLAG_NOTIFYのビット論理和の組み合わせです。戻り値は、タプル(各項目は値ハンドル)のリスト(サービスごとに1項目)です。キャラクタリスティックとディスクリプタのハンドルは、定義された順序で同じタプルにフラット化されます。
次の例では、2つのサービス(心拍数と Nordic UART)を登録します。
HR_UUID = bluetooth.UUID(0x180D) HR_CHAR = (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,) HR_SERVICE = (HR_UUID, (HR_CHAR,),) UART_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E') UART_TX = (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,) UART_RX = (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE,) UART_SERVICE = (UART_UUID, (UART_TX, UART_RX,),) SERVICES = (HR_SERVICE, UART_SERVICE,) ( (hr,), (tx, rx,), ) = bt.gatts_register_services(SERVICES)
3項目のハンドル (
hr,tx,rx) はgatts_read,gatts_write,gatts_notify,gatts_indicateで使えます。注記: サービスを登録する前に、アドバタイジングを停止する必要があります。
-
BLE.gatts_read(value_handle)¶ このハンドルのためのローカル値(
gatts_writeかリモートセントラルで書き込まれたもの)を読み取ります。
-
BLE.gatts_write(value_handle, data)¶ このハンドルのローカル値を書き込みます。これは、セントラルによって読み取ることができます。
-
BLE.gatts_notify(conn_handle, value_handle[, data])¶ 接続されているセントラルにノーティフィケーション要求を送信します。
data を指定すると、その値が通知の一部としてセントラルに送信されます。ローカル値は変更されません。
data を指定しない場合、現在のローカル値(
gatts_writeで設定された値)が送信されます。
-
BLE.gatts_indicate(conn_handle, value_handle)¶ 接続されているセントラルにインディケーション要求を送信します。
注記: このメソッドは現在のところカスタム値の送信をサポートしておらず、常に現在のローカル値(
gatts_writeで設定したもの)を送信します。acknowledgment (あるいはタイムアウトなどの失敗)があった場合、
_IRQ_GATTS_INDICATE_DONEイベントが発生します。
-
BLE.gatts_set_buffer(value_handle, len, append=False, /)¶ 値の内部バッファサイズをバイト数で設定します。これにより、受信可能な最大の書き込みが制限されます。デフォルトは 20 です。
append を
Trueに設定すると、すべてのリモート書き込みが現在の値に置き換えられるのではなく、追加されます。この方法では、最大で len バイトをバッファリングできます。gatts_readを使用すると、読み取り後に値がクリアされます。この機能は、Nordic UART サービスのようなものを実装するときに役立ちます。
セントラルロール(GATT クライアント)¶
-
BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, /)¶ ペリフェラルに接続します。
成功すると
_IRQ_PERIPHERAL_CONNECTイベントが発生します。
-
BLE.gap_disconnect(conn_handle)¶ 指定した接続ハンドルを切断します。
成功すると
_IRQ_PERIPHERAL_DISCONNECTイベントが発生します。接続ハンドルが接続されていなければ
Falseが返り、さもなければTrueが返ります。
-
BLE.gattc_discover_services(conn_handle[, uuid])¶ サービスについて接続されたペリフェラルを問い合わせます。
オプションで照会するサービスの uuid を指定できます。
検出された各サービスについて
_IRQ_GATTC_SERVICE_RESULTイベントが発生し、検索が完了すると_IRQ_GATTC_SERVICE_DONEになります。
-
BLE.gattc_discover_characteristics(conn_handle, start_handle, end_handle[, uuid])¶ 指定した範囲のキャラクタリスティックについて接続されたペリフェラルを問い合わせます。
オプションで照会するキャラクタリスティックの uuid を指定できます。
任意のサービスのキャラクタリスティックを検索するには
start_handle=1,end_handle=0xffffとします。検出された各キャラクタリスティックについて
_IRQ_GATTC_CHARACTERISTIC_RESULTイベントが発生し、検索が完了すると_IRQ_GATTC_CHARACTERISTIC_DONEになります。
-
BLE.gattc_discover_descriptors(conn_handle, start_handle, end_handle)¶ 指定した範囲のディスクリプタについて接続されたペリフェラルを問い合わせます。
検出された各ディスクリプタについて
_IRQ_GATTC_DESCRIPTOR_RESULTイベントが発生し、検索が完了すると_IRQ_GATTC_DESCRIPTOR_DONEになります。
-
BLE.gattc_read(conn_handle, value_handle)¶ 指定したキャラクタリスティックあるいはディスクリプタについて接続されたペリフェラルにリモート読み込みを発行します。
値は有効であれば
_IRQ_GATTC_READ_RESULTイベントが発生し、加えて_IRQ_GATTC_READ_DONEが発生します。
-
BLE.gattc_write(conn_handle, value_handle, data, mode=0, /)¶ 指定したキャラクタリスティックあるいはディスクリプタについて接続されたペリフェラルにリモート書き込みを発行します。
引数 mode は書き込み動作を指定します。現在サポートされている値は次のとおりです:
mode=0(デフォルト)は応答なしの書き込みです。書き込みはリモートペリフェラルに送信されますが、確認は返されず、イベントは発生しません。mode=1は応答付きの書き込みです。リモートプリフェラルはデータを受信したという応答/承認(acknowledgement)を送信するように要求されます。
リモートペリフェラルから応答を受信すると
_IRQ_GATTC_WRITE_DONEイベントが発生します。