Adafruit MacroPad RP2040

AdafruitのLearning Guideの非公式日本語訳です。
英語独特の言い回しを可能な限り日本語的な表現に直していますが、不自然に感じる部分も残っていますことを何卒ご容赦ください。

概要

この3×4のキーボードコントローラには、Raspberry Piの最新技術であるRP2040が採用されています。RP2040はたくさんのGPIOピンと、アポロ計画の管制コンピュータの64倍のRAMを備えた、スピード感あふれる小さなマイクロコントローラーです。また、8MBのフラッシュメモリを搭載しているので十分な容量を確保できます。

12個のボタン、有機ELディスプレイ、スピーカー、ロータリーエンコーダーを備えたCircuitPythonまたはArduino搭載のMacropadで、あなたのデスクのミッションコントロールステーションをアップグレードしましょう。また、お気に入りの絵文字を入力してもらうこともできます。

12個のソケットには、それぞれCherry MX互換のキースイッチを装着することができます。ハンダ付けの必要もなく、カチッとはめるだけです。お好きなキースイッチをお使いいただけますが、下の12個のNeoPixelsが映えるようなスロットのあるものをお勧めします。

MacroPad RP2040には、128×64のモノクロ有機ELが搭載されており、ArduinoやCircuitPythonでキーマップや統計情報、コンピュータのパフォーマンスなどを表示できる鮮明なヘッドアップディスプレイになっています。また、プッシュボタン付きのロータリーエンコーダーがハンダ付けされています。ねじったり、回したり、押したりすることで、音量やモニターの明るさ、スクロールなど、お好きなように変更できます。小さなスピーカーは、音声フィードバックを与えたり、楽しいピコピコした曲を演奏したりできます。

さらにハードウェアを追加したい場合、側面にSTEMMA QTポートがありますので、数多くのSTEMMA QT / Qwiicボードを接続できます。

このマクロパッドは、ArduinoまたはCircuitPythonでプログラムするように設計されています!
RP2040チップは、現在QMKをサポートしていませんのでご注意ください。

  • Raspberry Pi RP2040チップ+8MBフラッシュメモリ – デュアルコアCortex M0+(~130MHz)、264KBまたはRAM。CircuitPython、Arduino、MicroPythonを簡単に実行でき、開発コードやファイルを保存するための大きなスペースがあります。
  • 電源/データ用USB Cコネクタ – HIDデバイスとしてはもちろん、MIDIやUARTなどにも対応します。
  • 3×4メカニカルキースイッチソケット – Cherry MX互換のスイッチが使用可能です。個別にGPIOピンに接続されている(マトリックス配線ではない)
  • スイッチごとに1個のNeoPixel RGB LEDを北側に配置。
  • ロータリーエンコーダー、1回転20パルス出力、GPIOピンにプッシュスイッチ付き。プッシュスイッチは、電源投入時やリセット時に押したままにするとブートローダーモードに入るためにも使用されます。
  • 128×64 SH1106 モノクロ有機ELディスプレイ – 高速ハードウェアSPIポートで素早くアップデート可能。
  • 8mmスピーカー/ブザー – クラスDアンプとRCフィルターを搭載し、簡単なビープ音や効果音を鳴らすことができます。
  • STEMMA QTコネクタ – I2Cセンサー/ディスプレイ/デバイスをプラグアンドプレイケーブルで追加できます。
  • リセットボタン – 側面にあり、コードを素早く再起動することができます。
  • 4つのM3マウント用ボス – 自作の筐体をネジ止めすることができます。

ピンアサイン

MacroPad RP2040は、マクロパッドの美味しさが詰まっています。キー以外の機能も充実しています。

上のピンアサイン画像のPDFはこちらです。

キースイッチソケット

MacroPad上には、Cherry-MX対応のキースイッチのソケットが3×4のグリッド状に配置されています。これらのソケットは基板の背面に取り付けられており、ソケットが正面を向くようになっています。キースイッチのソケットは、個別にGPIOピンに接続されています(マトリクス配線はされていません)。

