LoginSignup
6
1

More than 1 year has passed since last update.

Raspberry Pi Picoを使ってパスコード自動入力機を作る【後編】 / Adafruit Trinkey QT2040

Posted at

はじめに

前回の続きです。
前回の記事をまだ読まれていない方は、そちらを読んでから本稿をお読みいただけるとより楽しめます。

前回はRaspberry Pi Pico (以下ラズパイピコ)を用いて、パスワードを自動で入力するプログラムを製作しました。

eacb998e-6884-4f33-bec7-31c1b0b382b4.jpg

今回は新たなデバイスを使って、パスワード入力機を完成させます。

前回の課題点

前回明らかになった課題点が2つありました。

1つ目はセキュリティ面が弱いという点でした。
今回使うファームウェアのCircuitPythonは、PCに接続した際、ストレージとして認識されますが、
これだとソースコードが丸見えになってしまいます。
今回はこれを解決します。

2つ目はスタイリッシュではないという点でした。
前回はラズパイピコを使って実装しましたが、パスワードを自動で入力するだけのデバイスとしては大きすぎました。
特に、今回使っていないGPIOピンは必要ないですし、PCと接続するためにはmicroUSBケーブルを用意しなければなりません。
これを新たなデバイスを用意することで解決します。

今回使うデバイス

今回使うのが、Adafruit Trinkey QT2040 というデバイスです。

QT2040_1.jpg

QT2040_2.jpg

このデバイスはラズパイピコの心臓部であるチップRP2040と同じものを積んでおり、ラズパイピコでのプログラム等をそのまま移植することができます。

そして見ての通り、GPIOピンが一切ありません!
これで小型化を実現できます。

さらに!
PCB上にUSB-A端子があり、直接USBポートに挿すことができます!
これで、接続のためのmicroUSBケーブルも必要ありません。

これで課題点の2つ目はクリアとなります。

CircuitPythonにおける起動手順

ここで、課題点1つ目を解決するために、CircuitPythonにおける起動手順、いわゆるブートシーケンスについて整理したいと思います。
以下のサイトを参考にさせていただきました。

こちらのサイトより、MicroPython及びCircuitPythonのブートシーケンスを引用させていただくと、

  1. MicroPython システム起動
  2. boot.py 実行
  3. REPL および USB ドライブ動作開始
  4. main.py 実行
  5. code.py 実行(CircuitPython のみ?)

このようになっているようです。

前回書いたプログラムは、code.pyだったので、上の手順によると一番最後に実行されることとなります。

一方上述のブートシーケンスによると、現在課題となっているUSBドライブが動作する前に、boot.pyというプログラムが実行されるようです。
つまり、ここでソースコードを見せないような処理を書けば良いということになります。

boot.pyで書く処理について

上で述べたように、boot.pyの中でストレージを無効化出来ればな~と思い、色々とリサーチしていました。
すると、Adafruit公式の以下のサイトを発見しました。

こちらに、以下のような記述がありました。

The CIRCUITPY drive is normally visible on the host computer. To disable it showing up as a USB device, use code like this in boot.py:

訳すと…

CIRCUITPYドライブは通常、ホストコンピュータ上に表示されます。USBデバイスとして表示されないようにするには、boot.pyで次のようなコードを使用します。

ということです。
そして、そのコードというのがこちらです。

boot.py
import storage

storage.disable_usb_drive()

プログラムの意味としては、

  1. storageライブラリをインポート
  2. USBドライブを無効化する関数を実行

といった感じです。

storageライブラリについては、以下のリファレンスに詳しく書かれています。

これにより、ストレージが無効化→すなわちソースコードが見られる心配が(ほぼ)無いので、課題点1つ目もクリアとなります。
(実は抜け道はありますが、それはまたの機会に…)

ということでQT2040のストレージには、

  • USBドライブを無効化するboot.py
  • メインプログラム用のcode.py

の2つのファイルを保存することとなります。

プログラムの修正

Adafruit Trinkey QT2040にはプログラマブルボタンが1つと、NeopixelのフルカラーLEDが搭載されていますので、これを使えるように少しだけプログラムを修正します。
↓参考にAdafruit Trinkey QT2040のピンアサイン(Adafruit公式ページより)

sensors_Untitled.jpg

code.py
import usb_hid
from adafruit_hid.keyboard import Keyboard
from time import sleep
import board
import neopixel
import digitalio

keyboard = Keyboard(usb_hid.devices)

pixel_pin = board.NEOPIXEL
num_pixels = 1

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)

button = digitalio.DigitalInOut(board.BUTTON)
button.direction = digitalio.Direction.INPUT

RED = 0xFF0000
GREEN = 0x00FF00
BLUE = 0x0000FF
YELLOW = 0xFFFF00

#パスコード(例) : ABCDEfghij01234

pass_list = [4,5,6,7,8,9,10,11,12,13,39,30,31,32,33]
big_or_small = [1,1,1,1,1,0,0,0,0,0,0,0,0,0,0]

pixels[0] = YELLOW
pixels.show()
sleep(0.5)

while button.value==True:
    sleep(0.01)

pixels[0] = GREEN
pixels.show()

