あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

自作Breakout Gardenモジュール「ボタン」基板を作ってみた(失敗)

OTP表示機の続き。

akkiesoft.hatenablog.jp

前回の最後に書いた自作Breakout Gardenモジュール「ボタン」が届きました。

シルクの文字が思ったより小さく、「ボタン」が「ホタン」になったり文字が潰れて読めなくなっていたりはしているものの、パッと見は問題なさそうです。スロットにもひとまずはまりましたが、実際に押して見ないとわからんので、まずはボタンをつけます。

ボタンは、PimoroniのButton SHIMと同型の、表面実装タイプのボタンです。以前Button SHIMのボタンが壊れて、AliExpressからボタンを買って補修したときに余った部材を使い切ることを考えて、これを採用しました。ボタンは9個なので、全部つけても4つ余りますね。まだ作れる。

ボタンを付けたので早速動作確認!……ン!動かない!(おわり)。少し浮かせると反応するようになったので、せにもらすらみにのブレイクアウトと比べてみたところ、差し込み部分が0.5mmくらい長過ぎたようでした。あと、スルーホールのサイズのことを忘れてデフォルト値にしていたので、一般的なスルーホールより小さくなっていました。これのせいやん。。

長さが足りないなら板を削れば済んだのですが、長すぎる方なので何かを付け足すのはなかなか難易度が高いです。ひとまずホットボンドで付け足してみました。

あらためて動作確認。これで動くようになったので、改良版を作るまではこれで運用ですね。

交換前のボタンと比較。パッチは必要になったものの、大変スッキリしました。うれしい。

さて、Breakout Garden向けとしては失敗基板となってしまったのですが、回路自体は正常なので、ピンソケットを使えばRaspberry Piに直接挿して使えるボタンとして使えます。板は3.3V, SDA, SCLのパターンには接続しておらず、INTとGNDが刺さる任意の位置に差し替えて使えるので、なんかちょっとボタンがほしいときには使える……?かもしれません。

改良版基板はもう作成し終わっていて、他のTinyPicoKeyとかとまとめて発注しようと思っているので、出来上がったらまたブログに書こうかと思いますー。

(追記) データ

GitHubにアップロードしました。

github.com

モニターアームを導入した

なんとなく気になっていたけどどんなもんなのかよくわかっていなくて、いままで買うのを躊躇していたモニターアームを導入しました。

会社に1つ余っていたらしく、見て欲しかったら持ってっていいよとのことだったので、今週出社してもらってきました。自分でAmazonベーシックのを買おうかと思っていたのですが、もらってきてみたら、何か3倍くらい高いやつで笑ってしまた……。

設置にあたり、利用頻度の低いHDMIとUSB-Cは配線を撤去(使うときだけつなぐ運用にする)して、電源とDPだけアームに配線しました。ので、配線に関しては当たり前ながらスッキリしました。それにしても、アーム内に収納したりできるようになったので、見栄えは相当良くなりましたね。モニターのピボットはスタンドでもできましたが、スタンドを引っ張ったりあげたりしなくてもすすっと動かせるようになったのは便利そうです。

スタンドがアームの土台に置き換わったおかげで、机がやたら広く感じるようになりました。下の写真みたいに土台のところに小物を置く癖があったので、小物入れを用意することになりましたが、それでもスペースが有り余るようになったのでけっこう不思議です。キーボードを奥に起きやすくなったのが良いですね。

あと、モニターアームに変えたことで、モニターが4.5cmほど壁側に寄せられたのが結構大きいです。これが机が広く見える一番の理由かもしれません。奥行き60cmのエレクター机なので、スタンドの後ろのデッドスペースが地味にデカかったのかなと。

というわけで、思ったよりも結構導入メリットが多かったモニターアームでした。さっさと買うかもらうかすればよかったですね。会社で1年近く眠っていたらしいので。。

余談ですが、DPは会社支給のM1 Mac miniで使用中です。USB-C変換アダプターをAliExpressで買ってつないでいます。

以前はモニターからUSB-Cケーブルで自分のMBAに接続していましたが、MBA 2018がもう遅すぎて話にならない(M2の1/5の性能とかギャグか?)ので、朝から晩まで基本M1 Macで生活しています。Montereyの新機能でマウスカーソルが端末間で移動できるようになったので、 MBAはmikutter専用機と化しています……。M1 Macでmikutterが動けばIntel Macはお払い箱にできるんですけど、相変わらずまともに動かせないのでしょんぼりです。

CircuitPython自作キーでPCのスリープの時にスクリプトがコケてしまうやつの対処

MacにTinyPicoKeyを繋ぎっぱなしにしていたら、スリープあけに使えなくなる現象が起きて、しばらく不便していました。

TinyPicoTrioもできたしと重い腰をあげて調べてみたらなんのことはなく、キーボード(あるいはマウス)を初期化する時に、初期化に成功するまで再試行してやればいいだけでした。

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.mouse import Mouse

