[[ファンアウト仙台]]

&ref(button1.jpg,zoom,250x200);
&ref(button2.jpg,zoom,250x200);
&ref(button3.jpg,zoom,250x200);

*概要 [#hdcecd2a]
Arduino 互換の Digispark という小型ボード(写真右)を利用して Windows PC の USB 端子に接続する大きな電源ボタンを作りました。
接続すると「HID 準拠システムコントローラ」として認識されます。
ボタンを長押しすると、キーボードの SLEEP ボタンを押した時の信号が出力されて、PC がスリープ状態になります。ボタンを短く押すと、PC がスリープ状態から復帰します。Windows7,8.1,10 で動作確認しました。


*動作 [#d9388c23]
-まず下記の「Windows の電源の設定」を行っておく必要があります。
-あらかじめ下記の「Windows の電源の設定」を行っておく必要があります。
-スイッチを長押し(1秒以上)すると、PC がスリープ状態になります。
-PC がスリープ状態の時にスイッチを短く押すと、スリープから復帰します。

*Windows の電源の設定 [#ye71442c]
-COLOR(RED){Windows 側で下記の設定をしておかないと動作しません。}
**スリープさせる [#u3974888]
-電源オプション → 電源ボタンの動作を選択する → スリープボタンを押したときの動作」を「スリープ状態」にします。

#ref(setting1.png,zoom,300x200)

**スリープ状態からウェイクアップさせる [#uf2e3667]
-電源オプション → プラン変更の設定 → 詳細な電源設定の変更 → USB設定 → USBのセレクティブサスペンドの設定 を「無効」にします。

#ref(setting3.png,zoom,300x200)

-デカスギ電源ボタンが Windows に「HID 準拠システムコントローラ」として認識されてから、デバイスマネージャ → ヒューマンインタフェースデバイス → HID 準拠システムコントローラ の設定で、「このデバイスでコンピュータのスタンバイ状態を解除できるようにする」にチェックを入れます。
-デカスギ電源ボタンを USB コネクタに接続して、Windows に「HID 準拠システムコントローラ」として認識されてから、デバイスマネージャ → ヒューマンインタフェースデバイス → HID 準拠システムコントローラ の設定で、「このデバイスでコンピュータのスタンバイ状態を解除できるようにする」にチェックを入れます。

#ref(setting2.png,zoom,300x200)

*作り方 [#t88c1676]
**回路 [#lbbf04d7]
-PB0 と GND の間にスイッチを1個付けるだけです。
-図のように PB0(D0) と GND の間にスイッチを1個付けるだけです。
-USB ケーブルが長いと不安定になることがあります。また USB ハブを通さないと認識されないことがあります。
#ref(sch.png);

**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 からも書き込めます。
 # micronucleus --run DigiUSB.hex
--Windows の場合: [[DigiSpark に対応した Arduino の統合開発環境:https://sourceforge.net/projects/digistump/files/DigisparkArduino-Win32-1.0.4-May19.zip/download]] に含まれる [[micronucleus.exe:http://purose.net/fanout/index.php?plugin=attach&pcmd=open&file=micronucleus-static.zip&refer=Digispark%E6%B8%A9%E5%BA%A6%E8%A8%88]] を使えば、上と同じ手順で Windows PC からも書き込めます(ドライバのインストールが必要です)。


*原理 [#vaf903f5]
Windows PC の動作を調べたところ、USB 接続のキーボードからスリープさせる方法と、スリープからのウェイクアップをさせる方法は全く異なっていました。

**Windows PC をスリープさせる [#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] キーのキーコードを受け取るとスリープ状態になります。

**Windows PC をスリープ状態からウェイクアップさせる [#u673b69e]
PC がスリープ状態になった後で、同じくキーボードの [Wake] キーを押すとウェイクアップします。ただしスリープ状態では OS 側からどのキーを押したかを判定できません。

そこで、キーボード側から USB の信号線の電圧レベルを一定のパターンで変化させることでウェイクアップさせるようになっているのですが、この手順がなかなか見つからずに苦労しました。

(参考) [[USB1.1仕様書:http://esd.cs.ucr.edu/webres/usb11.pdf]] の"7.1.7.5 Resume" に書いてありますが複雑です。また "Table 9-8. Standard Configuration Descriptor (Continued)" にある bmAttributes の "D5: Remote Wakeup" を有効にする必要がありました。今回は関係ありませんでしたが、[[HID 仕様書:http://www.usb.org/developers/hidpage/Hut1_12v2.pdf]] に出てくる "Boot Keyboard" とは BIOS 画面の操作に使えるキーボードのことだそうです。
(参考) [[USB1.1仕様書:http://esd.cs.ucr.edu/webres/usb11.pdf]] の"7.1.7.5 Resume" に書いてありますが複雑です。また "Table 9-8. Standard Configuration Descriptor (Continued)" にある bmAttributes の "D5: Remote Wakeup" を有効にする必要がありました。

最終的には [[PS2USB:https://github.com/robszy/ps2usb]] というプロジェクトの sendRemoteWakeUp() 関数内で実現できているのを見つけて、これを真似して実装しました。


*補足 [#a3f15429]
-ファームウェアは C言語 で書いて avr-gcc-4.9.3 でコンパイルしました。
-ソースコードは [[USB HID keyboard with V-USB:http://codeandlife.com/2012/06/18/usb-hid-keyboard-with-v-usb/]] をベースにしていますが、main.c 中の HID ディスクリプタを全面変更しています。
-OS をウェイクアップ可能な USB デバイスにするために、usbdrv.c 中のコンフィグレーションのアトリビュート(bmAttributes) を変更する必要がありました。
-スリープ中の OS をウェイクアップできる USB デバイスにするために、usbdrv.c 中のコンフィグレーションのアトリビュート(bmAttributes) を変更する必要がありました。

 [usbdrv.c : ウェイクアップ可能デバイスにするための bmAttributes の変更]
 #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 デバイスのディスクリプタやキーを押したときに発生するイベントを調べるためのツールです。有料ですが1ヶ月間の評価版もダウンロードできます。
-今回は関係ありませんでしたが、[[HID 仕様書:http://www.usb.org/developers/hidpage/Hut1_12v2.pdf]] に出てくる "Boot Keyboard" とは BIOS 画面の操作に使えるキーボードのことだそうです。


----
#counter


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS