これって何?
人が近づいたら、USB経由でキー入力を送信するデバイスです。Digispark ATtiny85とPIRセンサ(人感センサー)をつないだだけです。プログラムはArduino IDEで作ります。
はじめに
先日 古いWindows10タブレットを再活用!MagicMirror2を稼働してGoogleフォトフレームを作ろう!の記事を書きました。最近、少し前のタブレットPCが中古屋さんなどに安く出回っています。MagicMirror2など、ちょっとした情報を常時出力する端末として活用すると便利です。
ただ、普通に設定すると、画面は常時点灯することになるので、ちょっとうるさい…。画面を見ていないときは、自動的に画面が消えたりするとよさそうです。PIRセンサ(人感センサー)を使って、近くに誰かいるときキーを押すことで、PCが復帰するデバイスを作りました。
具体的には、以下のような動作をします。USBキーボードとして認識しますので、PC側は無改造、PC側に特別なドライバも不要です。
- PCは、指定時間でディスプレイを消灯するよう設定しておきます。
- PIRセンサ(人感センサー)をつないで、人が近づいたらテキトウなキーボード信号([WAKE UP]キー)を送って、PCを復帰します。(Windowsでは、[WAKE UP]キーを押しても何も起こらないようです。ただ、キー入力することで画面OFFは復帰します。)
- 人がいる間は、テキトウな間隔で(作例では1分間隔)キーボード信号を送ります。
世の中にはちょうど良いことに、Atmel ATtiny85と呼ばれる、USBデバイスを容易に作れるマイコンがあります。開発はArduino互換ですのでとても楽です。
ATtiny85が載っている「Digispark ATtiny85」互換のボードは、USBコネクタも付いているので便利です。例えばShigezoneで入手できます。
PIRセンサは、秋月電子で薄型の焦電型赤外線センサーモジュールを利用しました。
※写真左:焦電型赤外線センサーモジュール 右:Digispark ATtiny85
組み立てる
Digispark ATtiny85に、PIRセンサをつなぐだけです。上記センサの場合、センサのVCC(赤色)を「5V」(AtTiny85の8ピン)、GND(黒)を「GND」(4ピン)、センサ出力(黄)を「P0」(5ピン)につなぎます。
ATtiny85互換のボードには、動作確認用のLEDとして、P1にLEDが実装されています。ただ、モノによってP0につながっているボードもあるらしいので、その場合は「P1」(6ピン)か「P2」(7ピン)につなぎます(ソースコードの PIN_SENSOR をP1の場合は1、P2の場合は2に変更します)。
プログラムを作って書き込む
プログラムはArduino IDEで作ります。あらかじめ、ボードマネージャーとしてATTinyCoreを入れておきます。(この記事作成時点では1.5.2が最新です。なお1.5.2は、最新のArduino2.xでは上手く動かないかもしれませんので、その場合はArduino 1.8.xを入れて下さい。)
ボード設定は、以下を設定しました。
- Board: ATTinyCore -> ATTiny 45/85(OptiBoot)
- Chip : ATTiny 85
- Clock source:16MHz
- millis()/micros() : Enabled
※ Digisparkに使われているMicronucleusブートローダーを使う場合は、Boardを「Digispark Pro (Default 16mhz)」に変更すれば動くと思います(未確認です)。
また、ライブラリとして、USBキーボードライブラリAdafruit-Trinket-USBを事前に入れて下さい。
今回は、ブートローダーを変更して(「ツール」→「ブートローダーを書き込む」)、Arduino as ISP経由でバイナリを書き込んでいます。
プログラムについて
見ての通り、超短いです。コピーしてArduinoの新規スケッチに貼り付けてビルドしてみて下さい。人が近づいたら押すキーは[WAKE UP]キー( SYSCTRLKEY_WAKE ) を設定しました。他のキーに変えたい場合は、 libraries/TrinketHidCombo/TrinketHidCombo.h を参考にして、 PIR_PRESS_KEY を変更してください。また、手元のDigispark ATtiny85互換ボードは、P1にLEDが実装されていましたので、PIRセンサが感知したときに点灯するようにしています。
#include <TrinketHidCombo.h>
#include <TrinketHidComboC.h>
#include <cmdline_defs.h>
#include <usbconfig.h>
// PIN assign
#define PIN_SENSOR 0
#define PIN_LED 1
// PIR SENSOR
#define PIR_SENSOR_ON LOW
#define PIR_SENSOR_OFF HIGH
// PRESS KEYBOARD
#define PIR_PRESS_KEY SYSCTRLKEY_WAKE
// SLEEP time (60 seconds)
#define KEY_PRESS_ROUND_TIME (60 * 1000L)
// SENSOR debounce delay
#define SENSOR_DELAY_TIME 1000L
unsigned long lRoundTime;
unsigned long lNowTime;
bool bPressKey;
void setup()
{
// button pins as inputs
pinMode(PIN_SENSOR,INPUT_PULLUP);
pinMode(PIN_LED ,OUTPUT); // LED pins as output
// start USB stuff
TrinketHidCombo.begin();
//
lRoundTime = 0;
bPressKey = false;
}
void loop()
{
lNowTime = millis();
if (digitalRead(PIN_SENSOR) == PIR_SENSOR_ON)
{
digitalWrite(PIN_LED, HIGH);
if ( lRoundTime < lNowTime )
{
lRoundTime = lNowTime + KEY_PRESS_ROUND_TIME;
bPressKey = true;
}
}
else
{
digitalWrite(PIN_LED, LOW);
if ( lRoundTime < lNowTime )
{
lRoundTime = lNowTime + SENSOR_DELAY_TIME ;
}
}
if (bPressKey)
{
TrinketHidCombo.pressSystemCtrlKey(PIR_PRESS_KEY);
delay(5); // debounce delay
// this releases the key (otherwise it is held down!)
TrinketHidCombo.pressKey(0, 0);
bPressKey = false;
}
TrinketHidCombo.poll();
delay(10); // keystroke delay
}
完成例
PIRセンサをPCの前面に張り付ければ完成です(写真では、左下に張り付けてあります。)。自分は、タブレットPCを机の横の壁に貼り付けました。机に座っている時だけ、画面が表示されます。