1key-boardの作製
Attiny85ではUSBに2端子、電源、GNDに2端子使うので、残りが4つのピンがあるのでで最大物理的に4つのキーをもつキーボードが作成できる。
でリセットピンを解除して、4つのキーボードのプロトタイプを作った。
しかし、プロトタイプを作って使っているとある結論に至った・・・
結果1つで十分!!たくさんキーがある方が良いと最初は思うが、そうではなかった・・・
まず、沢山キーがっても、何を登録しているかを覚えられるのはせいぜい4つ。
アンチスクリーンモードを搭載すると今機能しているのか?していないのか?LEDのインディケーターがないとやはり不便。で3つにする?でもね・・・
物理的に、4つのキーがなくても、シングルクリック、ダブルクリック、トリプルクリック、長押しとキーのアクションで4つの動作を区別すればいいから・・結果、シンプルな1つキーのキーボードでいいのではという結論に・・・
【回路作製】
表面側に紙を両面テープで全面に張る。
Attiny85をすでに写真では実装しているが、実装前に、ライターで最低限ブートローダー書き込みしてから半田付けする。さもなければ・・・
リセットピンのPB05を使っているので、
も参考に。
実際にコマンドプロンプトから流し込んだコマンドは、
avrdude -C avrdude.conf -v -pattiny85 -carduino -PCOM22 -b19200 -Uflash:w:t85_default.hex -U lfuse:w:0xe1:m -U hfuse:w:0x5d:m -U efuse:w:0xfe:m
【スケッチ】
さくっとシングルクリック、ダブルクリック、トリプルクリック、長押しの区別をするために
Button2のライブラリーを利用。
また、TimerOneというタイマーのライブラリーも利用。
動作的には、ボタンを長押しすると、アンチスクリーンーセーバーモードに入って、約10分でタイマーの割り込みが入って、Pauseボタンを1回だけ押す動作にしている。
Timer1.initialize(500000);
Timer1.attachInterrupt(tfunction);
Timer1.stop();
セットアップで、タイマーをイニシャライズして、インターラプトとスタートしたらすぐにストップ(一時停止)。ボタンが長押しされ、アンチスクリーンモードでないなら、アンチスクリーンモードにするためタイマーをTimer1.resume()で再開し、LEDを点灯。すでにアンチスクリーンモードだったら逆に、Timer1.stop()でタイマーを止めて、アンチスクリーンモードを解除して、LEDを消灯する。
はまった所は、タイマーの割り込みでキーを押す場合、一度stopをして、それからキーを送り込まないと、ずっと同じキーを押した状態になってしまう。それを回避するために、キーを送りだす前に、いったんタイマーを止めて、送って、再開という動作にする。
TimerOneのライブラリーだが8ビットのAttiny85では0.5秒までしか測れない。そこで0.5秒ごとにタイマー割り込みが入るが、カウンターを設けて目的のカウントだったら処理するようにして長時間を測定する。1714というのがその所。
ただ、キーを送り込む際にストップして送って再開をしているのでだいたいの時間になる。
まず、テストの段階では、1714の所を10とかの数字にしておいて、動作を確認。実際に実測した所、10のカウントで約3.5秒だったので、10分=600秒を3.5で割ると171.4、つまり1714カウントとしている。これで
include <TrinketKeyboard.h>
#include <TimerOne.h>
#include "Button2.h"
// Attiny85
// PB5(reset)-| |-VCC
// PB3-| |-PB2
// PB4-| |-PB1
// GND-| |-PB0
const int PB5pin = 5; //For Switch
const int PB2pin = 2; //For LED
int ledState = LOW;
long cnt=0;
Button2 buttonPB5;
void setup() {
//pinMode set for LED
pinMode (PB2pin, OUTPUT);
//start USB stuff
TrinketKeyboard.begin();
//Timer setting
Timer1.initialize(500000);
Timer1.attachInterrupt(tfunction);
Timer1.stop();
//button setting
buttonPB5.begin(PB5pin);
buttonPB5.setClickHandler(handlerPB0);
//buttonPB5.setLongClickHandler(handlerPB0);
buttonPB5.setLongClickDetectedHandler(handlerPB0);// this will only be called upon detection
buttonPB5.setDoubleClickHandler(handlerPB0);
buttonPB5.setTripleClickHandler(handlerPB0);
}
void loop() {
TrinketKeyboard.poll();
buttonPB5.loop();
delay(1);
}
/////////////////////////////////////////////////////////////////
void handlerPB0(Button2& btn) {
switch (btn.getType()) {
case single_click:
TrinketKeyboard.print("single_click");
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
break;
case double_click:
TrinketKeyboard.print("double_click");
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
break;
case triple_click:
TrinketKeyboard.print("triple_click");
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
break;
case long_click:
if (ledState==LOW)
{
Timer1.resume();
ledState=HIGH;
digitalWrite(PB2pin, HIGH);
}
else {
Timer1.stop();
ledState=LOW;
digitalWrite(PB2pin, LOW);
}
break;
case empty:
return;
}
}
/////////////////////////////////////////////////////////////////
void tfunction(){
if (cnt%1714==0) //cnt=10 correspond to 3.5 sec
{
Timer1.stop();
TrinketKeyboard.pressKey(0,0x48);
TrinketKeyboard.pressKey(0,0);
Timer1.resume();
cnt=0;
}
cnt=cnt+1;
}
/////////////////////////////////////////////////////////////////
【ケーシング】
100均で売っているフォトフレームを切断して、トッププレートとボトムプレートを作成。
トッププレートはスイッチの部分とLEDの部分が干渉しないように穴をあけている。
スイッチは3.5mmの大きさなのでクリアランスを考えて4.5mmであけて、LEDは3mmなので4mmであけている。
上の写真では上からビスを通して、ナットで裏で固定しているが、そうすると高さが高くなり、USBハブやノートPCのUEBポートに刺すとこのキーボードの方が高くなってしまったので、ビスとナットを入れかえている。
ナットを上にするとシンデレラフィットで高さが丁度!!またLEDの光が透明な板に導波して板全体が光ってくれてナイス。
ノートパソコンにつけても若干ノートPCが薄いので高さの不一致あるものの、気にならないレベルでジャストフィット!
コメント
コメントを投稿