あっきぃ日誌

ラズピッピブログのようなオタクブログのようななにか

CircuitPythonで作ったデバイスの普段使いに邪魔なUSBドライブを無効化する(ただし7.0.0から)

CircuitPythonで自作キーボード的なものを作成して実際に使い始めると、CIRCUITPYTHONドライブが邪魔ということに気が付きます。Windowsだとそこまで気にならないかもしれませんが、Macの場合はこうなりがちです。

f:id:Akkiesoft:20210816184341j:plain

CircuitPython 7.0.0からはこうした状況をどうにかできる機能が追加されているようなので、ちょっと試してみました。なお、書いた時点ではAlpha6の状態だったので、正式リリースはまだ先っぽそうです。

しくみ

Adafruitの記事で解説されているので、基本的にはこれをなぞるだけです。

learn.adafruit.com

code.pyとは別にboot.py(MicroPythonとごっちゃになりそうで微妙なネーミングだなあ)というファイルが追加され、ここでUSBストレージやREPLの無効化や、USB HID機能の有効化をするようになったようです。ちなみに、code.py側で書いていた内容に変更を加える必要はありませんでした。

記事にあるとおり、何でもかんでも無効化すると、再び有効化できなくなってただの板にしてしまう恐れがある点には注意が必要です。USBストレージとREPLを同時に無効化しなければ、どちらかを使って復旧させられるので、そこだけ気をつければ良さそうです。

USBストレージを無効化するためのboot.pyの内容はこうなります。

import storage
storage.disable_usb_drive()

しかしこれは罠で、ただ単に無効化するとあとから有効化するのが面倒になります。storage.enable_usb_drive()という関数もあるので、REPLで実行すれば良いように見えますが、boot.pyでしか実行できないため、たぶんですがREPLから以下のコードを実行してboot.pyを消す以外の方法がありません。

import os
import storage
storage.remount('/', readonly=False)
os.remove('boot.py')

よって、必要に応じて「USB接続時にボタンが押されていたらUSBストレージを無効化しない」などの実装はあったほうが良いと思われます。

REPLを無効化した場合ならUSBストレージからboot.pyを修正できるので影響は軽微そうですけど、REPLを無効化したいケースは簡易な自作キーボード程度では思いつかないのでまあ……。

やっていき

さて、昨日ブログに書いたKeybow用にスクリプトを作成してみました。

akkiesoft.hatenablog.jp

以下をboot.pyとして配置します。

import storage
import board
import digitalio
from time import sleep
import adafruit_dotstar as dotstar
import usb_hid

usb_hid.enable((usb_hid.Device.KEYBOARD,))
dots = dotstar.DotStar(board.GP2, board.GP3, 30, brightness=0.5)

button = digitalio.DigitalInOut(board.GP11)
button.pull = digitalio.Pull.UP
if button.value:
    storage.disable_usb_drive()
    dots[2] = (0, 255, 0)
    sleep(0.1)
else:
    dots[2] = (0, 0, 255)
    sleep(1)
dots[2] = (0, 0, 0)

board.GP11に相当するキー(Keybowはたしか左下、Keybow miniはKEYBOWの文字がある端)を押した状態でUSB接続すると、1秒青く光ってからUSBストレージがマウントされますが、キーが押されていなければ一瞬緑に光るだけでUSBストレージはマウントされません。どちらの状態でもLEDが点滅したあとはcode.pyが続けて実行されて、キーボードとして使えるようになります。

まとめ

boot.pyのネーミングだけ引っかかりますが、USBストレージを無効化できるのはMac使いとしては非常にありがたい機能追加です。また、自作キーボード向けならboot.pyはこう言う感じの実装が基本になりそうかなあと思いました。CircuitPython 7.0.0の正式リリースに期待です。