今回は、音楽や動画などの再生・停止、早送り・巻き戻し、音量の調節などをキーに割り当ててメディアコントローラーを作成してみようと思います。
Arduinoを使用してメディアコントローラーを作成するためには、すでに何度も使ってきたKeyboard.hライブラリと特殊キーの組み合わせで作成するか、HID-Project.hライブラリを利用して作成するかどちらかになりますが、今回は2パターンともご紹介しますのでお好きなほうをお使いください。
また、今回新しく出てきたHID-Project.hライブラリについても後ほど詳しく説明いたします。
Keyboard.hを利用したメディアコントローラー
Keyboard.hライブラリを使ったパターン概要
Keyboard.hライブラリを使ってメディアコントローラーを作成します。このライブラリは、キーボードエミュレーションをサポートしていますが、メディアキーはサポートしていません。そのため、メディアコントロールは標準のキーボードショートカットを使用します。
Keyboard.hライブラリを使ったスケッチ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <Keyboard.h> // ボタンのピン番号を定義 const int buttonPins[] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 16 }; // ボタンの状態を記録する配列 bool buttonStates[ 10 ]; void setup () { // 各ボタンピンを入力に設定 for ( int i = 0 ; i < 10 ; i + + ) { pinMode (buttonPins[i], INPUT_PULLUP); buttonStates[i] = HIGH ; } // キーボードを開始 Keyboard.begin(); } void loop () { // 各ボタンの状態をチェック for ( int i = 0 ; i < 10 ; i + + ) { bool currentState = digitalRead (buttonPins[i]); if (currentState ! = buttonStates[i]) { // ボタンが押されたとき if (currentState = = LOW ) { handleButtonPress(i); } buttonStates[i] = currentState; } } } void handleButtonPress( int buttonIndex) { switch (buttonIndex) { case 0 : Keyboard.press(KEY_MEDIA_VOLUME_UP); delay ( 100 ); Keyboard.release(KEY_MEDIA_VOLUME_UP); break ; case 1 : Keyboard.press(KEY_MEDIA_VOLUME_DOWN); delay ( 100 ); Keyboard.release(KEY_MEDIA_VOLUME_DOWN); break ; case 2 : Keyboard.press(KEY_MEDIA_PLAY_PAUSE); delay ( 100 ); Keyboard.release(KEY_MEDIA_PLAY_PAUSE); break ; case 3 : Keyboard.press(KEY_MEDIA_NEXT_TRACK); delay ( 100 ); Keyboard.release(KEY_MEDIA_NEXT_TRACK); break ; case 4 : Keyboard.press(KEY_MEDIA_PREVIOUS_TRACK); delay ( 100 ); Keyboard.release(KEY_MEDIA_PREVIOUS_TRACK); break ; case 5 : Keyboard.press(KEY_MEDIA_STOP); delay ( 100 ); Keyboard.release(KEY_MEDIA_STOP); break ; case 6 : Keyboard.press(KEY_MEDIA_MUTE); delay ( 100 ); Keyboard.release(KEY_MEDIA_MUTE); break ; case 7 : Keyboard.press(KEY_MEDIA_EJECT); delay ( 100 ); Keyboard.release(KEY_MEDIA_EJECT); break ; case 8 : Keyboard.press(KEY_MEDIA_FAST_FORWARD); delay ( 100 ); Keyboard.release(KEY_MEDIA_FAST_FORWARD); break ; case 9 : Keyboard.press(KEY_MEDIA_REWIND); delay ( 100 ); Keyboard.release(KEY_MEDIA_REWIND); break ; } } |
スケッチの説明
1 | #include <Keyboard.h> |
Keyboardライブラリをインクルードします。このライブラリは、キーボードエミュレーションを提供します。
1 | const int buttonPins[] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 16 }; |
ボタンが接続されているピン番号を配列として定義します。
1 | bool buttonStates[ 10 ]; |
ボタンの状態を記録する配列を定義します。
1 2 3 4 5 6 7 | void setup () { for ( int i = 0 ; i < 10 ; i + + ) { pinMode (buttonPins[i], INPUT_PULLUP); buttonStates[i] = HIGH ; } Keyboard.begin(); } |
setup
関数では、各ボタンピンを入力プルアップに設定し、キーボード機能を初期化します。
1 2 3 4 5 6 7 8 9 10 11 | void loop () { for ( int i = 0 ; i < 10 ; i + + ) { bool currentState = digitalRead (buttonPins[i]); if (currentState ! = buttonStates[i]) { if (currentState = = LOW ) { handleButtonPress(i); } buttonStates[i] = currentState; } } } |
loop
関数では、各ボタンの状態をチェックし、状態が変わった場合にボタンの処理を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | void handleButtonPress( int buttonIndex) { switch (buttonIndex) { case 0 : Keyboard.press(KEY_MEDIA_VOLUME_UP); delay ( 100 ); Keyboard.release(KEY_MEDIA_VOLUME_UP); break ; case 1 : Keyboard.press(KEY_MEDIA_VOLUME_DOWN); delay ( 100 ); Keyboard.release(KEY_MEDIA_VOLUME_DOWN); break ; case 2 : Keyboard.press(KEY_MEDIA_PLAY_PAUSE); delay ( 100 ); Keyboard.release(KEY_MEDIA_PLAY_PAUSE); break ; case 3 : Keyboard.press(KEY_MEDIA_NEXT_TRACK); delay ( 100 ); Keyboard.release(KEY_MEDIA_NEXT_TRACK); break ; case 4 : Keyboard.press(KEY_MEDIA_PREVIOUS_TRACK); delay ( 100 ); Keyboard.release(KEY_MEDIA_PREVIOUS_TRACK); break ; case 5 : Keyboard.press(KEY_MEDIA_STOP); delay ( 100 ); Keyboard.release(KEY_MEDIA_STOP); break ; case 6 : Keyboard.press(KEY_MEDIA_MUTE); delay ( 100 ); Keyboard.release(KEY_MEDIA_MUTE); break ; case 7 : Keyboard.press(KEY_MEDIA_EJECT); delay ( 100 ); Keyboard.release(KEY_MEDIA_EJECT); break ; case 8 : Keyboard.press(KEY_MEDIA_FAST_FORWARD); delay ( 100 ); Keyboard.release(KEY_MEDIA_FAST_FORWARD); break ; case 9 : Keyboard.press(KEY_MEDIA_REWIND); delay ( 100 ); Keyboard.release(KEY_MEDIA_REWIND); break ; } } |
handleButtonPress
関数では、ボタンが押された場合に対応するメディアコントロールショートカットをキーボードとして送信します。各ショートカットの送信後に100ミリ秒の遅延を入れ、キーを解放します。
HDI-Project.hを利用したメディアコントローラー
HDI-Project.hライブラリを使ったパターン概要
HID-Project.hライブラリを使ってメディアコントローラーを作成する場合のスケッチとその説明です。
HDI-Project.hライブラリを使ったスケッチ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <HID - Project.h> // ボタンのピン番号を定義 const int buttonPins[] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 16 }; // ボタンの状態を記録する配列 bool buttonStates[ 10 ]; void setup () { // 各ボタンピンを入力に設定 for ( int i = 0 ; i < 10 ; i + + ) { pinMode (buttonPins[i], INPUT_PULLUP); buttonStates[i] = HIGH ; } // HIDを開始 HID.begin(); } void loop () { // 各ボタンの状態をチェック for ( int i = 0 ; i < 10 ; i + + ) { bool currentState = digitalRead (buttonPins[i]); if (currentState ! = buttonStates[i]) { // ボタンが押されたとき if (currentState = = LOW ) { handleButtonPress(i); } buttonStates[i] = currentState; } } } void handleButtonPress( int buttonIndex) { switch (buttonIndex) { case 0 : Consumer.write(MEDIA_VOLUME_UP); break ; case 1 : Consumer.write(MEDIA_VOLUME_DOWN); break ; case 2 : Consumer.write(MEDIA_PLAY_PAUSE); break ; case 3 : Consumer.write(MEDIA_NEXT); break ; case 4 : Consumer.write(MEDIA_PREVIOUS); break ; case 5 : Consumer.write(MEDIA_STOP); break ; case 6 : Consumer.write(MEDIA_MUTE); break ; case 7 : Consumer.write(MEDIA_EJECT); break ; case 8 : Consumer.write(MEDIA_FAST_FORWARD); break ; case 9 : Consumer.write(MEDIA_REWIND); break ; } } |
HID-Project.hライブラリを使ったパターン
スケッチの説明
1 | #include <HID - Project.h> |
HID-Projectライブラリをインクルードします。このライブラリは、HIDデバイスとしての機能を提供します。
1 | const int buttonPins[] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 16 }; |
ボタンが接続されているピン番号を配列として定義します。
1 | bool buttonStates[ 10 ]; |
ボタンの状態を記録する配列を定義します。
1 2 3 4 5 6 7 | void setup () { for ( int i = 0 ; i < 10 ; i + + ) { pinMode (buttonPins[i], INPUT_PULLUP); buttonStates[i] = HIGH ; } HID.begin(); } |
setup
関数では、各ボタンピンを入力プルアップに設定し、HID機能を初期化します。
1 2 3 4 5 6 7 8 9 10 11 | void loop () { for ( int i = 0 ; i < 10 ; i + + ) { bool currentState = digitalRead (buttonPins[i]); if (currentState ! = buttonStates[i]) { if (currentState = = LOW ) { handleButtonPress(i); } buttonStates[i] = currentState; } } } |
loop
関数では、各ボタンの状態をチェックし、状態が変わった場合にボタンの処理を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | void handleButtonPress( int buttonIndex) { switch (buttonIndex) { case 0 : Consumer.write(MEDIA_VOLUME_UP); break ; case 1 : Consumer.write(MEDIA_VOLUME_DOWN); break ; case 2 : Consumer.write(MEDIA_PLAY_PAUSE); break ; case 3 : Consumer.write(MEDIA_NEXT); break ; case 4 : Consumer.write(MEDIA_PREVIOUS); break ; case 5 : Consumer.write(MEDIA_STOP); break ; case 6 : Consumer.write(MEDIA_MUTE); break ; case 7 : Consumer.write(MEDIA_EJECT); break ; case 8 : Consumer.write(MEDIA_FAST_FORWARD); break ; case 9 : Consumer.write(MEDIA_REWIND); break ; } } |
handleButtonPress
関数では、ボタンが押された場合に対応するメディアコントロールコマンドを送信します。
HID-Project.hライブラリに関して補足
HID-Project.hを利用した場合は、メディアコントロールきーに対してwrite関数が使えるので、press、releaseを記載する必要がなくコードが短くて済みます。
HID-Project.hで利用できるメディアコントロールキー
HID-Project.hライブラリでは、以下のメディアキー定数が利用できます。
MEDIA_PLAY_PAUSE
:再生/一時停止MEDIA_NEXT
:次のトラックMEDIA_PREVIOUS
:前のトラックMEDIA_STOP
:停止MEDIA_VOLUME_UP
:音量を上げるMEDIA_VOLUME_DOWN
:音量を下げるMEDIA_MUTE
:ミュートMEDIA_EJECT
:イジェクトMEDIA_FAST_FORWARD
:早送りMEDIA_REWIND
:巻き戻し
Kyeboard.hライブラリとの違い
Kyeboard.hライブラリとHID-Project.hライブラリの一番の違いは、HID-Project.hライブラリはキーボード以外、マウスやジョイスティックなどのHIDデバイス全般の制御が出来るライブラリです。
前回でKeyboard.hライブラリとMouse.hライブラリの2つのライブラリを読み込みましたが、HID-Project.hライブラリを利用した場合は1つのライブラリでキー制御とマウス制御が行えます。
また、メディアキーなどを利用する場合はHID-Project.hライブラリにメディアキー定数として含まれているのでwriteが利用でき非常に楽ですが、マイクのミュートを行いたいと思った場合は、メディアキー定数にない為、Keyboard.hライブラリと同様なスケッチが必要になります。
以下のサンプルスケッチはマイクミュートのショートカットキーを送っています(Windows用)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include <HID - Project.h> // ボタンのピン番号を定義 const int buttonPins[] = { 2 }; // マイクミュートボタンを1つだけ定義 // ボタンの状態を記録する変数 bool buttonState = HIGH ; void setup () { pinMode (buttonPins[ 0 ], INPUT_PULLUP); // ボタンピンを入力プルアップに設定 HID.begin(); // HIDを開始 } void loop () { bool currentState = digitalRead (buttonPins[ 0 ]); // ボタンの状態を読み取る if (currentState ! = buttonState) { if (currentState = = LOW ) { handleButtonPress(); } buttonState = currentState; } } void handleButtonPress() { // Ctrl + Shift + M を送信 Keyboard.press(KEY_LEFT_CTRL); Keyboard.press(KEY_LEFT_SHIFT); Keyboard.press( 'M' ); delay ( 100 ); Keyboard.release( 'M' ); Keyboard.release(KEY_LEFT_SHIFT); Keyboard.release(KEY_LEFT_CTRL); } |
キー操作のみを行う前提であればKeyboard.hライブラリで良いでしょうし、今回のマクロキーボードなどキーボード、マウスなどHIDデバイスを総合的に制御したい場合はHID-Project.hライブラリを使うと良いと思います。
※もちろん両方のライブラリを読み込んで使い分けも可能です。
HID-Project.hライブラリの関数などの詳しい情報は別記事にアップしていますので興味のある方は下のリンクからご覧ください。
まとめ
これまで7回に分けてマクロキーボード・プログラマブルキーボードに必要なライブラリや関数などを説明してきました。
- 単一文字送信
- 複数文字送信
- スイッチの長押しなどでの条件分け
- 複数のキーでの操作
- ショートカットキー送信
- 順次キー送信をしてアプリやファイルの起動
- キーでのマウス操作
- メディアコントロールなどの特殊操作
上記の組み合わせを行えば、マクロキーボードとして十分利用できるレベルになると思います。
せっかくですので、ぜひスケッチをカスタマイズして好みのマクロキーボードに仕上げてください。
コメント