マイクロビットの無線通信で常に新しい値を取得してみる


マイクロビットの無線通信の受信機側の値の取り扱い方を調べるで、無線通信では、送信側(transmitter)から送信された値は、受信側(receiver)ではキューというデータ構造で扱います。

キューは先入れ先出しのデータ構造で、キューを理解していないと、無線通信で常に欲しい値を得ることができません。


上記の問題を実際のコードで確かめてみます。


transmitter.py

from microbit import *
import radio

display.show(Image.ASLEEP)

radio.config(group=1)
radio.on()

i = 0
while True:
	display.show(Image.YES)
	sleep(500)
	radio.send(str(i))
	i += 1
	display.show(Image.ASLEEP)
	sleep(500)

送信側で1秒毎に数値を 1 ずつ増やした値を送信するプログラムを作成します。


receiver.py

from microbit import *
import radio

display.show(Image.TARGET)

radio.config(group=1)
radio.on()

while True:
	msg = radio.receive()
	print(msg)
	sleep(3000)

受信側では、値を取得した後に3秒待った後に改めて値を取得するという処理を繰り返すプログラムを作成します。

シリアルを表示するで受信側の値を確認してみると、

0
1
2
3
4
5
6
7
8
9
10
11
12
13
15
18
21
24
27
30
33
36
42
45

13までは連番ですが、それ移行は 2 増え、その後は 3 ずつ値が増えていきます。

上記の出力内容で連番になっているのは一見正しそうに見えますが、送信側が 1秒毎に 1 ずつ値を増加に対して、受信側は 3秒毎に取得した値を確認するという処理ですので、15以降の出力から正しい挙動になります。

13まではキューに格納された連番の値の取り出し(デキュー)をしていましたが、キュー内に空きができた時に直近で値を入れる(エンキュー)という処理が開始し、3 ずつ離れた値が格納されるようになります。


上記のような値の取り扱いは電子工作をする上で、常に欲しい値を得られないので意図していない動作(バグ)の発生要因に繋がります。

そこで受信側で常に新しい値を使えるように書き換えてみます。


receiver.py

from microbit import *
import radio

display.show(Image.TARGET)

radio.config(group=1)
radio.on()

while True:
	msg = ""
	while True:
		tmp = radio.receive()
		if tmp == None:
			break
		msg = tmp
	print(msg)
	sleep(3000)

上記のコードでは、


msg = ""
while True:
	tmp = radio.receive()
	if tmp == None:
		break
	msg = tmp

の箇所でキューの中の値が空(Noneが返ってきた時に空になったと判断します)になったことを確認し、その前に得られた値を msg に格納することで常に新しい値を得られるようになりました。


シリアルを表示するで受信側の値を確認してみると、

2
5
8
11
14

のように値が 3 ずつ増えるといった正しい挙動になりました。