Raspberry Pi 2でMicroPythonを体験しよう


★この記事はMicroPython Advent Calendar 2018に参加しています。★

この1年の締めくくりとして、Raspberry Pi 2で使えるMicroPythonお試し環境を作ってみたので紹介します。

USBキーボード(日本語配列)とHDMIでのコンソール、SDカードの読み書きを有効にしてありますので、Raspberry Pi 2があれば使ってみることができます。
(Raspberry Pi 2専用で、Pi 3では使えません)

準備

必要なファイルは以下のZIPファイルと、Raspberry Piのファームウェア(bootcode.bin、start.elf、fixup.dat)です。

mp-rpi2-20181223.zip(for JP keyboard)
mp-rpi2-20181228-uskbd(for US keyboard)

Raspbian等を使っているなら、ファームウェアは既にSDカードに入っているはずです。また、最新版のファームウェアはRaspberry Piのサイトからダウンロードできます。

ZIPファイルを展開し、全体をそのままSDカードのルートディレクトリにコピーしてください。

SDカードに既にconfig.txtが入ってる場合は、そのファイルのファイル名を変えるなどして、元に戻せるようにしておいてください。

起動

Raspberry Pi 2をモニタにつないで起動すると、2秒程度でこんな感じの画面が出ます。

USBキーボードから入力できるはずですが、今回用意したソフトウェアとキーボードとの相性問題が出る可能性もあります(その場合はあきらめてください)。

help()

と入力してみてください。ヘルプメッセージが出ればOKです。

os.listdir()

と入力すると、カレントディレクトリのファイル/フォルダのリストが得られます。
これはコマンドではなくPythonの関数なので、戻り値はPythonのオブジェクトです。

osモジュールで用意されている関数の一覧は、

dir(os)

で表示できます。

osモジュールの関数の詳細はuosモジュールの解説を参照してください。(MicroPythonではosモジュールはuosモジュールの別名として定義されています。)

ファイルの表示・実行

ファイルをオープンするのはopen(‘filename’)、オープンしたファイルを読むのはread()です。
例えばファイルconfig.txtの中身を画面に表示するには、以下のようにします。

print(open('config.txt').read())

ファイルを実行するには、exec()を使います。
実行可能なサンプルのPythonスクリプトを用意してありますので、以下のように入力して試してみてください。

exec(open('basic/01.py').read())

下の写真のように矩形が表示されます。

カーソルの上矢印キーを押すと、過去の入力履歴を呼び出すことができ、呼び出した履歴を編集して再度入力することもできます。
一つ前の入力を呼び出し、execをprintに修正して、サンプルの中身を確認してみてください。

print(open('basic/01.py').read())

boot.pyとmain.py

basic/01.pyの中を見ると、scrという変数が出てきます。
これはMicroPythonに組み込まれた変数ではなく、main.pyの中で宣言されている変数です。

MicroPythonは、起動後にboot.py、次いでmain.pyを(ファイルが存在していれば)実行することになっています。
これを使ってスイッチオンで動作する組み込みシステムを作ることができます。

今回のお試し用システムは、main.pyで以下のような処理を行っています。(boot.pyは何もしていません。)

・Raspberry Pi 2のフレームバッファオブジェクトを作成
・そのフレームバッファを用いて、フレームバッファをコンソール代わりに使うFBConsoleクラスのオブジェクトscrを作成
・os.dupterm(scr)でMicroPythonのREPLをscrへ出力するよう指定

これによって、「電源を入れるとスクリーンにREPLが出力されるシステム」を作っています。

サンプルプログラム

「basic/」フォルダの中に、7つのサンプルを入れてあります。
それぞれ、内容は以下の通りです。

・basic/01.py 画面に矩形を描画
・basic/02.py ボード上のLEDを5回点滅(ループ+スリープ)
・basic/03.py 画面上の矩形を点滅(タイマ割込み)
・basic/04.py 画面上の2つの矩形を異なるタイミングで点滅(タイマ割込み×2)
・basic/05.py 画面にSDカードから読み出したビットマップ画像を描画
・basic/06.py 画面にマンデルブロ集合を描画
・basic/07.py ヘッドホンジャックから鋸波、矩形波、三角波のサウンドを出力

なお、現状では、USBキーボードからCTRL-Cでプログラムをストップさせることができません(シリアルポートからなら可能です)。そのため、02.pyは無限ループではなく規定回数分のループになっています。

また、FPUがうまく動作しておらず、ソフトウェアで浮動小数点演算をさせています。そのため、マンデルブロ集合の計算はとても遅いです。そのうちFPU対応にしたいと思いますが、今回は見逃して下さい。

終わりに

ようやく動くようになったばかりの、Raspberry Pi 2用のMicroPythonのご紹介でした。
Raspberry Pi 2だけで完結するようにしたので、できることは限定的ではありますが、MicroPythonの雰囲気を感じてもらえれば幸いです。

MicroPythonのご利益はハードウェアを抽象化する(多様なハードウェアを論理的には同一のものと見なせるようにする)点にではなく、抽象化されていないリアルなハードウェアへ対話的にアクセスできる点にあると思っています。

たとえば、今回のサンプルにはPinクラスを用いてLEDを点滅させるスクリプトを入れてありますが、BCM2835のデータシートのGPIOの章を読み解けば、同じことをPinクラスを使わずに、レジスタを直接読み書きして実現することも可能です。

データシートとにらめっこしながらメモリマップドI/Oを直接叩いて、ハードウェアがデータシートの通りには動いてくれなくて悩む、という体験を楽しんでいただければと思います。

コメント