無線通信

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.on()

無線通信をオンにします。

MicroPython-on-micro:bit v1.1 以降、radio モジュールをインポートすると、デフォルトで radio がオンになります。以前のリリースでは、必要な時まで消費電力を減らすために、この関数を明示的に呼び出す必要がありました。どちらの場合でも 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 のどちらかを指定します。

注釈

micro:bit V1 では 250kbit/sec の低データレートをサポートしていて、micro:bit V2 でも使える可能性はありますが、すべてのデバイスでの動作を保証するものではありません。この隠し機能を V1 との互換性をのために利用するには、 data_rate の引数に 2 を指定します。

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)を行うために必要な情報を提供するのに便利です。

サンプルコード

# A micro:bit Firefly.
# By Nicholas H.Tollervey. Released to the public domain.
import radio
import random
from microbit import display, Image, button_a, sleep

# Create the "flash" animation frames. Can you work out how it's done?
flash = [Image().invert()*(i/9) for i in range(9, -1, -1)]

# Event loop.
while True:
    # Button A sends a "flash" message.
    if button_a.was_pressed():
        radio.send('flash')  # a-ha
    # Read any incoming messages.
    incoming = radio.receive()
    if incoming == 'flash':
        # If there's an incoming "flash" message display
        # the firefly flash animation after a random short
        # pause.
        sleep(random.randint(50, 350))
        display.show(flash, delay=100, wait=False)
        # Randomly re-broadcast the flash message after a
        # slight delay.
        if random.randint(0, 9) == 0:
            sleep(500)
            radio.send('flash')  # a-ha