BBC micro:bit MicroPython ドキュメンテーション¶
ようこそ!
The BBC micro:bit is a small computing device for children. One of the languages it understands is the popular Python programming language. The version of Python that runs on the BBC micro:bit is called MicroPython.
このドキュメンテーションには、学校の先生向けのレッスンと開発者向けの API ドキュメンテーションから成っています(左側の目次を参照)。MicroPython を使って BBC micro:bit の開発を楽しんでいただければ幸いです。
プログラミング初心者、学校の先生、どこから始めてよいのかわからない人は、 チュートリアル から始めてください。micro:bit のプログラミングには micro:bit Python エディタ を使ってみてください。
注釈
MicroPython API は MakeCode エディタでは動作しません。MicroPython と MakeCode にある Python は 別のもので互換がない ためです。

BBC micro:bit の MicroPython に関連するプロジェクトには以下があります:
- micro:bit Python エディタ - Micro:bit Educational Foundation が開発しているシンプルなWeb ブラウザベースのコードエディタです。このエディタは学校の先生や学習者が micro:bit を使ったテキストベースのプログラミングを最大限に活用できるように設計されています。
- Mu - 子ども、学校の先生、プログラム初心者向けのシンプルなオフラインコードエディタです。
- uFlash - 素の Python スクリプトを BBC micro:bit に書き込むためのコマンドラインツールです。
はじめに¶
このチュートリアルにしたがってプログラムするにあたっては micro:bit Python エディタ または mu エディタ の利用を勧めます。
micro:bit をコンピュータに USB ケーブルで繋いでください。
エディタウィンドウでスクリプトを書いたら "ダウンロード" ボタンまたは "転送" ボタンをクリックして micro:bit にスクリプトを転送します。
MicroPython またはエディタで何かうまくいかない場合、 support.microbit.org で Micro:bit Educational Foundation チームのサポートを受けられます。
Hello, World!¶
新しい言語を始める伝統的な方法は、コンピュータに "Hello, World!" と言わせることです。

これを MicroPython でするのは簡単です:
from microbit import *
display.scroll("Hello, World!")
各行は何か特別なことを行っています。最初の行:
from microbit import *
... は、BBC micro:bit で実行するのに必要となるすべてものものを入手するよう MicroPython に指示します。すべてのものは microbit
と呼ばれるモジュールの中にあります(モジュールは既存のコードのライブラリです)。なにかを import
するということは、MicroPython にそれを使いたいと伝えることで、*
は すべてのもの を示す Python の方法です。すなわち、 from microbit import *
を日本語にすると「microbit コードライブラリからすべてのものを使用できるようにしてほしい」となります。
2行目:
display.scroll("Hello, World!")
... は、文字列 "Hello, World!" をディスプレイにスクロール表示するよう MicroPython に伝えます。行中の display
部分は microbit
モジュールにある オブジェクト で、デバイスの物理ディスプレイを表します(「オブジェクト」という言葉は「例のあれ」、「あの何か」、「その何か」の代わりに使っています)。ディスプレイに何を行うかを伝えるには句点 .
の後にコマンドのようなもの(実際には メソッド というもの)を付けます。この場合では scroll
メソッドを使っています。scroll
は物理ディスプレイでスクロールする文字列が何であるかを知る必要があるので、括弧内((
と )
)に二重引用符で囲んだものにスクロールするものを指定しています。これは 引数 というものです。したがって、 display.scroll("Hello, World!")
を日本語にすると「テキスト 'Hello, World!' をディスプレイにスクロール表示してほしい」となります。メソッドが引数を一つも必要としない場合は、引数の無い括弧 ()
を使うことでこれを示します。
"Hello, World!" のコードをエディタにコピーして、デバイスに転送してください。表示するメッセージを変更するにはどうすればよいですか? あなたに挨拶させるにはどうすればよいですか? たとえば私の場合だったら "Hello, Nicholas!" と表示させます。これがヒントです。scroll メソッドの引数を変更してみましょう。
警告
変更したらうまく動かなくなるかもしれません。 :-)
この原因を突き止めるのは楽しいことで、MicroPython はこれに役立とうとします。エラーが発生すると、micro:bit のディスプレイにヘルプメッセージがスクロールします。可能であれば、エラーが発生したところの行番号が表示されます。
Python は 正確に コード入力されることを前提にしています。たとえば Python にとって Microbit
, microbit
, microBit
はすべて異なるものです。MicroPython が NameError
という場合は、おそらく何かを不正確に入力しています。これは "Nicholas" と "Nicolas" の違いに似ています。彼らは2人の違う人物ですが、名前は非常に似ています。
MicroPython が SyntaxError
という場合は、単に MicroPython が解釈できないコードを入力しています。 "
や :
といった特殊文字の間違いがないかチェックしてみてください。これはゴルフのパットのようなものです。文中のどこかに止めているものがあります。本来の意図を解釈するのはなかなかに困難です。
microbit の反応が無くなることもあります: こうなると新しいコードをフラッシュすることも、REPL でコマンドを入力することもできません。これが起きてしまったら、電源を入れ直してみてください。つまり、USB ケーブルを抜いて(バッテリーケーブルを繋げているなら、それも抜く)、ケーブルをまた差し込みます。また、コードエディタも一度終わらせて再起動する必要があるかもしれません。
イメージ¶
MicroPython は、5×5 グリッドの赤色 LED (発光ダイオード - デバイスの前面で点灯するもの)を使ってできうる限りのアート機能を提供します。MicroPython はディスプレイ上の非常に多くの制御を提供しているので、あらゆる種類の面白いい効果を作り出すことができます。
MicroPython には、ディスプレイに表示できる多くの内蔵ピクチャがあります。たとえば、デバイスがハッピーに見えるようにするには、次のように入力します。
from microbit import *
display.show(Image.HAPPY)
最初の行が何であるかは既に知っていると思います。2行目は、 display
オブジェクトに内蔵イメージを show
で表示させています。表示させたいハッピーのイメージは Image
に属する HAPPY
というものです。これを括弧内((
と )
)に指定することにより、このイメージの利用を show
に伝えます。

以下は内蔵イメージの一覧です:
Image.HEART
Image.HEART_SMALL
Image.HAPPY
Image.SMILE
Image.SAD
Image.CONFUSED
Image.ANGRY
Image.ASLEEP
Image.SURPRISED
Image.SILLY
Image.FABULOUS
Image.MEH
Image.YES
Image.NO
Image.CLOCK12
,Image.CLOCK11
,Image.CLOCK10
,Image.CLOCK9
,Image.CLOCK8
,Image.CLOCK7
,Image.CLOCK6
,Image.CLOCK5
,Image.CLOCK4
,Image.CLOCK3
,Image.CLOCK2
,Image.CLOCK1
Image.ARROW_N
,Image.ARROW_NE
,Image.ARROW_E
,Image.ARROW_SE
,Image.ARROW_S
,Image.ARROW_SW
,Image.ARROW_W
,Image.ARROW_NW
Image.TRIANGLE
Image.TRIANGLE_LEFT
Image.CHESSBOARD
Image.DIAMOND
Image.DIAMOND_SMALL
Image.SQUARE
Image.SQUARE_SMALL
Image.RABBIT
Image.COW
Image.MUSIC_CROTCHET
Image.MUSIC_QUAVER
Image.MUSIC_QUAVERS
Image.PITCHFORK
Image.XMAS
Image.PACMAN
Image.TARGET
Image.TSHIRT
Image.ROLLERSKATE
Image.DUCK
Image.HOUSE
Image.TORTOISE
Image.BUTTERFLY
Image.STICKFIGURE
Image.GHOST
Image.SWORD
Image.GIRAFFE
Image.SKULL
Image.UMBRELLA
Image.SNAKE
Image.SCISSORS
かなりたくさんあります! 他の内蔵イメージがどのように表示されるかを調べるためにハッピーの micro:bit コードを変更してみませんか? (Image.HAPPY
のところを、上記の内蔵イメージのいずれかに置き換えるだけです。)
自作イメージ¶
もちろん、自分で作成したイメージを micro:bit に表示したいですよね?
それは簡単です。
物理ディスプレイ上の各 LED ピクセルは 10 個の値の1つに設定できます。ピクセルを 0 (ゼロ)に設定するとオフになります。文字通りゼロの明るさになります。ピクセルを 9 に設定すると最も明るいレベルになります。値 1 から 8 はオフ(0
)と最大(9
)の間の明るさのレベルを表します。
以上の情報があれば、次のような新しいイメージを作成することができます:
from microbit import *
boat = Image("05050:"
"05050:"
"05050:"
"99999:"
"09990")
display.show(boat)
(実行すると、デバイスは昔ながらの "Blue Peter" 帆船を表示します。船体よりもマストが暗くなっています。)
絵を描く方法を解明できましたか? 物理ディスプレイの各行が二重引用符で囲まれ、 :
で終わる一連の数字で表されていることに気づきましたか? 各数字は明るさを指定します。5個の数字が5行あるので、物理ディスプレイ上の5行のそれぞれにある5個のピクセルのそれぞれに個別の明るさを指定することができます。これが新しいイメージを作成する方法です。
簡単!
実際のところ、複数の行に分けて書く必要はありません。各行を追えるのであれば、次のように書き直すことができます:
boat = Image("05050:05050:05050:99999:09990")
アニメーション¶
静止したイメージは楽しいですが、それを移動させるのはもっと楽しいです。これを行うもの MicroPython では驚くほど簡単です ~ イメージのリストを使うだけです!
ここに買い物リストがあります:
Eggs
Bacon
Tomatoes
このリストを Python で表現する方法は次のとおりです:
shopping = ["Eggs", "Bacon", "Tomatoes" ]
単に shopping
というリストを作成し、3つの要素を入れました。Python はそれが角括弧 ([
と ]
) で囲まれているので、リストだと分かります。リスト内の要素はカンマ (,
) で区切られ、このインスタンス内の要素は3個の文字列 "Eggs"
, "Bacon"
, "Tomatoes"
となっています。各要素は引用符で囲まれているので、文字列であると分かります。
Python ではリストに任意のデータを格納できます。数値のリストは次のとおりです:
primes = [2, 3, 5, 7, 11, 13, 17, 19]
注釈
数値は(文字列ではなく)単一の値を表すため、引用符で囲む必要はありません。 2
(数値の 2) と "2"
(数字の 2 を表す文字)は違うものです。今のところはよく分からなくても心配要りません。すぐに違いに慣れるでしょう。
同じリストにさまざまな種類のデータを入れることもできます:
mixed_up_list = ["hello!", 1.234, Image.HAPPY]
最後の要素に注目してください。イメージです!
イメージのリストをアニメーション化するよう MicroPython に指示できます。幸いにも既に内蔵イメージのリストがあります。 Image.ALL_CLOCKS
と Image.ALL_ARROWS
です。
from microbit import *
display.show(Image.ALL_CLOCKS, loop=True, delay=100)
単一の画像と同様に、デバイスのディスプレイに表示するには display.show
を使います。しかし、MicroPython には Image.ALL_CLOCKS
の利用を伝えているので、リスト中の各イメージを次々に表示する必要があることを理解します。また、イメージのリストをループするよう(アニメーションが永遠に続くよう) MicroPython に伝えるために loop=True
を指定しています。さらに、各イメージ間の表示間隔を 100 ミリ秒 (0.1 秒)とするために引数 delay=100
を指定しています。
Image.ALL_ARROWS
リストをアニメーション化する方法を考え出せますか? 永遠にループしないようにするにはどうしますか? (ヒント: True
の反対は False
ですが、 loop
引数のデフォルト値は False
です) アニメーションのスピードを変えることができますか?
最後に、自前のアニメーションを作成する方法について説明します。この例では、ボートをディスプレイの底に沈めます:
from microbit import *
boat1 = Image("05050:"
"05050:"
"05050:"
"99999:"
"09990")
boat2 = Image("00000:"
"05050:"
"05050:"
"05050:"
"99999")
boat3 = Image("00000:"
"00000:"
"05050:"
"05050:"
"05050")
boat4 = Image("00000:"
"00000:"
"00000:"
"05050:"
"05050")
boat5 = Image("00000:"
"00000:"
"00000:"
"00000:"
"05050")
boat6 = Image("00000:"
"00000:"
"00000:"
"00000:"
"00000")
all_boats = [boat1, boat2, boat3, boat4, boat5, boat6]
display.show(all_boats, delay=200)
コードの仕組みは次のとおりです:
- 先に説明したのとまったく同じ方法で6個のイメージを作成
- 作成したイメージすべてを
all_boats
というリストに格納 display.show
でリストのイメージを 200 ミリ秒間隔でアニメーション化loop=True
は指定していないので、ボートは一度だけ沈没(すなわちアニメーションは科学的に正確)。:-)
あなたは何をアニメーションにしますか? 特殊効果をアニメーション化できますか? イメージをフェードアウトさせてから再びフェードインするにはどうしますか?
ボタン¶
これまでは、デバイスに何かをさせるコードを作成しました。これは 出力 と呼ばれます。しかし、物事に反応するためのデバイスも必要です。このような事は 入力 と呼ばれます。
これを憶えるの簡単です: 出力はデバイスが世界に出すものであり、入力はデバイスが処理するものです。
micro:bit で入力を行う最も当たり前の手段は、 A
と B
のラベルのついた2個のボタンです。ボタンが押されたことに反応するには MicroPython が必要そうです。
これはとても簡単です:
from microbit import *
sleep(10000)
display.scroll(str(button_a.get_presses()))
このスクリプトの全貌は、1万ミリ秒(すなわち10秒)スリープしている間にボタン A
を押した回数をスクロール表示するというものです。それでおしまい!
これはほとんど役に立たないスクリプトですが、面白い新アイデアをいくつか紹介します:
sleep
関数 は micro:bit を指定のミリ秒数だけスリープさせます。プログラムの実行を一時停止させたいなら、この関数を使うとよいです。関数 は メソッド のようなものですが、 オブジェクト にドットで結びつけられていません。button_a
というオブジェクトがあり、そのget_presses
メソッド で押した回数を得られます。
get_presses
は数値を返し、 display.scroll
は文字だけを表示するので、数値を文字列に変換する必要があります。これを行うのが str
関数です("string" の略 ~ 指定されたものを文字列に変換します)。
3行目はちょっと玉ねぎみたいになってます。括弧が玉ねぎ状になっているので、 display.scroll
が str
を含み、それがまた button_a.get_presses
を含んでいることがわかるでしょう。Python は、最初に最も内側の答えを出し、次の外側に向かって実行していこうとします。これは 入れ子 (nesting)といいます。このようなコードは、ロシアのマトリョーシカ人形の作りと同じです。

あなたがボタンを10回押したとしましょう。Python が3行目で起こっていることをどう処理しているかは以下のとおりです:
Python は行全体を解釈して、 get_presses
の値を求めます:
display.scroll(str(button_a.get_presses()))
Python はボタンが何回押されたかを知ったので、この数値を文字列に変換します:
display.scroll(str(10))
もう、Python は何をスクロール表示するのかが分かりました:
display.scroll("10")
これは大変な作業のように見えるかもしれませんが、MicroPython はこれを非常に高速に行います。
イベントループ¶
何かが起こるのを待つプログラムが必要になることがよくあります。これを行うには、ボタンを押すなどの特定のイベントにどう反応するかを定義するコードの周りにループを作ります。
Python でループを作るために、 while
キーワードを使います。これは何かが True
であるかをチェックします。True
であるなら、ループの 本文 と呼ばれる コードブロック を実行します。そうでない場合は、ループから抜け出し(本文を無視して)、後のプログラムを続行します。
Pythonでは、コードブロックを簡単に定義できます。紙の上に書かれた to-do リストがあるとします。これはたぶん次のようなものになります:
Shopping
Fix broken gutter
Mow the lawn
to-do リストをもう少し具体的にしたいと思ったら、次のように書くかもしれません:
Shopping:
Eggs
Bacon
Tomatoes
Fix broken gutter:
Borrow ladder from next door
Find hammer and nails
Return ladder
Mow the lawn:
Check lawn around pond for frogs
Check mower fuel level
メインタスクがサブタスクに分解されていることが一目瞭然です。メインタスクの下に関連するものがサブタスクとして インデント (字下げ)された構造になっています。つまり Eggs
, Bacon
, Tomatoes
が Shopping
に関連づけられていることは明らかです。インデントすることで、タスクが互いにどのように関連しているかを一目で分かりやすくします。
これは 入れ子 (nesting)と呼ばれます。入れ子を使って次のようなコードブロックを定義します:
from microbit import *
while running_time() < 10000:
display.show(Image.ASLEEP)
display.show(Image.SURPRISED)
running_time
関数は、デバイスが始動してからのミリ秒数を返します。
while running_time() < 10000:
の行は動作時間が1万ミリ秒(すなわち10秒)未満であるかをチェックします。このチェックにとおり、 その実行中に見ていたならば 、イメージ Image.ASLEEP
を表示します。これが、先の to-do リストのように while
文の下にインデントされていることに注目してください。
もちろん、実行時間が 10000 ミリ秒以上になれば、その後の Image.SURPRISED
を表示します。どうしてかって? while
条件は False
になるので(running_time
はもう < 10000
ではありません)、ループが終了し、 while
ループのコードブロックの後のプログラムを続けて実行します。あなたのデバイスは 10 秒間眠ってから、驚いた顔で目を覚まします。
試してみてください!
イベントの処理¶
MicroPython がボタンを押すイベントに反応するようにしたい場合、ボタンが押されたかをチェックする is_pressed
を無限ループの中に入れます。
無限ループは簡単です:
while True:
# 処理の実行
(while
は何かが True
であるかをチェックし、そうであればコードブロックを実行するということを思い返してください。つまり、条件に True
を指定すると明らかに True
であるので、無限ループを実現できるわけです!)
簡単なサイバーペットを作りましょう。あなたが A
ボタンを押している場合を除き、常に悲しい顔をします。あなたが B
ボタンを押すと死にます。(これがとても楽しいゲームではないことが分かりますので、きっとあなたが楽しいゲームにする方法をあみだしてくれることでしょう):
from microbit import *
while True:
if button_a.is_pressed():
display.show(Image.HAPPY)
elif button_b.is_pressed():
break
else:
display.show(Image.SAD)
display.clear()
どのボタンが押されているかをチェックする方法がわかりますか? if
, elif
("else if" の短縮形), else
を使っています。これは 条件文 というもので、次のように処理します:
if 何か is True:
# 何かを行う
elif 他の何か is True:
# 別の何かを行う
else:
# さらに別の何かを行う
これは英語に非常に似ています!
is_pressed
メソッドは2つの結果だけを返します: True
か False
です。ボタンを押している場合は True
を返し、そうでない場合は False
を返します。上記のコードを日本語で表すと「永遠に、ボタン A が押されたら幸せな顔を表示し、ボタン B が押されたらループから抜け、さもなければ悲しい顔を表示します」となります。ループの外に抜ける(永遠に動き続けるプログラムを止める)には break
文を使います。
最後に、サイバーペットが死んで、ディスプレイを clear
します。
このゲームをあまり悲惨なものでなくする方法を考えてみませんか? 両方 のボタンが押されたことをチェックするにはどうしますか? (ヒント: Python には、複数の条件(True
または False
のどちらかを結果とするもの)のチェックを助ける論理演算子 and
, or
, not
があります。
入出力端子¶
BBC micro:bit の下端に沿って金属の端子があります。歯が並んでいるかのように見えるアレです。これは入出力端子というものです(略称 I/O 端子)。

端子のいくつかは他の端子よりも大きいので、ワニ口クリップを取り付けられます。大きい端子には 0, 1, 2, 3V, GND のラベルが付いています(コンピュータは常にゼロから数え始めます)。デバイスにエッジコネクタボードを取り付けると、他の(より小さい)端子にワイヤを結線できるようになります。
MicroPython では、BBC micro:bit の各端子を pinN
という オブジェクト で表します。ここで N
は端子番号です。
たとえば、0 (ゼロ)のラベルの付いた端子で何かを行うには、スクリプトで pin0
というオブジェクトを使います。
これらのオブジェクトには様々な メソッド があり、端子に固有の機能に応じたものが用意されています。たとえば read, write, touch などです。
くすぐったがりな Python (Ticklish Python)¶
端子を介した入力の最も単純な例は、それに触れているかどうかをチェックすることです。micro:bit をくすぐって笑わせてみましょう:
from microbit import *
while True:
if pin0.is_touched():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)
片手で micro:bit の GND 端子を持ちます。次に、もう一方の手で 0 (ゼロ)の端子を触れてください。ディスプレイが心配顔から笑い顔に変わるのを見てください!
これは非常に基本的な入力測定の一つです。しかし、端子を使って回路や他のデバイスを接続すると、もっと楽しいことが始まります。
ブーピー音¶
micro:bit に取り付けられる最も簡単なものは圧電ブザーです。圧電ブザーには2種類あります。最もシンプルなのはアクティブブザーと呼ばれるものです。アクティブブザーには発振器が内蔵されていて、電流を流すと決められた音程で音が鳴ります。パッシブブザーには発振する周波数で音を出すために、発振電流を流す必要があります。つまり、アクティブブザーは使い方が簡単ですが1つの音しか出ず、パッシブブブザーは使い方が少し複雑ですが、さまざまな音を出せます。

ここでは、出力にアクティブピエゾブザーを使います。BBC micro:bit に取り付けるには、下図のようにワニ口クリップを使って端子 0 と GND に接続します。

端子 0 からの線をブザーのプラス側に接続し、GND からの線をマイナス側に接続します。
次のプログラムはブザー音を鳴らします:
from microbit import *
pin0.write_digital(1)
5秒ほどは楽しいかもしれませんが、すぐにうるさくなって音を止めたくなるでしょう。先のプログラムを改善して、デバイスを鳴らしてみましょう:
from microbit import *
while True:
pin0.write_digital(1)
sleep(20)
pin0.write_digital(0)
sleep(480)
このスクリプトの仕組みを理解できますか? デジタルの世界では 1
が「オン」で 0
が「オフ」であることを思い出してください。
デバイスは無限ループに入り、すぐに端子 0 をオンに切り替えます。これによりブザー音が鳴ります。ブザーが鳴っている間、デバイスは 20 ミリ秒間スリープし、端子 0 をオフに切り替えます。これにより短いブザー音を発生させます。最後に、デバイスは 480 ミリ秒間スリープしてから、ループバックして、もう一度やり直します。つまり、1 秒間に 2 回の鳴動(500 ミリ秒ごとに 1 回)が発生します。
私たちは非常に簡単なメトロノームを作ったのです!
ミュージック¶
BBC micro:bit の MicroPython には、強力な音楽とサウンドのモジュールがあります。 スピーカーや有線のヘッドフォンを接続すれば 、デバイスから音を鳴らすのは非常に簡単です。
スピーカーやヘッドフォンを繋ぐには、ワニ口クリップを使って、端子 0 と GND をスピーカー/ヘッドフォンの正と負の入力に接続します。スピーカーの場合はどちらでもかまいませんが、圧電ブザーの場合は極性があるので注意してください(プラス端子に "+" マークがあることを確認してください)。

