無線通信
radio
モジュールにより、デバイスは単純な無線ネットワークを介して連携することができます。
radio モジュールは概念的には非常に単純です:
ブロードキャストメッセージは設定可能な長さ(最大251バイト)です。
受信したメッセージは、設定可能なサイズのキューから読み込まれます(キューが大きいほど、RAM が多く使用されます)。キューが満杯の場合、新しいメッセージは無視されます。読み込んだメッセージは、キューから取り除かれます。
メッセージはブロードキャストされ、あらかじめ選択されたチャネル(0〜83 の番号が付けられています)で受信されます。
ブロードキャストは一定の電力レベルにあります。電力が増えるほど範囲が広がります。
メッセージはアドレス(家の住所のようなもの)とグループ(指定されたアドレスの受取人の名前のようなもの)でフィルタリングされます。
スループットのレートは、3つの事前設定のいずれかになります。
任意のデータを使用するためにバイト列を送受信します。
入ってくるメッセージについて詳細を得るには receive_full を使います: 得られる情報には、データ、受信信号強度、メッセージを受信したタイムスタンプ(ミリ秒単位)があります。
子供たちの便宜のために、メッセージを文字列として送受信するのは簡単です。
デフォルトの設定は、BBC micro:bit をターゲットとする他のプラットフォームと合理的で互換性があります。
このモジュールにアクセスするには、以下を行う必要があります:
import radio
以降の例では、これが行われていることを前提としています。
定数
- radio.RATE_1MBIT
1 MBit/秒のスループットを示すために使われる定数です。
- radio.RATE_2MBIT
2 MBit/秒のスループットを示すために使われる定数です。
- radio.RATE_250KBIT
非推奨 。micro:bit V1ではこのレートを利用可能ですが、V2での動作は保証されません。そのため、互換性の観点から利用は非推奨としました。
関数
- radio.on()
無線通信をオンにします。
micro:bit 用 MicroPython v1.1 より、radio モジュールをインポートすると、デフォルトで無線機能がオンになります。より前のリリースでは、必要となるまで消費電力を削減するために、この関数を明示的に呼び出す必要がありました。v1.1 以降で無線通信の使わないときの消費電力を抑えるには、インポート後に
radio.off()
を呼び出します。
- radio.off()
無線通信をオフにして、電力とメモリを節約します。
- radio.config(**kwargs)
無線通信に関連するさまざまなキーワードベースの設定を構成します。利用可能な設定とその適切なデフォルト値を以下に示します。
length
(デフォルト=32)は、無線を介して送信されるメッセージのバイト単位の最大長を設定します。最大で 251 バイト(254 から S0、長さ、S1 プリアンブルを引いた値)にできます。queue
(デフォルト=3)は、受信メッセージキューに格納できるメッセージの数を指定します。着信メッセージのキューに空きがない場合、着信メッセージは捨てられます。channel
(デフォルト=7)は、無線が同調されている任意の「チャネル」を定義するもので、0 から 83 までの整数値を設定できます。メッセージはこのチャネル経由で送信され、このチャネル経由で受信したメッセージだけが受信メッセージキューに入れられます。各ステップは 1MHz 幅で、2400MHz を基準にしています。power
(デフォルト=6)は、メッセージをブロードキャストするときに使用される信号の強度を示すもので、0 から 7 までの整数値を設定できです。値が高いほど信号は強くなりますが、デバイスが消費する電力が大きくなります。指定の番号は次のリストの dBm (デシベルミリワット)値の位置に変換されます: -30, -20, -16, -12, -8, -4, 0, 4 。address
(デフォルト=0x75626974)は、32 ビットのアドレスとして表される任意の名前であり、ハードウェアレベルで着信パケットをフィルタリングするために使用されます。フィルタリングはユーザーが設定したアドレスと一致するもののみを維持します。他の micro:bit 関連のプラットフォームで使われるデフォルトは、ここで使用されるデフォルト設定です。group
(デフォルト=0)は、8ビットの値(0〜255)であり、address
フィルタしたメッセージで使います。概念的に "address" は自宅/事務所の住所のようなものであり、 "group" はその住所のメッセージを受け取る人のようなものです。data_rate
(デフォルト=radio.RATE_1MBIT)は、データスループットが起こる速度を示しています。radio
モジュールに定義されている以下の定数のいずれかになります:RATE_1MBIT
,RATE_2MBIT
。config
を呼び出さない場合は、上記のデフォルトが仮定されます。
- radio.reset()
設定を既定値にリセットします(上記の
config
関数のドキュメントに記載されています)。
注釈
無線通信がオンになるまで、以下の送受信のメソッドは機能しません。
- radio.send_bytes(message)
バイト列を含むメッセージを送信します。
- radio.receive_bytes()
メッセージキューで次の着信メッセージを受信します。保留中のメッセージがない場合は
None
を返します。メッセージはバイト列として返されます。
- radio.receive_bytes_into(buffer)
メッセージキューで次の着信メッセージを受信します。メッセージを
buffer
にコピーし、必要に応じてメッセージの最後を切り取ります。保留中のメッセージがない場合はNone
を返し、そうでない場合はメッセージの長さを返します(バッファの長さ以上の場合もあります)。
- radio.send(message)
メッセージ文字列を送信します。これは
send_bytes(bytes(message, 'utf8'))
と同等ですが、b'\x01\x00\x01'
を前に付加します(micro:bit をターゲットとする他のプラットフォームと互換性を持たせるためです)。
- radio.receive()
receive_bytes
と同じように動作しますが、送信されてきたものはすべて返します。現在のところ、これは
str(receive_bytes(), 'utf8')
と同等ですが、最初の3バイトがb'\x01\x00\x01'
であることをチェックします(micro:bit をターゲットとする可能性のある他のプラットフォームと互換性を持たせるため)。文字列に変換する前に、先頭に付加された3バイトを削除します。文字列への変換が失敗した場合は、
ValueError
例外が発生します。
- radio.receive_full()
キューにある次のメッセージを表す3つの値のタプルを返します。キューに保留しているメッセージがない場合には
None
を返します。タプルで返す3つの値は次のものです:
キューにある次のメッセージのバイト列。
RSSI (信号強度): dBm で測った信号の強さ。0 が最も強く、-255 が最も弱い。
マイクロ秒単位のタイムスタンプ: メッセージを受信したときの
time.ticks_us()
が返す値。
たとえば、次のように使います:
details = radio.receive_full() if details: msg, rssi, timestamp = details
この関数は、他の micro:bit デバイスとの三角測量(Triangulation)や三辺測量(Triliteration)を行うために必要な情報を提供するのに便利です。
サンプルコード
# micro:bit ホタル。
# 作成者 Nicholas H.Tollervey。パブリックドメインで公開。
import radio
import random
from microbit import display, Image, button_a, sleep
# "発光" (flash)アニメーションフレームを作成。何をしているかわかりますか?
flash = [Image().invert()*(i/9) for i in range(9, -1, -1)]
# イベントループ。
while True:
# ボタンAは "flash" メッセージを送ります。
if button_a.was_pressed():
radio.send('flash') # a-ha
# 受信メッセージを読み込みます。
incoming = radio.receive()
if incoming == 'flash':
# "flash" メッセージを受信したら、ランダムな短い
# 一時停止の後にホタルの発光アニメーションを表示
# します。
sleep(random.randint(50, 350))
display.show(flash, delay=100, wait=False)
# 少し休んだ後に、flash メッセージをランダムに
# 再送信します。
if random.randint(0, 9) == 0:
sleep(500)
radio.send('flash') # それっ