Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

PICA Tower(ピカ・タワー)をCircuitPythonで光らせる

この記事はMicroPython Advent Calendar 2017の24日目の投稿です。

PICA Tower(ピカ・タワー)

12月24日なので、クリスマスっぽいものということでPICA Tower(ピカ・タワー)をオモチャ箱から取り出してきました。これは、イーケイジャパンと福岡県立福岡工業高等学校の、共同開発プロジェクトのもので、PICのCプログラミング教材として使うことを意図しているようです。

IMG_4270.JPG

中身はキットで、たくさんのLEDと抵抗、メッキ線、ICソケットなどをはんだ付けします。けっこう面倒です。できあがったものは以下で、何ができるかといえばLチカ豪華版+CDSによる環境光検知です。

IMG_4271.MOV.gif

これをプログラミングの教材として使うためのプログラミングマニュアルも用意されています。

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を用意します。

IMG_4275.JPG

LED部をArduino M0 Proに挿します。何の問題もなく挿さります。

IMG_4276.JPG

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()

動かしたところです。部屋を暗くすると点滅します。

IMG_4277.MOV.gif

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?