注釈
アクティブ圧電ブザーでこれを試してはいけません - アクティブ圧電ブザーでは単一の音しか出せません。
音楽を演奏しましょう:
import music
music.play(music.NYAN)
music
モジュールをインポートすることに注意してください。これにはサウンドの作成と制御に使うメソッドが含まれています。
MicroPython には多くの内蔵メロディがあります。ここに完全なリストがあります:
music.DADADADUM
music.ENTERTAINER
music.PRELUDE
music.ODE
music.NYAN
music.RINGTONE
music.FUNK
music.BLUES
music.BIRTHDAY
music.WEDDING
music.FUNERAL
music.PUNCHLINE
music.PYTHON
music.BADDY
music.CHASE
music.BA_DING
music.WAWAWAWAA
music.JUMP_UP
music.JUMP_DOWN
music.POWER_UP
music.POWER_DOWN
先のサンプルコードのメロディーを変更してください。どれがお気に入りですか? このような曲をお知らせの合図としてどのように使いますか?
ヴォルフガング・アマデウス・マイクロビット(Wolfgang Amadeus Microbit)¶
自分の曲を作成するのは簡単です!
各音符には音階名(C#
や F
など)、オクターブ(音の高さ)、持続時間(鳴らす時間)があります。オクターブは数字で示します ~ 0 は最低のオクターブ、4は中位の C を含み、8 は犬のための音楽を作っていない限りは必要ないぐらいに高くなります。持続時間も数字で表されます。持続時間の値が高いほど音を鳴らす時間が長くなります。持続時間の値はお互い関連しています ~ たとえば、持続時間 4
は 持続時間 2
の 2 倍の長さです。音階名 R を使用すると、MicroPython は指定された持続時間だけ、休符(つまり無音)を再生します。
各音符は次のような文字列で表されます。
NOTE[octave][:duration]
たとえば 、"A1:4"
は音階名が A
、オクターブが 1
、持続時間が 4
である音符を指します。
音符のリストを作成してメロディーを作成しましょう(これは、画像のリストでアニメーションを作成するのと同じです)。たとえば、MicroPython が "Frere Jaques" (フランス民謡)の冒頭を演奏するようにする方法は次のとおりです:
import music
tune = ["C4:4", "D4:4", "E4:4", "C4:4", "C4:4", "D4:4", "E4:4", "C4:4",
"E4:4", "F4:4", "G4:8", "E4:4", "F4:4", "G4:8"]
music.play(tune)
注釈
は上記のメロディを簡単にできます。オクターブと持続時間は次に変更するまで値をおぼえています。結果として、上記の例は次のように書き直すことができます:
import music
tune = ["C4:4", "D", "E", "C", "C", "D", "E", "C", "E", "F", "G:8",
"E:4", "F", "G:8"]
music.play(tune)
オクターブと持続時間の値がどの変えているかに注目してください。このほうが入力がずっと簡単で、読むのが簡単です。
音響効果¶
MicroPython では、音符ではないトーンを作成できます。たとえば、警察のサイレン効果を作成する方法は次のとおりです:
import music
while True:
for freq in range(880, 1760, 16):
music.pitch(freq, 6)
for freq in range(1760, 880, -16):
music.pitch(freq, 6)
この例で music.pitch
メソッドがどのように使われているかに注目してください。このメソッドは周波数の指定を期待しています。たとえば、周波数 440
は、交響楽団がチューニングするために使用する調律音 A
と同じです。
上記の例では range
関数を使用して数値の範囲を生成しています。これらの数字は音色のピッチを定義するために使用されます。 range
関数の3つの引数は、開始値、終了値、間隔幅です。したがって、 range
関数を最初に使っているところを日本語で言うと「880 から 1760 までの範囲の数字を 16 間隔で作成する」となります。2 番目に使っている range
では「1760 から 880 の範囲の値を -16 間隔で作成する」となります。これは、サイレンのような音程で上下に変化する周波数の範囲を得る方法です。
サイレンを永遠に続けるために、無限の while
ループで囲います。
重要なのは、 while
ループ内に新しい一連のループ( for
ループ)を入れたことです。この for
ループを日本語で言えば「あるコレクションの各アイテムそれぞれについて何らかのアクティビティを実行する」ということです。具体的には上記の例では「指定された周波数範囲の各周波数に対して、その周波数のピッチを6ミリ秒間再生する」ということです。for
ループの各項目に対して行う処理はインデント(先に説明済み)していますので、Python は個々の項目を処理するコードを正確に認識しています。
ランダム¶
場合によっては、偶然な要素を入れたい、または少し混ぜたいことがあります: デバイスをランダムに動作させたいことがあるでしょう。
MicroPython には random
モジュールがあり、コードに偶然と少し混乱を導入できます。たとえば、ディスプレイ上でランダムな名前をスクロールする方法は次のとおりです:
from microbit import *
import random
names = ["Mary", "Yolanda", "Damien", "Alia", "Kushal", "Mei Xiu", "Zoltan" ]
display.scroll(random.choice(names))
リスト (names
)には、文字列として定義された7つの名前が含まれています。最後の行は 入れ子 になっています(先に紹介した「玉ねぎ」状のことです)。この random.choice
メソッドは names
リストを引数として取り、ランダムに選択された項目を返します。この項目(無作為に選ばれた名前)が display.scroll
の引数になります。
自分の名前を含むようにリストを変更できますか?
乱数¶
乱数は非常に便利です。ゲームでは一般的に使われています。サイコロを使ったりするのも乱数を得るためですよ。
MicroPython には、いくつかの便利な乱数メソッドがあります。シンプルなサイコロを作る方法は次のとおりです:
from microbit import *
import random
display.show(str(random.randint(1, 6)))
デバイスがリセットされるたびに、1 から 6 までの数字が表示されます。入れ子 にも慣れてきたでしょうが、 random.randint
は2つの引数の間の整数を返します。 display.show
は文字の引数を期待しているので、 str
関数を使用して数値を文字に変換します(たとえば 6
を "6"
に変換します)。
0
から N
までの数字が欲しいこともあると思いますが、そのようなときには random.randrange
メソッドを使います。このメソッドに単一の引数 N
を与えると、0 から N
未満の乱数を整数で返します(これは "random.randint
の振舞いと違っています)。
場合によっては小数点以下の数字が必要になることがあります。これは 浮動小数点数 と呼ばれ、そのような数値を random.random
メソッドで生成できます。これは 0.0 から 1.0 の間の値を返すだけです。より大きなランダムな浮動小数点数が必要な場合は、以下のように random.randrange
と random.random
の結果を加算するとよいです:
from microbit import *
import random
answer = random.randrange(100) + random.random()
display.scroll(str(answer))
混沌の種(Seeds of Chaos)¶
コンピュータで使われている乱数生成器は本当にランダムではありません。開始シード値を与えられた結果のようにランダム値を生成します。シード値の生成には、現在時刻やチップ内に内蔵されている温度計などのセンサー値のようなランダム性のあるものを使うこと多いです。
反復可能なランダム性、すなわち再現性のある乱数発生が欲しいこともあります。サイコロを投げるたびに同じ5つのランダムな値が必要であるようなことです。
これはシード値を設定することで簡単に実現できます。既知のシードが与えられると、乱数ジェネレータは同じ乱数セットを作成します。シードは random.seed
に任意の整数を指定します。以下バージョンのサイコロプログラムは常に同じ結果を生成します:
from microbit import *
import random
random.seed(1337)
while True:
if button_a.was_pressed():
display.show(str(random.randint(1, 6)))
このプログラムが最初のサイコロの例のようにデバイスをリセットする代わりに、ボタン A を押すようにしているのはなぜでしょう?
動きの検知¶
BBC micro:bit には加速度センサーがついています。これは 3 軸に沿った動きを測定します:
- X - 左右の傾き
- Y - 前後の傾き
- Z - 上下の動き
各軸についてミリg単位の測定結果を正または負の数を返すメソッドがあります。読み取り値が 0 の場合は、その特定の軸に沿って「水平」になっているということです。
たとえば、X 軸に沿ってどのくらいの動きかを測定するために get_x
を使う、非常にシンプルな判定プログラムは以下のようになります:
from microbit import *
while True:
reading = accelerometer.get_x()
if reading > 20:
display.show("R")
elif reading < -20:
display.show("L")
else:
display.show("-")
デバイスを水平にしておくと -
を表示します。しかし、左右に傾けるとそれぞれ L
と R
を表示します。
デバイスが絶えず変化に反応するように、無限 while
ループを使います。 ループの本体内で 行っている最初のことは X 軸に沿った測定で、結果を reading
としています。加速度センサーはとても感度が高いので、+/-20 レベルを検知の幅としました。これが if
と elif
の条件式で > 20
と < -20
をチェックしている理由です。 else
文は reading
が -20 と 20 の範囲内なら水平とみなすことを意味します。これらの条件のそれぞれについて、適切な文字を表示するためにディスプレイを使っています。
Y軸のための get_y
メソッドと Z 軸のための get_z
メソッドもあります。
スマートフォンの縦横で表示が切り替わるのは、上のプログラムと同じように加速度センサーを使っているからです。また、ゲームコントローラーの中には、ゲームでの操作や移動を支援するために加速度センサーが含まれているものもあります。
ミュージカル・メイヘム(Musical Mayhem)¶
BBC micro:bit の MicroPythonの の最も素晴らしい点の1つは、デバイスのさまざまな機能を簡単にリンクする方法です。たとえば、楽器(のようなもの)に変えてみましょう。
ミュージックのチュートリアルのようにスピーカーを接続します。ワニ口クリップを使用して、端子 0 と GND をスピーカーの正と負の入力に接続します。スピーカーにどのように接続するかは関係ありません。

