「MicroPython化」はBBC micor:bitで3機種目であったのですが、このほど4機種目を追加いたしました。Seeed Studio社Wio Terminalであります。MicroPythonの実装としてはArduPyというお名前で呼ばれているもの。MicroPythonとして共通する部分は多いものの比べてみるといろいろと違いもあり。
※「MicroPython的午睡」投稿順 Indexはこちら
まずは Wio Terminal のMicroPython化です。SeeedStudio社のArduPy Wikiページへ行けば手順が書かれています。しかし個人的には
SeeedStudio社のYouTubeチャネルの
Wio Terminal Classroom with Ardupy #1 | Getting Started with Ardupy
をお勧めしたいです。必要な情報はWikiページみれば全てかかれているのだけれど、髭のLakshanthaお兄さん(時々髭が無くなることもある)が実際に操作しているところを見ると「それで良いのね」的な非文章的なものが伝わってくるのであります。
さて、Wio Terminal上でもArduPy(MicroPython)が動作しました。過去に「MicroPython化」したものも含めると手元には4機種、MicroPythonの実行環境があることになります。
- M5StickV上のMicroPython実装であるMaix.py
- M5StickC上のUIFlowのバックエンド?のMicroPython
- BBC micro:bit上のMicroPython
- Wio Terminal上のMicroPython実装であるArdupy
それぞれのハードウエアや開発環境等の制約があり、それぞれに特徴(違い)のある実装になっています。M5StickVはAIマイコンKendryte K210とカメラの組み合わせでありPC側のIDEも含めAIにフォーカスしています。M5StickCの実装はビジュアルなブロックプログラミング環境のバックエンドです。モジュール化した部品を簡単に使えるように工夫されています。ただし、どちらも同じM5Stack社による実装なので共通するマナーで拡張されている感じがいたします。後日4機種の比較を整理しておくかとも考えますが、とりあえず今回は後ろ2つの環境について、Pythonから使えるモジュールを中心とした比較としたいです。前2つ、M5StickVについてはこちら、M5StickCについてはこちらの投稿をご参照ください。以下は、
「モダンOSのお砂場(10) MicroPython、モジュールとhelp」
でM5StickVのMicroPythonについて調べたときと同様に、REPL使ってどんなモジュールのどんな機能が使えるのが簡単に調べてみた結果です。
BBC micro:bit
UARTを明示的に操作していなければUSBでPCに接続すればCOMポートが見えて適当なターミナルソフトで接続できると思います。私は伝統的にTeraTerm派。デフォルトで115200,8N1だと思うので該当のCOMポートに接続します。ただし、micro:bit上で既にPythonのスクリプトが走り続けていると思われるので
CTRL-C
でスクリプトの実行を中断させ、REPLのプロンプトに返ってこさせます。
KeyboardInterrupt: MicroPython v1.9.2-34-gd64154c73 on 2017-09-01; micro:bit v1.0.1 with nRF51822 Type "help()" for more information. >>>
その際、MicroPythonのバージョンとか表示されます。help()使えと勧められるので使ってみると操作方法について「インフォーマティブな」ことが書いてあります。使用可能なモジュールの一覧は、help(‘modules’)でできます。
>>> help('modules') __main__ love os time antigravity machine radio ucollections array math random ustruct audio microbit speech utime builtins micropython struct collections music sys gc neopixel this Plus any modules on the filesystem
パッと見、他を圧して「love」というモジュールが目に入るので、ついimportしてみました。
>>> import love
このモジュールはimportするだけで走り始め、micro:bitのLEDアレイにハートマークを点滅表示しました。インプレッシブ?多分、BBC micro:bitならでは。他のモジュールの中身を覗くためには一度importしてからクオートせずにhelpを使います(モジュール名をクオートすると文字列についての説明をいただいてしまいます。)まずはmicro:bitのハードウエアを利用するメインとなる microbit モジュール
>>> import microbit >>> help(microbit) Useful stuff to control the micro:bit hardware.
既に microbit モジュールには何度もお世話になっており、多くの機能が含まれていることを知っています。でも多すぎてhelp()では出してくれないみたい。オンラインで詳細なドキュメント(日本語もあり)があるのでそちらを見よ、ということでしょう。他に気になるモジュールだけ見ておくと
>>> import machine >>> help(machine) object <module 'machine'> is of type module __name__ -- machine unique_id -- <function> reset -- <function> freq -- <function> disable_irq -- <function> enable_irq -- <function> mem8 -- <8-bit memory> mem16 -- <16-bit memory> mem32 -- <32-bit memory> time_pulse_us -- <function>
micro:bitのmachineモジュールにはリセットとか割り込みとかメモリ操作とか「危ない」ものどもが隠れています。
>>> import sys >>> help(sys) object <module 'sys'> is of type module __name__ -- sys version -- 3.4.0 version_info -- (3, 4, 0) implementation -- (name='micropython', version=(1, 9, 2)) platform -- microbit byteorder -- little exit -- <function> print_exception -- <function>
sysモジュールにはmicro:bit実装関係の情報が。
>>> help(os) object <module 'os'> is of type module __name__ -- os remove -- <function> listdir -- <function> size -- <function> uname -- <function> >>> os.listdir('/') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: function takes 0 positional arguments but 1 were given >>> os.listdir() ['main.py']
osモジュールにはファイルシステムの操作関係が含まれますが、かなり限定的です。他の実装では、os.listdir()には引数としてパス文字列を渡せるのですが、micro:bit実装では引数なしです。上のように引数与えるとエラーになります。micro:bitの実装でも一応ファイルシステムが用意されているのですが、階層構造なしフラットで、容量も限られたものです。「永続的」と銘うたれていますがFlashメモリの一部を転用しているのでFlashを書き換えると消えてしまいます。
>>> import micropython >>> help(micropython) object <module 'micropython'> is of type module __name__ -- micropython const -- <function> opt_level -- <function> mem_info -- <function> qstr_info -- <function> stack_use -- <function> heap_lock -- <function> heap_unlock -- <function> kbd_intr -- <function> >>> micropython.mem_info() stack: 544 out of 1800 GC: total: 10048, used: 5776, free: 4272 No. of 1-blocks: 113, 2-blocks: 37, max blk sz: 45, max free sz: 256 >>> micropython.qstr_info() qstr pool: n_pool=1, n_qstr=16, n_str_data_bytes=159, n_total_bytes=255 >>>
micropythonモジュールの中でmicro:bitらしいなと思うのがメモリ関係の情報を取り出せることです。極めてメモリの限られたシステムなので、チェックできるようになっているようです。
Wio Terminal ArduPy
Wio Terminalの場合、PCに接続するとデフォルト9600ボーでCOMポートのドライバがセットアップされました。ここでは、そのまま成行で接続しています。micro:bitとは異なりリターンキーを押すだけでREPLのプロンプトが返ってきました。help()と打つと華々しくSeeedStudioのロゴが登場するのですが、詳しいことはWebで見てね、という感じでmicro:bitのような実用性?はありません。使えるモジュールを調べてみます。
>>> help('modules') __init_ gc os uhashlib __main__ hashlib random uheapq arduino heapq select uio ardupy io sys ujson array json time uselect binascii machine ubinascii uzlib builtins math ucollections zlib collections micropython uctypes Plus any modules on the filesystem
こちらでちょっと目を引いたのは arduino や ardupy などのモジュールです。中身を調べてみると、arduinoには
grove_bme280クラス
が入っていました。BME280はBosch製の圧力センサの筈です。Groveポートにモジュールを接続したときに使えるのではないですかね(未確認)。また、ardupyモジュールの中には
Flashクラス
が入っていました。どうもFlashメモリをブロックでリード、ライトするためのものみたい。
先ほどのmicro:bitでは固有ハードウエアの制御は自身の名を冠した microbitモジュールの中に格納されていました。Wio Terminalでは、machineモジュールの中にあります。とくにこのデバイスらしいのはカラーLCDを制御するLCDクラスとそれと連携させるSpriteクラスかと思います。
>>> import machine >>> help(machine) object <module 'umachine'> is of type module __name__ -- umachine Pin -- <class 'Pin'> ADC -- <class 'ADC'> DAC -- <class 'DAC'> PWM -- <class 'PWM'> Map -- <class 'Map'> UART -- <class 'UART'> LCD -- <class 'LCD'> Sprite -- <class 'eSprite'>
micro:bitとの違いが際立つのはファイルシステムです。ささやかな、オマケのようなファイルシステムしか持たないmicro:bitに対して、Wio Terminalの方は4Mバイトものファイルシステムを使えます。勿論階層化できるもの。なんといっても主記憶のFlashメモリとは別チップのQSPIフラッシュメモリ上に実装されているようです。こちらは真の意味で「永続的」です。それもあって、osモジュール(MicroPython的には uos モジュール。どちらの名前でimportしても実体は同じ)は充実しています。勿論、os.listdir()は引数にパスを指定する文字列をとれます。
>>> import os >>> help(os) object <module 'uos'> is of type module __name__ -- uos uname -- <function> chdir -- <function> getcwd -- <function> ilistdir -- <function> listdir -- <function> mkdir -- <function> remove -- <function> rename -- <function> rmdir -- <function> stat -- <function> statvfs -- <function> unlink -- <function> sync -- <function> sep -- / mount -- <function> umount -- <function> VfsFat -- <class 'VfsFat'> >>> os.listdir('/') ['main.py', 'System Volume Information', 'abc.txt']
大分だらだら書いてしまいました。