for i in range(len(pass_list)):
    if big_or_small[i]==1:
        keyboard.press(225)
        sleep(0.01)
    keyboard.send(pass_list[i])
    sleep(0.01)
    keyboard.release(225)

keyboard.send(40)

pixels[0] = RED
pixels.show()
sleep(10)

ボタンについて

ボタンについての記述を抜粋します。

code.py
import board
import digitalio

button = digitalio.DigitalInOut(board.BUTTON)
button.direction = digitalio.Direction.INPUT

while button.value==True:
    sleep(0.01)

ライブラリはboarddigitalioの2つをインポートします。(1・2行目)

次に、buttonという変数を用意し、これがボタンのIOであると定義します。(4行目)
さらに、IOをインプットであると認識させます。(5行目)

これにより、button.valueでボタンが押されているか(False)、いないか(True)を取得することができ、7行目のようにボタンが押されるまで待機といった処理が可能となります。

NeoPixel フルカラーLEDについて

先述の通り、Adafruit Trinkey QT2040にはAdafruitのNeoPixel規格のフルカラーLEDが1個搭載されています。
↓こんな感じ

P3220004.jpg

これを制御するのが、以下のプログラムです。(上記プログラムより抜粋)

code.py
import board
import neopixel

pixel_pin = board.NEOPIXEL
num_pixels = 1

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)

RED = 0xFF0000
GREEN = 0x00FF00
BLUE = 0x0000FF
YELLOW = 0xFFFF00

pixels[0] = YELLOW
pixels.show()

ライブラリはboardneopixelの2つをインポートします。(1・2行目)
なお、neopixelライブラリは前回のadafruit_hidと同様に、ライブラリファイルをボード側に転送しておく必要があります。
やり方に関しては前回の記事のライブラリ導入手順を参考にしてください。

次に、変数pixel_pinを用意し、board上のNEOPIXELを指定します。(4行目)

さらに、変数num_pixelsを用意し、LEDの数を指定します。(5行目)
今回は1つしかありませんが、数珠つなぎにして複数個操ることも可能です。

続いて新たに変数(正確にはリスト)pixelsを用意し、neopixelの関数を用いて、LEDを定義します。(7行目)

ここまででLEDの設定は終わりましたが、光らせる色を簡単に指定するために、よく使う色を定義しておきます。
それぞれ、
【9行目】赤 #FF0000
【10行目】緑 #00FF00
【11行目】青 #0000FF
【12行目】黄 #FFFF00
となります。

これにより、14行目のように変数名(すなわち色の名前)を指定するだけで、光らせたい色を指定できます。
最後に15行目のpixels.show()という関数により、LEDは点灯を始めます。

色の意味

フルカラーLEDは、今回のデバイスの唯一のインジケータとなります。
プログラム中の色の意味は、

#FFFF00 → 入力準備完了
#00FF00 → 入力中
#FF0000 → 入力完了・終了待機中

というようになっています。

実行映像

ここまでで大方のプログラムが出来上がったので、実際にテストしてみた映像を御覧いただきたいと思います。

本体保護について

今回使ったAdafruit Trinkey QT2040ですが、小さくてコンパクトなのはいいものの、PCBの上に素子が載っていて、それが剥き出しという状態なのはちょっと怖いですよね。
素子が載っている面に圧力がかかると、すぐに壊れてしまいそうです。

そこで、↓こちらの画像を参考にして、基盤を保護するための部品を製作することにしました。

sensors_QTT_sensor_connected.jpg

3DPCBの取得

まず、Adafruit Trinkey QT2040の3DPCBが、Adafruit公式のGithubリポジトリにアップされているので、こちらよりダウンロードします。
ダウンロードできたら、boardファイルをAutodesk社のEAGLEで開きます。

EAGLEをAutodeskのアカウントと連携させておくと、EAGLE上の3DPCBを3DCADソフトのFusion 360に送ることができます。

↓矢印のところから

スクリーンショット (159).png

以下のようなダイアログが出てくるので、それに沿って進めていくと簡単にエクスポートすることができます。

スクリーンショット (160).png

3DCADでのデザイン

今度はこれをFusion 360で開きます。

スクリーンショット (161).png

あとはこれを元に3DCAD上でデザインを進めて行きます。

出来上がったのが、以下のようなモデルです。

スクリーンショット (168).png

透けて見えているのがAdafruit Trinkey QT2040本体です。

上面に一枚、下面にもう一枚の覆いがあり、USBポート部分にもカバー(キャップ)があります。
上面のカバーとキャップにはストラップホルダーが用意されていて、キャップを無くさないようにしています。

完成へ

上記の3つのオブジェクトを3Dプリンタで印刷しました。

P3220008.jpg

さらに↓これらの細かい部品を用意し、本体と組み合わせます。
(Φ2のビス・ナット・スペーサーとボールチェーン)

P3220013.jpg

そして遂に、完成品がこちら!!

P3220017.jpg

P3220019.jpg

P3220015.jpg

我ながら、非常に上手くできたと思っています👍

考察・感想

実際に何度か現場で使用してみましたが、めちゃくちゃ便利です!!
やはり長くてランダムで覚えられないようなパスワードにはとても有用だと思います。

前回のラズパイピコを使う方法も含め、非常に便利なデバイスだと思うので是非みなさんも作ってみて下さい!!

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1