加速度センサーからの値をピッチとして演奏するとどうなりますか? 確認してみましょう:
from microbit import *
import music
while True:
music.pitch(accelerometer.get_y(), 10)
問題の行は最後にありますが、非常に簡単です。 music.pitch
メソッドに渡す周波数として Y 軸の読込みを 入れ子 にしています。デバイスが傾けられたときに音色をすばやく変更したいので、10ミリ秒間だけ再生させます。デバイス操作は無限 while
ループにあるので、Y 軸測定の変化にすぐに反応します。
これでおしまい!
デバイスを前後に傾けます。Y 軸に沿った読み取り値が正の場合、マイクロビットで演奏される音のピッチが変わります。
これらのデバイスを使った楽団を想像してみてください。あなたは曲を演奏できますか? micro:bit のサウンドをより楽器らしくするためにプログラムをどう改善しますか?
ジェスチャー¶
加速度センサーを持つことの実に興味深い副作用はジェスチャーの検出です。BBC micro:bit を特定の手段(ジェスチャー)で動かすと、MicroPython はこれを検出できます。
MicroPythonは、次のジェスチャーを認識することが可能です: up
, down
, left
, right
, face up
, face down
, freefall
, 3g
, 6g
, 8g
, shake
。ジェスチャーは常に文字列として表されます。名前でほとんどのものは明らかですが、ジェスチャー 3g
, 6g
, 8g
は、デバイスが(宇宙飛行士が宇宙に打ち上げされたときのような) g 力のこれらのレベルを受けたことを検出します。
現在のジェスチャーを取得するには、 accelerometer.current_gesture
メソッドを使います。その結果は上に挙げた名前のジェスチャーの1つになるでしょう。たとえば、以下のプログラムを使用すると、デバイスが表向きの場合にのみデバイスがハッピーになります。
from microbit import *
while True:
gesture = accelerometer.current_gesture()
if gesture == "face up":
display.show(Image.HAPPY)
else:
display.show(Image.ANGRY)
前にもやったように、デバイスが変化する状況に対応させるために while
ループを使います。ループの スコープ 内で、現在のジェスチャーが読み込まれて gesture
に入ります。 if
条件は gesture
が "face up"
であるかをチェックします(Python では等価性の検査に ==
を使い、単一の等価記号 =
は代入に使います - ちょうどジェスチャーを読んで gesture
に代入しているように)。ジェスチャーが "face up"
であれば、ディスプレイを使ってハッピーな顔を表示します。それ以外の場合、デバイスは怒って見えるようになります!
マジック8¶
マジック8ボールは 1950 年代に最初に発明されたおもちゃです。遊び方はイエス/ノーの質問をして、マジック8ボールを振り、真実を明らかにするのを待つことです。これをプログラムに変えるのは簡単です:
from microbit import *
import random
answers = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful",
]
while True:
display.show("8")
if accelerometer.was_gesture("shake"):
display.clear()
sleep(1000)
display.scroll(random.choice(answers))
プログラムのほとんどは、 ansawers
というリストです。実際のゲームは最後の while
ループです。
ゲームのデフォルト状態は文字 "8"
を表示することです。しかし、プログラムはそれが揺れているかどうかを検出する必要があります。was_gesture
メソッドはその引数にしたがい(この場合、ゆさぶっていることを検出したいので、文字列 "shake"
を指定しています)、 True
/ False
の応答を返します。デバイスを振った場合、 if
条件のコードブロックに入り、画面をクリアし、1 秒間待って(デバイスがあなたの質問について考えているように見える)、無作為に選択された回答を表示します。
これが今までに書かれた最高のプログラムかを、このプログラム自身に聞いてみませんか? 「ズル」をして答えを常にポジティブまたはネガティブな回答にするにはどうすればよいですか? (ヒント: ボタンを利用)
方角の検知¶
BBC micro:bit にはコンパスがついています。気象観測を行ったことがあるなら、風向きを調べるのにこのデバイスを利用できます。
コンパス¶
以下のプログラムは北の方角を教えてくれます:
from microbit import *
compass.calibrate()
while True:
needle = ((15 - compass.heading()) // 30) % 12
display.show(Image.ALL_CLOCKS[needle])
注釈
測定値を得る前にコンパスの調整が必要です。 そうしないと不正な結果が出ます。 calibration
メソッドは楽しいミニゲームを実行し、その中で地球の磁場と関連するようデバイスを補正します。
コンパスを調整するには、ピクセルの円がディスプレイの外縁に描かれるまで micro:bit を傾けます。
プログラムは compass.heading
の値をとり、シンプルながらも巧妙に 床除算(floor division) //
と 剰余(modulo) %
を使って画面に表示するクロックの数字を計算し、おおよその北を指すように表示します。
ストレージ¶
有用な情報を保存しなければならないこともあります。そのような情報はそれを表現するデータとして保存します(コンピュータに保存されるときのデジタル形式)。コンピュータにデータを保存すると、デバイスの電源を入れ直してもデータは保持されます。
幸い micro:bit の MicroPython では非常に単純なファイルシステムでこれを行うことができます。メモリの制約のため、ファイルシステムで 利用可能な容量は約 30KB となっています。
注釈
micro:bit を PC に繋いだときに USB ドライブとして現れるマスストレージモードと micropython ファイルシステムを混同しないでください。マスストレージモードは HEX ファイル全体をコピーするためのものなので、MICROBIT ドライブのファイルシステム上ではファイルを作れません。
ファイルシステムとは何か?
ファイルシステムとは、データを永続的に格納・編成する手段です。ファイルシステムに格納されたデータは、デバイスの再起動後も残っている必要があります。名前が示すように、ファイルシステムに格納されたデータはファイルに編成されます。

コンピュータのファイルは、ファイルシステムに格納された名前付きのデジタルリソースです。そのようなリソースには、有用な情報がデータとして含まれています。これは、紙のファイルの仕組みとまったく同じです。それは有益な情報を含む一種の名前付きコンテナです。通常、紙でもデジタルでもファイルには名前が付けられています。コンピュータでは .something
のような接尾辞をファイル名の終わりにつけるのが一般的です。通常、"something" は情報を表すために使用されるデータのタイプを示します。たとえば .txt
はテキストファイル、 .jpg
は JPEG 画像、 .mp3
は MP3 としてエンコードされたサウンドデータを示します。
(ラップトップや PC のように)ファイルシステムによっては、ファイルをディレクトリにまとめることができます。これは名前付きびコンテナであり、関連するファイルとサブディレクトリをまとめてグループ化します。ただし、 MicroPython が提供するファイルシステムはフラットファイルシステムです 。フラットファイルシステムにはディレクトリがありません。すべてのファイルは同じ場所に保存されます(訳注: MicroPython がフラットファイルシステムであるという制限はあくまで BBC micro:bit での話です)。
Python プログラミング言語は、コンピュータのファイルシステムを操作するための使いやすく強力な方法を提供しています。micro:bit の MicroPython は、これらの機能の便利なサブセットを実装して、デバイス上のファイルを簡単に読み書きできるようにしています。また、他のバージョンの Python との一貫性も提供します。
警告
micro:bit にプログラムを転送すると、デバイスによって使用されるすべてのフラッシュメモリが書き換えられます。ファイルシステムがフラッシュメモリに再設定されるため、すべてのデータが破棄されてしまいます。
ただし、デバイスの電源を切っただけではデータはそのまま残り続けます。データが消えるのは、ファイルを削除するか、デバイスを再フラッシュした場合です。
開けゴマ(Open Sesame)¶
ファイルシステム上でのファイルの読み書きは、 open
関数によって実現されます。ファイルを開いたら、それを閉じるまでファイルの中身をいじれます(紙ファイルの使用方法に似ています)。ファイル作業の完了を MicroPython に知るには、ファイルを閉じることが不可欠です。
これを行う最も良い方法は、次のように with
文を使うことです:
with open('story.txt') as my_file:
content = my_file.read()
print(content)
with
文は、open
関数でファイルを開き、開いたファイルをオブジェクトに割り当てます。上記の例では、 open
関数が story.txt
(明らかに何らかのストーリーを含むテキストファイル)というファイルを開きます。Python コードでファイルを表現するために使われるオブジェクトには my_file
という名前をつけています。その後、 with``文の下にインデントされたコードブロックで、 ``my_file
オブジェクトは read()
で内容を読み出され、読み出された内容は content
に代入されます。
重要な点は次の行の print
がインデントされていないことです。with
文に関連付けられたコードブロックは、ファイルを読み取る単一の行だけです。 with
文に関連付けられたコードブロックを抜けると、Python (および MicroPython)によって自動的にファイルが閉じられます。これはコンテキスト処理と呼ばれ、 open
関数はファイルのためのコンテキストハンドラを作成します。
簡単に言えば、ファイルとのやりとりの範囲は、ファイルを開いた with
文に関連付けられたコードブロックによって定義されます。
混乱してますか?
心配しないでください。コードは次のようになパターンになるというだけです:
with open('ファイル名') as some_object:
# with 文のこのコードブロック内で
# some_object をいじれます
# ブロックを抜けると MicroPython が
# 自動でファイルをクローズしてくれます
紙ファイルと同様にに、デジタルファイルは2つの理由で開きます。1つは(上に例示したように)ファイルの内容を読むこと、もう1つはファイルに何かを書き込むことです。デフォルトのモードはファイルを読むことです。ファイルに書き込む場合 open
関数には、次のように関数に指示する必要があります。
with open('hello.txt', 'w') as my_file:
my_file.write("Hello, World!")
この 'w'
引数は、 my_file
オブジェクトを書込みモードに設定するために使います。 'r'
引数でファイルオブジェクトを読み取りモードに設定することもできますが、これはデフォルトなので、省略することが多いです。
ファイルへのデータの書き込みには(推測どおりかもしれませんが) write
メソッドを使います。ファイルに書き込む文字列を引数に指定します。上の例では、 "hello.txt" というファイルに "Hello、World!" というテキストを書き込んでいます。
簡単!
注釈
ファイルを開いて書き込むとき、ファイルがすでに存在する場合はファイルの内容を上書きします。
ファイルにデータを追加するには、最初にそれを読み出し、読み出した内容をどこかに保持し、ファイルを閉じ、読み込んだ内容にデータを追加して、再度ファイルを開いて、改訂した内容を書き直す必要があります。
これは MicroPython の場合ですが、 "通常の" Python では "append" モードで書き込むファイルを開くことができます。micro:bit でこれを行うことができないのは、ファイルシステムの実装を簡略化したためです。
OS SOS¶
Python には、ファイルの読み書き以外にもできるファイル操作があります。ファイルシステム上に何のファイルがあるかを知る必要があるでしょうし、またそれらを削除が必要になることもあるでしょう。
通常のコンピュータにおいて、オペレーティングシステム(Windows, OSX, Linuxなど)の役割は Python などのためにこのような管理をすることです。このような機能は Python では os
というモジュールを介して利用できます。MicroPython はオペレーティングシステム でもある ため、 os
モジュールの適切な機能を一貫性のあるものに保つことにしました。そのため、ラップトップや Raspberry Pi のようなデバイスで「通常の」Python を使う場合と同様の操作があります。
基本的に、ファイルシステムに関連する3つの操作、つまりファイルの一覧表示、ファイルの削除、ファイルのサイズの確認を行うことができます。
ファイルシステム上のファイルを一覧表示するには、 listdir
関数を使用します。これはファイルシステム上のファイルのファイル名を示す文字列のリストを返します:
import os
my_files = os.listdir()
ファイルを削除するには、 remove
関数を使用します。これは削除するファイルのファイル名を表す文字列を引数として指定します:
import os
os.remove('filename.txt')
最後に、ファイルを読む前にファイルの大きさを知ることが有用な場合もあります。これを行うには、 size
関数を使用します。 remove
関数と同様に、サイズを知りたいファイルのファイル名を表す文字列を指定します。この関数はファイルが占めるバイト数を示す整数を返します:
import os
file_size = os.size('a_big_file.txt')
ファイルシステムを操作するのはよいのですが、デバイスにファイルを出し入れする場合はどうしたらよいでしょうか?
microfs
ユーティリティを使うだけです!
ファイル転送¶
BBC micro:bit のプログラミングに使うコンピュータに Python がインストールされているなら、microfs
という特別なユーティリティを使えます(コマンドラインで使うときには ufs
と短縮した名前を使います)。microfs のインストールと利用について詳しい手順は microfs のドキュメンテーション を参照してください。
ここでは、ほとんどこれだけで用が足りるという4つの基本コマンドだけを説明します:
$ ufs ls
story.txt
ls
サブコマンドは、ファイルシステム上のファイルの一覧表示します(同じ機能を提供する一般的な Unix コマンド ls
にちなんで名付けられています)。
$ ufs get story.txt
get
サブコマンドは、接続した micro:bit からファイルを取得し、コンピュータの現在の場所に保存します(同じ機能を提供する一般的なファイル転送プロトコル [FTP] のコマンド get
にちなんで名付けられています)。
$ ufs rm story.txt
rm
サブコマンドは、接続した micro:bit から指定の名前のファイルを削除します(同じ機能を提供する一般的な Unix コマンド rm
にちなんで名付けられています)。
$ ufs put story2.txt
put
サブコマンドは、コンピュータから接続されたデバイスにファイルを置きます(同じ機能を提供する一般的なファイル転送プロトコル [FTP] のコマンド put
にちなんで名付けられています)。
注釈
ufs の get と put コマンドは、一度に1つのファイルに対してのみ動作します。
主役 main.py¶
ファイルシステムには興味深いプロパティがあります: MicroPython ランタイムだけをデバイスに転送した後で起動すると、何かを行うことを待っているだけです。ただし、 main.py
という特別なファイルをファイルシステムにコピーして、デバイスを再起動すると、MicroPython はその main.py
ファイルの内容を実行します。
さらに、他の Python ファイルをファイルシステムにコピーすると、他の Python モジュールと同様にそれを import
できます。たとえば次の単純なコードを含むファイル hello.py
があったとします。
def say_hello(name="World"):
return "Hello, {}!".format(name)
これを次のようにインポートして say_hello
関数を使えます:
from microbit import display
from hello import say_hello
display.scroll(say_hello())
もちろん、 "Hello、World!" というテキストが表示されます。重要な点は、この例では2つの Python モジュールに分割され、 import
文がコードを共有するために使われていることです。
注釈
MicroPython ランタイムに加えてデバイスにスクリプトを転送した場合、MicroPython は main.py
無視して、代わりに埋め込みスクリプトを実行します。
ランタイムだけを転送するには、エディタで作成したスクリプトに何も文字が含まれていないことを確認するだけです。転送されると、main.py" ファイルをコピーすることができます。
音声¶
コンピュータやロボットが話せれば、より「人間」らしくなるでしょう。
グラフィカルユーザーインターフェイス(GUI)を通してコンピュータで何をするかを学ぶことが多いと思います。BBC micro:bit の場合、GUI は 5×5 の LED マトリックスであり、望まれる多くのことを捨てています。
micro:bit を話せるようにすることは、楽しく、効率的で、有用な方法で情報を表現する方法の1つです。この目的のために、私たちは、1980 年代初めのシンセサイザーのリバースエンジニアリングバージョンに基づく簡単な音声合成装置を統合しましたサウンドは "all humans must die" みたいな感じでとてもキュートです(訳注: この章は、イギリスのTVシリーズ「Doctor Who」を知らないと分からないネタばかりです)。
以上を念頭に置いて、音声シンセサイザを使っていくことにしましょう ...
DALEK の詩¶

DALEK が詩、特にリメリック(滑稽五行詩)を楽しむことはちょっと知られています。DALEK は厳格な AABBA 形式の弱強格韻脚でワイルドになります。誰が考えたのでしょうか?
(実際には、以降で学ぶように、DALEK がリメリックを好きなのはドクターの仕業であり、ダブロス博士の悩みの種です)
いずれにしても、必要に応じて DALEK の詩のリサイタルを作成する予定です。
何か言わせてみる¶
デバイスが話せるようにする前に、以下のようにスピーカーを接続する必要があります:

デバイスに話させる最も簡単な方法は、次のように speech
モジュールをインポートして、 say
関数を使うことです:
import speech
speech.say("Hello, World")
これでもキュートですが、DALEK のレベルとしては十分でないので、音声合成装置が音声を生成するために使ういくつかのパラメータを変更する必要があります。音声シンセサイザは、この点で非常に強力です。なぜなら、4つのパラメータを変更できるからです:
pitch
- 音声の高低s (0 = 高, 255 = Barry White)speed
- デバイスが話す速度 (0 = impossible, 255 = bedtime story)mouth
- 音声の発音の不明瞭または明瞭の程度 (0 = 腹話術師の人形, 255 = Foghorn Leghorn)throat
- 声の調子のリラックスまたは緊張の程度 (0 = falling apart, 255 = totally chilled)
まとめると、これらのパラメータは音の質を制御します。正直言って、望む声の音を得る最良の方法は、実験を繰り返して調整することです。
設定を調整するには、それらを say
関数の引数として渡します。詳細は speech
モジュールの API ドキュメンテーションを参照してください。
何回かの実験の後、以下でかなり DALEK 風の音声になりました。
speech.say("I am a DALEK - EXTERMINATE", speed=120, pitch=100, throat=100, mouth=200)
詩オンデマンド(Poetry on Demand)¶
サイボーグである DALEK はロボットの能力を使って詩を作っています。彼らが使うアルゴリズムは Python で次のように書かれています:
# DALEK の詩の自動作成プログラム(著者:ドクター)
import speech
import random
from microbit import sleep
# テンプレートに挿入する断片をランダムに選びます
location = random.choice(["brent", "trent", "kent", "tashkent"])
action = random.choice(["wrapped up", "covered", "sang to", "played games with"])
obj = random.choice(["head", "hand", "dog", "foot"])
prop = random.choice(["in a tent", "with cement", "with some scent",
"that was bent"])
result = random.choice(["it ran off", "it glowed", "it blew up",
"it turned blue"])
attitude = random.choice(["in the park", "like a shark", "for a lark",
"with a bark"])
conclusion = random.choice(["where it went", "its intent", "why it went",
"what it meant"])
# 詩のテンプレート。名前をつけた断片で {} を置き換えます
poem = [
"there was a young man from {}".format(location),
"who {} his {} {}".format(action, obj, prop),
"one night after dark",
"{} {}".format(result, attitude),
"and he never worked out {}".format(conclusion),
"EXTERMINATE",
]
# ループで詩の各行を先頭から見て行き、speech モジュールを使って暗唱します
for line in poem:
speech.say(line, speed=120, pitch=100, throat=100, mouth=200)
sleep(500)
コメントが示すように、デザインは非常にシンプルです:
- 予め定義された言葉のリストから、ランダムに名前つき断片(location、prop、attitudeなど)が生成されます。
random.choice
を使って、リストから単一の項目を選んでいることに注目してください。 - 詩のテンプレートは、その中に「穴」(
{}
で表現)のある節のリストとして定義されています。この穴にformat
メソッドを使って名前つき断片を埋めます。 - 最後に、Python は、埋め込まれた詩の節のリストの各項目をループして
speech.say
を使って DALEK の声で詩を暗唱します。DALEK でも息をする必要があるので、500 ミリ秒の休止を各行の間に挿入しています。
興味深いことに、当初の詩の関連ルーチンはダブロス博士によって FORTRAN (すべて英大文字でタイプする DALEK の標準言語)で書かれました。しかし、ダブロス博士の 単体テスト パスと デプロイパイプライン の間のポイントにドクターが正確に時を戻して、その瞬間、MicroPython インタプリタを DALEK のオペレーティングシステムに入れ、上記のコードを長い隠される イスターエッグ または リックロール のようなものとして、DALEK のメモリバンクに入れることができました。
音素¶
場合によっては say
関数が英語の単語から正しい音に正確に変換されないことがあります。出力をきめ細かく制御するには、言語の音の最小単位である音素を使用します。
音素を使用する利点は、綴り方を知る必要がないことです。むしろ、それを音声学的に綴るためには、言葉の使い方を知る必要があります。
音声シンセサイザーが理解している音素の全リストは、speech の API ドキュメンテーションにあります。あるいは、英語の単語を translate
関数に渡すことで、時間を節約できます。この関数は、オーディオを生成するために使う音素の近似を最初に生成して返します。この結果は、(もっと自然に聞こえるように)精度、屈曲、強調を手で編集して改善できます。
音素出力には次のように pronounce
関数を使います。
speech.pronounce("/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP.")
ドクターのコードを音素を使って改善してみてください。
micro:bit の歌を歌う¶
pitch
設定の変更と sing
関数の呼出しによって、デバイスを歌えるようにできます(ただし、Eurovision で勝てるとは限りません)。(訳注: Eurovision は欧州放送連合の音楽コンテストです)
pitch 番号から音符へのマッピングを以下に示します。

次のように、 sing
関数には音素と pitch を入力する必要があります。
speech.sing("#115DOWWWW")
歌う pitch の設定として、音素の前にハッシュ(#
)で前置した値があることに注目してください。新しい pitch 設定があるまで、pitch は後続の音素に対して同じままとなります。
次の例は、3つの関数(say
, pronounce
, sing
)を使った音声の生成方法を示しています。
"""
speech.py
~~~~~~~~
micro:bit に何かを言わせたり、発音させたり、歌わせたりするための簡単な
speech の利用例です。
この例では P0 と GND に接続されたスピーカー/ブザー/ヘッドフォン、
またはスピーカー内蔵の最新の micro:bit デバイスが必要です。
"""
import speech
from microbit import sleep
# say メソッドは英語から音素への変換を試みます。
speech.say("I can sing!")
sleep(1000)
speech.say("Listen to me!")
sleep(1000)
# throat をクリーンにするには音素を使う必要があります。
# pitch と speed を変更することでも適切な効果が得られます。
speech.pronounce("AEAE/HAEMM", pitch=200, speed=100) # えへん
sleep(1000)
# 歌わせるには各音節ごとに音階の音素が必要です。
solfa = [
"#115DOWWWWWW", # ド
"#103REYYYYYY", # レ
"#94MIYYYYYY", # ミ
"#88FAOAOAOAOR", # ファ
"#78SOHWWWWW", # ソ
"#70LAOAOAOAOR", # ラ
"#62TIYYYYYY", # シ
"#58DOWWWWWW", # ド
]
# 音階が順に高くなっていくよう歌わせます。
song = ''.join(solfa)
speech.sing(song, speed=100)
# 音節のリストの順番を逆にします。
solfa.reverse()
song = ''.join(solfa)
# 音階が順に低くなっていくよう歌わせます。
speech.sing(song, speed=100)
ネットワーク¶
デバイスの間で互いにメッセージの送受信を行えます。これをネットワークといいます。相互接続されたネットワークのネットワークはインターネットと呼ばれます。ザ・インターネットはすべてのインターネットのインターネットです。
ネットワーク処理は大変であり、これは以降のプログラムにも表れています。しかし、このプロジェクトの美しいところは、あなたが知る必要があるネットワークプログラミングの共通点がすべて含まれていることです。それはまた非常にシンプルで楽しいものです。
しかし、まず、シーンを設定しましょう ...
結線¶
ネットワークを一連の階層と想像してみてください。一番下の部分は通信の最も基本的な部分です。あるデバイスから別のデバイスに信号を到達するための何らかの方法が必要です。これは無線接続で行われることもありますが、この例では単に2本のワイヤを使用します。

この基盤の上に、 ネットワークスタック 内の他のすべての階層を構築できます。
図に示すように、青と赤のマイクロビットはワニ口クリップのリード線で接続します。両方とも出力には端子1を使い、入力の場合は端子2を使います。一方のデバイスからの出力は、他方の入力に接続します。これは、電話の受話器をどう持つのかを知っているようなものです。一方の端にはマイク(入力)があり、他方にはスピーカー(出力)があります。マイクによるあなたの声は、もう一方の人のスピーカーから聞こえます。あなたが受話器を間違って持てば、奇妙な結果を得るでしょう!
この場合もまったく同じです。ワイヤを正しく接続する必要があります。
信号¶
ネットワークスタック の次の層が信号です。多くの場合、これは接続の特性に依存します。この例では、単に I/O 端子を介してワイヤーで送られるデジタルのオン/オフ信号です。
覚えているでしょうが、I/O 端子は次のように使えます:
pin1.write_digital(1) # 信号をオンにする
pin1.write_digital(0) # 信号をオフにする
input = pin2.read_digital() # 信号の値(1か0)を読む
次のステップでは、信号の使用方法と処理方法を説明します。そのために必要なのは ...
プロトコル¶
あなたがエリザベス女王に会ったことがあるなら、あなたがどう行動すべきかについて期待されることがあります。たとえば、女王が到着したときには身を低くしてお辞儀し、女王が手を丁寧に振ってくれたら、「陛下」と言い、その後「女王様」と言います。この一連の規則はロイヤルプロトコルと呼ばれます。プロトコルは、特定の状況(女王との出会いなど)が与えられたときの行動の仕方を説明します。ある状況が起こる前に何が起こっているのかを誰もが確実に理解できるように、プロトコルがあらかじめ定義されています。

この理由から、コンピュータネットワークを介してメッセージを伝達するためのプロトコルを定義して使用します。コンピュータでは、メッセージを送受信する方法を渡す前に同意する必要があります。おそらく、最もよく知られているプロトコルは、ワールドワイドウェブによって使用されるハイパーテキスト転送プロトコル(HTTP)でしょう。
メッセージを送信するためのもう1つの有名なプロトコルは(コンピュータが現れる前のからありますが)モールス符号です。これは、長時間または短時間のオン/オフ信号を介して文字ベースのメッセージを送信する方法を定義します。このような信号は、しばしばビープ音として再生されます。長い信号は長点(-
)と呼ばれ、短い信号は短点(.
)です。長点と短点を組み合わせることで、モールスは文字を送信する方法を定義しています。たとえば、標準のモールスアルファベットがどのように定義されているかを次に示します。
.- A .--- J ... S .---- 1 ----. 9
-... B -.- K - T ..--- 2 ----- 0
-.-. C .-.. L ..- U ...-- 3
-.. D -- M ...- V ....- 4
. E -. N .-- W ..... 5
..-. F --- O -..- X -.... 6
--. G .--. P -.-- Y --... 7
.... H --.- Q --.. Z ---.. 8
.. I .-. R
上図を見ると、文字 "H" を送信するには、4つの短点(....
)で示してあるとおり、短い信号を4回スイッチオンします。文字 ""L" についても、信号を4回スイッチオンしますが、第2信号はより長い持続時間になります(.-..
)
明らかに、信号のタイミングは重要です。短点と長点の方法を取り決めておく必要があります。これはプロトコルのもう一つのポイントです。そうしたことに同意することで、すべてのプロトコルの実装が他のすべての実装と連携できるようになります。この例では、次のように言います。
- 持続時間が 250 ミリ秒未満の信号は短点とします。
- 250 ミリ秒から 500 ミリ秒未満の持続時間を有する信号は長点とします。
- 他の持続時間の信号は無視するものとします。
- 信号のない時間が 500 ミリ秒を超えると、文字の終わりを示します。
このように、文字 "H" の送信は、それぞれが250ミリ秒を超えない4つの「オン」信号として定義され、続いて信号を出さない時間を 500 ミリ秒(文字の終りを示す)を超えるまで続けます。
メッセージ¶
私たちは最終的にメッセージを作り上げる段階に入りました。メッセージは実際に私たち人間にとって何かを意味します。これはネットワークスタックの一番上の層となります
上で定義したプロトコルを使用して、以下の信号シーケンスを物理的なワイヤーを介して他の micro:bit に送ることができます:
...././.-../.-../---/.--/---/.-./.-../-..
あなたはそれが何を言っているのか解明できますか?
アプリケーション¶
ネットワークスタックを作ることは非常にうまくいっていますが、メッセージを送受信するためのアプリケーションの形式も必要です。HTTP は興味深いですが、 ほとんど の人はそれを知らず、Web ブラウザで処理します。ワールドワイドウェブの基盤となる ネットワークスタック は隠されています(そうあるべきなのです)。
では、BBC micro:bit のためにどのようなアプリケーションを書くべきでしょうか? ユーザーの視点からは、どのように機能すべきでしょうか?
明らかに、メッセージを送信するには、短点と長点を入力できる必要があります(これにはボタン A を使用できます)。送受信したメッセージを見たい場合は、ディスプレイ上にメッセージをスクロールするよう指示できる必要があります(そのためにボタン B を使用できます)。最後に、これはモールス符号であり、スピーカーが接続されている場合は、ユーザーがメッセージを入力している間にビープ音を聴覚フィードバックの一形態として再生する必要があります。
最終結果¶
以下がプログラムです。上記に検討したことはすべて盛り込んであります。何を行っているかが分かりやすいようにたくさんのコメントをつけています:
from microbit import *
import music
# モールス信号とそれが表す文字のルックアップテーブル。
MORSE_CODE_LOOKUP = {
".-": "A",
"-...": "B",
"-.-.": "C",
"-..": "D",
".": "E",
"..-.": "F",
"--.": "G",
"....": "H",
"..": "I",
".---": "J",
"-.-": "K",
".-..": "L",
"--": "M",
"-.": "N",
"---": "O",
".--.": "P",
"--.-": "Q",
".-.": "R",
"...": "S",
"-": "T",
"..-": "U",
"...-": "V",
".--": "W",
"-..-": "X",
"-.--": "Y",
"--..": "Z",
".----": "1",
"..---": "2",
"...--": "3",
"....-": "4",
".....": "5",
"-....": "6",
"--...": "7",
"---..": "8",
"----.": "9",
"-----": "0"
}
def decode(buffer):
# ルックアップテーブルからモールス信号を探します
# 該当するものがなければ、終止符を返します。
return MORSE_CODE_LOOKUP.get(buffer, '.')
# 単一の短点を表示する方法。
DOT = Image("00000:"
"00000:"
"00900:"
"00000:"
"00000:")
# 単一の長点を表示する方法。
DASH = Image("00000:"
"00000:"
"09990:"
"00000:"
"00000:")
# 短点を作るには 250 ミリ秒未満でボタンを押す必要あり。
DOT_THRESHOLD = 250
# 長点を作るには 250 ミリ秒未満でボタンを押す必要ある。
DASH_THRESHOLD = 500
# 入ってくるモールス信号を保持。
buffer = ''
# モールス信号から文字に変換したものを保持。
message = ''
# 次にボタンが押されるのをデバイスが待ち始めた時間。
started_to_wait = running_time()
# デバイスがボタンの押下を待って反応するためのループ。
while True:
# デバイスがボタンの押下を待っている時間を計算。
waiting = running_time() - started_to_wait
# key_down_time のタイムスタンプをリセット。
key_down_time = None
# ボタンAが押されたら ...
while button_a.is_pressed():
# ビープ音を鳴らす - つまりモールス信号を鳴らします ;-)
music.pitch(880, 10)
# 端子1 (出力) を "オン" にします。
pin1.write_digital(1)
# ... そして key_down_time が設定されていない場合はすぐに設定 !
if not key_down_time:
key_down_time = running_time()
# 端子2が信号を受け取っている場合は、ボタンAが押されたかのような
# ふりをして ...
while pin2.read_digital():
if not key_down_time:
key_down_time = running_time()
# 現在の時刻を取得して key_up_time に入れます。
key_up_time = running_time()
# 端子1 (出力)を "オフ" にします。
pin1.write_digital(0)
# key_down_time に値が入っていた場合(ボタンAが押されたときに
# 設定されます)
if key_down_time:
# ... ボタンが押されていた時間を調べます。
duration = key_up_time - key_down_time
# 押されていた時間が "短点" の最大長未満であれば ...
if duration < DOT_THRESHOLD:
# ... 着信したモールス信号を格納するバッファに短点を追加して、
# ディスプレイに短点を表示。
buffer += '.'
display.show(DOT)
# そうでなく、押されていた時間が "長点" の最大長未満であれば ...
# (しかし、上で判定した短点よりは長い)
elif duration < DASH_THRESHOLD:
# ... バッファに長点を追加し、長点を表示
buffer += '-'
display.show(DASH)
# さもなければ、その他の押下時間は無視します。(これは必要ではなく、
# "わかりやすさ" のために追記しています)
else:
pass
# ボタン押下を処理したので、ボタン押下をデバイスが
# 待ち始める時間をリセット。
started_to_wait = running_time()
# さもなければ、このループのサイクルではボタンAの押下が無かったで、
# モールス信号文字の終端を示す一時停止が無いかをチェックします。
# 一時停止は長点信号の時間よりも長い必要があります。
elif len(buffer) > 0 and waiting > DASH_THRESHOLD:
# バッファになにかあり、信号の終端に達したので ...
# バッファにあるものをデコードします。
character = decode(buffer)
# バッファを空にリセットします。
buffer = ''
# デコード結果の文字を表示します。
display.show(character)
# メッセージに文字を追加します。
message += character
# 最後に、上記すべてが行われている間にボタンBが押されていたら ...
if button_b.was_pressed():
# ... メッセージを表示して、
display.scroll(message)
# メッセージを空にリセットします(新しいメッセージの準備)。
message = ''
どのように改善しますか? 短点と長点の定義を変更して、高速のモールスコードをユーザが使えるようにできますか? 両方のデバイスが同時に送信している場合はどうなりますか? この状況を処理するためには何をすればよいでしょうか?
無線通信¶
離れた場所での対話は魔法のようです。
あなたがエルフ、魔法使い、ユニコーンであれば、魔法が使えるでしょうが、そのようなことは物語にしかありません。
しかし、魔法よりもはるかに優れたものがあります: 物理学です!
無線のやりとりはすべて物理学に基づくものです: 電波(可視光に似た電磁波の一種)は、送信機によって変調される特性(振幅、位相、パルス幅など)を持っていて、これを利用して情報をコード化して送信します。電波が電気導体(すなわち、アンテナ)に遭遇すると、波の情報が抽出され、元の形に変換された交流電流が発生します。
レイヤー上のレイヤー¶
覚えているでしょうか? ネットワークは複数の層で構成しています。
ネットワークにとって最も基本的な要件は、信号があるデバイスから別のデバイスに到達できるようにする何らかの接続です。ネットワークのチュートリアルでは、I/O 端子に接続されたワイヤを使用しました。無線モジュールのおかげで、ワイヤーをなくし、上記で要約した物理学をデバイス間の見えない接続として使用することができます。
ネットワークスタック内の次のレイヤーも、ネットワークのチュートリアルの例とは異なります。有線の例では、デジタルのオンとオフを使用して端子から信号を送信して読み取りました。micro:bit に内蔵の無線機能を使用すると、信号の最小単位が 1 バイトになります。
バイト¶
バイトは、(通常) 8 ビットで構成される情報の単位です。ビットは、オンまたはオフの2つの状態しかないので、最小限の情報単位です。
バイトは、一種のそろばんのように機能します。バイトの各位置は、そろばんの列のようなもので、関連する数字を表します。そろばんは通常、千、百、十、一のように並びます。バイトでは 128, 64, 32, 16, 8, 4, 2, 1 となります。ビット(オン/オフ信号)が無線で送信されると、それらは受信側でバイト列に再結合されます。
あなたはそのパターンを見つけましたか? (ヒント: 基数が2)
「オン」に設定されたバイト内の位置に数を割り当てることにより、0 〜 255 の数値を表すことができます。下の図は、これが 5 ビットでどのようになるのかを示しています。

