あっきぃ日誌

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

Raspberry Pi PicoでTOTP表示機をつくりたい (2)

9日目です。

adventar.org

RTCモジュールが来た

スイッチサイエンスで注文したRTCモジュールが来ました。電池交換式なので、電池が切れても安心です。サイズはCR1220という、CR2032と比べて聞き慣れない型番ですが、100円ショップで買える型番です。WaveShare製CM4向けIOボードのときに買ったやつの余りがあったので買いに行かずにすみました。

www.switch-science.com

f:id:Akkiesoft:20211208235952j:plain

ちなみに、となりのやつはスマホとかの画面にタッチできるらしいなにかです。面白そうだったので買ってみました。これもそのうちにネタになります。たぶん。

RTCモジュールの取り付け

このDS3231は3.3Vで動作するため、Raspberry Piの1,3,5,7,9ピンにつながればOKです。よって、Breakout Gardenのエクステンダーを使えばこんな感じに接続できます。

f:id:Akkiesoft:20211209000020j:plain

なんか……微妙くなってしまった……。ディスプレイと水平に立っていて欲しい感がありますね。というわけで、Breakout Gardenのモジュールを買うとついてくるヘッダーとソケットを使って90度曲げるやつを作りました。

f:id:Akkiesoft:20211209000048j:plain

f:id:Akkiesoft:20211209000226j:plain

こんな感じ。収まりは良い感じがします。が、RTCモジュールが目立っちゃう感じがしなくもないですね。

f:id:Akkiesoft:20211209000108j:plain

反転させてるとこう。こちらだとバランスが不安定な感じですが、ディスプレイが一番前に来るので良さそうです。これでいってみましょう。

f:id:Akkiesoft:20211209000241j:plain

コード入力用ボタンをまとめる

Breakout Gardenのエクステンダーを2つも使うのはもったいないので、さきほどの90度曲げるやつのコーナー部分にむりやりピンを生やしてしまいました。アア……だいぶバカっぽいビジュアルになった気がする……。

f:id:Akkiesoft:20211209000310j:plain

物理的な最終形態はこうなりました。禍々しい。

f:id:Akkiesoft:20211209000319j:plain

RTCモジュールの時刻合わせ

最初の時刻設定は、Circuitpythonにシリアル接続をして、REPLから設定すると良いでしょう。コードが実行中ならCtrl+Cを押せば、REPLの「>>> 」が表示されるので、表示されたら以下のコードを入力して時刻を合わせます。設定後はCtrl+Dでcode.pyの実行に戻ります。

import board
import busio
import time
import adafruit_ds3231

i2c = busio.I2C(board.GP5, board.GP4)
ds3231 = adafruit_ds3231.DS3231(i2c)
ds3231.datetime = time.struct_time((2021, 12, 9, 0, 15, 23, 0, -1, -1))
# structure_timeの最後の0, -1, -1は曜日、週数、夏時間なのでこのままでOK

コードの実装

RTCモジュールの部分は、RTC3231用のライブラリがあるのでそれを使って終わりです。

import board
import busio
import rtc
import adafruit_ds3231

i2c = busio.I2C(board.GP5, board.GP4)
ds3231 = adafruit_ds3231.DS3231(i2c)
rtc.set_time_source(ds3231)

ボタンを押したときの処理は、Adafruitのオリジナルのコードとこちらでは違いそうだったので、普通のGPIO入力検知を使って実装しました。

from digitalio import DigitalInOut, Direction, Pull

code_sent = False

btn = DigitalInOut(board.GP3)
btn.direction = Direction.INPUT
btn.pull = Pull.UP

while True:
    if not btn.value:
        if not code_sent:
            code_sent = True
            # 抜粋なので動かないけど実際にはここで
            # TOTPの数字をPCに打ち込んでいる
            # keyboard_layout.write(totp_code)
    else:
        code_sent = False

動作のようす

入力ボックス(画像ではテキストエディター)にフォーカスを合わせて、TOTP表示機のボタンを押せば、表示されているコードがPCに打ち込まれます。オリジナルにはあったEnterキーの送出は省略してしまいましたが、含めれば実際の運用時にはより便利そうです。

f:id:Akkiesoft:20211209000758g:plain

まとめ

Adafruitの作例ベースで、Raspberry Pi PicoとBreakout GardenのLCDを使ったちょいオシャレなTOTP表示機&入力装置ができました。

ソースコードはこちらに放り投げたので興味のある方はどうぞ。

https://github.com/Akkiesoft/akkiesoft-pico/tree/main/CircuitPython/totp-displaygithub.com

あと、これを言うとぶち壊しな感じなんですが、時刻==TOTPがあってる前提で言えば、表示部分なくてもいいかなあ……?という気持ちにちょっとなりました。