LoginSignup
12
8

More than 3 years have passed since last update.

ダイソーのBluetoothリモートシャッター(330円)を2ボタンBluetoothキーボードにしてみよう(Windows)

Last updated at Posted at 2020-10-09

はじめに

remote-shutter.png

このリモートシャッターを前回は、RaspberryPi3 のシャットダウンボタンにしましたが、今回は Windows の Bluetooth 2ボタンキーボードにしてみようと。
色々ネットを探してみたのですが、Windows で使用している記事が無くて結構ハマりました。

※ABShutter3の仕様が変わったらしく、2つのボタンで送信キーの差がなくなったようです。どちらのボタンを押しても同じになってしまいました。 1ボタンとしては使えます。2020/10/26更新

test1.gif

Bluetoothリモートシャッターとは

  • そもそもこれは、スマホのシャッター用ボタン
  • スマホとBluetooth接続して使う
  • iOSボタンとAndroidボタンの2つある
  • 使わないと自動的に数分で電源OFFになる
  • ボタン電池のRS2032
  • HIDキーボードとして認識される

用途

キーボードフックを使って、別のキーにねじ曲げてしまおう!

ハード

  • Bluetoothリモートシャッター(AB Shutter3)(ダイソー 324円)
  • Windows10 Pro 1909

開発用IDE

ソース

作成したソース:ABShutter3Key(github)

Windowsとペアリング

このリモートシャッターは、Windowsとペアリングすれば HIDキーボードとして認識される。ドライバーなどのインストールは必要ない。

リモートシャッターの電源をOFFにしておく
Windows10 > 設定 > デバイス > Bluetoothとその他のデバイス

+Bluetooth またはその他のデバイスを追加する を押下

Bluetooth を押下。リモートシャッターの電源をONにする
通信距離が短いので、近くで行う。1m以内

AB Shutter3 を押下

ペアリング済み:

先程のWindows10 > 設定 > デバイス > Bluetoothとその他のデバイス画面に戻ると以下のようになっているはず。もしくは「接続済み」。
デバイスがWindowsに登録された状態。次回以降は、リモートシャッターの電源を入れるとすぐに接続される。この状態はまだ使用できない。リモートシャッターは数分使用しないと電源がOFFになりPCとはこの状態になる。

接続済み:

ペアリングが完了して、リモートシャッターと通信できる状態にある。この状態でないと使用できない。
もしリモートシャッターの電源がONで「ペアリング済み」状態ならiOSボタンを押してみよう「接続済み」になるはず。もしならなけれは、一度電源をOFF→ONにすればいい。

接続動作確認

「接続済み」の状態で iOS/Androidボタンを押して、デスクトップ画面の左上に下図のようボリューム表示が出てれくればOK。

開発メモ

「能書きはいいから使いたんじゃ」というひとは 使い方

iOS/Androidボタン

  • iOSボタンは、キーVK_VOLUME_UP にマッピングされている。なので先程のボリューム表示される。
  • Androidボタンは、キーVK_ENTER VK_VOLUME_UP にマッピングされている。VOLUME_UP の前に ENTER が送信されるので、エディタを開いた状態で押すと、改行とボリューム表示がされる。

今回はこのキーVK_ENTER VK_VOLUME_UPをねじ曲げて、別のボタンにしてしまおうということです。

※新しいモノだと仕様が変わったらしく、AndroidボタンでVK_ENTERキーが送信されなくなっています。2020/10/26更新

RawInput API

キーVK_ENTER VK_VOLUME_UP は、当たり前だが通常使用しているキーボードからも送信さる。なので通常のキーボードとリモートシャッターの判定をしないといけない。判定方法として RawInput API を使用する。RawInput APIを使うと HID デバイスの一覧と入力されたHIDデバイスが取得できる。だがRawInput APIでは入力されたキーの変更は一切できない、参照のみ。

VID

HIDデバイスには、VID(ベンダーID)とPID(プロダクトID)があって、これをRawInput APIで取得できるのでリモートシャッターの判定として使う。以下がリモートシャッターのVIDとPID(デバイスドライバ)。

違うようであれば setting.ini を変更する。

setting.ini
[ABShutter3Key]
VID="_VID&02248a_PID&8266"

システムフックAPI SetWindowsHookEx()

