[[ファンアウト仙台]] &ref(button1.jpg,zoom,200x150); &ref(button2.jpg,zoom,200x150); &ref(button3.jpg,zoom,200x150); *概要 [#hdcecd2a] Arduino 互換の Digispark という小型ボードを利用して Windows PC の USB 端子に接続する大きな電源ボタンを作りました。 接続すると「HID 準拠システムコントローラ」として認識されます。 ボタンを長押しすると、キーボードの SLEEP ボタンを押した時の信号が出力されて、PC がスリープ状態になります。ボタンを短く押すと、PC がスリープ状態から復帰します。 *原理 [#vaf903f5] 動作を調べたところ、Windows PC を USB 接続のキーボードからスリープさせる方法と、スリープからのウェイクアップさせる方法は全く異なっていました。 **スリープさせる [#pd260cf8] #ref(102key.jpg,zoom) Windows7,8,10 では [Power][Sleep][Wake] のキーがあるキーボード(日本語112キーボード) の [Sleep] キーを押すとスリープ状態になります(この挙動はコントロールパネルの[電源オプション][電源ボタンの動作を選択する] から変更できます)。 #ref(dev.png,zoom,300x200) 通常の USB キーボードを Windows PC に接続すると、デバイスマネージャ上に [キーボード]-[HIDキーボードデバイス] として表示されますが、[Sleep] キーのあるキーボードの場合は、これに加えて [ヒューマンインタフェースデバイス]-[HID 準拠システムコントローラ] という項目が追加されます。Windows はこのデバイスから [Sleep] キーのキーコードを受け取るとスリープ状態になります。 **スリープ状態からウェイクアップさせる [#u673b69e] PC がスリープ状態になった後で、同じくキーボードの [Wake] キーを押すとウェイクアップします。ただしスリープ状態では OS 側からどのキーを押したかを判定できません。 そこで、キーボード側から USB の信号線を一定のパターンでプルアップ、プルダウンすることでウェイクアップするようになっているのですが、この手順がなかなか見つからずに苦労しました。最終的には [[PS2USB:https://github.com/robszy/ps2usb]] というプロジェクトの sendRemoteWakeUp() 関数内で同じことをやっているのを見つけて実現しました。 ファームウェアのソースコードは C言語 で書いて avr-gcc でコンパイルしました。[[USB HID keyboard with V-USB:http://codeandlife.com/2012/06/18/usb-hid-keyboard-with-v-usb/]] をベースにしていますが、キーボードではなく HID 準拠システムコントローラとして認識させるために main.c 中のディスクリプタを変更しました。また OS をウェイクアップ可能な USB デバイスにするために、usbdrv.c 中のコンフィグレーションのアトリビュート(bmAttributes) を変更する必要がありました。 [usbdrv.c : ウェイクアップ可能デバイスにするための変更箇所] #if USB_CFG_IS_SELF_POWERED (1 << 5) | (1 << 7) | USBATTR_SELFPOWER, /* 変更後 */ // (1 << 7) | USBATTR_SELFPOWER, /* 変更前 */ #else (1 << 5) | (1 << 7), /* 変更後 */ // (1 << 7), /* 変更前 */ #endif **参考にしたツール [#ce0386eb] -[[USBlyzer:http://www.usblyzer.com/download.htm]] : USB デバイスのディスクリプタやキーを押したときのイベントを調べるためのツールです。有料ですが評価版もダウンロードできます。 *作り方 [#t88c1676] **Digispark用ファームウェア [#xb86aef8] -ZIP ファイル中の "DigiUSB.hex" というファイルがコンパイル後のバイナリファイルで、これを Digispark に書き込みます。 --&ref(Digispark_pwrbtn.zip); : デカスギ電源ボタン Digispark 用ファームウェア(ソース+コンパイル済みバイナリ) -書き込み方 --RaspberryPi, Linux, FreeBSD の場合: [[Digispark+gcc Lチカチュートリアル(RaspberryPi, Linux, FreeBSD 版):http://milkandlait.blogspot.jp/2017/08/digisparkgcc-lfreebsd.html]] を参考に、書き込みツール micronucleus で書き込んで下さい。 --Windows の場合: [[DigiSpark に対応した Arduino の統合開発環境:https://sourceforge.net/projects/digistump/files/DigisparkArduino-Win32-1.0.4-May19.zip/download]] に含まれる micronucleus.exe を使えば、上と同じ手順で Windows PC からも書き込めます。 **回路 [#lbbf04d7] -PB0 と GND の間にスイッチを1個付けるだけです。 #ref(sch.png); **動作 [#d9388c23] -まず下記の Windows の電源の設定を行う必要があります(COLOR(RED){重要}) -スイッチを長押し(1秒以上)すると、PC がスリープ状態になります。 -PC がスリープ状態の時にスイッチを短く押すと、スリープから復帰します。 *Windows の電源の設定 [#ye71442c] **スリープさせる [#u3974888] -「スリープボタンを押したときの動作」を「スリープ」状態にします。 #ref(setting1.png,zoom,300x200) **スリープ状態からウェイクアップさせる [#uf2e3667] - -デバイスマネージャの、このデバイス(HID 準拠システムコントローラ)の設定で、「このデバイスでコンピュータのスタンバイ状態を解除できるようにする」にチェックを入れる必要があります。 #ref(setting2.png,zoom,300x200)