互換性のあるキースイッチを基板の上からソケットに押し込むだけです。スイッチを所定の位置に固定するために、接着剤をひと塗りすることができます。ホットグルーやエポキシ樹脂が有効です。

ロータリーエンコーダ・BOOTボタン

BOOTボタンをロータリーエンコーダーのボタンスイッチとして忍ばせました。ロータリーエンコーダーを押して、BOOTボタンを押してください。

基板の右上(上から見たとき)には、ロータリーエンコーダーとBOOTボタンが配置されています。ロータリーエンコーダーは、1回転あたり20個のパルス出力があります。BOOTボタンは、ブートローダー(CircuitPythonとArduinoの両方に必要)に入るために必要であり、ご自身のコードからユーザー入力としても利用できます。このボタンを使用するには、ロータリーエンコーダーを押し下げるだけです。

ロータリー・エンコーダーは、CircuitPythonではboard.ROTAboard.ROTBで利用できます。Arduinoでは、PIN_ROTAPIN_ROTBで利用できます。

BOOTボタンはCircuitPythonのboard.ENCODER_SWITCHにあります。ArduinoではPIN_SWITCHで利用できます。

有機ELディスプレイ

ボードの左上(上から見たとき)には、128×64のSH1106モノクロ有機ELディスプレイが搭載されています。ディスプレイ用のリボンケーブルは、基板の穴を通って背面に出ており、ディスプレイ用のコネクタに挿入されています。この有機ELディスプレイは、高速ハードウェアSPIを採用しており、迅速な更新が可能です。

NeoPixel LED

各キースイッチソケットの上には、RGB NeoPixel LEDが同じ3×4のグリッドに配置されています。これらのリバースマウントLEDは、基板の背面に取り付けられており、前面を照らすようになっています(キースイッチが基板の前面と同じ高さになるようにしています!)。

NeoPixel LEDはCircuitPythonではboard.NEOPIXELとして利用できます。ArduinoではPIN_NEOPIXELとして使用できます。

RP2040マイクロコントローラ

基板裏面の中央上部にある大きな四角いものがRP2040マイコンです。これがこのボードの頭脳です。

QSPIフラッシュ

RP2040マイクロコントローラの上にある小さな四角は、8MBのQSPIフラッシュです。

QSPIは、SPIのシングルラインインとシングルラインアウトではなく、4つのデータイン/アウトラインを持つことができるという点で優れています。これは、QSPIが少なくとも4倍高速であることを意味しています。しかし、実際には、QSPIペリフェラルは普通のSPIペリフェラルよりもはるかに速くクロックできるので、少なくとも10倍は速いです。CircuitPythonでは、QSPIフラッシュはインタープリタでネイティブに使用され、ユーザコードからは読み取り専用となっていますが、フラッシュは書き込み可能なディスクドライブとして表示されます。

スピーカー

裏面の基板の中央から少し右にあるグレーの四角いものが8mmスピーカー/ブザーです。D級アンプとRCフィルターで、簡単なビープ音や効果音を出すことができます。

このスピーカーは、CircuitPythonではboard.SPEAKERで入手できます。ArduinoではPIN_SPEAKERで利用できます。

コードで動作させるには、スピーカーを有効にする必要があります。CircuitPythonでのスピーカー有効化ピンはboard.SPEAKER_SHUTDOWNです。ArduinoではPIN_SPEAKER_ENABLEです。

STEMMA QTコネクタ

ボード背面の右上、マウントボスの下には、STEMMA QTコネクタがあります。このQwiic互換のI2Cコネクターは、STEMMA QTセンサーとブレークアウトを非常に簡単に接続できるように設計されています。

USB Type-Cコネクタ

ボードの上部中央、両側から見えるところに、USB Type Cコネクタがあります。このコネクターは、コンピューターからのデータ転送(CircuitPythonのcode.pyファイルの更新や、Arduinoスケッチのアップロードなど)と、ボードへの電源供給の両方に使用します。

赤色LED

基板背面の上端、USB Type-Cコネクタの右側には、赤色LEDがあります。これをコードで制御することができます。

赤色LEDは、CircuitPythonではboard.LEDで利用できます。ArduinoではPIN_LEDで利用できます。

リセットボタン

基板裏面の右端(正面から見える部分)、STEMMA QTコネクタの下に、リセットボタンがあります。1 回タップすると、ボードがリセットされます。ブートボタンと組み合わせることで、リセットボタンからブートローダに入ることができます。

マウント用ボス

基板の上2隅と下2隅には4つのマウントボスが配置されており、MacroPadのエンクロージャーキットを使用したり、独自の筐体を設計することができます。

CircuitPythonの基礎

Lチカ

どんなプログラミング言語を学ぶにしても、最初はHello, World!のようなものから始めますね。CircuitPythonでは、Hello, World! はLEDをチカチカ(Lチカ)させることです。LチカはCircuitPythonの中でも最もシンプルなプログラムの一つです。
3つの組み込みモジュールと2行の設定、そして短いループで構成されています。そのシンプルさにもかかわらず、ほとんどのCircuitPythonプログラムに必要な基本的な概念の多くを示しており、より複雑なプロジェクトのためのしっかりとした基礎を提供しています。

LEDの位置

赤色LEDは、基板背面の上端、USBコネクターの左側に配置されています。

Lチカする

以下をcode.pyとしてCIRCUITPYドライブに保存します。

import time
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

while True:
    led.value = True
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)

内蔵の赤色LEDが点滅し始めます。

このコードは「Python的」ではないことに注意してください。time.sleep(0.5)を1回行うだけで、led.value = not led.valueと書くこともできます。しかしこの記法はプログラミングに慣れていない人には理解しにくいので、読みやすくするために上記の例は必要以上に長くなっています。

このプログラムで何が行われているかを理解することが重要です。

まず、time、board、digitalioの3つのモジュールをインポートします。これにより、これらのモジュールがあなたのコードで使用できるようになります。この3つのモジュールはCircuitPythonに組み込まれているので、何かをダウンロードする必要はありません。

次に、LEDを設定します。CircuitPythonでハードウェアを操作するためには、コードでハードウェアがどこにあるのか、何をするのかをボードに知らせなければなりません。そこで、digitalio.DigitalInOut()オブジェクトを作成し、boardモジュールを使ってLEDピンを与え、変数ledに保存します。そして、そのピンにOUTPUTとして動作するように指示します。

最後に、while True: ループを作成します。これは、ループ内のすべてのコードが無限に繰り返されることを意味します。ループの中では、led.value = Trueを設定し、LEDの電源を入れます。そして、time.sleep(0.5)を使って、次の行に移る前に半秒待つように指示しています。次の行では、led.value = Falseを設定し、LEDの電源をオフにします。次の行では、LED.value = False を設定して LED をオフにし、さらに time.sleep(0.5) で半秒待ってからループを再開しています。

ほんの少しの更新で、点滅速度をコントロールできるようになりました。まばたきの速度は、time.sleep()で次に進むまでの時間を指定します。この例では0.5を使っていますが、これは1秒の半分です。この値を増やしたり減らしたりして、点滅の様子を確認してみてください。

以上、CircuitPythonを使ってLチカする方法でした。

デジタル入力

CircuitPythonのdigitalioモジュールには様々な用途があります。基本的なLチカプログラムでは、LEDをデジタル出力として設定します。また、ボタンなどのデジタル入力を設定して、LEDを制御することもできます。この例では、基本的なLチカの例をベースに、ボタンスイッチの設定を加えています。LEDを点滅させるためにタイムモジュールを使用する代わりに、ボタンスイッチのステータスを使用して、LEDをオンまたはオフにするかどうかを制御します。

LEDとボタン

  • 赤色LED(赤で強調表示)は、ボード背面の上端、USBコネクターの左側にあります。
  • ボタン(緑色で表示)は、ロータリー・エンコーダーの中にあり、ボタンを使用するには、ロータリー・エンコーダーを押し下げるだけです。

ボタンでLEDを制御する