私たちが(バイトでエンコードされた) 255 個の数値のそれぞれが〜1文字〜を表すのに同意すれば、一度に 1 バイトあたり 1 文字のテキストを送ることができます。
面白いことに、人々はすでに このことを考えていて いました。情報のエンコードとデコードにバイト列を使用するのが普通です。これは、有線ネットワーキングの例でのモールス符号の「プロトコル」層にほぼ対応します。
「バイト列のすべて」についての実に素晴らしい子ども(と教師)向けのの説明が、CS unplugged ウェブサイトにあります。
アドレッシング¶
無線通信の問題は、一人に直に送信できないということです。適切なアンテナを持っていれば、あなたの送信したメッセージを受け取れてしまいます。つまり、誰が放送を受信すべきかを区別できるようにすることが重要となります。
micro:bit に内蔵の無線通信では、この問題を解決するのが非常に簡単です。
- 無線通信を異なるチャンネル(0〜83 の番号)にチューニングすることは可能です。これは、子ども向けのトランシーバーのおもちゃとまったく同じように機能します。誰もが同じチャンネルに同調し、誰もがそのチャンネルを介してブロードキャストするものを聞きます。トランシーバーと同様に、隣接するチャンネルを使っても干渉の可能性はわずかです。
- 無線モジュールでは、アドレスとグループという2つの情報を指定できます。アドレスは郵便アドレスのようなものですが、グループはアドレスの特定の受信者に似ています。重要なのは、無線通信があなたのアドレスとグループと一致しない受信したメッセージを除外することです。つまり、アプリケーションが使用する予定のアドレスとグループを事前に配置することが重要です。
もちろん、 micro:bit は、他のアドレス/グループの組み合わせのブロードキャストメッセージも受信しています。重要なことは、それらをフィルタリングすることについて心配する必要はないということです。それにもかかわらず、誰かが賢明だったなら、ターゲットアドレス/グループが何を想定していたとしても、すべての無線ネットワークのトラフィックを読み取ることができます。この場合、暗号化された通信手段を使用することが 不可欠 であり、そのようにすれば必要な受信者だけが実際にブロードキャストされたメッセージを読むことができます。暗号は魅力的なテーマですが、残念ながらこのチュートリアルの範囲を超えています。
ホタル¶
これはホタルです:

ホタルは生物発光を使って(ワイヤなしで)仲間に信号を送る虫の一種です。お互いに信号を送るときの様子は次のとおりです:

BBC はオンラインで入手できるホタル`美しい映像 "<http://www.bbc.com/earth/story/20160224-worlds-largest-gathering-of-synchronised-fireflies>`_ を持っています。
無線モジュール radio を使って、ホタルの群れがお互いに交信するようなものを作ってみましょう。
まず Python プログラムで関数を利用できるように import radio
します。次に、無線をオンにする radio.on()
関数を呼び出します。これを行うと radio はパワーを得てメモリを確保するので、 あなた が無線通信の有効化を決定したことになります(もちろん、無効にする radio.off
関数もあります)。
この時点で、radio モジュールは、BBC micro:bit をターゲットとする可能性のある他のプラットフォームと互換性を持つように、適切なデフォルトに設定されています。上述した多くの機能(チャネルやアドレス指定など)や、メッセージをブロードキャストするための電力量や着信メッセージキューが占有する RAM の量を制御することが可能です。APIドキュメントには、必要に応じて radio を設定するために必要なすべての情報があります。
デフォルトで十分であれば、メッセージを送信する最も簡単な方法は次のようなものです:
radio.send("a message")
この例では、"a message" をブロードキャストするために send
関数を使っています。メッセージを受け取るのはさらに簡単です:
new_message = radio.receive()
メッセージが受信されると、それらはメッセージキューに置かれます。receive
関数は、新しい着信メッセージのためのスペースを作り、文字列としてキューから最も古いメッセージを返します。メッセージキューがいっぱいになると、新しい受信メッセージは無視されます。
本当にこれだけです(が、radio モジュールは文字列だけでなく任意のタイプのデータを送信することもできます。これについてはAPIドキュメントを参照してください)。
この知識を武器とすれば、 micro:bit のホタルを作るのは以下のように簡単です:
# 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)]
# 無線を使うためのスィッチをオンにします。
radio.on()
# イベントループ。
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') # それっ
重要なことはイベントループ内で起きています。最初に、ボタン A が押されたかどうかをチェックし、そうであれば、radio を使用してメッセージ "flash" を送信します。次に、 radio.receive()
でメッセージキューからメッセージを読み込みます。メッセージがある場合は、(ディスプレイをより面白くするために)短くランダムな時間の休止と display.show()
を使って、ホタルの光の点滅を表現します。最後に、物事を少しエキサイティングにするために、誰かに ""flash" メッセージを再ブロードキャストするチャンスが 1/10 になるように乱数を選択します(これはいくつかのデバイス間でホタルの表示を維持する手段です)。ブロードキャストを決定すると、 "flash" 信号を再び送信する前に(最初のフラッシュメッセージからの表示が確実に終われるように)、0.5秒間待機します。このコードは while True
ブロック内にあるため、無限に処理を継続します。
このプログラムを使った様子は次のようになります(micro:bit のグループを使用)。

次のステップ¶
ここまでのチュートリアルは、MicroPython を BBC micro:bit で使う最初のステップにすぎません。音楽でいえば、あなたは非常に簡単な楽器の基本的な理解を得て、自信を持って "Three Blind Mice" (訳注: イギリスの古いマザーグース)を演奏しているところです。
これは築き上げた成果です。
あなたが巨匠コーダーになるエキサイティングな旅の始まりです。
あなたは欲求不満、失敗、愚かさに直面します。そうなるのは、あなただけではないことを覚えておいてください。Python には秘密兵器があります。それは地球上で最も素晴らしいプログラマーのコミュニティです。このコミュニティとつながり、友達を作り、メンターを見つけ、お互いをサポートし、リソースを共有します。
チュートリアルの例は説明が簡単ですが、最も単純で効率的な実装ではありません。私たちは 本当は楽しいもの をたくさん残してきましたので、あなたに基本に集中することができました。あなたが BBC micro:bit で 本当に MicroPython を極めたいのであれば API リファレンスを参照してください。利用可能な機能に関する すべての 情報があります。
探検、実験、そして恐れずに試してみてください〜これは巨匠コーダーの特性です。あなたをはげますために、MicroPython とコードエディタにいくつかの イースターエッグ を隠しました。これらは "looking under the hood" や "poking with a stick" (訳注: 念入りに調べること)への楽しい報酬です。
Python のスキルは貴重です。これは世界で最も人気のある専門プログラミング言語の1つです。
あなたのコードで私たちを驚かせてください! 私たちを喜ばせるものを作る! 何よりも、楽しんでください!
ハッピーハッキング!
Python は 世界的に最も人気のある プログラミング言語の一つです。知らず知らずに Python を使って書かれたソフトウェアを日々使っているかもしれません。あらゆる業種の企業や組織が多様なアプリケーションに Python を使用しています。Google, NASA, Bank of America, Disney, CERN, YouTube, Mozilla, The Guardian - このリストは、経済、科学、芸術のすべての分野を網羅しています。
たとえば、 重力波の検出 の発表を憶えていますか? 測定を行う機器は Python で 制御されていました。
簡単に言えば、Python を教えたり学んだりすると、人間が活動するすべての分野に適用される高いスキルを開発することになります。
そのような領域の一つが、BBC の驚くべき micro:bit デバイスです。このデバイスでは MicroPython という Python の一派生版が動きます。MicroPython は BBC micro:bit のような小さなコンピュータで動くようデザインされています。MicroPython は Python 3 のフル実装したものであるので、他のものに移る場合でも(たとえば Raspberry Pi で Python プログラミングするような場合でも)、まったく同じ言語を使えます。
MicroPython には "通常の" Python にある標準ライブラリがありませんしかし、MicroPython でデバイスを制御するよう特別に用意した microbit
モジュールがあります。
Python と MicroPython はフリーソフトウェアです。これは Python を使用するにあたって何も支払わないことを意味するだけでなく、自由に Python コミュニティに貢献できることも意味します。コード、ドキュメント、バグ報告、コミュニティグループの活動、(本書のような)チュートリアルの作成などの形で貢献できるのです。実際、BBC micro:bit のための Python 関連のリソースはすべて、自由な時間に活動するボランティアの国際チームによって作成されています。
このレッスンでは MicroPython と BBC micro:bit を実践しやすい順で紹介していきます。教室でのレッスンのためにこれを採用して実践してもよいですし、家で自分で実践することもできます。
探索し、実験し、遊んでみることで多くの成功を得ることができるでしょう。間違ったコードを書いても micro:bit は壊れません。とにかくやってみましょう!
注意の言葉: あなたは何度も失敗するでしょうが 、それでよいのです。 失敗はよいソフトウェア開発者が学んでいる方法なのです 。ソフトウェア開発者として働いている私たちには、バグの追跡し、間違いの繰り返しを避けるようにすることが、とても楽しいものなのです。
疑わしいときは Zen of MicroPython を思い起こしてください:
Code, (コード)
Hack it, (ハックしよう)
Less is more, (小さいほど豊かである)
Keep it simple, (単純にしよう)
Small is beautiful, (小さいことは美しい)
Be brave! Break things! Learn and have fun! (勇気を出そう! 前に進もう! 学び、楽しもう!)
Express yourself with MicroPython. (MicroPython で自分を表現しよう)
"Happy hacking! :-)
幸運を祈ります!
micro:bit Micropython API¶
microbit モジュール¶
ハードウェアと相互に直接関係するものはすべて microbit モジュールにあります。使いやすさを考慮して、すべてのスクリプトは次の方法で起動することをお勧めします:
from microbit import *
以下のドキュメントは、これを行ったことを前提としています。
いくつかの関数が直接利用できます:
# 指定したミリ秒数だけ休止します。
sleep(ms)
# micro:bit の電源が入ってから経過したミリ秒数を返します。
running_time()
# micro:bit をパニックモードにします(これは通常、デバイス抽象レイヤーがメモリ不足になったときに
# 起き、ディスプレイに悲しい顔が出ます)。エラーコードには任意の整数値を指定できます。
panic(error_code)
# micro:bit をリセットします。
reset()
残りの機能は、後述するように microbit モジュール内のオブジェクトおよびクラスによって提供されます。
ここで使った API は数値として整数だけを利用しています(つまり、浮動小数点数は必要ないということですが、受け付けるものもあります)。したがって標準の時間単位にはミリ秒を使用します。
注釈
利用できるモジュールの一覧は REPL で help('modules')
とすることで参照できます。
ボタン¶
2つのボタンがあります:
button_a
button_b
これらはどちらもオブジェクトであり、次のメソッドがあります:
# メソッドを呼んだときにボタンが押されているかにより True または False
# を返します。
button.is_pressed()
# デバイスが始動まやは前回にこのメソッドが呼び出されてからボタンが
# 押されたかにより True または False を返します。
button.was_pressed()
# ボタン押下の回数を返し、このカウンタをゼロにリセットします。
button.get_presses()
ディスプレイ¶
LED ディスプレイは display オブジェクトを介して利用します:
# ピクセル (x, y)の照度を得ます。照度は 0 (ピクセルがオフ)から 9 (ピクセルが最大照度)
# までの値をとります。
display.get_pixel(x, y)
# ピクセル (x, y)の照度に val (0 [オフ] から 9 [最大照度] の範囲)
# を設定します。
display.set_pixel(x, y, val)
# ディスプレィをクリアします。
display.clear()
# イメージを表示します。
display.show(image, delay=0, wait=True, loop=False, clear=False)
# iterable のイメージまたは文字のそれぞれを delay ミリ秒間隔で表示する。
display.show(iterable, delay=400, wait=True, loop=False, clear=False)
# 文字列 string をディスプレイでスクロールします(メッセージを表示するなら display.show
# よりも効果的)。
display.scroll(string, delay=400)
端子¶
コネクタの端子に、デジタルおよびアナログの入出力機能を提供します。一部の端子は LED マトリクスとボタンを駆動する I/O に内部接続されています。
各端子は microbit
モジュールで直接オブジェクトとして提供されます。これにより API が比較的フラットに保たれ、利用が非常に簡単になります。
- pin0
- pin1
- ...
- pin15
- pin16
- 注意: P17-P18 は利用できません。
- pin19
- pin20
これらの端子はそれぞれ MicroBitPin
クラスのインスタンスであり、次のAPIを提供します。
# 値 value を 0, 1, False, True のいずれかにできます。
pin.write_digital(value)
# 1 か 0 を返します。
pin.read_digital()
# value は 0 から 1023 の範囲の値です。
pin.write_analog(value)
# 0 から 1023 の範囲の整数値を返します。
pin.read_analog()
# 端子の PWM 出力周期をミリ秒単位で設定します。
# (https://ja.wikipedia.org/wiki/パルス幅変調 を参照)
pin.set_analog_period(int)
# 端子の PWM 出力周期をマイクロ秒単位で設定します。
# (https://ja.wikipedia.org/wiki/パルス幅変調 を参照)
pin.set_analog_period_microseconds(int)
# タッチ端子 0, 1, 2 のみ使えます。端子に触れているかをブール値で返します。
pin.is_touched()
イメージ¶
イメージ API
# 空の 5x5 イメージを作成。
image = Image()
# 文字列からイメージを作成 - 文字列中の各文字は LED を表す - 0 (またはスペース)はオフ、
# "9 は最大照度。コロン ":" は行の終端を示します。
image = Image('90009:09090:00900:09090:90009:')
# 与えたサイズの空のイメージを作成します。
image = Image(width, height)
# 指定の width と height でイメージを初期化します。buffer は長さが
# width * height の配列です。
image = Image(width, height, buffer)
# メソッド
# イメージの width (最大 5)を返します。
image.width()
# イメージの height (最大 5)を返します。
image.height()
# 指定の位置のピクセルを設定します(0 から 9 の範囲)。組込みのイメージでは
# 失敗します。
image.set_pixel(x, y, value)
# 指定の位置のピクセルを得ます(0 から 9 の範囲)。
image.get_pixel(x, y)
# イメージを左に 'n' 回シフトした新しいイメージを返します。
image.shift_left(n)
# イメージを右に 'n' 回シフトした新しいイメージを返します。
image.shift_right(n)
# イメージを上に 'n' 回シフトした新しいイメージを返します。
image.shift_up(n)
# イメージを下に 'n' 回シフトした新しいイメージを返します。
image.shift_down(n)
# イメージのコンパクトな文字列表現を得ます。
repr(image)
# イメージのより可読性のある文字列表現を得ます。
str(image)
#演算子
# 2つのイメージを重ね合わせた新しいイメージを返します。
image + image
# 各ピクセルの照度に n を掛けた新しいイメージを返します。
image * n
内蔵イメージ
Image.HEART
Image.HEART_SMALL
Image.HAPPY
Image.SMILE
Image.SAD
Image.CONFUSED
Image.ANGRY
Image.ASLEEP
Image.SURPRISED
Image.SILLY
Image.FABULOUS
Image.MEH
Image.YES
Image.NO
Image.TRIANGLE
Image.TRIANGLE_LEFT
Image.CHESSBOARD
Image.DIAMOND
Image.DIAMOND_SMALL
Image.SQUARE
Image.SQUARE_SMALL
Image.RABBIT
Image.COW
Image.MUSIC_CROTCHET
Image.MUSIC_QUAVER
Image.MUSIC_QUAVERS
Image.PITCHFORK
Image.XMAS
Image.PACMAN
Image.TARGET
Image.TSHIRT
Image.ROLLERSKATE
Image.DUCK
Image.HOUSE
Image.TORTOISE
Image.BUTTERFLY
Image.STICKFIGURE
Image.GHOST
Image.SWORD
Image.GIRAFFE
Image.SKULL
Image.UMBRELLA
Image.SNAKE
Image.SCISSORS
時計:
Image.CLOCK1
Image.CLOCK2
Image.CLOCK3
Image.CLOCK4
Image.CLOCK5
Image.CLOCK6
Image.CLOCK7
Image.CLOCK8
Image.CLOCK9
Image.CLOCK10
Image.CLOCK11
Image.CLOCK12
矢印:
Image.ARROW_N
Image.ARROW_NE
Image.ARROW_E
Image.ARROW_SE
Image.ARROW_S
Image.ARROW_SW
Image.ARROW_W
Image.ARROW_NW
次のものはイメージの Python リストで、自動的にアニメーションを表示したり、手動で反復して表示するのに便利です。
Image.ALL_CLOCKS
Image.ALL_ARROWS
加速度センサー¶
加速度センサーは accelerometer
オブジェクトを介して利用します:
# デバイスの X 軸を読みます。ミリg単位で計測します。
accelerometer.get_x()
# デバイスの Y 軸を読みます。ミリg単位で計測します。
accelerometer.get_y()
# デバイスの Z 軸を読みます。ミリg単位で計測します。
accelerometer.get_z()
# X, Y, Z の3軸すべてを(この順番の並びで)得ます。
accelerometer.get_values()
# 現在のジェスチャの名前を返します。
accelerometer.current_gesture()
# 指定の名前のジェスチャが現在行われているかにより True または False を返します。
accelerometer.is_gesture(name)
# 最後に呼び出されてから、指定の名前のジェスチャが行われたかにより True または False を
# 返します。
accelerometer.was_gesture(name)
# ジェスチャの履歴のタプルを返します。直近のものが最後に並びます。
accelerometer.get_gestures()
認識ジェスチャーは以下のとおりです: up
, down
, left
, right
, face up
, face down
, freefall
, 3g
, 6g
, 8g
, shake
。
コンパス¶
コンパスは compass コンパスオブジェクトを介して利用します:
# コンパスを調整します(これは正確な計測のために必要です)。
compass.calibrate()
# "北" からの相対角度を示す数値を返します。
compass.heading()
# micro:bit の周りの磁場の強度を示す数値を返します。
compass.get_field_strength()
# コンパスが調整されているかにより True または False を返します。
compass.is_calibrated()
# コンパスの調整されていた状態をリセットします。
compass.clear_calibration()
I2C バス¶
micro:bit には I2C バスがあり、 i2c オブジェクトを介して利用します。このオブジェクトには以下のメソッドがあります:
# アドレス addr のデバイスから n バイト読み込みます。repeat=True はストップビットが
# 送信されないことを意味します。
i2c.read(addr, n, repeat=False)
# アドレス addr のデバイスに buf を書き出します。repeat=True はストップビットが
# 送信されないことを意味します。
i2c.write(addr, buf, repeat=False)
UART¶
I/O 端子に接続されたシリアルデバイスとの通信には uart
を使います:
# ボーレート 9600 で(端子 0 [TX] と 1 [RX] を使う)通信をセットアップします。
uart.init()
# 読込みを待っている文字を受信しているかにより True または False を
# 返します。
uart.any()
# 受信している文字を n だけ読んで返します。
uart.read(n)
# 受信している文字を可能なだけ(読んで)返します。
uart.read()
# 改行文字に達するまでのすべての文字を(読んで)返します。
uart.readline()
# 指定のバッファにバイト列を読み込みます。
uart.readinto(buffer)
# 接続したデバイスにバッファのバイト列を書き出します。
uart.write(buffer)
Microbit モジュール¶
microbit
モジュールは、ボードに組み込まれて内蔵のハードウェアすべてにアクセスするためのものです。
関数¶
-
microbit.
panic
(n)¶ すべての実行を停止するパニックモードに入ります。このモードに入ると micro:bit ディスプレイにエラーコードをスクロール表示し再起動が必要となります。
microbit.panic(255)
パラメータ: n -- エラーコードを示す 0 から 255 までの任意の整数。
-
microbit.
reset
()¶ ボードを再起動します。
-
microbit.
running_time
()¶ 戻り値: ボードの電源が入ったか再起動してからの経過時間(ミリ秒)。
-
microbit.
sleep
(n)¶ n
ミリ秒だけ待機します。1 秒は 1000 ミリ秒なので、microbit.sleep(1000)
は 1 秒間実行を一時停止します。パラメータ: n -- 待機するミリ秒を示す整数または浮動小数点数。
-
microbit.
temperature
()¶ 戻り値: micro:bit の温度(摂氏)を示す整数。
属性¶
ボタン¶
ボードには2つのボタンがあります。 button_a
と button_b
です。
クラス¶
-
class
Button
¶ ボタンを表します。
注釈
このクラスは実際には利用できません。既に用意されている2つのボタンインスタンスをとおして使えるだけです。
-
is_pressed
()¶ 指定のボタンが押されていれば
True
を返し、押されていなければFalse
を返します。
-
was_pressed
()¶ デバイスが起動されてから、もしくは前回このメソッドが呼ばれてからボタンが(上から下へ)押されたかによって
True
またはFalse
を返します。このメソットを呼び出すとボタンが押されたかの状態がクリアされるので、再度このメソッドがTrue
を返すようにするには、このメソッドを呼び出す前にボタンが押されなければなりません。
-
get_presses
()¶ ボタンを押した回数の合計を返し、返す前に回数をゼロにリセットします。
-
サンプルコード¶
import microbit
while True:
if microbit.button_a.is_pressed() and microbit.button_b.is_pressed():
microbit.display.scroll("AB")
break
elif microbit.button_a.is_pressed():
microbit.display.scroll("A")
elif microbit.button_b.is_pressed():
microbit.display.scroll("B")
microbit.sleep(100)
入出力端子¶
端子はボードに接続された外部デバイスと通信するための手段。使用できる端子は 19 あります。番号 0-16 と 19-20 を利用できます。端子 17 と 18 は利用できません。
たとえば、以下のスクリプトは端子 0 のデジタル読み取り、値に応じてマイクロビットの表示を変更します。
from microbit import *
while True:
if pin0.read_digital():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)
各端子の機能¶

次の表は、利用可能な端子とそのタイプ、および内部接続をまとめたものです。端子は microbit
モジュールの属性 microbit.pin0
- microbit.pin20
として利用できます。
端子 | タイプ | 機能 |
---|---|---|
0 | タッチ | パッド 0 |
1 | タッチ | パッド 1 |
2 | タッチ | パッド 2 |
3 | アナログ | 列 1 |
4 | アナログ | 列 2 |
5 | デジタル | ボタン A |
6 | デジタル | 列 9 |
7 | デジタル | 列 8 |
8 | デジタル | |
9 | デジタル | 列 7 |
10 | アナログ | 列 3 |
11 | デジタル | ボタン B |
12 | デジタル | |
13 | デジタル | SPI SCK |
14 | デジタル | SPI MISO |
15 | デジタル | SPI MOSI |
16 | デジタル | |
19 | デジタル | I2C SCL |
20 | デジタル | I2C SDA |
PWM (Pulse-Width Modulation)¶
ボードの端子は、オーディオアンプが行っているような電圧の変調によるアナログ信号を出力できません。端子は、3.3V のフル出力をイネーブルするか、または 0V にプルダウンするだけです。しかし、LED の明るさや電気モーターの速度を制御することは、その電圧を非常に高速にオン/オフし、オン時間とオフ時間を制御することによっても可能です。この技術はパルス幅変調(PWM)と呼ばれ、 write_analog
メソッドで行います。

