Mono Netflix専用キーボード を Digistump で作る (その2)

目次
前回の続き。
プログラム
10年以上、ほぼ使っていなかった Digistump 。
今回も、思い知る、その容量の小ささ。
最初はお手軽に、Pimoroni で購入した I2C で繋げる光るロータリーエンコーダーを利用しようとしたが、Arduino用のseesawライブラリを組み込むと、6Kbytesを越えてしまい、メモリが足りない。
しょうがないので、ロータリーエンコーダーの動作を検知するプログラムを自作する。
GPIO の INPUT_PULLUP
まず、なぜか。いやまあわかるけど、 P1 が INPUT PULLUP として利用できなかった。
本体上のLEDと同期しているので、無理目ではあるけど、 できない という記述を見つけられないので、正し仕様はわからず。
SWITCH A と SWITCH B の INPUT PULLUP には、 PINP0 と P2 を利用する。
ロータリーエンコーダーの回転検出
ロータリーエンコーダーは、2つのスイッチのON/OFFの組み合わせで、回転方向を検出することができる。
実際には、4回の状態変化を検出できる。
| 時間経過 | SWITCH A | SWITCH B |
|---|---|---|
| t0 | OFF | OFF |
| t1 | ON | OFF |
| t2 | ON | ON |
| t3 | OFF | ON |
| t4 | OFF | OFF |
t0 から t4 までの時間経過は、 カチ っと1メモリ動かす時間なので、数百msec くらい。
- t1
SWITCH Aが先にONになり、ちょっと遅れてSWITCH BもON - t3
SWITCH Aが先にOFFになり、ちょっと遅れてSWITCH BもOFF
逆回転では、SWITCH B が先に変化する。
最初は、 t0->t1 になるところで回転方向を取得していたがうまくいかない。
DEBUGをいれてみると、 t1 のタイミングがとれてない。
どうやら、 t4 直後に USBのキーボードとしてキー入力を送信するコストで t1 が間に合わず、検出漏れしてる感じ。
ということで、 t3->t4 のタイミングで回転方向を検知するようにした。
プッシュスイッチ
これは簡単、シンプルな、PULLUPスイッチ。
が、モデルによっては、 PIN P5 が使えないこともあるらしい。
自分の使った Digistump 初号機では、 P5 も正しく動作した。
code
#include <Arduino.h>
#include <DigiKeyboard.h>
#include <DigiUSB.h>
#include <stdlib.h>
int _switch_a, _switch_b, _switch_push;
#define SWICTH_A_PIN 0
#define SWICTH_B_PIN 2
#define LED_PIN 1
#define PUSH_PIN 5
void setup()
{
pinMode(SWICTH_A_PIN, INPUT_PULLUP);
pinMode(SWICTH_B_PIN, INPUT_PULLUP);
pinMode(PUSH_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
_switch_a = _switch_b = _switch_push = 0;
for (int i = 0; i < 5; i++)
{
digitalWrite(LED_PIN, HIGH);
delay(50);
digitalWrite(LED_PIN, LOW);
delay(100);
}
}
void loop()
{
int a, b, p;
a = digitalRead(SWICTH_A_PIN);
b = digitalRead(SWICTH_B_PIN);
p = digitalRead(PUSH_PIN);
if (_switch_push != p)
{
if (p)
{
// SPACE
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.sendKeyStroke(KEY_SPACE);
}
_switch_push = p;
}
if (_switch_a == a && _switch_b == b)
{
// no change
return;
}
if (!a && !b)
{
//
// 1 -> 0
// END OF MOVING
//
if (_switch_a && !_switch_b)
{
// #define KEY_ARROW_LEFT 0x50
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.sendKeyStroke(0x50);
}
else if (_switch_b && !_switch_a)
{
// why don't define KEY_ARROW_RIGHT
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.sendKeyStroke(0x4f);
}
}
_switch_a = a;
_switch_b = b;
delay(1);
}3D データ

ケースと合うように、ペットボトルキャップのデータは、数mm くらい低くなるように修正した。