以下をcode.pyとしてCIRCUITPYドライブに保存します。

"""CircuitPython Digital Input example for MacroPad"""
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)

while True:
    if not button.value:
        led.value = True
    else:
        led.value = False

では、ボタンを押してみましょう。LEDが点灯しました ボタンを離すと、LEDが消灯します。

このコードは、”Python的 “ではないことに注意してください。このコードは、led.value = not button.value と書くこともできます。しかしこの記法はプログラミングに慣れていない人には理解しづらいので、読みやすくするために、例は必要以上に長くなっています。

まず、boardとdigitalioという2つのモジュールをインポートします。これにより、これらのモジュールをあなたのコードで使用できるようになります。どちらもCircuitPythonに組み込まれているので、何かをダウンロードする必要はありません。

次に、LEDを設定します。CircuitPythonでハードウェアを操作するためには、コードでハードウェアの場所や操作方法をボードに知らせる必要があります。そこで、digitalio.DigitalInOut()オブジェクトを作成し、boardモジュールを使ってLEDピンを与え、変数ledに保存します。そして、そのピンにOUTPUTとして動作するように指示します。

また、ボタンの設定も行います。LEDの設定と似ていますが、ボタンはINPUTなので、プルアップが必要になります。

ループの中では、ボタンが押されたかどうかをチェックし、押された場合はLEDを点灯させます。そうでなければ、LEDはオフになります。

以上、ボタンスイッチでLEDを制御する方法でした。

キーパッド

キーパッド・モジュールを使用するには、CircuitPythonの最新バージョンをダウンロードする必要があります!
circuitpython.org/downloadsの “Absolute Newest “にある “Browse S3 “リンクをクリックしてください。

CircuitPythonでAdafruit MacroPadのキーを使うのは、キーパッドモジュールのおかげでとても簡単です。このモジュールでは、キー番号を印刷したり、キーの押下やリリースを読み取ったりすることができます。rotaryioモジュールは、ロータリーエンコーダの回転を読み取ることができ、digitalioは、ロータリーエンコーダのボタンスイッチの押下を読み取ることができます。これらのモジュールはすべてCircuitPythonに組み込まれているので、これらを使用するために、別途ライブラリをMacroPadにロードする必要はありません。

ただし、次の例ではNeoPixel LEDを使用していますが、これには別途ライブラリ(Adafruit CircuitPython NeoPixel)が必要です。

以下を code.py として CIRCUITPY ドライブに保存してください。

"""Keypad and rotary encoder example for Adafruit MacroPad"""
import board
import digitalio
import rotaryio
import neopixel
import keypad
from _pixelbuf import colorwheel


key_pins = (board.KEY1, board.KEY2, board.KEY3, board.KEY4, board.KEY5, board.KEY6,
            board.KEY7, board.KEY8, board.KEY9, board.KEY10, board.KEY11, board.KEY12)
keys = keypad.Keys(key_pins, value_when_pressed=False, pull=True)

encoder = rotaryio.IncrementalEncoder(board.ROTA, board.ROTB)
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)

pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.2)

last_position = None
while True:
    if not button.value:
        pixels.brightness = 1.0
    else:
        pixels.brightness = 0.2

    position = encoder.position
    if last_position is None or position != last_position:
        print("Rotary:", position)
    last_position = position

    color_value = (position * 2) % 255

    event = keys.events.get()
    if event:
        print(event)
        if event.pressed:
            pixels[event.key_number] = colorwheel(color_value)
        else:
            pixels[event.key_number] = 0

ここで、いずれかのキーを押してみると、メッセージがプリントアウトされます。対応するNeoPixelが点灯します。NeoPixelの色を変えて数値を表示させるには、ロータリーエンコーダーを回転させます。一時的にNeoPixelの輝度を上げるには、ロータリーエンコーダーを押し下げます。

なお、キー番号は0から始まるので、プリントされるキー番号は0~11となります。CircuitPythonのピン名はKEY1~KEY12です。KEY1はキー番号0、KEY2はキー番号1、などで、KEY12はキー番号11です。

Follow me on Twitter