昔からあるWindowsシステムAPIで user32.dll にあります。これを使うと色々なイベントをフックできる。SetWindowsHookExW function(winuser.h)
今回はこの中でも、 WH_KEYBOARDWH_KEYBOARD_LL を使う。昔は WH_KEYBOARD しかなかったと思う。WH_KEYBOARD_LL は 低レベルキーボードフックと言って WH_KEYBOARD よりも低レベルでフックするよう。どちらもグローバルフック(システム全体にフック)することは可能だが、WH_KEYBOARD_LL は実行ファイルだけでグローバルフックできるのに対し、WH_KEYBOARD は DLL にフックプロシージャを書かないといけない決まりがある。そして両フックともフックプロシージャで 戻り値 を 0 以外にすると残りのフックチェーンにメッセージが渡らなくなり、その入力キーをブロックできるはずなのだが VK_VOLUME_UPWH_KEYBOARD ではブロックできない・・・。仕方がないので両方使う

低レベルであるWH_KEYBOARD_LLのイベントが先に来る。さきほどの RawInput API を含めると
WH_KEYBOARD_LLRawInput APIWH_KEYBOARD
(※あくまでも私の環境での実測値。公式ではないので、動かなかった場合はゴメンナサイ。)

  • VK_ENTERRawInput API で HIDデバイス判定をして、WH_KEYBOARDでその入力がリモートシャッターならブロックする
  • VK_VOLUME_UPWH_KEYBOARD_LL でブロックする

ということは、VK_VOLUME_UP は HIDデバイス判定をしていないので、すべてのHIDデバイスでブロックされてしまうことになる。しかし、どのみち RawInput APIVK_VOLUME_UP は判定できないようだった。VK_VOLUME_UP時のHIDデバイスハンドルがNULLなのだ。
まぁ VK_VOLUME_UP キーなんて普段使わないしブロックされても特に日常で困ることはないのでOKとする。

SendKeys

キーボードフックして、VK_ENTER VK_VOLUME_UP キーをブロックしたタイミングで、代替したいキー(もしくは文字列)を送信する。送信は WindowsAPIのSendInput() を使うのだが、ライブラリとして完成度の高いこちらを使わせて頂いた。

使い方

  1. ここから(ABShutter3Key)一式をダウンロードする。(Code > Download Zip)
  2. ダウンロード>解凍後に、x64/Release フォルダにある settings.ini をエディタで開く
  3. ボンタンに割り当てたいキーを iOS="任意のキー"、Andoroid="任意のキー" に記述し保存(※)
  4. x64/Release フォルダにある ABShutter3Key.exe を実行する
  5. iOS/Androidボタンを押して任意のキーが出力できたら成功
  6. 終了する場合は、タスクトレイ(システムトレイ)の ABShutter3Keyアイコンをクリックして EXITをクリック
  7. 任意のキーが出力できずに、ボリューム表示されるようならばキーボードフックに失敗してかも。 ABShutter3Key を再起動する
  8. それでもダメなら、setting.iniVIDを確認する
  9. 任意のキーが出力できずに、ボリューム表示もされないようならば 「接続済み:」か再確認する
setting.ini
[ABShutter3Key]
VID="_VID&02248a_PID&8266"
iOS="iOS{ENTER}"
Android="Android{ENTER}"

(※)キーの記述は、一文字だけであれば "A"。その他は

KEY CODE 記述例
WIN @ @d :デスクトップ表示
SHIFT + +2 :"ダブルクォーテーション
CTRL ^ ^c :コピー
ALT % %{TAB} :タスク切換え

なお、こちら(SendKeys in C++) の記述が使用可能。ただし、DELAYは使えない。
画面ロック(WIN+L) は {LOCKWORKSTATION}。

(※) settings.iniを編集したら 再起動が必要

最後に

  • 私の持っているリモートシャッターが数年前のモノなので VID などが変わっている可能性大です。
  • 2つ持っているのですが、個体差があります。
  • チャタリングが凄いです(特にAndroidボタン)、連続して表示されるかもしれません。
  • SendKeysのDELAYコマンドが使えないので、そのうち使えるように改良したい。
  • チャタリング対応もソフト的にしたい。

もし「動いたよ!」とかあればコメントして頂けると励みになります。
良い IoT ライフを!

SpecialThanks!!

SendKeys-in-C (CodeProject)
Combining Raw Input and keyboard Hook to selectively block input from multiple keyboards (CodeProject)

12
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8