keyboard = 0
while not keyboard:
    try:
        keyboard = Keyboard(usb_hid.devices)
    except:
        pass
    sleep(1)

たぶん、スリープ中か復帰前後のどこかで、デバイスとしては切断しているけれど、単に電源が供給されるタイミングがあるのかもしれません。まあ、このくらいのループで解決するなら良かった。

逆に、初期化に失敗したら再試行せずに、デバイスとしてじゃなくても遊べるモードみたいなのもあったら楽しいかなーと思って、カーソルがランダム移動するだけの拙作クソアプリことうろうろマウスのCircuitPython+Tiny2040版でやってみました。

github.com

バイスとして認識したときは、ボタンを押すとPC上のマウスカーソルがうろつきながら、Tiny2040のLEDもRGB適当に光るのですが、単に電源だけ供給したときでもLEDが光るやつだけはできるようになりました。これで、外でモバイルバッテリーとかにつないで無駄にビカビカ光らして遊べるようになりましたね。

social.mikutter.hachune.net

そんなことするか???

RV3028 RTCモジュールをCircuitPythonで動かす

PimoroniのBreakout Gardenで唯一のRTCであるRV3028モジュールをついに買ってしまいました。しかしこれはついでに買ったもので、本命は最新アイテムのVL53L5CXモジュールでした。でもブログの本題はRV3028です。ややこしいですね。

VL53L5CXモジュールはToFセンサーですが、8x8のアレイになっているものです。レーザーで距離を測るやつが縦横8x8の64個ぶんできるというわけです。楽しそうですね。ひとまずはサンプルを動かして満足しました。何かすぐに使いたいわけではないので、いつか思いついたら使うことになると思います。そう言って引き出しの肥やしになるかと思いきや、なぜか仕事で使うことがたまに発生するようになってしまっているので恐ろしいところ。


RV3028モジュールでOTP表示機をスマートにしたい

RV3028モジュールの方はすぐに使いたいやつで、前に作ったOTP表示機に使っているRTCモジュールが不格好なのでスマートにしたいという動機があります。

akkiesoft.hatenablog.jp

再掲。やばすぎる。ボタンもヤバいのですが、これは後日どうにかすることにしつつ、今回はRTCを置き換えます。

RV3028は、あらかじめRaspberry Piで時刻をセットしました。

RV3028とCircuitPython

RV3028モジュールのCircuitPython用ライブラリは……実は存在しておらず、普通のPython用しかありませんでした。Pimoroni版MicroPythonならサポートされていますが、CircuitPythonのサポートがないのを忘れたまま買ってしまいました。

github.com

しかし、I2Cで通信してるんだから最悪自力で移植できるだろうと思って読み解いたところ、rv3028のライブラリがPimoroni作のi2cdeviceライブラリで書かれており、i2cdeviceライブラリはSMBusを呼び出して読み書きの2つができればOKということがわかりました。

github.com

さらに調べると、SMBusの読み書きをいい感じにCircuitPython向けに変換してくれるアダプターを、やはりPimoroniが書いていました。最高。

github.com

というわけで、このアダプターを使えば以下のスクリプトで動くはずです。

from pimoroni_circuitpython_adapter import not_SMBus as SMBus
import board
import rv3028

i2c = SMBus(SDA = board.GP4, SCL = board.GP5)
rtc = rv3028.RV3028(i2c_dev = i2c)

rtc_time = rtc.get_time_and_date()
print("{:02d}/{:02d}/{:02d} {:02d}:{:02d}:{:02d}".format(rtc_time.year, rtc_time.month, rtc_time.day, rtc_time.hour, rtc_time.minute, rtc_time.second))

しかし、いくつかCircuitPython(MicroPython)の制約などで動かない部分があったので、手直しが必要でした。

i2cdeviceの修正

i2cdeviceで使われている__dict__が、CircuitPython(MicroPython)では取得しかできず、設定はできないらしいので、代わりにsetattrで記述しました。

--- i2cdevice-python-0.0.7/library/i2cdevice/__init__.py	2020-07-09 20:32:41.000000000 +0900
+++ __init__.py	2022-06-10 23:05:32.000000000 +0900
@@ -169,7 +169,8 @@
             self.locked[register.name] = False
             self.values[register.name] = 0
             self.registers[register.name] = register
-            self.__dict__[register.name] = _RegisterProxy(self, register)
+            setattr(self, register.name, _RegisterProxy(self, register))
 
     def lock_register(self, name):
         self.locked[name] = True

rv3028の修正

datetimeモジュールはCircuitPythonに存在しないので、adafruit_datetimeモジュールで代用します。

--- rv3028-python-0.0.5/library/rv3028/__init__.py	2019-11-01 18:23:19.000000000 +0900
+++ __init__.py	2022-06-10 22:49:48.000000000 +0900
@@ -1,7 +1,7 @@
 import time
 from i2cdevice import Device, Register, BitField
 from i2cdevice.adapter import Adapter, LookupAdapter, U16ByteSwapAdapter
