- ねんがんの Qiita Advent Calendar の記事を 書いたぞ!
-
今年こそは Advent Calendar に参加したいということでネタを探してググっていると、
思いの外、 gazell(import radio のやつ)を取り上げている記事が少ないことに気付きました。 -
ひょっとすると、こんなに便利な機能の良さがあまり認知されていないのでは?
と思い、勢いで「参加する」をクリックし現在に至ります。
おさらい
そもそも Gazell って何ぞ?
-
ハードウェア紹介 の画像にある通り、
micro:bit の無線通信機能は Nordic nRF51822 という SoC が担っています。 -
Gazell は、その Nordic さんの独自無線通信規格です。
Gazell の Bad なところ
下げてから上げる方が良い印象が残りやすいそうなので、まずは残念な点から。
- 独自規格のため、その辺の PC やスマホと通信することはできず、
乱暴に言うと通信するには 2 台以上の micro:bit が必要になります。- この点で micro:bit でも BLE の方が人気が高いのは当然の帰結と言えます。
Gazell の Good なところ
-
めちゃくちゃ手軽に使えます。
- 設計思想が UDP とよく似ており、事前のペアリングなどは無く
いきなり payload を投げます。- そのため、特定の相手に transfer するのではなく、
電波が届く範囲にいる相手に broadcast する動作になります。
- そのため、特定の相手に transfer するのではなく、
- Wi-Fi や Bluetooth など、無線通信と言うと事前の手続きが本当に煩わしく、
コードを順番に追っていくとうんざりしてしまったという方も多いと思いますが、
あまりに簡単に通信が成立してしまうのでびっくりします。
- 設計思想が UDP とよく似ており、事前のペアリングなどは無く
-
MicroPython からでも利用できます。
- BLE は MakeCode Editor でのプログラミングでしか使うことができません。
- MicroPython の処理系を RAM に置くことで、
stack size の大きな BLE は RAM に乗り切らないためです。 - Gazell は simple & small なため、利用できます。
実際のサンプルコード
-
これが全てです。a-ha
- 送信/受信どちらの役割も兼ねているため、
2 台の micro:bit とも同じコードで動くのがナイスですね。
- 送信/受信どちらの役割も兼ねているため、
つくろう
- 2 台の micro:bit でキャッキャするのもたいへん楽しいのですが、
せっかくの機会なので、4 台の micro:bit で 4 x 5 cm リレーをしたいと思います。- 上述の通り、送信は broadcast になるため、
誰が受け取るべき payload かは string の内容によって判断するようにします。
- 上述の通り、送信は broadcast になるため、
import と定数定義
# coding: utf-8
"""
flash :
$ uflash [name].py
"""
from microbit import sleep as msleep
from microbit import button_a as ba
from microbit import button_b as bb
from microbit import display as dp
from microbit import Image
import radio
MEMBERS = 4
MY_ID = 1 # define : 1 ~ MEMBERS
CYCLE_MS = 100
WAIT_MS = 1000
-
MEMBERS は参加する micro:bit の台数です。
-
今回は 4 台の micro:bit を使うので、
MY_ID は 1, 2, 3, 4 としたものを
それぞれの micro:bit に書き込みます。- 上述のサンプルコードにならい、
MY_ID 以外は書き換えなくて良いようにしました。
- 上述のサンプルコードにならい、
GazellRelay クラス
class GazellRelay :
myid = 0
def __init__( self, myid) :
radio.on()
self.myid = myid
def get_id( self) :
return self.myid
def send( self, cmd) :
sendstr = '{}:{}'.format( self.myid + 1, str( cmd))
print( sendstr)
radio.send( sendstr)
def recv( self) :
recvstr = radio.receive()
if recvstr is None :
return None, None
print( recvstr)
items = recvstr.split( ':')
if len( items) != 2 :
return None, recvstr
print( items)
return items
gr = GazellRelay( MY_ID)
- gazell 機能の処理を担当するクラスです。
- 誰向けの payload かを識別するための myid と、
何をするのかの cmd を扱います。
- 誰向けの payload かを識別するための myid と、
micro:bit の周期/イベント処理
def init() :
dp.show( Image.SAD)
def hdr_ba() :
if gr.get_id() == 1 :
dp.show( Image.HAPPY)
gr.send( 'fire')
def hdr_bb() :
pass
def loop() :
r_id, cmd = gr.recv()
if r_id is None :
return
if cmd == 'finish' :
dp.show( Image.HEART)
return # END
if int( r_id) != gr.get_id() :
return # it's not my biz.
if cmd == 'fire' :
msleep( WAIT_MS)
if gr.get_id() != MEMBERS :
dp.show( Image.HAPPY)
gr.send( cmd)
else : # I am anchor :)
dp.show( Image.HEART)
gr.send( 'finish')
if __name__ == "__main__" :
init()
while True :
if ba.is_pressed() :
hdr_ba()
elif bb.is_pressed() :
hdr_bb()
else :
loop()
msleep( CYCLE_MS)
- 最初の 1 台だけAボタンで送信します。
- 残りは順次発火していきます。
実際の動作
こんな感じです。
demo: gazell relay on micro:bit. pic.twitter.com/jPhnbHdyiL
— AndromeDroid (@AndromeDroid) 2018年12月20日
-
直列に配置することで中継器として使うこともでき、
離れた 4 点の気温をリレーして伝えてくるような使い方も
簡単にできます。 -
全体のコードは GitHub に上げました。
- GitHub のものは Tab indent にしています。
最後に
-
micro:bit の生まれ故郷である遠い英国の地では 小学生にあまねく配布されている と聞きます。
- クラス全員でやったら、何台リレーできるんでしょうね?
ドミノチャレンジみたいで楽しそうです。
- クラス全員でやったら、何台リレーできるんでしょうね?
-
私が担任の先生なら「みんな1つずつピタゴラ装置を考えてー」なんて課題を出して
クラス全員でピタゴラスイッチしたら盛り上がるだろうなーと思います。- 伝達遅延も自由に設計できるので、
「止まっちゃった?…あっ動いた」みたいな演出もできますね。
- 伝達遅延も自由に設計できるので、
-
いやー、micro:bit って、本当にいいものですね!
それではまた、ご一緒に楽しみましょう。