上には 3 つの異なる PWM 信号の図があります。それらはすべて同じ周期(つまり周波数)を持ちますが、時間幅周期が異なります。
最初のものは write_analog(511)
で生成されたものであり、正確に 50% の時間幅を持ちます。パワーは時間の半分がオン、時間の半分がオフです。その結果、この信号の全エネルギーは、3.3V の代わりに 1.65V の場合と同じです。
第2の信号は 25% の時間幅周期を有し、 write_analog(255)
を用いて生成できます。この端子に 0.825V が出力されている場合と同様の効果があります。
第 3 の信号は 75% の時間幅周期を有し、 write_analog(767)
を用いて生成できます。第 2 の信号の 3 倍のエネルギーを有し、第 1 端子に 2.475V を出力することと同等です。
これは、大きな慣性を持っているモーターなどのデバイスや、人間の目ではわからないほど速く点滅している LED などのデバイスではうまくいきますが、音の発生ではあまりよい結果になりません。このボードは矩形波の音だけを生成可能で、非常に古いコンピュータゲームによく似たものです -- そのようなゲームのほとんどもそうやっているからです。
クラス¶
3種類の端子があり、利用法も異なります。それらは、以下に列挙されるクラスによって表されます。これらクラスは階層を形成しています。各クラスは前のクラスのすべての機能を持ち、独自のものを追加しています。
注釈
これらのクラスは実際には利用できません。新しいクラスのインスタンスを作成することはできません。ボード上の物理的な端子を表す、すでに提供されているインスタンスのみを使用できます。
-
class
microbit.
MicroBitDigitalPin
¶ -
read_digital
()¶ 端子がハイの場合は 1 を返し、ローの場合は 0 を返します。
-
write_digital
(value)¶ value
が 1 の場合はハイに設定し、0 の場合はローに設定します。
-
set_pull
(value)¶ プル状態を次の3つの値どれかに設定します:
pin.PULL_UP
,pin.PULL_DOWN
,pin.NO_PULL
(ここでpin
は端子のインスタンスのことです)。既定のプル状態については後述します。
-
get_pull
()¶ 現在の端子のプル設定を返します。次の3つのいずれかの値が返ります:
NO_PULL
,PULL_DOWN
,PULL_UP
。これらの値はset_pull()
メソッドで設定されるか、端子モードで必要なときに自動的に設定されます。
-
get_mode
()¶ 端子モードを返します。デジタル値の書き込みやアナログ値の読み出しなど、端子を特定の機能で使うと端子モードが変化します。端子は次のいずれかのモードを持つことができます:
"unused"
,"analog"
,"read_digital"
,"write_digital"
,"display"
,"button"
,"music"
,"audio"
,"touch"
,"i2c"
,"spi"
-
write_analog
(value)¶ PWM 信号を端子に出力します。時間幅周期は供給電圧
value
に比例します。value
には 0 (時間幅周期 0%)から 1023 (時間幅周期 100%)までの整数または浮動小数点数を指定できます。
-
set_analog_period
(period)¶ 出力される PWM 信号の周期を
period
にミリ秒単位で設定します。有効な最小値は 1ms です。
-
set_analog_period_microseconds
(period)¶ 出力される PWM 信号の周期を
period
にマイクロ秒単位で設定します。有効な最小値は 256μs です。
-
get_analog_period_microseconds
()¶ PWM 信号の設定周期をマイクロ秒単位で返します。
-
-
class
microbit.
MicroBitAnalogDigitalPin
¶ -
read_analog
()¶ 端子の電圧を読み取り、0 (0V の意味)から 1023 (3.3V の意味)までの間の整数として返します。
-
-
class
microbit.
MicroBitTouchPin
¶ -
is_touched
()¶ 端子を指で触れている場合は
True
、そうでない場合はFalse
を返します。このテストは、端子と接地(GND)の間にどれだけの抵抗があるかを測定することによって行われます。抵抗が少ないと
True
の判定を返します。指での検出を確実にするには、体の別の部分、たとえばもう片方の手で GND 端子に触れる必要があるかもしれません。
-
端子のプルモードは、端子が入力モードに変わると自動的に構成されます。入力モードは read_analog
/ read_digital
/ is_touched
を呼び出すと自動で設定されます。これらのメソッドで設定されるデフォルトのプルモードは、それぞれ NO_PULL
, PULL_DOWN
, PULL_UP
です。 set_pull
を呼び出すと、read_digital
モードにある端子を指定のプルモードに設定します。
注釈
タッチセンスが機能するために、micro:bit は端子 0, 1, 2 にのみ外付けの弱い(10M)プルアップを装備しています。
ボタンAとボタンBが機能するように、端子 5 と 11 にも外付け(10k)プルアップを装備しています。
詳しくは エッジコネクタのデータシート を参照してください。
注釈
先の表に示されているように、GPIO 端子はディスプレイにも使われています。別の目的でこれらの端子を使いたいときには ディスプレイを無効 にする必要があります。
詳しくは エッジコネクタのデータシート を参照してください。
クラス¶
イメージ¶
Image
クラスはデバイス LED マトリクスに容易に表示できるイメージを作成するために使います。予め組み込まれているイメージオブジェクトを display
API で表示することもできます:
display.show(Image.HAPPY)