-import datetime
+import adafruit_datetime as datetime
 
 __version__ = '0.0.5'

rtcモジュールのrtc.set_time_source()で使うために、RV3028クラスの中にdatetimeプロパティが必要らしいので、適当に実装しました。後ろから3つのパラメータは適当に埋めたので必要な人は適宜実装してください……。ただ、動かしてみた感じでは、後述のスクリプト実行例の通り、特に問題なさそうに見えました。

    @property
    def datetime(self):
        return time.struct_time((
            self._rv3028.get('YEAR').year + 2000,
            self._rv3028.get('MONTH').month,
            self._rv3028.get('DATE').date,
            self._rv3028.get('HOURS').t24hours,
            self._rv3028.get('MINUTES').minutes,
            self._rv3028.get('SECONDS').seconds,
            self._rv3028.get('WEEKDAY').weekday,
            0, # tm-ydayの実装が面倒なので省略
            -1
        ))

動かす

先ほどのスクリプトを実行して、時刻が返ってくることを確認します。

>>> (省略)
>>> print("{:02d}/{:02d}/{:02d} {:02d}:{:02d}:{:02d}".format(rtc_time.year, rtc_time.month, rtc_time.day, rtc_time.hour, rtc_time.minute, rtc_time.second))
2022/06/10 16:32:28

rtcモジュールのset_time_source()を使う時はこんな感じ。

from pimoroni_circuitpython_adapter import not_SMBus as SMBus
import board
from rv3028 import RV3028
import rtc
import time

i2c = SMBus(SDA = board.GP4, SCL = board.GP5)
rv3028 = RV3028(i2c_dev = i2c)
rtc.set_time_source(rv3028)

time.localtime()

こちらもこんな感じで返ってきました。

>>> time.localtime()
struct_time(tm_year=2022, tm_mon=6, tm_mday=10, tm_hour=16, tm_min=36, tm_sec=2, tm_wday=4, tm_yday=161, tm_isdst=-1)

そうしたらあとはOTP表示機のスクリプトをRV3028仕様に変更したら完成です。


まとめ

OTP表示機のRTCモジュールをRV3028に差し替えて、Breakout Gardenなモジュールでまとめることができました。いや、まだボタンがまとまっていませんでした。それでも見た目はだいぶおとなしくなりました。よかった。

ボタンはですが、なんと自作Breakout Gardenモジュール「ボタン」を作ってしまいました。一昨日発送されたので、再来週くらいには届くんじゃないかなあ……?と思います。ボタンのスイッチはButton SHIMと同じものが保守部品として余っているのでそれを採用できるように設計してみましたが、もろもろ寸法が合うかどうかは届いてのお楽しみ状態です。一応頑張って寸法を測ったり調べたりはしましたが……。

TinyPicoTrio

昨年、TinyPicoKeyを3つ並べられるTinyPicoTrioを手作りしました。

akkiesoft.hatenablog.jp

これをいよいよ基板設計して、今朝到着しました。

形状は凸っぽい感じになりました。そのまま凸にしても良かったのですが、なんとなくカーブを付けて遊びたくなったのでこんな形状になっています。あと、キー数をもっと増やしてみても良いかなとも思いましたが、今回は3キーのままとしました。もっと欲しくなったらまた作るだけですね。

さっそく組み立て。TinyPicoKeyは律儀に8ピンx2列の穴を用意していましたが、キー自体は2ピンしか使わないので、TinyPicoTrioでは四隅2ピンずつの8ピンだけ穴を用意して、必要なピンソケットの数を削減しました。ピンソケットは意外といいお値段しますしね。

TinyPicoKeyとTiny2040を搭載するとこんなかんじ。裏面は適当にゴム足を貼り付けましたが、将来的にケースを作りたくなった時とかを想定して、基板に3ヶ所穴を用意してあります。

配線はGP4〜GP6にして、GP6は1キーとして使うときと共通としました。ボタンを押したまま接続して、boot.pyでストレージ無効化を阻止する動作がどちらの場合でもできるので、便利かなと思っています。

ちょっと遊んでみた要素として、キーをひっくり返して搭載することが可能です。写真では真ん中をひっくり返していますが、左右のキーも同じ用にひっくり返せます。指の置き方に合わせて好きな向きにできます。

半年ちょっとぶりにKiCadを触ったので色々忘れていてアレでしたけど、思い出したあとはサクサクと作れた感があります。が、シルク印刷の代わりに文字をソルダーペーストにしてキラキラにさせようと欲張ってみたら、やり方をわかっておらず、基板の地の色になってしまい、やや失敗しました……。MaskとCuを重ねて配置するのが正解だったっぽいです。続けて別の基板を作っていた時に気づきました。こっちの基板も届いたらまたブログにしたいと思います。