Digisparkを使用したフットスイッチの製作

先日のセキュリティ・キャンプでお土産としてDigisparkをいただいた.
寝かせておくのもなんかもったいないので,フットスイッチをつくってみる.

 
さて,最近”自作キーボード”が流行っている.自作キーボードはプラモデルのようにキットを買って組み立てるものが多いが,個人的には自由度が高いマイコンを使ってキー入力を行うほうが楽しい.形状に関しても決まった形よりもその場にあるもので適当に組むのも良さがある.また,キットは高性能なだけに高価なものが多い.そして私には金がない.
 
フットスイッチとは要するに”足用キーボード”である.普段PCをよく使う人は,手の指先ばかりを忙しく動かし,その間に足は全く動かさないという人が多い.
しかし,足を使ってPCを使うことができれば作業効率が上る可能性がある.例えばEmacsを使うときにCtrlを足に割り当てれば,これ以上小指を痛めることがなくなるかもしれない.あるいは,右足に→キー,左足に←キーを割り当てることで食事をしながら電子書籍を読むことができる.
 

環境構築

ミニキャンプではVM上のコンソールからコンパイル・転送を行ったが,今回はArduino IDEを用いる.環境構築はこのページに従って行う.なお,Wiresharkなどに付いてくるUSBpcapがインストールされているとDigisparkが認識できないので,事前に消しておく.
 

ソフトウェアの作成

右足と左足で2つのスイッチを使う.そのため,それぞれP0とP2のピンを使う.P1が使えないのはLEDがつながっているため.また,P3とP4はUSBで使うため,スイッチには使えない.これは回路図で確認できる.
‘0’でスイッチが押されていない状態,’1’で押されている状態として解釈する.
作成したソースコードを以下に示す.どのキーが入力されるかについてはKEY_RIGHTやKEY_MOD_RIGHTで指定している.MODがついている方は修飾キーで,例えばAlt,Ctrlを指定できる.なお,指定にはKEY_Aなどを指定するが,これはDigiKeyboard.hで定義されている.
また,単純にキーを押すだけでなく,長押しした場合はキー入力が短い間隔で連続して押される挙動を再現した.最初にキーを押してから長押しの挙動が行われる間隔は20(78行目)×50(68行目)=1,000[ms]となっている.78行目の1ループあたりの待ち時間を短くするとスイッチを押してからキー入力が行われるまでの時間が短くなり,68行目の条件式内の定数を短くすると長押しの挙動が始まる時間が短くなる.

 
 

ハードウェアの製作

スイッチ

スイッチとしてダイソーに売っているプッシュライトを改造して使用した.また,導線としてLANケーブルをバラして使用した.

 
ダイソーのプッシュライトは,分解すると以下のような構造になっている.

ただし,このスイッチはプッシュスイッチなので一度押すとONの状態を維持してしまう.そのため,プッシュスイッチを外してタクトスイッチに替える.
タクトスイッチは押しているときだけONになり(キーボードのキーと同じ),押すとカチッとなる.下の写真の左がプッシュスイッチ,右がタクトスイッチ.

 
プッシュライトを回路図に直すとおそらくこの様になっている.抵抗の値は赤黒茶なので200[Ω]となる.本来は乾電池3本で動作するので4.5[V]がかかり,22.5[mA]の電流が流れる.なお,今回はUSBのバスパワーで5[V]かけるので25[mA]が流れることになる.

ここで,先述の通り’0’をスイッチが離されている状態,’1’をスイッチが押されている状態としてスイッチの状態を読み込みたい.
よって,プルダウンを行う回路が必要となる.なお,プルダウン抵抗の値は10[kΩ]程度が望ましいらしいが,手元になかったので1[kΩ]のものを使用した.

そのため,以下のような回路が必要になると考えた(間違っていたが).

それに従い,プッシュスイッチの配線を下のようにした(この時点でも間違いに気付かなかったが).
左は基板とスイッチと電池の電極がある面,右は電池ボックスの部分(電池ボックスは下から見ると図とは逆に見えるが,左右の図で対応を取るために左右反転している).

こんな感じで抵抗をつける.はんだをつけた後の写真は撮り忘れた.

しかし,この状態でスイッチを押しても動かない.実測してみると2.2[V]程度しか入力に入っていない.よく考えると,LEDによる電圧降下を忘れていた.
理想ダイオードであれば200[Ω]と1[kΩ]の直列接続となり,I=5[V]/(200+1000)[Ω]=4.2[mA]でプルダウン抵抗にかかる電圧はV2=1[kΩ]*4.2[mA]=4.2[V]となって’1’と判定される.ちなみにArduinoのdigitalReadでは3[V]以上がHIGHとして認識されるとのこと.しかしLEDの電圧降下により1つあたり0.6~0.7[V]電圧降下が発生する(LEDの電圧降下についてはこのページが詳しい).よって,LED1つあたりの電圧降下が0.65[V]とすると,プルダウン抵抗にかかる電圧は4.2[V]-0.65[V]*3=2.25[V].これでは’0’として認識される.
 
LED部分を切り捨てるという手もあったが,押したときに光ったほうが楽しいような気がするので,LED部分と入力部分を並列にした回路を考える.

先程電池ボックス側に抵抗をつけてしまって外すのが面倒なので,基板のある側の配線を並列版回路図に合うように変更する.

これでスイッチ部分は正しく動作した.
もし次にやる機会があったら,下の形で配線を変更するのが一番楽かもしれない(未検証).

 

導線

さて,スイッチ部分ができたので,導線でDigisparkとスイッチ2つを結ぶ.
今回導線に使うのはダイソーのLANケーブルである.1つのスイッチで必要となる線の数は+側電源,-側電源,入力で3本なので,2つスイッチを使う場合は6本必要となる.LANケーブルは8本線が通っているため,被覆を剥けば使うことができる.外側の白い被覆に関してはカッターで両面を軽く切り何回か折り曲げると外せる.中の各線の被覆に関してはワイヤーストリッパーを使うと簡単に剥ける.ない場合はカッターを使うしかない.
また,左右の足の幅の分だけケーブルを枝分かれさせる必要がある.これは線を4本ずつに分けた後,間にカッターの刃を入れて切っていく.地味に難易度が高いが,2本までなら断線させても大丈夫.


 

Digispark側とスイッチ側で対応が分かるようにマジックで2進数を記し,あとはそれぞれはんだを付けていく.久々にはんだごて握ったらすごく時間かかった….


 

完成


 

動作確認


形状も,押したら光るところも,なんか音ゲーっぽいなーって思う.
そういえば東京フレンドパークで似たような音ゲーあったなって調べてみたら,こういうものがあった.頑張ればこういうのも行けそうかなーという感じ.というか東京フレンドパークが7年も前に終わってたことを知ってちょっとショックだった….
それはともかく,とりあえずキー入力をa,bから→,←に変えてしばらく使ってみる.
 
追記
なんでDigiKeyboard.hにはKEY_ARROW_LEFTが定義されててKEY_ARROW_RIGHTはないんだろう.まあHID Usage Tablesの55ページあたりに値が書いてあるから,それを入れれば良いんだけど.