イメージを作るには4つの方法があります:
Image()
- 空の 5x5 イメージを作成Image(string)
- 1文字がそのグリフを表す文字列を解析してイメージを作成Image(width, height)
- 与えたサイズの空のイメージを作成Image(width, height, buffer)
- 与えたバッファからイメージを作成
クラス¶
-
class
microbit.
Image
(string)¶ -
class
microbit.
Image
(width=None, height=None, buffer=None) string
を指定した場合、引数の文字列はイメージを記述した 0-9 の数字を複数行に配置したものになります。たとえば次のものは X を 5x5 のイメージを作成します:image = Image("90009:" "09090:" "00900:" "09090:" "90009")
行の終わりはコロンで示します。行の終わりには次のように改行文字(n)を使うこともできます:
image = Image("90009\n" "09090\n" "00900\n" "09090\n" "90009")
もう1つの指定方法では
width
列とheight
行の空イメージを作成します。オプションのbuffer
は、イメージを初期化するためのもので、0-9 の整数値をwidth
×height
個並べた配列を指定します:Image(2, 2, b'\x08\x08\x08\x08')
または
Image(2, 2, bytearray([9,9,9,9]))
は、2 x 2 のピクセルイメージを最大輝度で作成します。
注釈
キーワード引数を
buffer
に渡すことはできません。-
width
()¶ イメージの列数を返します。
-
height
()¶ イメージの行数を返します。
-
set_pixel
(x, y, value)¶ x
列y
行のピクセルの明るさをvalue
に設定します。明るさは 0 (暗い) から 9 (明るい)までの整数値で指定します。このメソッドは、
Image.HEART
のような読取り専用の内蔵イメージに対して呼び出すと例外を起こします。
-
get_pixel
(x, y)¶ x
列y
行のピクセルの明るさを 0-9 の整数値で返します。
-
shift_left
(n)¶ n
列だけ左にシフトした新しいイメージを返します。
-
shift_right
(n)¶ image.shift_left(-n)
と同じです。
-
shift_up
(n)¶ n
行だけ上にシフトした新しいイメージを返します。
-
shift_down
(n)¶ image.shift_up(-n)
と同じです。
-
crop
(x, y, w, h)¶ x
列y
行のピクセルから始まってw
幅h
高さ分をトリミングした新しいイメージを返します。
-
copy
()¶ イメージ全体のコピーを返します。
-
invert
()¶ 元のイメージのピクセルの明るさを反転した新しいイメージ返します。
-
fill
(value)¶ イメージのピクセルの明るさを
value
に設定します。value
の値は 0 (暗い) から 9 (明るい)までの整数値です。このメソッドは、
Image.HEART
のような読取り専用の内蔵イメージに対して呼び出すと例外を起こします。
-
blit
(src, x, y, w, h, xdest=0, ydest=0)¶ イメージ
src
からx
,y
,w
,h
で指定する矩形領域を、このイメージのxdest
,ydest
にコピーします。矩形領域ではあるが元のイメージの外側にあるピクセルは値が 0 であるとして扱います。shift_left()
,shift_right()
,shift_up()
,shift_down()
,crop()
はすべてblit()
を用いて実現しています。たとえば img.crop(x, y, w, h) は以下で実現しています。def crop(self, x, y, w, h): res = Image(w, h) res.blit(self, x, y, w, h) return res
-
属性¶
Image
クラスには、属性として以下の内蔵インスタンスを持っています(属性名はイメージが何であるかを示しています):
Image.HEART
Image.HEART_SMALL
Image.HAPPY
Image.SMILE
Image.SAD
Image.CONFUSED
Image.ANGRY
Image.ASLEEP
Image.SURPRISED
Image.SILLY
Image.FABULOUS
Image.MEH
Image.YES
Image.NO
Image.CLOCK12
,Image.CLOCK11
,Image.CLOCK10
,Image.CLOCK9
,Image.CLOCK8
,Image.CLOCK7
,Image.CLOCK6
,Image.CLOCK5
,Image.CLOCK4
,Image.CLOCK3
,Image.CLOCK2
,Image.CLOCK1
Image.ARROW_N
,Image.ARROW_NE
,Image.ARROW_E
,Image.ARROW_SE
,Image.ARROW_S
,Image.ARROW_SW
,Image.ARROW_W
,Image.ARROW_NW
Image.TRIANGLE
Image.TRIANGLE_LEFT
Image.CHESSBOARD
Image.DIAMOND
Image.DIAMOND_SMALL
Image.SQUARE
Image.SQUARE_SMALL
Image.RABBIT
Image.COW
Image.MUSIC_CROTCHET
Image.MUSIC_QUAVER
Image.MUSIC_QUAVERS
Image.PITCHFORK
Image.XMAS
Image.PACMAN
Image.TARGET
Image.TSHIRT
Image.ROLLERSKATE
Image.DUCK
Image.HOUSE
Image.TORTOISE
Image.BUTTERFLY
Image.STICKFIGURE
Image.GHOST
Image.SWORD
Image.GIRAFFE
Image.SKULL
Image.UMBRELLA
Image.SNAKE
Image.SCISSORS
関連するイメージのコレクションもあります。
* ``Image.ALL_CLOCKS``
* ``Image.ALL_ARROWS``
演算子¶
repr(image)
イメージのコンパクトな文字列表現を得ます。
str(image)
イメージの可読可能な文字列表現を得ます。
image1 + image2
2つのイメージの各ピクセルの明るさを足した新しいイメージを作成します。
image * n
各ピクセルの明るさを n
倍した新しい画像を作成します。
モジュール¶
加速度センサー¶
このオブジェクトでボード上の加速度センサーにアクセスできます。
MicroPython はデフォルトで加速度センサーの測定範囲を +/- 2000 mg に設定します(g
は標準重力に基づく加速度の単位)。この測定範囲から加速度センサーの関数が返す最大値と最小値も決まります。microbit.accelerometer.set_range()
を使うと測定範囲を変更できます。
加速度センサーはジェスチャーをの検出にも使えます。認識できるジェスチャーは文字列で表され、次のものがあります: up
, down
, left
, right
, face up
, face down
, freefall
, 3g
, 6g
, 8g
, shake
注釈
ジェスチャーはバックグラウンドで更新されないので、ジェスチャーの検出を行うには何らかの加速度センサーのメソッドを常に呼び出す必要があります。たいてい、ジェスチャーは microbit.sleep()
による短い遅延のあるループを使って検出できます。
関数¶
-
microbit.accelerometer.
get_x
()¶ 戻り値: x
軸のミリg単位の加速度。値は正または負の整数値です。
-
microbit.accelerometer.
get_y
()¶ 戻り値: y
軸の加速度(ミリg単位)。値は正または負の整数値です。
-
microbit.accelerometer.
get_z
()¶ 戻り値: z
軸の加速度(ミリg単位)。値は正または負の整数値です。
-
microbit.accelerometer.
get_values
()¶ 戻り値: すべての軸の加速度。X, Y, Z の並びで整数値のタプルが返ります。
-
microbit.accelerometer.
get_strength
()¶ すべての軸を合成した加速度測定値を正の整数値で得ます。これは X軸、Y軸、Z軸のピタゴラス和になります。
戻り値: すべての軸の合成加速度(ミリg単位)。
-
microbit.accelerometer.
current_gesture
()¶ 戻り値: 現在のジェスチャーの名前を表す文字列。
-
microbit.accelerometer.
is_gesture
(name)¶ パラメータ: name -- チェックするジェスチャーの名前を表す文字列。 戻り値: 指定した名前のジェスチャーが認識されているかを示す真偽値。
-
microbit.accelerometer.
was_gesture
(name)¶ パラメータ: name -- チェックするジェスチャーの名前を表す文字列。 戻り値: 直前の呼出し以降に指定した名前のジェスチャーが認識されたかを示す真偽値。
-
microbit.accelerometer.
get_gestures
()¶ 記録されたジェスチャーの履歴リストを得ます。
この呼出しを行うと、結果を戻す前にジェスチャーの履歴をクリアします。
戻り値: ジェスチャー履歴のタプル。タプルは古い順に並び、最新のものが最後の要素になります。
-
microbit.accelerometer.
set_range
(value)¶ 加速度センサーの感度範囲を g (標準重力)で設定します。設定値は、ハードウェアがサポートする最も近い値、すなわち
1
,2
,4
,8
g のいずれかに丸められます。パラメータ: value -- 加速度センサーの新しい測定範囲。 g
単位の整数値で指定します。
サンプルコード¶
マジック8ボール占いです。質問の後にデバイスをゆさぶってください。
# マジック8ボール占い 作成者:Nicholas Tollervey 2016年2月。
#
# 質問の後にデバイスを振ってゆさぶってください。
#
# このプログラムはパブリックドメインで公開します。
from microbit import *
import random
answers = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful",
]
while True:
display.show('8')
if accelerometer.was_gesture('shake'):
display.clear()
sleep(1000)
display.scroll(random.choice(answers))
sleep(10)
単純なスラロームです。デバイスを動かして障害物を避けてください。
# 単純なスラローム 作成者:Larry Hastings 2015年9月。
#
# このプログラムはパブリックドメインで公開します。
import microbit as m
import random
p = m.display.show
min_x = -1024
max_x = 1024
range_x = max_x - min_x
wall_min_speed = 400
player_min_speed = 200
wall_max_speed = 100
player_max_speed = 50
speed_max = 12
while True:
i = m.Image('00000:'*5)
s = i.set_pixel
player_x = 2
wall_y = -1
hole = 0
score = 0
handled_this_wall = False
wall_speed = wall_min_speed
player_speed = player_min_speed
wall_next = 0
player_next = 0
while True:
t = m.running_time()
player_update = t >= player_next
wall_update = t >= wall_next
if not (player_update or wall_update):
next_event = min(wall_next, player_next)
delta = next_event - t
m.sleep(delta)
continue
if wall_update:
# 新しいスピードを計算
speed = min(score, speed_max)
wall_speed = wall_min_speed + int((wall_max_speed - wall_min_speed) * speed / speed_max)
player_speed = player_min_speed + int((player_max_speed - player_min_speed) * speed / speed_max)
wall_next = t + wall_speed
if wall_y < 5:
# 古い壁を消す
use_wall_y = max(wall_y, 0)
for wall_x in range(5):
if wall_x != hole:
s(wall_x, use_wall_y, 0)
wall_reached_player = (wall_y == 4)
if player_update:
player_next = t + player_speed
# 新しい X 座標を得る
x = m.accelerometer.get_x()
x = min(max(min_x, x), max_x)
# print("x accel", x)
s(player_x, 4, 0) # 古いピクセルをオフ
x = ((x - min_x) / range_x) * 5
x = min(max(0, x), 4)
x = int(x + 0.5)
# print("have", position, "want", x)
if not handled_this_wall:
if player_x < x:
player_x += 1
elif player_x > x:
player_x -= 1
# print("new", position)
# print()
if wall_update:
# 壁の位置を変更
wall_y += 1
if wall_y == 7:
wall_y = -1
hole = random.randrange(5)
handled_this_wall = False
if wall_y < 5:
# 新しい壁を表示
use_wall_y = max(wall_y, 0)
for wall_x in range(5):
if wall_x != hole:
s(wall_x, use_wall_y, 6)
if wall_reached_player and not handled_this_wall:
handled_this_wall = True
if (player_x != hole):
# 衝突! ゲームオーバー!
break
score += 1
if player_update:
s(player_x, 4, 9) # 新しいピクセルをオン
p(i)
p(i.SAD)
m.sleep(1000)
m.display.scroll("Score:" + str(score))
while True:
if (m.button_a.is_pressed() and m.button_a.is_pressed()):
break
m.sleep(100)
コンパス¶
このモジュールを使うと内蔵の電子コンパスにアクセスできます。使用する前にコンパスを調整する必要があります。調整しておかないと検知を誤る可能性があります。
警告
コンパスの調整を開始すると、調整が完了するまでプログラムが一時停止します。調整は、デバイスを回転させてLEDディスプレイに円を描く小さなゲームとなっています。
関数¶
-
microbit.compass.
calibrate
()¶ 調整処理を開始します。指示メッセージがユーザにスクロールで示された後、LEDディスプレイ上に円を描くようデバイスを回転させます。
-
microbit.compass.
is_calibrated
()¶ 調整が成功したかどうかにより
True
またはFalse
を返します。
-
microbit.compass.
clear_calibration
()¶ 調整を取り消し、コンパスを調整されていない状態にします。
-
microbit.compass.
get_x
()¶ x
軸の磁場強度をナノテスラで得ます。磁場の方向に応じて正または負の整数値になります。
-
microbit.compass.
get_y
()¶ y
軸の磁場強度をナノテスラで得ます。磁場の方向に応じて正または負の整数値になります。
-
microbit.compass.
get_z
()¶ z
軸の磁場強度をナノテスラで得ます。磁場の方向に応じて正または負の整数値になります。
-
microbit.compass.
heading
()¶ 3軸の磁力から計算された方位を返します。値は時計回りの角度を示す 0 から 360 までの整数で、0 は北となります。
-
microbit.compass.
get_field_strength
()¶ デバイスのまわりの磁場の強さを示す整数値をナノテスラで返します。
サンプルコード¶
"""
compass.py
~~~~~~~~~~
方位磁石の作成。
まず最初にコンパスを調整する必要があります。
コンパスは内蔵の時計イメージを使って針の位置を表示します。
"""
from microbit import *
# 調整の開始
compass.calibrate()
# 針が(大まかに)正しい方向を向くようにします
while True:
sleep(100)
needle = ((15 - compass.heading()) // 30) % 12
display.show(Image.ALL_CLOCKS[needle])
ディスプレイ¶
このモジュールは、ボードの前面にある 5×5 LED ディスプレイを制御します。イメージ、アニメーション、テキストの表示に利用できます。

関数¶
-
microbit.display.
get_pixel
(x, y)¶ x
列y
行の LEDの明るさを返します。返り値は 0 (オフ)から 9 (明るい)までの整数値です。
-
microbit.display.
set_pixel
(x, y, value)¶ x
列y
行の LEDの明るさを設定します。value
にはv 0 (オフ)から 9 (明るい)までの整数値を指定します。
-
microbit.display.
clear
()¶ すべての LED の明るさを 0 (オフ)に設定します。
-
microbit.display.
show
(image)¶ イメージ
image
を表示します。
-
microbit.display.
show
(image, delay=400, *, wait=True, loop=False, clear=False) image
が文字列、浮動小数点数、整数であれば、文字/数字を順番に表示します。image
がイメージの並びであれば、そのイメージの並びを順番に表示します。それぞれの文字、数字、イメージはdelay
ミリ秒間隔で表示されます。wait
がTrue
である場合、アニメーションが終了するまで関数がブロックし、False
の場合にはバックグラウンドで実行されます。loop
がTrue
である場合、アニメーションが永遠に繰り返します。clear
がTrue
である場合、表示が終了後にディスプレイをクリアします。wait
,loop
,clear
引数は、キーワードを用いて指定する必要があることに注意してください。
注釈
iterable
でジェネレータを使う場合、ジェネレータでメモリをアロケートしないよう注意してください。割り込みでメモリをアロケートすると MemoryError
が起きます。
-
microbit.display.
scroll
(text, delay=150, *, wait=True, loop=False, monospace=False)¶ ディスプレィ上に
text
を水平方向にスクロールさせます。text
が整数か浮動小数点数であれば、表示の前にstr()
を使って文字列に変換します。delay
パラメータはテキストのスクロール速度を制御します。wait
がTrue
である場合、アニメーションが終了するまで関数がブロックし、False
の場合にはバックグラウンドで実行されます。loop
がTrue
である場合、アニメーションが永遠に繰り返します。monospace
がTrue
である場合、文字は 5 ピクセル幅になります。False
の場合はスクロールでの文字間が 1 ピクセルのブランクになります。wait
,loop
,monospace
引数は、キーワードを用いて指定する必要があることに注意してください。
-
microbit.display.
on
()¶ ディスプレイを有効にします。
-
microbit.display.
off
()¶ ディスプレイを無効にするのは off() を使います(ディスプレイに関連づけられた GPIO 端子を他の目的に再利用できるようにします)。
-
microbit.display.
is_on
()¶ ディスプレイが有効であれば
True
、無効であればFalse
を返します。
-
microbit.display.
read_light_level
()¶ ディスプレイの LED を逆バイアスモードで利用して、ディスプレイのまわりの光量を検出します。戻り値は明度を表す 0 から 255 までの整数値で、値が大きいほど強い明度を意味します。
サンプルコード¶
ディスプレイに文字列を連続してスクロール表示することをバックグラウンドで実行します:
import microbit
microbit.display.scroll('Hello!', wait=False, loop=True)
I²C¶
i2c
モジュールを使えば BBC micro:bit に接続したデバイスと I²C バスプロトコルで通信できます。同時に複数のスレーブデバイスと通信つることができ、それぞれのデバイスには一意のアドレスがあります。このアドレスはデバイスに固定されているか、設定されています。BBC micro:bit は I²C マスタとして動作します。
ここ に書かれている理由により、デバイスには 7 ビットアドレッシングを使います。
これは、他の micro:bit 関連のソリューションと違っている可能性があります。
デバイスとどのくらい正確に通信する必要があるか、すなわち、送信するバイト数と応答の解釈方法は対象のデバイスに依存しますので、そのデバイスのドキュメンテーションを別途参照する必要があります。
関数¶
-
microbit.i2c.
init
(freq=100000, sda=pin20, scl=pin19)¶ 指定の端子
sda
とscl
と指定のクロック周波数freq
でデバイスを再初期化します。警告
I²C 端子をデフォルトから変更すると、加速度センサーやコンパスの動作が停止します。これらセンサーが内部でデフォルト以外の端子に結線されているからです。
-
microbit.i2c.
scan
()¶ デバイスのバスをスキャンします。スキャンに応答したデバイスに該当する7ビットアドレスのリストを返します。
-
microbit.i2c.
read
(addr, n, repeat=False)¶ 7 ビットアドレス
addr
のデバイスからn
バイトを読み込みます、repeat
がTrue
にすると、ストップビットが送られません。
-
microbit.i2c.
write
(addr, buf, repeat=False)¶ 7 ビットアドレス
addr
のデバイスにbuf
のバイト列を書き込みます、repeat
がTrue
にすると、ストップビットが送られません。
結線¶
デバイスの SCL
は micro:bit の端子 19 に、 SDA
は micro:bit の端子 20 に結線してください。また、デバイスのグランドを micro:bit のグランド(端子 GND
)に結線する必要があります。デバイスよっては外部電源または micro:bit から電力を供給する必要があります。
ボードの I²C ラインには内部にプルアップ抵抗がありますが、長い配線がある場合や多くのデバイスがある場合などでは、ノイズの無い通信を確保するために、プルアップ抵抗を追加する必要があります。
SPI¶
spi
モジュールを使用すると、シリアルペリフェラルインターフェイス(SPI)バスを使用して、ボードに接続されたデバイスと通信できます。SPI はいわゆる、単一マスターでのマスター/スレーブアーキテクチャを使用します。SPI は3つの信号の接続を指定する必要があります:
- SCLK : シリアルクロック(マスターから出力)。
- MOSI : マスター出力、スレーブ入力(マスターから出力)。
- MISO: マスター入力、スレーブ出力(スレーブから出力)。
関数¶
-
microbit.spi.
init
(baudrate=1000000, bits=8, mode=0, sclk=pin13, mosi=pin15, miso=pin14)¶ 指定の端子
pin
と指定のパラメータで SPI 通信を初期化します。正しい通信のためには、両方の通信デバイスでパラメータが同じでなければならないことに注意してください。baudrate
は通信速度を定義します。bits
は送信するバイト列のサイズを定義します。現在のところはbits=8
だけをサポートしています。しかし、これは将来的に変更するかもしれません。mode
は、以下の規則にしたがってクロックの極性と位相の組み合わせを決定します。極性は上位ビット、極性は下位ビットになります:SPI モード 極性 (CPOL) 位相 (CPHA) 0 0 0 1 0 1 2 1 0 3 1 1 極性(CPOL)が 0 の場合、クロックがアイドル時には論理値 0、アクティブ時にはハイ(論理値 1)になることを意味します。極性が 1 の場合、クロックがアイドル時には論理値 1、アクティブ時にはロー(論理値 0)になることを意味します。位相(CPHA)0 の場合はデータがクロックのリーディングエッジでサンプリングされ、1 の場合はトレーリングエッジでサンプリングされることを意味します(エッジについては https://en.wikipedia.org/wiki/Signal_edge を参照)。
sclk
,mosi
,miso
引数には、信号のそれぞれのタイプに使う端子を指定します。
-
spi.
read
(nbytes)¶ 最大
nbytes
を読み込みます。読み込んだものを返します。
-
spi.
write
(buffer)¶ バイト列の
buffer
をバスに書き出します。
-
spi.
write_readinto
(out, in)¶ out
バッファをバスに書き出し、応答をin
バッファに読み込みます。2つのバッファーの長さは同じでなければなりません。2つのバッファは同じオブジェクトでもかまいません。
UART¶
uart
モジュールを使用すると、シリアルインタフェースを使用してボードに接続されたデバイスと通信できます。
関数¶
-
microbit.uart.
init
(baudrate=9600, bits=8, parity=None, stop=1, *, tx=None, rx=None)¶ 指定の
tx
とrx
端子と指定のパラメータでシリアル通信を初期化します。正しい通信のためには、両方の通信デバイスでパラメータが同じでなければならないことに注意してください。警告
外部端子で UART を初期化すると、同じハードウェアを使っている USB で Python のコンソールにアクセスできなくなります。コンソールを元に戻すには、
tx
またはrx
を渡すことなく(あるいはこれらの引数にNone
を渡して)UART を再初期化する必要があります。つまり、uart.init(115200)
を呼び出すだけで、Python のコンソールを復元できます。baudrate
は通信速度を定義します。一般的なボーレートは次のとおりです:- 9600
- 14400
- 19200
- 28800
- 38400
- 57600
- 115200
bits
は送信するバイト列のサイズを定義します。現在のところはbits=8
だけをサポートしています。parity
パラメータはパリティのチェック方法を定義するもので、None
,microbit.uart.ODD
,microbit.uart.EVEN
を指定できます。stop
パラメータは、ストップビットの数を知らせるもので、このボードでは 1 にする必要があります。tx
とrx
を指定しない場合、内部の USB-UART TX/RX 端子を使用して micro:bit" の USB シリアルコンバータに接続し、UART を PC に接続します。望みの端子オブジェクトをtx
とrx
パラメータに渡すことにより、他の端子を使うように指定できます。注釈
デバイスを接続するときは、ワイヤを "交差させる" ことを確認してください。ボード上の TX 端子はデバイスの RX 端子と、RX 端子はデバイスの TX 端子と接続する必要があります。また、両方のデバイスのグランドピンが接続されていることを確認してください。
-
uart.
any
()¶ なにか待っているデータがあれば
True
を返し、さもなければFalse
を返します。
-
uart.
read
([nbytes])¶ バイト列を読み込みます。
nbytes
が指定されていれば、そのバイト数まで読み込みます。指定されていなければ、できるだけ多く読み込みます。戻り値: バイト列オブジェクト、タイムアウトが起きれば
None
。バイト列オブジェクトにはバイトの列が含まれます。ASCII 文字は1バイトに収めることができるので、このタイプのオブジェクトはしばしば単純なテキストを表現するために使われ、それをそのまま操作する方法を提供します。たとえば `` print()`` 関数を使ってテキストを表示できます。
このオブジェクトを文字列オブジェクトに変換することもできます。非 ASCII 文字が存在する場合は、エンコードを指定できます:
msg_bytes = uart.read() msg_str = str(msg, 'UTF-8')
注釈
すべての UART 読込みのタイムアウトはボーレートに依存していて、Pythonからは変更できません。タイムアウト値は次の式でミリ秒単位で決まります:
microbit_uart_timeout_char = 13000 / baudrate + 1
注釈
内部 UART RX バッファは 64 バイトなので、バッファがいっぱいになる前にデータを読み込んでください。さもないとデータが失われることになります。
警告
0x03
を受信すると、キーボード割り込みを起こしてプログラムを停止します。これを有効化/無効化するためにはmicropython.kbd_intr()
を使います。
-
uart.
readall
()¶ バージョン 1.0 から削除されました。
代わりに
uart.read()
を引数なしで使えば、できるだけ多くのデータを読み込みます。
-
uart.
readinto
(buf[, nbytes])¶ buf
にバイト列を読み込みます。nbytes
が指定されていれば、そのバイト数まで読み込みます。さもなければlen(buf)
のバイト数まで読み込みます。戻り値:
buf
に読み込んで格納したバイト数。タイムアウト時はNone
。
-
uart.
readline
()¶ 1行、すなわち改行文字まで読み込みます。
戻り値: 読み込んだ行。タイムアウト時は
None
。返すバイト列に改行文字は含まれます。
-
uart.
write
(buf)¶ バッファをバスにに書き出します。バッファはバイト列か文字列です:
uart.write('hello world') uart.write(b'hello world') uart.write(bytes([1, 2, 3]))
戻り値: 書き出したバイト数。タイムアウト時は
None
。
オーディオ¶
このモジュールは Microbit に接続されているスピーカーからサウンドを再生できるようにします。
audio
モジュールは import audio
でインポートするか、 microbit
モジュールの microbit.audio
にアクセスすることで利用できるようになります。
オーディオモジュールを使用するには、音源を用意する必要があります。
音源は、フレームのイテレーティブ(リスト、タプルなどのシーケンス、またはジェネレータ)であり、個々のフレームは32個のサンプルを持ちます。この audio
モジュールは、毎秒 7812.5 サンプルのレートでサンプルを再生します。つまり、最大 3.9 kHzの周波数を再生できます。
関数¶
-
audio.
play
(source, wait=True, pin=pin0, return_pin=None)¶ 音源を最後まで再生します。
パラメータ: - source -- イテレーティブな音源。各項目は
AudioFrame
である必要があります。 - wait --
wait
がTrue
の場合、音源の再生が終わるまでこの関数から戻りません。 - pin -- スピーカを接続した端子を指定します。
- return_pin -- スピーカのもう一方をつなぐ先として GND の代わりに接続する端子を指定します。
- source -- イテレーティブな音源。各項目は
クラス¶
オーディオの使い方¶
play
関数への入力として音源が必要になります。音源を自作する例は examples/waveforms.py
にあります。
技術的な詳細¶
注釈
audio
モジュールを使うのにこのセクションを理解する必要はありません。このモジュールがどのように機能するのか知りたい方のためにあります。
audio
モジュールは AudioFrame
インスタンスのイテレーティブ(リストまたはタプルなどのシーケンス、あるいはジェネレータ)を消費します。7812.5 Hz で各 32 サンプルを消費し、線形補間を使って 32.5 kHz の PWM 信号を出力します。これにより、許容できる音質が得られます。
関数 play
は、次のフレームを得るのに next()
呼び出す前に、 各 AudioFrame
からすべてのデータを完全にコピーするので、音源は同じ AudioFrame
を繰り返し使用できます。
audio
モジュールには64個のサンプルバッファがあり、そこからサンプルを読み取ります。読み取りがバッファの開始点または中間点に達すると、次の AudioFrame
を取り込むコールバックをトリガして、バッファにコピーします。これは、音源が次の AudioFrame
を処理するのに 4ms 以下かかり、信頼できる操作のために 2ms 以下を要する必要があることを意味します(32000 サイクルなので十分です)
サンプルコード¶
from microbit import display, sleep, button_a
import audio
import math
def repeated_frame(frame, count):
for i in range(count):
yield frame
# 次の波形に行くには A ボタンを押します。
def show_wave(name, frame, duration=1500):
display.scroll(name + " wave", wait=False,delay=100)
audio.play(repeated_frame(frame, duration),wait=False)
for i in range(75):
sleep(100)
if button_a.is_pressed():
display.clear()
audio.stop()
break
frame = audio.AudioFrame()
for i in range(len(frame)):
frame[i] = int(math.sin(math.pi*i/16)*124+128.5)
show_wave("Sine", frame)
triangle = audio.AudioFrame()
QUARTER = len(triangle)//4
for i in range(QUARTER):
triangle[i] = i*15
triangle[i+QUARTER] = 248-i*15
triangle[i+QUARTER*2] = 128-i*15
triangle[i+QUARTER*3] = i*15+8
show_wave("Triangle", triangle)
square = audio.AudioFrame()
HALF = len(square)//2
for i in range(HALF):
square[i] = 8
square[i+HALF] = 248
show_wave("Square", square)
sleep(1000)
for i in range(len(frame)):
frame[i] = 252-i*8
show_wave("Sawtooth", frame)
del frame
#三角波から方形波になる波形を、適度になめらかに生成。
frames = [ None ] * 32
for i in range(32):
frames[i] = frame = audio.AudioFrame()
for j in range(len(triangle)):
frame[j] = (triangle[j]*(32-i) + square[j]*i)>>5
def repeated_frames(frames, count):
for frame in frames:
for i in range(count):
yield frame
display.scroll("Ascending wave", wait=False)
audio.play(repeated_frames(frames, 60))
Bluetooth¶
BBC micro:bit は Bluetooth Low Energy (BLE)デバイスとして動作できるハードウェアを備えていますが、RAM は 16 KBしかありません。BLE スタックだけで 12k のRAMが必要になります。つまり、MicroPython が Bluetooth をサポートするのに十分なメモリがありません。
ローカル永続ファイルシステム¶
データの永続的な保存は、デバイスの再起動の間に変更されないようにしておくと便利です。従来のコンピュータでは、生データを保持する名前付きファイルとファイルを含む名前付きディレクトリで構成されるファイルシステムによって実現されているものが多いです。Python は、そのようなファイルシステムで作業するために必要なさまざまな操作をサポートしています。
ただし、micro:bit はハードウェアとストレージの両方の容量で制限されたデバイスなので、MicroPython はデバイス上のデータを保持するために必要な機能の小さなサブセットを提供します。メモリの制約のため、ファイルシステムの 記憶域は約 30 KB となっています
警告
デバイスを再フラッシュするとデータが破棄されます。
ファイルシステムは micro:bit のフラッシュメモリに保存されているため、デバイスをフラッシュするとフラッシュメモリがすべて書き換えられるため、すべてのデータが失われます。
ただし、デバイスの電源を切っただけではデータはそのまま残り続けます。データが消えるのは、ファイルを削除するか(後述)、デバイスを再フラッシュした場合です。
micro:bit の MicroPython は、フラットファイルシステムを提供します。すなわち、ディレクトリ階層の概念がなく、ファイルシステムは名前付きファイルのリストにすぎません。ファイルの読み書きは、標準 Python と同様の open タイプの関数と、この関数が返す TextIO
または BytesIO
型のファイル形式オブジェクト(ファイルを表す)によって実現されます。ファイルシステム上のファイルを操作する操作(ファイルの一覧表示や削除など)は os
モジュール内にあります。
ファイル拡張子 .py
のついたファイルがある場合は、それをインポートできます。たとえば、ファイル名 hello.py
は import hello
でインポートできます。
MicroPython の REPL から操作してみた例は、次のようになります。
>>> with open('hello.py', 'w') as hello:
... hello.write("print('Hello')")
...
>>> import hello
Hello
>>> with open('hello.py') as hello:
... print(hello.read())
...
print('Hello')
>>> import os
>>> os.listdir()
['hello.py']
>>> os.remove('hello.py')
>>> os.listdir()
[]
-
open
(filename, mode='r')¶ 引数
filename
に指定されたファイルを表すファイルオブジェクトを返します。モードのデフォルトは 'r' で、テキストモードでの読み込みを意味します。もう1つの共通モードは 'w' で、書き込み用です(すでに存在する場合はファイルの内容を上書きします)。上で説明したものと組み合わせて使用できる他の2つのモードは、't'
のテキストモード(文字列の読み書き用)と'b'
のバイナリモード(バイトの読み書き用)を意味します。これらが指定されていない場合は't'
(テキストモード)とみなされます。テキストモードでは、ファイルオブジェクトはTextIO
のインスタンスになります。バイナリモードでは、ファイルオブジェクトはBytesIO
のインスタンスになります。たとえば、'rb'
はバイナリデータをファイルから読み込むために使用します。
-
class
TextIO
¶ -
class
BytesIO
¶ これらのクラスのインスタンスは、micro:bit のフラットファイルシステム内のファイルを表します。TextIO クラスは、テキストファイルを表すために使われます。BytesIO クラスは、バイナリファイルを表すために使われます。TextIO は文字列を扱い、BytesIO はバイト列を扱う点を除いて、まったく同じように動作します。
これらのクラスを直接インスタンス化するわけではありません。むしろ、適切に構成されたクラスのインスタンスは、上記の
open
関数によって返されます。-
close
()¶ ファイルをフラッシュして閉じます。このメソッドは、ファイルがすでにクローズしている場合は効果がありません。ファイルがクローズしていると、そのファイルに対する操作(たとえば、読み込みまたは書き込み)によって例外が発生します。
-
name
()¶ オブジェクトが表すファイルの名前を返します。これは 、オブジェクトをインスタンス化する
open
関数を呼び出す際に渡すfilename
引数と同じになります。
-
read
(size)¶ ファイルから最大
size
文字の単一文字列またはsize
バイトを読み込んで返します。便宜上、size
が与えられないか -1 の場合はファイルに含まれるすべてのデータが返されます。ファイルから読み込む残りがsize
未満である場合、size
より小さな文字列またはバイト列が返されます。長さが 0 の文字列またはバイト列が返され場合、
size
指定が 0 でなければファイルの終わりを示します。size
が使用可能な RAM より大きい場合には MemoryError 例外が発生します。
-
readinto
(buf, n=-1)¶ バッファ
buf
に文字列またはバイト列を読み込みます。n
が指定された場合は、バッファbuf
に指定のバイト数または文字数を読み込みます。
-
readline
(size)¶ ファイルから1行を読み込んで返します。
size
を指定すると、最大size
文字が読み込まれます。行終端は常に文字列では
'\n'
、バイト列ではb'\n'
です。
-
writable
()¶ 書き込みをサポートしていれば
True
を返しますこれがFalse
の場合にwrite()
を行うとOSError
が発生します。
-
write
(buf)¶ バッファ
buf
の文字列またはバイト列をファイルに書き込み、書き込んだ文字数またはバイト数を返します。
-
Machine¶
machine モジュールは micro:bit ハードウェアに関連する固有の関数を含んでいます。このモジュールのほとんどの機能はシステム上のハードウェアブロック(CPU、タイマー、バスなど)への直接的かつ無制限のアクセスと制御を実現します。誤って使用すると、誤動作、ロックアップ、ボードのクラッシュ、および極端な場合にはハードウェアの損傷を招く可能性があります。
関数¶
-
machine.
unique_id
()¶ ボードの一意な識別子を持つバイト列を返します。この値はボードの個体ごとに異なります。
-
machine.
reset
()¶ 外部 RESET ボタンを押すのと同じようにデバイスをリセットします。
-
machine.
freq
()¶ CPU周波数をヘルツ単位で返します。
-
machine.
disable_irq
()¶ 割り込み要求を無効にします。無効にする前の IRQ 状態を返しますが、これは不明瞭な値とみなす必要があります。この戻り値は
machine.disable_irq()
を呼び出す前の元の状態に割り込みを復元するためにmachine.enable_irq()
関数に渡す必要があります。
-
machine.
enable_irq
(state)¶ 割り込み要求を再度有効にします。 state パラメータは
machine.disable_irq()
関数の最も最近の呼び出しから返された値である必要があります。
-
machine.
time_pulse_us
(pin, pulse_level, timeout_us=1000000)¶ 指定の pin にパルスの持続時間をマイクロ秒単位で返します。 pulse_level 引数には、低パルスの時間計測で 0、高パルスの時間計測で 1 を指定します。
ピンの現在の入力値が pulse_level と異なる場合、関数は最初にピン入力が pulse_level に等しくなるまで待機し(*)、次にそのピンが pulse_level に等しい時間を測ります(**)。ピンが既に pulse_level に等しい場合、計測はすぐに開始されます
タイムアウトが発生した場合、上記の(*)の状態を待っていた場合は -2 を返し、上記の(**)の場合は -1 を返します。タイムアウト時間は両方のケースで同じで、 timeout_us (マイクロ秒単位)で指定します。
メモリの読取り¶
machine
モジュールでは、物理アドレスを指定してデバイスのメモリから、1バイト(8ビット; mem8
)、2バイト(16ビット; mem16
)、4バイト(32ビット; mem32
)のワードを取得できます。たとえば mem8[0x00]
は、物理アドレス 0x00
の1バイトを読み取ります。これには nRF51 レジスタからデータを読み取るなど、さまざまな用途があります。
MicroPython¶
MicroPython 内部のアクセスと制御
関数¶
-
micropython.
const
(expr)¶ コンパイルが最適化できるように、式が定数であることを宣言するために使います。この関数の使い方は次のとおりです:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
このように宣言された定数でも、宣言されているモジュールの外部からグローバル変数としてアクセス可能です。一方、定数名がアンダースコアで始まっていれば不可視となり、グローバル変数として利用でくなくなり、実行中のメモリを消費しません
-
micropython.
opt_level
([level])¶ level を指定した場合、この関数はスクリプトの後続のコンパイルの最適化レベルを設定して、 None を返します。指定しない場合は、現在の最適化レベルを返します。
最適化レベルは、次のコンパイル特性を制御します。
- アサーション: レベル 0 では、アサーションステートメントが有効になり、バイトコードにコンパイルされます。レベル 1 以上ではアサーションがコンパイルされません。
- 組込み
__debug__
変数: レベル 0 でこの変数が True に展開されます。レベル 1 以上では False で展開されます。 - ソースコード行番号: レベル 0, 1, 2 では、ソースコードの行番号がバイトコードとともに格納され、例外が発生した行番号を例外として報告することができます。レベル 3 以上では行番号が格納されません。
デフォルトの最適化レベルは通常レベル 0 です。
-
micropython.
mem_info
([verbose])¶ 現在使っているメモリに関する情報を表示します。 verbose を指定すると冗長モードとなり、詳しい情報を表示します。
-
micropython.
qstr_info
([verbose])¶ 現在のところのインターンド文字列(内部に蓄えられている文字列)に関する情報を表示します。 verbose を指定すると冗長モードとなり、詳しい情報を表示します。
これは現在のインターンド文字列の数とそれが使っている RAM のサイズは含みます。冗長モードでは RAM 上のインターンド文字列すべての名前を表示します。
-
micropython.
stack_use
()¶ 現在使われているスタックのサイズを表す整数を返します。この値そのものは特に有用ではなく、異なる時点でのスタック使用量の違いを計算するために使用されるべきです。
-
micropython.
heap_lock
()¶
-
micropython.
heap_unlock
()¶ ヒープをロックまたはロック解除します。ロックされているとメモリ割り当ては発生せず、ヒープを割り当てようとした場合は MemoryError が発生します。
-
micropython.
kbd_intr
(chr)¶ KeyboardInterrupt 例外を発生させる文字を設定します。デフォルトでは、スクリプト実行中の Ctrl-C に該当する 3 が設定されています。この関数に -1 を渡すと Ctrl-C のキャプチャが無効になり、3 を渡すと元に戻ります。
この関数は、通常は REPL で使っている文字の入力ストリームを他の目的で使う場合に、そのストリームで Ctrl-C がキャプチャーされるのを防ぐために使えます。
ミュージック¶
ミュージックのための music
モジュールが用意されています。スピーカーをボードに接続すれば、簡単な曲を演奏することができます。デフォルトで、music
モジュールはスピーカーが端子 0 を介して接続されることを期待しています:

この結線は(後述するように)変更できます。
このモジュールにアクセスするには、以下が必要です:
import music
以降の例ではこれを行ったと仮定します。
ミュージック表記¶
個々の音は次の形式で指定します:
NOTE[octave][:duration]
たとえば A1:4
は音名(NOTE) "A"、オクターブ(octave) 1、長さ(duration)が 4 ティックであることを意味します(ティックは後述するテンポ設定機能で定義された任意の長さです)。音の名前に R
が指定されている場合は、休符(無音)として扱われます。
臨時記号(フラットとシャープ)は b
(フラット - 小文字の b)と #
(シャープ - ハッシュ記号)で示されます。たとえば Ab
は A フラットであり C#
は C シャープです。
音名は大文字と小文字を区別しません。
オクターブ octave
と長さ duration
パラメータは、再び指定されるまで、後続の音に引き継がれます。デフォルトの状態は octave = 4
(ミドルの C を含む)と duration = 4
(後述のテンポ設定でデフォルトで与えられている4分音符)です。
たとえば、4 ティックが4分音符の場合、以下のリストは、4分音符、8分音符、8分音符、4分音符ベースのアルペジオです。
['c1:4', 'e:2', 'g', 'c2:4']
ベートーヴェンの第5交響曲のオープニングは次のようにコード化されるでしょう:
['r4:2', 'g', 'g', 'g', 'eb:8', 'r:2', 'f', 'f', 'f', 'd:8']
1 オクターブの定義と範囲は、 このページの科学的な音程表記についての表 にしたがいます。たとえば、ミドル "C" は 'c4'
で、コンサート "A" (440)は 'a4'
です。オクターブは音 "C" で始まります。
関数¶
-
music.
set_tempo
(ticks=4, bpm=120)¶ 再生するためのおおよそのテンポを設定します。
(整数で表される)ティック数
ticks
が1ビートを構成します。各ビートは、1分あたりの特定の周波数で再生されます(これはよく知られた BPM - beats per minute - を整数で指定します)。推奨されるデフォルト値では、次のような便利な動作が可能です:
music.set_tempo()
- テンポをデフォルト値の ticks = 4, bpm = 120 にリセットするmusic.set_tempo(ticks=8)
- ビートの「定義」を変更するmusic.set_tempo(bpm=180)
- テンポを変えるだけです
ミリ秒単位でティックの長さは非常に簡単な計算で求まります:
60000/bpm/ticks_per_beat
。デフォルト値は60000/120/4 = 125 ミリ秒
または1 beat = 500 ミリ秒
となります。
-
music.
get_tempo
()¶ 現在のテンポを整数のタプル
(ticks, bpm)
として取得します。
-
music.
play
(music, pin=pin0, wait=True, loop=False)¶ 先に説明したミュージック表記を含んだ
music
を演奏します。music
が文字列ならば'c1:4'
のような単一の音であることが期待されます。music
が音のリストとして指定されている場合(上記のミュージック表記で説明されていたように)、それらは順番に演奏されてメロディを演奏します。どちらの場合も、
duration
とoctave
の値は、音楽が再生される前にデフォルトにリセットされます。出力端子を指定するためのオプションの引数を使用して、出力端子のデフォルト
microbit.pin0
を変更できます。wait
がTrue
の場合、この関数はブロックします。loop
がTrue
の場合、曲はstop
(後述)が呼ばれるか、ブロックが解除されるまで繰り返し演奏されます。
-
music.
pitch
(frequency, duration=-1, pin=pin0, wait=True)¶ 指定されたミリ秒間の整数周波数でピッチを再生します。たとえば、周波数を 440 に設定し、長さを 1000 に設定すると、標準のコンサート A が1秒間聞こえます。
一度に一つの端子で一つのピッチしか再生できないことに注意してください。
wait
がTrue
の場合、この関数はブロックします。duration
が負の場合、ブロックが解除されるか、バックグラウンドで新しい周波数が設定されるか、stop
(後述)が呼び出されるまで、ピッチが連続して再生されます。
-
music.
stop
(pin=pin0)¶ 指定された端子のすべての音楽再生を停止します。たとえば
music.stop(pin1)``のように使います。``music.stop()
のように端子を指定しない場合は pin0 が指定されたものとします。
-
music.
reset
()¶ 次のように属性の状態をリセットします:
ticks = 4
bpm = 120
duration = 4
octave = 4
内蔵メロディ¶
教育と娯楽の目的のために、このモジュールには、Python のリストとして表現されるいくつかの楽曲が含まれています。これらは次のように使用できます:
>>> import music
>>> music.play(music.NYAN)
すべての曲は、著作権で保護されていないか、Nicholas H.Tollervey によって構成され、パブリックドメインに公開されているか、未知の作曲家による公平(教育的)使用規定の対象です。
内蔵されている曲は以下のとおりです:
DADADADUM
- ベートーヴェンの第5番交響曲第5番のオープニング曲。ENTERTAINER
- スコット・ジョプリンのラグタイム・クラシック"The Entertainer"
のオープニング部分。PRELUDE
- J.S.バッハの 48 のプレリュードとフーガの C メジャーの第1回プレリュードのオープニング。ODE
- ベートーヴェンの第9回シンフォニー・ミー・マイナーのテーマ"Ode to Joy"
NYAN
- Nyan Cat テーマ (http://www.nyan.cat/)。作曲家は不明です。これは educational porpoises にとって(彼らがニューヨークで言っているように)公正な利用です。RINGTONE
- 携帯電話の着信音のようなもの。着信メッセージを示すために使います。FUNK
- シークレット・エージェントと犯罪の黒幕のためのファンキーなベースライン。BLUES
- ブギー・ウーギーの 12 小節のブルース・ウォーキング・ベース。BIRTHDAY
- "Happy Birthday to You ..." の著作権表示については http://www.bbc.co.uk/news/world-us-canada-34332853 を参照してください。WEDDING
- ワグナーのオペラ「Lohengrin」のブライダルコーラス。FUNERAL
- フレデリック・ショパンのピアノソナタ第2番「B♭マイナー」の別名「葬儀の行進」35。PUNCHLINE
- ジョークが行われたことを意味する楽しい部分。PYTHON
- John Philip Sousa さんの行進「Liberty Bell」、別名「Monty Python's Flying Circus」(その後、Python プログラミング言語の名前となる)。BADDY
- 無声映画時代の悪役の登場。CHASE
- 無声映画時代のチェイスシーン。BA_DING
- 何かが起こったことを示す短い信号。WAWAWAWAA
- 非常に悲しいトロンボーン。JUMP_UP
- ゲームでの使用で、上方向の動きを示します。JUMP_DOWN
- ゲームでの使用で、下向きの動きを示します。POWER_UP
- パワーが解放されたことを示すファンファーレ。POWER_DOWN
- パワーが失われたことを示すための悲しい運命。
サンプルコード¶
"""
music.py
~~~~~~~~
microPython の music モジュールを使って簡単な曲を演奏します。
このサンプルでは、P0 と GND の端子にスピーカー/ブザー/ヘッドホンを繋ぐ必要があります。
"""
from microbit import *
import music
# C (4分の4拍子)でプレリュードを演奏。
notes = [
'c4:1', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5',
'c4', 'd', 'a', 'd5', 'f5', 'a4', 'd5', 'f5', 'c4', 'd', 'a', 'd5', 'f5', 'a4', 'd5', 'f5',
'b3', 'd4', 'g', 'd5', 'f5', 'g4', 'd5', 'f5', 'b3', 'd4', 'g', 'd5', 'f5', 'g4', 'd5', 'f5',
'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5',
'c4', 'e', 'a', 'e5', 'a5', 'a4', 'e5', 'a5', 'c4', 'e', 'a', 'e5', 'a5', 'a4', 'e5', 'a5',
'c4', 'd', 'f#', 'a', 'd5', 'f#4', 'a', 'd5', 'c4', 'd', 'f#', 'a', 'd5', 'f#4', 'a', 'd5',
'b3', 'd4', 'g', 'd5', 'g5', 'g4', 'd5', 'g5', 'b3', 'd4', 'g', 'd5', 'g5', 'g4', 'd5', 'g5',
'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5',
'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5',
'd3', 'a', 'd4', 'f#', 'c5', 'd4', 'f#', 'c5', 'd3', 'a', 'd4', 'f#', 'c5', 'd4', 'f#', 'c5',
'g3', 'b', 'd4', 'g', 'b', 'd', 'g', 'b', 'g3', 'b3', 'd4', 'g', 'b', 'd', 'g', 'b'
]
music.play(notes)
NeoPixel¶
neopixel
モジュールを使用すると、個別にアドレス可能な RGB LED または RGBW LED である NeoPixel (WS2812) を micro:bit で使えます。この neopixel
モジュールを使うには以下のモジュールのインポートが必要です:
import neopixel
注釈
From our tests, the Microbit NeoPixel module can drive up to around 256 NeoPixels. Anything above that and you may experience weird bugs and issues. The micro:bit can only supply 90mA to external devices, larger numbers of NeoPixels require an external power supply with common ground.
NeoPixel は 5V で動作するように設計されていますが、幸いにもBBCマイクロビットの 3V 電源を使って動作します。micro:bit の エッジコネクタは 5V を供給するものに接続しないでください。
NeoPixel はマルチカラーのプログラマブルな面白い LED ボードです。このモジュールには、micro:bit にプラグインするためのすべてが含まれており、以下に示すデモなどのファンキーなディスプレイ、アート、ゲームを作成できます。

Image attribution: adafruit flexible Neopixel matrix
neopixel ボードを接続するには、以下のように micro:bit を接続する必要があります(これは NeoPixel を端子 0 から駆動したい場合ですが、端子 1 や 2 に接続することもできます)。ワニ口クリップのラベルは、NeoPixel ボードにもう一方の端を取り付ける場所を示しています。VDD 端子は、NeoPixel によっては何か他のラベル、たとえば "V+" がついているかもしれません。ものによっては "+5V" とついていることもありますが、他に 5V のデバイスが繋がっていないのであれば問題ありません。
警告
micro:bit の 3V 端子から、一度に8つ以上の NeoPixel に給電しないでください。
8つ以上の NeoPixel を使用する場合は、ネオピクセルの電源端子に別の 3v - 5v 電源を使用する必要があります。

クラス¶
-
class
neopixel.
NeoPixel
(pin, n, bpp=3)¶ 端子
pin
を介して制御するn
個の neopixel LED を持つストリップを初期化します。RGBW neopixel もサポートするため、ピクセルあたりのバイト数(bpp
)を示す第3引数をNeoPixel
に渡せるようになっています。"RGBW の場合は bpp に4
を指定します。デフォルトの bpp は RGB と GRB を示す3
です。各ピクセルは(0から始まる)位置によってアドレス指定されます。NeoPixel にはタプルとして0-255 の RGB (赤, 緑, 青) / RGBW (赤, 緑, 青, 白) が与えられます。たとえば
(255,255,255)
は白になります。白を RGBW で指定する場合は(255,255,255,0)
または(0,0,0,255)
となります。-
clear
()¶ すべてのピクセルをクリアします。
-
show
()¶ ピクセルを表示します。更新が表示するには、これを呼び出す必要があります
-
演算子¶
色を書き込んでも表示は更新されません(表示するには show()
を呼び出します)。
np[0] = (255, 0, 128) # 最初の素子
np[-1] = (0, 255, 0) # 最後の素子
np.show() # 更新された値が表示されます
特定のピクセルの色を読み取るには、それを参照するだけです。
print(np[0])
NeoPixel の使い方¶
NeoPixel とのやりとりは、それがタプルのリストであるかのように行えます。各タプルは、特定のピクセルの色の RGB (赤, 緑, 青) / RGB (赤, 緑, 青, 白) の組み合わせを表します。RGBW 値の範囲は 0 から 255 までです。
たとえば、次のように pin0 に接続された 8 個の RGB ピクセルを持つ NeoPixel ストリップを初期化します:
import neopixel
np = neopixel.NeoPixel(pin0, 8)
それらピクセルを(Python のリストのように)インデックス付けして設定します。たとえば、最初のピクセルを最大照度の赤に設定するには次のようにします:
np[0] = (255, 0, 0)
最後のピクセルを紫色にするには次のようにします:
np[-1] = (255, 0, 255)
ピクセルの現在のカラー値を得るには、インデックス付けして参照します。たとえば、最初のピクセルの RGB 値を表示するには次のようにします。
print(np[0])
最後に、新しい色データを NeoPixel ボードの表示に反映するには、.show()関数を使います:
np.show()
何も起こらない場合、おそらくあなたはこの最終ステップを忘れてしまっているのです..!
注釈
NeoPixel ボードで何か変化が見られない場合、少なくともアップデートしたものが表示されていなければ、 show()
を確認してください。
サンプルコード¶
"""
neopixel_random.py
LED ボードにランダムな色を繰り返し表示します。
このサンプルでは、8 Neopixel のボード(WS2812)を pin0 に接続する必要があります。
"""
from microbit import *
import neopixel
from random import randint
# 8 ピクセルの Neopixel ボードを pin0 に接続されていることを設定
np = neopixel.NeoPixel(pin0, 8)
while True:
# ボードにある各 LED について繰り返し
for pixel_id in range(0, len(np)):
red = randint(0, 60)
green = randint(0, 60)
blue = randint(0, 60)
# 現在の LED を 0〜60 のランダムな赤、緑、青の値に設定
np[pixel_id] = (red, green, blue)
# Neopixel ボード上の現在のピクセルデータを表示
np.show()
sleep(100)
os
モジュール¶
MicroPython は Python 標準ライブラリの os
モジュールをベースにした os
モジュールを持っています。これは、伝統的にオペレーティングシステムに依存した機能にアクセスするために使われます。MicroPython にはオペレーティングシステムがないため、このモジュールはデバイス上の簡易な永続オンデバイスファイルシステムの管理や現在のシステムの情報に関連した機能を提供します。
このモジュールにアクセスするには、以下を行う必要があります:
import os
以降の例では、これが行われていることを前提としています。
関数¶
-
os.
listdir
()¶ ローカル永続オンデバイスファイルシステムにあるファイルすべての名前のリストを返します。
-
os.
remove
(filename)¶ 引数
filename
で指定した名前のファイルを削除します。ファイルが存在しない場合はOSError
例外が起きます。
-
os.
size
(filename)¶ 引数
filename
で指定した名前のファイルのサイスをバイト数で返します。ファイルが存在しない場合はOSError
例外が起きます。
-
os.
uname
()¶ 現在のオペレーティングシステムを識別する情報を返します。戻り値は次の5属性を持つオブジェクトです。
sysname
- オペレーティングシステム名nodename
- ネットワークのマシン名 (実装定義)release
- オペレーティングシステムのリリースversion
- オペレーティングシステムのバージョンmachine
- ハードウェア識別子
注釈
MicroPython にはオペレーティングシステムがありません。uname
関数が返す結果は、バージョンの詳細を知るためのものとして使います。
無線通信¶
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
()¶ 無線通信をオンにします。無線通信は電力を消費し、他で必要となるかもしれないメモリも占有するため、明示的に呼び出す必要があります。
-
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)]
# 無線を使うためのスィッチをオンにします。
radio.on()
# イベントループ。
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') # それっ
乱数生成¶
このモジュールは Python 標準ライブラリの random
モジュールをベースにしています。このモジュールはランダムな振舞いを生成する関数を持っています。
このモジュールにアクセスするには、以下を行う必要があります:
import random
以降の例では、これが行われていることを前提としています。
関数¶
-
random.
getrandbits
(n)¶ n
乱数ビット数を持つ整数を返します。
警告
基本となるジェネレータ関数は最大で 30 ビットを返すため、 n
は 1〜30 の値のみにできます。
-
random.
seed
(n)¶ 乱数ジェネレータを指定の整数
n
で初期化します。これは、与えられた開始状態(n
)から再現性のある決定論的なランダム性を与えます。
-
random.
randint
(a, b)¶ a <= N <= b
となるような整数の乱数N
を返します。これはrandrange(a, b+1)
と同等です。
-
random.
randrange
(stop)¶ 0 から
stop
未満までの間で無作為に選択された整数を返します。
-
random.
randrange
(start, stop) range(start, stop)
から無作為に選択された整数を返します。
-
random.
randrange
(start, stop, step) range(start, stop, step)
から無作為に選択された要素を返します。
-
random.
choice
(seq)¶ 空でないシーケンス
seq
からランダムな要素を返します。seq
が空の場合は、IndexError
が発生します。
-
random.
random
()¶ range(0.0, 1.0) から無作為に選択された浮動小数点数を返します。
-
random.
uniform
(a, b)¶ a <= b
の場合にa <= N <= b
、b < a
の場合にb <= N <= a
となるような浮動小数点数の乱数N
を返します。
音声¶
このモジュールで micro:bit に話をさせ、歌わせ、その他の音声のようなサウンドを作るのにスピーカーを以下に示すようにボードに接続するという前提で説明します。

注釈
この作業は、コモドール64のために1982年に最初にリリースされた SAM (Software Automated Mouth)と呼ばれる古い TTS (text-to-speech)プログラムに対して Sebastian Macke が行った驚くべきリバースエンジニアリングの努力に基づいています。結果として小さな C ライブラリが出きあがり、我々は micro:bit にそれを採用して適合させました。 彼のホームページ からもっと知ることができます。このドキュメントの情報の多くは、 ここ `here にある元のユーザーズマニュアルから取ってきています 。
音声シンセサイザーは、最大255文字のテキスト入力から約2.5秒分の音量を生成できます。
このモジュールにアクセスするには、以下を行う必要があります:
import speech
以降の例では、これが行われていることを前提としています。
関数¶
-
speech.
translate
(words)¶ 文字列
words
にある英単語の並びについて、発声するのに最適な音素を推測して、文字列として返します。出力は、 このテキスト-音素変換テーブル にしたがって生成されます。この関数は、音素の近似を最初に生成するために使うべきです。この結果を元に手で編集して、精度、屈曲、強調を改善することができます。
-
speech.
pronounce
(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)¶ 文字列
phonemes
が表す音素を発声します。音声合成器の出力を細かく制御するために音素を使用する方法の詳細については後述します。オプションの pitch, speed, mouth, throat の設定を上書きして、声の音色(音質)を変更します。
-
speech.
say
(words, *, pitch=64, speed=72, mouth=128, throat=128)¶ 文字列
words
にある英単語の並びを発声します。結果は実際の英語の半分程度の精度です。オプションの pitch、speed、mouth、throat の設定を上書きして、声の音色(音質)を変更します。この関数は次の呼び出しを短くしたものです:speech.pronounce(speech.translate(words))
-
speech.
sing
(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)¶ 文字列
phonemes
が表す音素を歌います。音符のピッチと持続時間を変更する方法は後述します。オプションの pitch、speed、mouth、throat の設定を上書きして、声の音色(音質)を変更します。
句読点¶
句読点は、音声の伝達を変更するのに使います。シンセサイザーは、ハイフン、カンマ、フルストップ、疑問符の4つの句読点を認識します。
ハイフン (-
)は音声に短い休止を入れることによって、句を区切ります。
カンマ (,
)はハイフンの約2倍のポーズを挿入することにより、フレーズを区切ります。
終止符 (.
) と疑問符 (?
) の終了文。
終止符はポーズを挿入し、ピッチを落とします。
疑問符もポーズを挿入しますが、ピッチが上がります。これは "are we home yet?" のような yes/no で答えられる質問に適しています"why are we going home?" のようなより複雑な質問では終止符を使ってください。
音色¶
音色は音の質です。それは、(たとえば) DALEK の声と人間の声の違いです。音色を制御するには、pitch
, speed
, mouth
, throat
引数の数値設定を変更します。
pitch (音程の高低)と speed (音声の速さ)の設定はかなり明白で、一般的に次のカテゴリに分類されます。
pitch:
- 0-20 実用的でない
- 20-30 非常に高い
- 30-40 高い
- 40-50 高めのノーマル
- 50-70 ノーマル
- 70-80 低めのノーマル
- 80-90 低い
- 90-255 非常に低い
(デフォルトは 64)
speed:
- 0-20 実用的でない
- 20-40 非常に速い
- 40-60 速い
- 60-70 早口な会話
- 70-75 普通の会話
- 75-90 説話
- 90-100 遅い
- 100-225 非常に遅い
(デフォルトは 72)
mouth と throat の値は説明するのが少し難しく、以下の説明は、各設定の値が変更されたときに生成される音声の聴覚の印象に基づいています。
mouth については、数字が低いほどスピーカーが唇を動かさずに話しているように聞こえます。対照的に、数字が高いほど(最大255)、声が誇張された口の動きで発声されるように聞こえます。
throat については、数が少ないほどスピーカーの響きが緩和されます。対照的に、数字が高いほど、緊張感が増します。
重要なことは、望む声の音を得る最良の方法は、実験を繰り返して調整することです。
とっかかりとして、いくつかの例を示しておきます:
speech.say("I am a little robot", speed=92, pitch=60, throat=190, mouth=190)
speech.say("I am an elf", speed=72, pitch=64, throat=110, mouth=160)
speech.say("I am a news presenter", speed=82, pitch=72, throat=110, mouth=105)
speech.say("I am an old lady", speed=82, pitch=32, throat=145, mouth=145)
speech.say("I am E.T.", speed=100, pitch=64, throat=150, mouth=200)
speech.say("I am a DALEK - EXTERMINATE", speed=120, pitch=100, throat=100, mouth=200)
音素¶
say
関数は音声を簡単に作成できます - しかし、正しくないことがよくあります。音声シンセサイザーにあなたの望むよう正しく発音させるためには、 音素を使う必要があります: 音素は知覚的に区別できる最小の単位で、異なる単語を区別するために使えます。基本的に、それは音声のビルディング・ブロック・サウンドです。
pronounce
関数は、簡略化された読みやすい形式の 国際音声アルファベット とオプションの注釈を含む文字列を使用して、屈曲と強調を示します。
音素を使用する利点は、綴り方を知る必要がないことです。むしろ、それを音声学的に綴るためには、言葉の使い方を知る必要があります。
以下の表は、シンセサイザが理解している音素の一覧です。
注釈
このテーブルには、音素と文字の例文が含まれています。例の単語は、音素の音を(かっこ内に)持ちますが、同じ文字である必要はありません。
見過ごされがちなこと: "H" の音のシンボルは /H
です。声門停止は音の強制停止です
単純母音 有声音
IY f(ee)t R (r)ed
IH p(i)n L a(ll)ow
EH b(e)g W a(w)ay
AE S(a)m W (wh)ale
AA p(o)t Y (y)ou
AH b(u)dget M Sa(m)
AO t(al)k N ma(n)
OH c(o)ne NX so(ng)
UH b(oo)k B (b)ad
UX l(oo)t D (d)og
ER b(ir)d G a(g)ain
AX gall(o)n J (j)u(dg)e
IX dig(i)t Z (z)oo
ZH plea(s)ure
二重母音 V se(v)en
EY m(a)de DH (th)en
AY h(igh)
OY b(oy)
AW h(ow) 無声音
OW sl(ow) S (S)am
UW cr(ew) SH fi(sh)
F (f)ish
TH (th)in
特殊な音素 P (p)oke
UL sett(le) (=AXL) T (t)alk
UM astron(om)y (=AXM) K (c)ake
UN functi(on) (=AXN) CH spee(ch)
Q kitt-en (glottal stop) /H a(h)ead
次の非標準シンボルもユーザーが使用できます:
YX diphthong ending (weaker version of Y)
WX diphthong ending (weaker version of W)
RX R after a vowel (smooth version of R)
LX L after a vowel (smooth version of L)
/X H before a non-front vowel or consonant - as in (wh)o
DX T as in pi(t)y (weaker version of T)
あまり使われない音素の組み合わせ(および提案された選択肢)は次のとおりです:
PHONEME YOU PROBABLY WANT: UNLESS IT SPLITS SYLLABLES LIKE:
COMBINATION
GS GZ e.g. ba(gs) bu(gs)pray
BS BZ e.g. slo(bz) o(bsc)ene
DS DZ e.g. su(ds) Hu(ds)son
PZ PS e.g. sla(ps) -----
TZ TS e.g. cur(ts)y -----
KZ KS e.g. fi(x) -----
NG NXG e.g. singing i(ng)rate
NK NXK e.g. bank Su(nk)ist
上記の音素以外のものを使用すると ValueError
例外が発生します。音素を次のような文字列として渡します。
speech.pronounce("/HEHLOW") # "Hello"
音素は母音と子音という2つの大きなグループに分類されます。
母音はさらに単純母音と二重母音に分けられます。単純母音は発音してみるとおり音が変わることはありません。二重母音は一つの音で始まり別の音で終わります。たとえば "oil" という言葉を言うとき、"oi" の母音は "oh" 音で始まり、"ee" 音に変化します。
子音もまた有声音と無声音の2つのグループに分けられます。有声音は、その音声を生成するために、その有声子音のコードを使用する必要があります。たとえば、 "L", "N", "Z" のような子音が発音されます。無声音の子音は、"P", "T", "SH" などの急速な息によって生成されます。
一度このようなことに慣れると、音素システムは簡単です。まず、いくつかのスペルは難しいように見えるかもしれません(たとえば、 "adventure" には "CH" があります)が、ルールはあなたが言うことを書くことであり、スペルは書きません。問題のある単語を解決するには、実験が最善の方法です。
音声は自然で分かりやすく理解できることも重要です。口頭による出力の質を向上させるために、内蔵のストレスシステムを使用して屈曲または強調を追加することはよくあります。
数字 1
- 8
で示される8つのストレスマーカーがあります。ストレスを与える母音の後に必要な番号を挿入するだけです。たとえば、"/HEHLOW" の表記が欠けているのは、 "/HEH3LOW" と書かれているとはるかに改善されています。
また、ストレスを感じる方法で言葉の意味を変えることも可能です。"Why should I walk to the store?" というフレーズを考えてみてください。それはいくつかの異なる方法で発音することができます:
# You need a reason to do it.
speech.pronounce("WAY2 SHUH7D AY WAO5K TUX DHAH STOH5R.")
# You are reluctant to go.
speech.pronounce("WAY7 SHUH2D AY WAO7K TUX DHAH STOH5R.")
# You want someone else to do it.
speech.pronounce("WAY5 SHUH7D AY2 WAO7K TUX DHAH STOHR.")
# You'd rather drive.
speech.pronounce("WAY5 SHUHD AY7 WAO2K TUX7 DHAH STOHR.")
# You want to walk somewhere else.
speech.pronounce("WAY5 SHUHD AY WAO5K TUX DHAH STOH2OH7R.")
簡単に言えば、言葉遣いのストレスによって、表現力豊かな声調が得られます。
これらはあなたが与える数に応じて、ピッチを上げたり下げたり、関連する母音を伸ばしたりすることによって動作します:
- 非常に感情的なストレス
- 非常に強調したストレス
- かなり強いストレス
- 普通のストレス
- タイトストレス
- ニュートラル(ピッチ変化なし)ストレス
- ピッチ落ちストレス
- 極端なピッチ落ちのストレス
数値が小さいほど、極端に強調されます。しかし、このようなストレスマーカーは難しい言葉を正しく発音するのに役立ちます。たとえば、音節が十分に強調されていない場合は、中立のストレスマーカーを入れます。
ストレスマーカーを使って単語を伸ばすこともできます:
speech.pronounce("/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP.”)
歌唱¶
MicroPython に音素を歌わせることは可能です。
これは音素にピッチ関連の番号を注釈することによって行います。数字が小さいほど、ピッチが高くなります。数字はおおよそ次の図に示すように音符に変換されます。

注釈は、音素の前にハッシュ記号(#
)とピッチ番号をあらかじめ付けておくことにより有効となります。新しい注釈が与えられるまで、ピッチは同じままになります。たとえばを次のようにして MicroPython に音階を歌わせます。
solfa = [
"#115DOWWWWWW", # ド
"#103REYYYYYY", # レ
"#94MIYYYYYY", # ミ
"#88FAOAOAOAOR", # ファ
"#78SOHWWWWW", # ソ
"#70LAOAOAOAOR", # ラ
"#62TIYYYYYY", # シ
"#58DOWWWWWW", # ド
]
song = ''.join(solfa)
speech.sing(song, speed=100)
特定の音符を歌わせるには、母音や母音の音韻を繰り返します(上記の例を参照)。二重母音に注意してください。これを伸ばすには、それらを構成部品に分解する必要があります。たとえば、 "OY" は ""OHOHIYIYIY" で伸ばすことができます。
試聴、慎重な聴取、調整は、音を望むだけ伸ばすよう何回音素を繰り返すかを決める唯一確実な方法です。
どのような仕組みなのですか?¶
オリジナルのマニュアルはそれをうまく説明しています:
まず、実際の音声波形を記録する代わりに、周波数スペクトルのみを保存します。こうすることで、メモリを節約し、他の利点も得られます。第2に、私たちは [...] タイミングに関するいくつかのデータを保存します。これらは、異なる状況下での各音素の継続時間に関連する数字があり、そしてまた遷移時間についてのいくつかのデータがあるので我々は隣り合った音素のブレンド方法を知ることができます。第3に私たちはこのデータをすべて処理するためのルールを考案しました。驚いたことに、私たちのコンピュータはすぐに何かしゃべりはじめました。
—S.A.M. オーナマニュアル。
出力は audio
モジュールによって提供される関数を介してパイプされます。あーら不思議、話す micro:bit のできあがりです。
サンプルコード¶
"""
speech.py
~~~~~~~~
micro:bit に何かを言わせたり、発音させたり、歌わせたりするための簡単な
speech の利用例です。
この例では P0 と GND に接続されたスピーカー/ブザー/ヘッドフォン、
またはスピーカー内蔵の最新の micro:bit デバイスが必要です。
"""
import speech
from microbit import sleep
# say メソッドは英語から音素への変換を試みます。
speech.say("I can sing!")
sleep(1000)
speech.say("Listen to me!")
sleep(1000)
# throat をクリーンにするには音素を使う必要があります。
# pitch と speed を変更することでも適切な効果が得られます。
speech.pronounce("AEAE/HAEMM", pitch=200, speed=100) # えへん
sleep(1000)
# 歌わせるには各音節ごとに音階の音素が必要です。
solfa = [
"#115DOWWWWWW", # ド
"#103REYYYYYY", # レ
"#94MIYYYYYY", # ミ
"#88FAOAOAOAOR", # ファ
"#78SOHWWWWW", # ソ
"#70LAOAOAOAOR", # ラ
"#62TIYYYYYY", # シ
"#58DOWWWWWW", # ド
]
# 音階が順に高くなっていくよう歌わせます。
song = ''.join(solfa)
speech.sing(song, speed=100)
# 音節のリストの順番を逆にします。
solfa.reverse()
song = ''.join(solfa)
# 音階が順に低くなっていくよう歌わせます。
speech.sing(song, speed=100)
utime¶
utime
モジュールには、現在の時間の取得、時間隔を測定、遅延についての関数があります。
注釈
utime
モジュールは、標準の Python の time
モジュールの MicroPython 版です。import utime
でも import time
でもインポートできますが、モジュールは同じものです。
関数¶
-
utime.
sleep
(seconds)¶ 指定された秒数の間スリープします。秒より細かい精度で指定したい場合は浮動小数点数を使うか、
utime.sleep_ms()
やutime.sleep_us()
関数を使ってください。
-
utime.
sleep_ms
(ms)¶ 指定のミリ秒間だけ遅延します。ミリ秒の指定は 0 以上の整数である必要があります。
-
utime.
sleep_us
(us)¶ 指定のマイクロ秒間だけ遅延します。マイクロ秒の指定は 0 以上の整数である必要があります。
-
utime.
ticks_ms
()¶ 呼出し時点での稼働時間をミリ秒単位で返します。稼働時間は最大値に達するとラップアラウンドします(一周して最低値に戻ります)。
-
utime.
ticks_us
()¶ 上記の
utime.ticks_ms()
と同じですが、マイクロ秒単位となります。
-
utime.
ticks_add
(ticks, delta)¶ 与えた数をティック値からのオフセットとして加算した値を返します。引数の値は正でも負でもかまいません。この関数は、ティック値のモジュール算術定義にしたがい、与えた ticks 値とその前後の delta ティックからティック値を算出します。
サンプルコード:
# 100ms 前のティック値を調べます print(ticks_add(time.ticks_ms(), -100)) # 操作やテストのためのデッドラインを算出します deadline = ticks_add(time.ticks_ms(), 200) while ticks_diff(deadline, time.ticks_ms()) > 0: do_a_little_of_something() # このポートの TICKS_MAX を調べます print(ticks_add(0, -1))
-
utime.
ticks_diff
(ticks1, ticks2)¶ utime.ticks_ms()
やticks_us()
関数の戻り値(ラップアラウンドである可能性のある符号付きの値)の間のティック値の差を計算します。引数の順序は減算演算子と同じで、
ticks_diff(ticks1, ticks2)
はticks1 - ticks2
と同じ意味を持ちます。utime.ticks_diff()
は、さまざまな使用パターンに対応するように設計されています:タイムアウトのポーリング - この場合、イベントの順序は既知であり、次のように
utime.ticks_diff()
の正の結果のみを処理します:# GPIOピンから入力があるのを待つが、最大でも50usまで start = time.ticks_us() while pin.value() == 0: if time.ticks_diff(time.ticks_us(), start) > 500: raise TimeoutError
イベントのスケジューリング - この場合、イベントが期限切れになると
utime.ticks_diff()
の結果が負になります:# このコードは最適化されていません now = time.ticks_ms() scheduled_time = task.scheduled_time() if ticks_diff(scheduled_time, now) > 0: print("Too early, let's nap") sleep_ms(ticks_diff(scheduled_time, now)) task.run() elif ticks_diff(scheduled_time, now) == 0: print("Right at time!") task.run() elif ticks_diff(scheduled_time, now) < 0: print("Oops, running late, tell task to run faster!") task.run(run_faster=true)
MicroPython のビルドと転送¶
MicroPython のビルド¶
MicroPython のビルドには yotta ツールを使います。ビルドの前には準備として Makefile で追加のファイルを生成しなければなりません。ビルドの後には付加データを hex ファイルに追加します。
リポジトリをクローンして、ディレクトリを移動します:
$ git clone https://github.com/bbcmicrobit/micropython
$ cd micropython
micro:bit のターゲットを使うように yotta に設定します::"
yotta target bbc-microbit-classic-gcc-nosd@https://github.com/lancaster-university/yotta-target-bbc-microbit-classic-gcc-nosd
yotta update を実行してリモートアセットを取得します::"
yotta up
makefile を使ってビルドを開始します:
make all
ビルドの結果、 firmware.hex
が build/
ディレクトリに作成されます。このファイルが micro:bit にコピーするものです。
Makefile はソースに対して追加の前処理を行います。これは qstrdefsport.h
に新しい登録済み文字列を追加する場合にのみ必要です。また、Makefile はビルド結果のファームウェア を build/firmware.hex に置き、いくつかの便利なターゲットを含みます。
Python プログラムを含んだ MicroPython の用意¶
tools/makecombinedhex.py
を使って、MicroPython ファームウェアにPython スクリプトを結合し、micro:bit にアップロードする hex ファイルを生成できます。
./makecombinedhex.py <firmware.hex> <script.py> [-o <combined.hex>]
出力先オプション(-o
)を指定しない場合、スクリプトは stdout
に出力します。
tools/hexlify.py
を使って、Pythonスクリプトを Intel HEX 形式に変換できます。結果は MicroPython の firmware.hex の最後に連結できます。簡単なヘッダーがスクリプトに追加されます:
./hexlifyscript.py <script.py>
標準入力からもデータを受けつけます。
micro:bit への転送¶
micro:bit を USB で接続すると MICROBIT
という名前の USB マスストレージデバイスとしてマウントされます。この USB ドライブに .hex ファイルをコピーするとmicro:bit に自動的に転送され、プログラムの実行を開始します。
REPL へのアクセス¶
REPL (Read-Evaluate-Print-Loop)は、プログラムコードを書いたそばからコードを読み込んで評価します。
micro:bit Python エディタを使う方法¶
ブラウザベースの Python エディタには組込みの REPL サポートがあり、 WebUSB を使ってアクセスできます。WebUSB がどのように使われているかについては、記事 direct flashing from the browser in the micro:bit apps and editors に詳しく説明されています。
WebUSB を使うには、Google Chrome ベースのブラウザとバージョン 0249 以上の ファームウェア を入れた micro:bit が必要です。
REPL を使う手順は次のとおりです:
- まだ Python プログラムを micro:bit に転送をしていない場合は転送します。
- Open Serial を選択して、REPL ウィンドウを開きます。
- 青いバー
Send CTRL-C for REPL
をクリックするか、キーボードからCTRL
+C
を入力して REPL に入ります。
シリアル通信プログラムを使う方法¶
Mu Editor は REPL を組み込みでサポートしていますし、リアルタイムデータプロッターも用意しています
picocom や screen があります。いずれにしても、通信プログラムをインストールし、適切なドキュメントを読んでデバイスに接続するための基本を理解する必要があります。
ポートの判別¶
micro:bit の REPL にアクセスするには次が必要です:
- micro:bit の通信ポート識別子の判別
- デバイスと通信するプログラムの用意
micro:bit にはコンピュータとの通信に使うポート識別子(tty, usb)を持ちます。micro:bit に接続する前に、ポート識別子を判別する必要があります。
Windows¶
前述したドライバをインストールすると micro:bit がデバイスマネージャに COM ポートとして現れます。
macOS¶
ターミナルを開いて ls /dev/cu.*
と入力し、接続されているシリアルデバイスのリストを確認します。リストの中に /dev/cu.usbmodem1422
のようなものが見つかります(実際の番号はコンピュータに依存)。
Linux¶
ターミナルで dmesg | tail
と入力し、micro:bit に割り当てられた /dev
ノードを確認します。
micro:bit との通信¶
ポート識別子を確認したら、シリアルターミナルプログラムを使って micro:bit と通信できます。
Windows¶
Tera Term, PuTTY など使いたいものをどうぞ。
- Tera Term の場合:
- micro:bit を繋ぎ、Tera Term を開きます
- Select Serial as the port
- 設定メニューからシリアルポートを選び、ポートを適切な COM ポートにします。
- ボーレートを
1115200
、データを 8 ビット、パリティを none、ストップを 1 bit にします。
- PuTTY の場合:
- micro:bit を繋ぎ、PuTTY を開きます
- 接続タイプをシリアルに切り替えます
- ポートを適切な COM ポートにします
- ボーレートを
115200
にします - 左のメニューの「シリアル」を選び、'Open' をクリックします
macOS¶
ターミナルを開いて screen /dev/cu.usbmodem1422 115200
を入力します。/dev/cu.usbmodem1422
のところは先に調べたポートに置き換えてください。これは micro:bit のシリアル出力をオープンし、デバイスから受信したメッセージすべてを表示します。
終了するには Ctrl-A の後に Ctrl-\ を入力し、質問に Yes と答えます。コマンドプロンプトに戻る方法は他にもあり、Ctrl-A の後に Ctrl-D を入力しても戻れますが、これでは画面が切り離されるだけで、シリアルポートはロックされたままになり、他のアプリケーションがアクセスできなくなります。そのようなときは screen -r
と入力することで screen を再起動できます。
Linux¶
Ubuntu など、Debian ベースのデストリビューションに繋ぐには、自分のユーザ名を dialout
グループに追加する必要があります。これにより、シリアルデバイス /dev/ttyACM0
への書込みアクセスが許可されます:
sudo usermod -a -G dialout ${USER}
グループの変更を有効にするには再ログインが必要です。
screen
プログラムを使う場合、screen /dev/ttyUSB0 115200
を入力します。/dev/ttyUSB0
のところは先に調べたポートに置き換えてください。
終了するには Ctrl-A
の後に \
を入力し、質問に Yes と答えます。コマンドプロンプトに戻る方法は他にもあり、Ctrl-A の後に Ctrl-D を入力しても戻れますが、これでは画面が切り離されるだけで、シリアルポートはロックされたままになり、他のアプリケーションがアクセスできなくなります。そのようなときは screen -r
と入力することで screen を再起動できます。
picocom
プログラムを使う場合、picocom /dev/ttyACM0 -b 115200
を入力します。/dev/ttyACM0
のところは先に調べたポートに置き換えてください。
終了するには Ctrl-A の後に Ctrl-Q を入力します。
MicroPython Hex ファイル¶
MicroPythonをビルドすると、コンパイラは MicroPython ファームウェアを含む Intel Hex ファイルを生成します。このファイルにデータを追加して、MicroPython バージョン情報、または起動時に実行する Python コードを含められます。
一般的なメモリレイアウトは次のとおりです:
0x00000000
: MicroPython ファームウェアの先頭 - 最大 248 KB0x0003e000
: 追加スクリプトの先頭(オプション) - 最大 8 KB0x100010c0
: UICR カスタマー[16]レジスター, MicroPython 情報の先頭 - 28バイト
注釈
Intel Hex ファイルにデータを追加したり変更したりする場合は、データのアドレスが増分順に格納されていることを確認してください。後方にアドレスジャンプがある場合、DAPLink はファイルをフラッシュできません。
UICR フォーマット¶
ユーザー情報構成レジスター (UICR: User Information Configuration Registers)は、不揮発性メモリーの領域で、ユーザー固有の設定を保管できます。最初の128バイトは予約されていますが、残りの128バイトを使用して任意のデータを格納できます。
MicroPython は、UICR カスタマー[16]レジスターから開始して、リトルエンディアンで次の情報を格納します。
0x100010c0
: 4バイト整数のマジック値0x17eeb07c
0x100010c4
: 4バイト整数値0xffffffff
0x100010c8
: 4バイト整数値0x0000000a
(フラッシュページサイズ 1024 の2進対数)0x100010ca
: 2バイト整数値0x0000
(ファームウェアの開始ページ)0x100010cc
: ファームウェアのページ数の2バイト整数値0x100010d0
: 4バイト整数値0xffffffff
0x100010d4
: ファームウェア内のバージョン文字列のあるアドレスを示す4バイト整数値0x100010d8
: 4バイト整数値0x00000000
firmware.hex ファイルを作成する手順¶
MicroPython をビルドするには yotta ツールを使いますが、その前にビルドの準備として Makefile で追加のファイルを生成しなければなりません。追加のデータは後で hex ファイルに追加されます。
make all
コマンドを実行すると、以下の順序で処理されます:
tools/makeversionhdr.py
スクリプトがmicrobitversion.h
ファイルを作成します。このファイルはビルド情報をもったマクロを定義しています。- yotta がソースをビルドし、ファームウェアだけの生の hex ファイルを作成します
tools/adduicr.py
スクリプトが生の hex ファイルに UICR を追加します- 完成した hex ファイルを
build/firmware.hex
に置きます - ユーザは、オプションで
tools/makecombinedhex.py
(または他のツール)を使ってスクリプトを追加できます
ユーザースクリプトのインクルード¶
ユーザースクリプトは MicroPython ファイルシステムに保存され、main.py スクリプトが存在すれば MicroPython の起動時に実行されます。追加の Python スクリプトを main.py ファイルや REPL からインクルードして実行することもできます。
ファイルシステムを作成し、それをHEXファイルにインクルードします。Python エディタは MicroPython V1 と V2 の HEX ファイルにファイルシステムを追加し、両方のハードウェアの互換性を確保するために両方を Universal HEX ファイルに結合しなければなりません。
追加スクリプトの形式(廃止予定) V1¶
スクリプトを MicroPython の最後に追加する方法は現在では使われていません。Python ファイルは ファイルシステム に格納されるようになり、 main.py
がプログラムの入り口になります。
MicroPython はアドレス 0x0003e000
の先頭2バイトをチェックします。これは、追加スクリプトがあるかを示すマジック文字列です。マジック文字列が見つかった場合、MicroPython ファイルシステム に main.py ファイルが格納されていない限り、追加されている Python コードを自動的に実行します。
0x0003e000
: 2 バイト "MP"0x0003e002
: 2バイト、追加されたスクリプトの長さ(バイト単位)のリトルエンディアン整数(この長さにヘッダ4バイト分は含みません)0x0003e004
: バイト列として格納したスクリプト。MicroPython で使う際には utf-8 でデコードします。
貢献¶
やあ! micro:bit の MicroPython を改善したいと思ってくれてありがとう。
貢献は、年齢、性別、宗教、人種、性別にかかわらず、誰の 迷惑にならずに大歓迎です。尊敬、ユーモア、インテリジェンスのある良質なコードと関与はいつも勝利をもたらします。
- かなりギークなグループで、うまく表せないものがあるなら参加してください - あなたの作り出した違いを手助けしたいと思います* 。
- かなりギークなグループで、うまく表せ られる ものがあるなら参加してください - あなたの作り出した違いを手助けしたいと思います 。
- 技術的に十分ではないと心配している場合は、参加してください - 新しい視点は非常に貴重です 。
- 自分が詐欺師だと思ったら、参加してください。
- 日常の業務がコードでなければ、参加してください。
- これはエキスパートのグループではなく、ただの人々です。参加してください!
- これは新しいコミュニティなので、参加してください。
貢献者は、Python Software Foundation の行動規範に従うことを期待しています: https://www.python.org/psf/codeofconduct/
貢献者にはフィードバックがあります。必要に応じて変更が丁寧に要求され、元の著者と議論されます。尊重しながらも堅実な議論は大歓迎です。
チェックリスト¶
- あなたのコードは 普通の英語 (英国のスペル)でコメントする必要があります。
- あなたの貢献が主要な作業ブロックのためのものであれば、そこにある慣習にしたがって、あなた自身を著者(AUTHORS)ファイルに追加しておいてください。
- 疑義がある場合は、質問をしてください。唯一の愚かな質問は、決して聞かれない質問です。
- 楽しんで!