この記事はMicroPython Advent Calendar 2017の24日目の投稿です。
PICA Tower(ピカ・タワー)
12月24日なので、クリスマスっぽいものということでPICA Tower(ピカ・タワー)をオモチャ箱から取り出してきました。これは、イーケイジャパンと福岡県立福岡工業高等学校の、共同開発プロジェクトのもので、PICのCプログラミング教材として使うことを意図しているようです。
中身はキットで、たくさんのLEDと抵抗、メッキ線、ICソケットなどをはんだ付けします。けっこう面倒です。できあがったものは以下で、何ができるかといえばLチカ豪華版+CDSによる環境光検知です。
これをプログラミングの教材として使うためのプログラミングマニュアルも用意されています。
Arduino M0に挿す
このキットのちょっと気がきいているのは、上のLED部と下のPIC基板部が分離可能で、しかもArduinoフォーム・ファクタに対応しているので、LED部をArduino UNOなどに挿して使えることです。ここからMicroPythonの話につなげますが、MicroPythonの派生であるAdafruit CircuitPythonがサポートしているボードにArduino Zeroがあります。手持ちのArduino M0 ProはArduino Zero Proの同等品であるので、今回はCircuitPythonを入たArduino M0でピカ。タワーを光らせてみます。
まずはLED部とPIC基板部を分離し、Arduino M0 Proを用意します。
LED部をArduino M0 Proに挿します。何の問題もなく挿さります。
Arduino M0 ProにCircuitPythonをインストール
CircuitPythonのリリースサイトからArduino Zero用のバイナリをダウンロードします。今回は2.1.0を使うことにしたので、adafruit-circuitpython-arduino_zero-2.1.0.binになります。
次にインストールツールであるBOSSAをリリースサイトよりダウンロードします。今回はMac OS X用1.8.0に含まれるbossacコマンドを使いました。
Aruduino M0 ProをUSBケーブルでホストコンピュータと繋いでシリアルポートを探します。Macの場合は /dev/tty.usb*
あたりを調べます。今回は /dev/tty.usbmodemFA1441
でした。
Arduino M0 ProのRESETボタンを二度押しするとファームの書き換えモードになるので、この状態にしたら以下でCircuitPythonをインストールします。
$ bossac -e -w -v -R -p /dev/tty.usbmodemFA1441 adafruit-circuitpython-arduino_zero-2.1.0.bin
以下のようにメッセージが出て、Verify successfulが出ればOKです。
Erase flash
Done in 0.863 seconds
Write 184276 bytes to flash (2880 pages)
[==============================] 100% (2880/2880 pages)
Done in 1.102 seconds
Verify 184276 bytes of flash
[==============================] 100% (2880/2880 pages)
Verify successful
Done in 10.457 seconds
プログラミング
CircuitPython の標準モジュール構成はオリジナルのMicroPythonからかなり改変してしまっています。デジタル入出力には digitalio
、アナログ入出力には analogio
、ボードのピンの指定には board
モジュールを import する必要があります。時間制御用に time
もインストールしておきましょう。
import digitalio
import analogio
import board
import time
LEDは27個もあるので、まともに繋げたのではArduinoのデジタルピンが足りません。そのため、ピカ・タワーではLEDのアノードに9ピン、カソードに3ピンを割り当て、アノード側は各段のLEDの位置、カソード側が段を示すようにして処理します。よくあるLチカではカソード側はGNDに接続し、アノード側のON/OFFだけで点滅させますが、ピカ・タワーではアノード/カソード両方の値設定が必要です。
たとえば、一段目の2番LEDでLチカをやるには以下のようにします。
anode = digitalio.DigitalInOut(board.D4) # D4ピンをデジタルI/Oに設定
anode.direction = digitalio.Direction.OUTPUT # D4ピンをデジタル出力に切り替え
cathode = digitalio.DigitalInOut(board.D11) # D11ピンをデジタルI/Oに設定
cathode.direction = digitalio.Direction.OUTPUT # D11ピンをデジタル出力に切り替え
while True:
# 点灯
anode.value = True
cathode.value = False
time.sleep(0.5)
# 消灯
anode.value = False
cathode.value = True
time.sleep(0.5)
LED部に載っているCDSの値を得るにはArduinoのA0ピンを使います。A0からアナログ入力してみて、環境光の明暗で値がどう変わるかを見てみます。
cds = analogio.AnalogIn(board.A0) # A0 をアナログ入力に指定
while True:
print(cds.value) # A0 の値
time.sleep(1.0)
上記を実行してみて、REPL上で値を確認すると以下のようになっていました。CDSを何かで覆うと値が65520になりました。65000の境界で明暗の判別をすればよさそうです。
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
main.py output:
47728
47918
48040
47987
65520
65520
65520
65520
65520
以上の検証結果をふまえて作成してみたCircuitPythonプログラムです。
import digitalio
import analogio
import board
import time
cds = analogio.AnalogIn(board.A0)
anodes = [
digitalio.DigitalInOut(board.D4),
digitalio.DigitalInOut(board.D3),
digitalio.DigitalInOut(board.D2),
digitalio.DigitalInOut(board.D5),
digitalio.DigitalInOut(board.D6),
digitalio.DigitalInOut(board.D7),
digitalio.DigitalInOut(board.D8),
digitalio.DigitalInOut(board.D9),
digitalio.DigitalInOut(board.D10)]
for anode in anodes:
anode.direction = digitalio.Direction.OUTPUT
anode.value = False
cathodes = [
digitalio.DigitalInOut(board.D11),
digitalio.DigitalInOut(board.D12),
digitalio.DigitalInOut(board.D13)]
for cathode in cathodes:
cathode.direction = digitalio.Direction.OUTPUT
cathode.value = True
def pattern0():
for anode in anodes:
anode.value = False
for cathod in cathodes:
cathod.value = True
def pattern1():
for anode in anodes:
anode.value = True
for cathode in cathodes:
cathode.value = False
time.sleep(0.5)
for cathode in cathodes:
cathode.value = True
time.sleep(0.5)
while True:
pattern0()
if cds.value < 65000:
pattern0()
else:
pattern1()
動かしたところです。部屋を暗くすると点滅します。