勝手な電子工作・・

勝手なオリジナル電子工作に関する記事を書きます

Zoom用かんたん操作ボタンをArduino-UNOで作る(その2)やったね!

とりあえず簡単な4ボタンを使ってプログラムをめでたく完成しました。ごく短いスケッチでできます。この装置をZoom会議本番で使ってみたら、操作ががぜん楽になりました。プログラムを含めて詳しくご紹介したいと思います。f:id:a-tomi:20200504214817j:plain

このサブジェクトの最初の記事(その1)の翌日に、プログラム(Arduinoスケッチ)を作り、テストしたら一発で動き快適!調整したのはチャタリング時間の定数設定だけ。最初のテストに作ったボタンは、次のようなブレッドボード上のタクトスイッチです。

f:id:a-tomi:20200504221720j:plain

このボタン装置ならちょっとした時間でできますね。

f:id:a-tomi:20200504221747j:plain

次は、なぜか作業時のマスクをしたままですが^^; 最初のテストをやってます。このテストへの参加者は白クマだけですが^^

f:id:a-tomi:20200505105434j:plain

検討の結果、ショートカットキーの1番目をMute All(ホスト以外)に変更しました。多数が参加するZoom会議本番では、メンバーの中の誰かのスピーカー音がマイクに戻る場合にエコーやハウリングを起こすことがあります。そういう場合、ホスト役としては各参加者のマイクをミュートにして確認しながら、邪魔なノイズを除去します。その際は1つのキーでホスト以外を全てミュートにできると楽ですね。1番目のボタンをそれに変更することにしました。

f:id:a-tomi:20200504220227j:plain

回路は単純で、各スイッチを押せばグランドに接続するようにつくります。他に部品は要りません。接続は次の本番プログラムを見ていただいたく方が早いかと思います(勝手ながら2020年5月13日プログラムを更新しました:ボタン名Bxにウォーニングが出る場合があるためBtnxにし、また、チャタリングの特に長いスイッチにも対応しました)。

//* **************************************************
       "Zoom" short-cut buttons with Arduino-UNO
          V00: Initial version for test   May 1, 2020
          V01: Updated Button assignment  May 2, 2020
          V02  For very long chatterings  May 10,2020
       Funcion: Provide four short-cut-buttons
        Button 1 for Mute all memabers (on/off) *V01
        Button 2 for View gallery (on/off=speaker) 
        Button 3 for Tool-bar (on/off)
        Button 4 for Full-screen (on/off)
      (c) Akira Tominaga, All rights reserved.
 ****************************************************
*/
#define B1 9            // Button 1 for Mute-all *V01
#define B2 10           // Button 2 for View-gallery
#define B3 11           // Button 3 for Toolbar
#define B4 12           // Button 4 for Full-screen
// Chattering time depends on the Buttons used
#define Cht 30          // chattering max time (mS)
#define lCht 200        // time to bypass longer chtrg

byte KbD[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // HID report
// KbD[0]=Modifier for USB HID Keyboard-code
#define rGUI B10000000  // right Windows key
#define rALT B01000000  // right Alt key
#define rSFT B00100000  // right Shift key
#define rCTL B00010000  // right Ctl key
#define lGUI B00001000  // left Windows key
#define lALT B00000100  // left Alt key
#define lSFT B00000010  // left Shift key
#define lCTL B00000001  // left Ctl key
// KbD[1] should always be 0x00
// KbD[2] to KbD[7] include key-codes (max 6 keys)
// Alphabet code = ASCIIcode-0x5D (ex.a:0x61 -> 0x04)
#define Csub 0x5D       // Character value to subtract
//   Special key codes
#define ScF1 0x3A       // USB KB code for F1 key (Speaker)
#define ScF2 0X3B       // USB KB code for F2 key (Gallery)
byte  Fk=ScF1;          // save area for cur Func key 

void setup() { // Setup **************************
  Serial.begin(9600);
  // define Buttons and pull them up
  pinMode(B1, INPUT_PULLUP);
  pinMode(B2, INPUT_PULLUP);
  pinMode(B3, INPUT_PULLUP);
  pinMode(B4, INPUT_PULLUP);
}

void loop() {  // Arduino loop ******************
  if (digitalRead(B1) == LOW) { // B1: Mute all members
    delay(Cht);         // avoid chattering
    while (digitalRead(B1) == LOW) {} // wait button-off
    // Serial.println("B1=Mute all"); // for test only
    KbD[2] = 'm' - Csub; // set character m
    KbD[0] = lALT;      // set ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B2) == LOW) { // B2: View gallery
    delay(Cht);         // avoid chattering
    while (digitalRead(B2) == LOW) {} // wait button-off
    // Serial.println("B2=View"); // for test only
    if (Fk == ScF2) {   // select function key
      Fk = ScF1;        // set F1 if currently F2
    } else {
      Fk = ScF2;        // set F2 if currently F1
    }
    KbD[2] = Fk;        // set the Func-key
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B3) == LOW) { // B3: Toolbar
    delay(Cht);         // avoid chattering
    while (digitalRead(B3) == LOW) {} // wait button-off
    // Serial.println("B3=Tool"); // for test only
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }

  if (digitalRead(B4) == LOW) { // B4: Full screen
    delay(Cht);         // avoid chattering
    while (digitalRead(B4) == LOW) {} // wait button-off
    // Serial.println("B4=Scrn"); // for test only
    KbD[2] = 'f' - Csub; // Set keyboard f char
    KbD[0] = lALT;      // set left ALT key
    KbWrite();          // send HID-Make and Brake
  }
}

/********************************
 * *** User defined functions ***
 * *****************************/
// *** KbWrite()  send HID-Make and HID-Brake
void KbWrite(void)
{
  Serial.write(KbD, 8); // HID-Make
  KbD[2] = 0x00;        // clear character
  KbD[0] = 0x00;        // clear modifier
  Serial.write(KbD, 8); // HID-Break
  delay(lCht);        // to ignore longer chtrg *V02
}

ボタンが押されたのを確認する処理は簡単そうですが、実は十分な注意が必要です。

単にLOWになったかどうかをチェックするだけでなく、数ミリ~数十ミリ秒のチャタリング(接点オン時のノイズ)回避用delay時間をとった後で、HIGHになる(ボタンを離す)まで待つ必要があります。ボタンに対する処理の量が少ない(つまりごく短時間に処理が終わる)場合には特に大事なことです。チャタリングの長いスイッチもあるので、念のために各処理の後に余分な時間を入れます。これは操作性には影響しません。

こうしないとチャタリングによって複数回押されたことになり、連続して複数回の同じ処理をしてしまうことにもなります。どれだけの時間を待つかはスイッチの品質にもよりますが、いかに高品質でも物理的なスイッチであればチャタリングは避けられません。回路上でローパスフィルタを入れれば多少は軽減できますが、現代ではそうはせずにソフトウェアで回避するのがいちばん妥当ですね。

人の手によるボタン操作の後処理なので、プログラム側で30mS待っても影響はありません。同じコーディングをされるようにお勧め。スイッチに合わせてこの時間を調節することもできますが、処理の後(この例ではユーザー定義関数の最後)に200mSをいれましたので、調整しなくともどれでも大丈夫ですし、操作性にも影響しません。

 

テスト段階で使うタクトスイッチは2ピンのものがお勧めです。ブレッドボードで使う場合、2本足のタクトスイッチなら取り付けも操作も安定していますから。普通のタクトスイッチは4ピンのものが殆どですが、基板用なので脚を延ばしても短すぎブレッドボードには不向きです。次の写真で奥のものが不適切な4ピン、手前の2つが適当な2ピンのタクトスイッチです。

f:id:a-tomi:20200504222001j:plain

 

2回の会議本番では、以上の4つのボタン装置があれば必要十分と感じました。ご自分の操作しやすさに合わせてお好みのものにするとか、ボタンを増やしたりされても使いやすいかもしれません。

Zoomが現在(2020年5月5日)提供しているショートカットキーは次のものです。

f:id:a-tomi:20200504222450j:plain

 

さて、とくに問題もみつからないので、ボタンのセットを作ることにします。

こんなに助かる装置なので、そのうちにArduino Microを調達してスイッチと併せて小さく作りたいと考えました。なので、前の記事(その1)で説明した本命の押釦はそれ用にとっておくことにしました。

そして翌日の会議に間に合うように急いで、一番早く製作できるボタンを使いました(その代り品質は個体差も多くてロクなものではありません、チャタリング回避時間を思い切り延ばしたわけです^^;)。これなら、例えばタカチのプラスチックケースにとりつけるならすぐに加工できますし。なお、消費税が5%の頃に入手した感じ^^

f:id:a-tomi:20200504222820j:plain

次のように完成しました。

f:id:a-tomi:20200504222848j:plain

左からMute all, View gallery, Tool, Full screen。4つなら頭文字だけ表示すればよいかな。

小さい箱なので配線にひと手間かかりますが、そこには生活の知恵を。スイッチに直接ケーブルを配線をするのではなく、ごく小さな基板をかませます。ここまではスズメッキ線などで配線します。こうすると速くて確実・丈夫にできます。中身は少しみっともないですが次。

f:id:a-tomi:20200504223159j:plain

使っているシールドケーブルは使わないUSBケーブルを流用したものです。中に4線がシールドされているのでノイズを拾わず、なにより柔らかい。そして百均のケーブルでも確実であり、こういう用途にはぴったりですね。内部には赤、緑、白、黒、そしてシールドがあります。シールド線にははんだ付け前に1mmφ熱収縮チューブ等をかぶせます。

Arduino UNOも別のケースに収めます。Arduinoとの配線は、ケースに収容して固定しない限り、操作中に抜けたり、長く使うとArduino側ヘダーピン(メス)が傷んでだんだん緩くなってしまいます。よって面倒でもケースに収めるわけです。

もしArduino Microでつくる場合なら、ボタンと併せて1つの筐体にしてしまいますが、今回はUNOなのでやむを得ないですね。こちらには秋月で売っている小さなポリカーボネートケースを使いました。割れないので工作がとても速くできます。余計なソケットなどは省くのが今回は得策ですね。

f:id:a-tomi:20200504223537j:plain

ところで、後で考えてみればこのUNOのケースにボタンをとりつけてもよかったのか・・?。手元に必要なスペースが増えるのは感心しませんので、これでいいか。

f:id:a-tomi:20200504223731j:plain

ヘダーピンのところにはL型オス1列ヘダーピンを使用。使うのはグランド、デジタルピン12、11、10、9です。ピン13はUNO基板のLEDを後で使うかもしれないので、スキップし、そのピンはL型ヘダーピンから抜いておきます。

f:id:a-tomi:20200504223931j:plain

1本ずつではなく連結したピンを使うと、全体が動きにくくなりArduino UNO側のメスピンが傷みにくくなります。

Arduino UNO専用のケースが、かつてAmazon等で百数十円で売られていましたので、その時に沢山入手してあります。そちらは体裁がよいのですが、日頃使う装置にこれを使うとピンの固定にひと工夫がいりますので、今回は敬遠。

f:id:a-tomi:20200504224212j:plain

 

以上について真似をされる方は事前に前の記事(その1)を読んでくださいね。Arsuino-UNOのUSB接続をKeyboardにしたりArduinoに戻したりする方法をそちらに書いてありますので。

a-tomi.hatenablog.com

 

また、キーボードの文字コードについての情報が必要かと思いますのでここに書きます。OADGで出されているHID(ヒューマンインターフェイスバイス)のプロトコルに従うものですが、次のコードをご覧になればわかりやすいかと思います。

日本語キーボードでもZoomのショートカットキーは幸い同じようですが、その他のキーの違いを知る必要のある場合は、”日本語  USB-HIDキーボード  コード”などでググっていただくとキー配列の設定がいくつか見つかりますのでそちらをご参照ください。

/**
MightyPork/usb_hid_keys.h
*
 * USB HID Keyboard scan codes as per USB spec 1.11
 * plus some additional codes
 * 
 * Created by MightyPork, 2016
 * Public domain
 * 
 * Adapted from:
 * https://source.android.com/devices/input/keyboard-devices.html
 */

#ifndef USB_HID_KEYS
#define USB_HID_KEYS

/**
 * Modifier masks - used for the first byte in the HID report.
 * NOTE: The second byte in the report is reserved, 0x00
 */
#define KEY_MOD_LCTRL  0x01
#define KEY_MOD_LSHIFT 0x02
#define KEY_MOD_LALT   0x04
#define KEY_MOD_LMETA  0x08
#define KEY_MOD_RCTRL  0x10
#define KEY_MOD_RSHIFT 0x20
#define KEY_MOD_RALT   0x40
#define KEY_MOD_RMETA  0x80

/**
 * Scan codes - last N slots in the HID report (usually 6).
 * 0x00 if no key pressed.
 * 
 * If more than N keys are pressed, the HID reports 
 * KEY_ERR_OVF in all slots to indicate this condition.
 */

#define KEY_NONE 0x00 // No key pressed
#define KEY_ERR_OVF 0x01 //  Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
// 0x02 //  Keyboard POST Fail
// 0x03 //  Keyboard Error Undefined
#define KEY_A 0x04 // Keyboard a and A
#define KEY_B 0x05 // Keyboard b and B
#define KEY_C 0x06 // Keyboard c and C
#define KEY_D 0x07 // Keyboard d and D
#define KEY_E 0x08 // Keyboard e and E
#define KEY_F 0x09 // Keyboard f and F
#define KEY_G 0x0a // Keyboard g and G
#define KEY_H 0x0b // Keyboard h and H
#define KEY_I 0x0c // Keyboard i and I
#define KEY_J 0x0d // Keyboard j and J
#define KEY_K 0x0e // Keyboard k and K
#define KEY_L 0x0f // Keyboard l and L
#define KEY_M 0x10 // Keyboard m and M
#define KEY_N 0x11 // Keyboard n and N
#define KEY_O 0x12 // Keyboard o and O
#define KEY_P 0x13 // Keyboard p and P
#define KEY_Q 0x14 // Keyboard q and Q
#define KEY_R 0x15 // Keyboard r and R
#define KEY_S 0x16 // Keyboard s and S
#define KEY_T 0x17 // Keyboard t and T
#define KEY_U 0x18 // Keyboard u and U
#define KEY_V 0x19 // Keyboard v and V
#define KEY_W 0x1a // Keyboard w and W
#define KEY_X 0x1b // Keyboard x and X
#define KEY_Y 0x1c // Keyboard y and Y
#define KEY_Z 0x1d // Keyboard z and Z

#define KEY_1 0x1e // Keyboard 1 and !
#define KEY_2 0x1f // Keyboard 2 and @
#define KEY_3 0x20 // Keyboard 3 and #
#define KEY_4 0x21 // Keyboard 4 and $
#define KEY_5 0x22 // Keyboard 5 and %
#define KEY_6 0x23 // Keyboard 6 and ^
#define KEY_7 0x24 // Keyboard 7 and &
#define KEY_8 0x25 // Keyboard 8 and *
#define KEY_9 0x26 // Keyboard 9 and (
#define KEY_0 0x27 // Keyboard 0 and )

#define KEY_ENTER 0x28 // Keyboard Return (ENTER)
#define KEY_ESC 0x29 // Keyboard ESCAPE
#define KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
#define KEY_TAB 0x2b // Keyboard Tab
#define KEY_SPACE 0x2c // Keyboard Spacebar
#define KEY_MINUS 0x2d // Keyboard - and _
#define KEY_EQUAL 0x2e // Keyboard = and +
#define KEY_LEFTBRACE 0x2f // Keyboard [ and {
#define KEY_RIGHTBRACE 0x30 // Keyboard ] and }
#define KEY_BACKSLASH 0x31 // Keyboard \ and |
#define KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
#define KEY_SEMICOLON 0x33 // Keyboard ; and :
#define KEY_APOSTROPHE 0x34 // Keyboard ' and "
#define KEY_GRAVE 0x35 // Keyboard ` and ~
#define KEY_COMMA 0x36 // Keyboard , and <
#define KEY_DOT 0x37 // Keyboard . and >
#define KEY_SLASH 0x38 // Keyboard / and ?
#define KEY_CAPSLOCK 0x39 // Keyboard Caps Lock

#define KEY_F1 0x3a // Keyboard F1
#define KEY_F2 0x3b // Keyboard F2
#define KEY_F3 0x3c // Keyboard F3
#define KEY_F4 0x3d // Keyboard F4
#define KEY_F5 0x3e // Keyboard F5
#define KEY_F6 0x3f // Keyboard F6
#define KEY_F7 0x40 // Keyboard F7
#define KEY_F8 0x41 // Keyboard F8
#define KEY_F9 0x42 // Keyboard F9
#define KEY_F10 0x43 // Keyboard F10
#define KEY_F11 0x44 // Keyboard F11
#define KEY_F12 0x45 // Keyboard F12

#define KEY_SYSRQ 0x46 // Keyboard Print Screen
#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
#define KEY_PAUSE 0x48 // Keyboard Pause
#define KEY_INSERT 0x49 // Keyboard Insert
#define KEY_HOME 0x4a // Keyboard Home
#define KEY_PAGEUP 0x4b // Keyboard Page Up
#define KEY_DELETE 0x4c // Keyboard Delete Forward
#define KEY_END 0x4d // Keyboard End
#define KEY_PAGEDOWN 0x4e // Keyboard Page Down
#define KEY_RIGHT 0x4f // Keyboard Right Arrow
#define KEY_LEFT 0x50 // Keyboard Left Arrow
#define KEY_DOWN 0x51 // Keyboard Down Arrow
#define KEY_UP 0x52 // Keyboard Up Arrow

#define KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
#define KEY_KPSLASH 0x54 // Keypad /
#define KEY_KPASTERISK 0x55 // Keypad *
#define KEY_KPMINUS 0x56 // Keypad -
#define KEY_KPPLUS 0x57 // Keypad +
#define KEY_KPENTER 0x58 // Keypad ENTER
#define KEY_KP1 0x59 // Keypad 1 and End
#define KEY_KP2 0x5a // Keypad 2 and Down Arrow
#define KEY_KP3 0x5b // Keypad 3 and PageDn
#define KEY_KP4 0x5c // Keypad 4 and Left Arrow
#define KEY_KP5 0x5d // Keypad 5
#define KEY_KP6 0x5e // Keypad 6 and Right Arrow
#define KEY_KP7 0x5f // Keypad 7 and Home
#define KEY_KP8 0x60 // Keypad 8 and Up Arrow
#define KEY_KP9 0x61 // Keypad 9 and Page Up
#define KEY_KP0 0x62 // Keypad 0 and Insert
#define KEY_KPDOT 0x63 // Keypad . and Delete

#define KEY_102ND 0x64 // Keyboard Non-US \ and |
#define KEY_COMPOSE 0x65 // Keyboard Application
#define KEY_POWER 0x66 // Keyboard Power
#define KEY_KPEQUAL 0x67 // Keypad =

#define KEY_F13 0x68 // Keyboard F13
#define KEY_F14 0x69 // Keyboard F14
#define KEY_F15 0x6a // Keyboard F15
#define KEY_F16 0x6b // Keyboard F16
#define KEY_F17 0x6c // Keyboard F17
#define KEY_F18 0x6d // Keyboard F18
#define KEY_F19 0x6e // Keyboard F19
#define KEY_F20 0x6f // Keyboard F20
#define KEY_F21 0x70 // Keyboard F21
#define KEY_F22 0x71 // Keyboard F22
#define KEY_F23 0x72 // Keyboard F23
#define KEY_F24 0x73 // Keyboard F24

#define KEY_OPEN 0x74 // Keyboard Execute
#define KEY_HELP 0x75 // Keyboard Help
#define KEY_PROPS 0x76 // Keyboard Menu
#define KEY_FRONT 0x77 // Keyboard Select
#define KEY_STOP 0x78 // Keyboard Stop
#define KEY_AGAIN 0x79 // Keyboard Again
#define KEY_UNDO 0x7a // Keyboard Undo
#define KEY_CUT 0x7b // Keyboard Cut
#define KEY_COPY 0x7c // Keyboard Copy
#define KEY_PASTE 0x7d // Keyboard Paste
#define KEY_FIND 0x7e // Keyboard Find
#define KEY_MUTE 0x7f // Keyboard Mute
#define KEY_VOLUMEUP 0x80 // Keyboard Volume Up
#define KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
// 0x82  Keyboard Locking Caps Lock
// 0x83  Keyboard Locking Num Lock
// 0x84  Keyboard Locking Scroll Lock
#define KEY_KPCOMMA 0x85 // Keypad Comma
// 0x86  Keypad Equal Sign
#define KEY_RO 0x87 // Keyboard International1
#define KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
#define KEY_YEN 0x89 // Keyboard International3
#define KEY_HENKAN 0x8a // Keyboard International4
#define KEY_MUHENKAN 0x8b // Keyboard International5
#define KEY_KPJPCOMMA 0x8c // Keyboard International6
// 0x8d  Keyboard International7
// 0x8e  Keyboard International8
// 0x8f  Keyboard International9
#define KEY_HANGEUL 0x90 // Keyboard LANG1
#define KEY_HANJA 0x91 // Keyboard LANG2
#define KEY_KATAKANA 0x92 // Keyboard LANG3
#define KEY_HIRAGANA 0x93 // Keyboard LANG4
#define KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
// 0x95  Keyboard LANG6
// 0x96  Keyboard LANG7
// 0x97  Keyboard LANG8
// 0x98  Keyboard LANG9
// 0x99  Keyboard Alternate Erase
// 0x9a  Keyboard SysReq/Attention
// 0x9b  Keyboard Cancel
// 0x9c  Keyboard Clear
// 0x9d  Keyboard Prior
// 0x9e  Keyboard Return
// 0x9f  Keyboard Separator
// 0xa0  Keyboard Out
// 0xa1  Keyboard Oper
// 0xa2  Keyboard Clear/Again
// 0xa3  Keyboard CrSel/Props
// 0xa4  Keyboard ExSel

// 0xb0  Keypad 00
// 0xb1  Keypad 000
// 0xb2  Thousands Separator
// 0xb3  Decimal Separator
// 0xb4  Currency Unit
// 0xb5  Currency Sub-unit
#define KEY_KPLEFTPAREN 0xb6 // Keypad (
#define KEY_KPRIGHTPAREN 0xb7 // Keypad )
// 0xb8  Keypad {
// 0xb9  Keypad }
// 0xba  Keypad Tab
// 0xbb  Keypad Backspace
// 0xbc  Keypad A
// 0xbd  Keypad B
// 0xbe  Keypad C
// 0xbf  Keypad D
// 0xc0  Keypad E
// 0xc1  Keypad F
// 0xc2  Keypad XOR
// 0xc3  Keypad ^
// 0xc4  Keypad %
// 0xc5  Keypad <
// 0xc6  Keypad >
// 0xc7  Keypad &
// 0xc8  Keypad &&
// 0xc9  Keypad |
// 0xca  Keypad ||
// 0xcb  Keypad :
// 0xcc  Keypad #
// 0xcd  Keypad Space
// 0xce  Keypad @
// 0xcf  Keypad !
// 0xd0  Keypad Memory Store
// 0xd1  Keypad Memory Recall
// 0xd2  Keypad Memory Clear
// 0xd3  Keypad Memory Add
// 0xd4  Keypad Memory Subtract
// 0xd5  Keypad Memory Multiply
// 0xd6  Keypad Memory Divide
// 0xd7  Keypad +/-
// 0xd8  Keypad Clear
// 0xd9  Keypad Clear Entry
// 0xda  Keypad Binary
// 0xdb  Keypad Octal
// 0xdc  Keypad Decimal
// 0xdd  Keypad Hexadecimal

#define KEY_LEFTCTRL 0xe0 // Keyboard Left Control
#define KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
#define KEY_LEFTALT 0xe2 // Keyboard Left Alt
#define KEY_LEFTMETA 0xe3 // Keyboard Left GUI
#define KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
#define KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
#define KEY_RIGHTALT 0xe6 // Keyboard Right Alt
#define KEY_RIGHTMETA 0xe7 // Keyboard Right GUI

#define KEY_MEDIA_PLAYPAUSE 0xe8
#define KEY_MEDIA_STOPCD 0xe9
#define KEY_MEDIA_PREVIOUSSONG 0xea
#define KEY_MEDIA_NEXTSONG 0xeb
#define KEY_MEDIA_EJECTCD 0xec
#define KEY_MEDIA_VOLUMEUP 0xed
#define KEY_MEDIA_VOLUMEDOWN 0xee
#define KEY_MEDIA_MUTE 0xef
#define KEY_MEDIA_WWW 0xf0
#define KEY_MEDIA_BACK 0xf1
#define KEY_MEDIA_FORWARD 0xf2
#define KEY_MEDIA_STOP 0xf3
#define KEY_MEDIA_FIND 0xf4
#define KEY_MEDIA_SCROLLUP 0xf5
#define KEY_MEDIA_SCROLLDOWN 0xf6
#define KEY_MEDIA_EDIT 0xf7
#define KEY_MEDIA_SLEEP 0xf8
#define KEY_MEDIA_COFFEE 0xf9
#define KEY_MEDIA_REFRESH 0xfa
#define KEY_MEDIA_CALC 0xfb

#endif // USB_HID_KEYS

 

また、FLIPツール(その1をご参照)を使ってUNOが正しくUSBキーボードになったのかを確認するためには、デバイスマネジャーを立ち上げておいて表示をみると良いと前回書きました。ついでですが、Windowsでさらに詳しく確認したい場合についてここでご紹介したいと思います。

マイクロソフトが提供している無料開発ツールのUSB ViewerあるいはUSB Tree Viewerのどちらかを導入して、それを使われると良いと思います。USB Tree Viewerの方が詳しい情報が得られます(が、USB Viewerの方が導入は単純です)。各名称でググっていただくとマイクロソフトの説明ページが出てきますので、必要な方は自己責任にてご導入ください。

次はUSB Tree viewer V3.3.8(現時点で最新)での表示例です。

f:id:a-tomi:20200505115159j:plain

上図は私の場合ですが、他のキーボードを常時2個(テンキーレスとテンキーをわけているためです)接続していますので、USB-HIDキーボードが3個になって少し紛らわしいかもしれませんね。 

この例ではPort7を選び表示される詳細は次です。


    =========================== USB Port7 ===========================

Connection Status        : 0x01 (Device is connected)
Port Chain               : 1-7
Properties               : 0x01
 IsUserConnectable       : yes
 PortIsDebugCapable      : no
 PortHasMultiCompanions  : no
 PortConnectorIsTypeC    : no
ConnectionIndex          : 7

      ======================== USB Device ========================

        +++++++++++++++++ Device Information ++++++++++++++++++
Device Description       : USB 入力デバイス
Device Path              : \\?\usb#vid_03eb&pid_2042#5&16caae6d&0&7#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
Device ID                : USB\VID_03EB&PID_2042\5&16CAAE6D&0&7
Hardware IDs             : USB\VID_03EB&PID_2042&REV_0000 USB\VID_03EB&PID_2042
Driver KeyName           : {745a17a0-74d3-11d0-b6fe-00a0c90f57da}\0032 (GUID_DEVCLASS_HIDCLASS)
Driver                   : \SystemRoot\System32\drivers\hidusb.sys (Version: 10.0.18362.175  Date: 2019-08-29)
Driver Inf               : C:\WINDOWS\inf\input.inf
Legacy BusType           : PNPBus
Class                    : HIDClass
Class GUID               : {745a17a0-74d3-11d0-b6fe-00a0c90f57da} (GUID_DEVCLASS_HIDCLASS)
Interface GUID           : {a5dcbf10-6530-11d2-901f-00c04fb951ed} (GUID_DEVINTERFACE_USB_DEVICE)
Service                  : HidUsb
Enumerator               : USB
Location Info            : Port_#0007.Hub_#0001
Location IDs             : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(7), ACPI(_SB_)#ACPI(PCI0)#ACPI(XHC_)#ACPI(RHUB)#ACPI(HS07)
Container ID             : {6a392c6f-8a75-11ea-9c58-b8aeedafcdef}
Manufacturer Info        : (標準システム デバイス)
Capabilities             : 0x84 (Removable, SurpriseRemovalOK)
Status                   : 0x0180400A (DN_DRIVER_LOADED, DN_STARTED, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
Problem Code             : 0
HcDisableSelectiveSuspend: 0
EnableSelectiveSuspend   : 0
SelectiveSuspendEnabled  : 0
EnhancedPowerMgmtEnabled : 1
IdleInWorkingState       : 0
WakeFromSleepState       : 0
Power State              : D0 (supported: D0, D3, wake from D0)
 Child Device 1          : HID キーボード デバイス
  DevicePath             : \\?\hid#vid_03eb&pid_2042#6&39102546&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}
  KernelName             : \Device\00000125
  Device ID              : HID\VID_03EB&PID_2042\6&39102546&0&0000
  Class                  : Keyboard

        ---------------- Connection Information ---------------
Connection Index         : 0x07 (7)
Connection Status        : 0x01 (DeviceConnected)
Current Config Value     : 0x01
Device Address           : 0x08 (8)
Is Hub                   : 0x00 (no)
Device Bus Speed         : 0x01 (Full-Speed)
Number Of Open Pipes     : 0x01 (1 pipe to data endpoints)
Pipe[0]                  : EndpointID=1  Direction=IN   ScheduleOffset=0  Type=Interrupt
Data (HexDump)           : 07 00 00 00 12 01 10 01 00 00 00 08 EB 03 42 20   ..............B 
                           00 00 01 02 00 01 01 01 00 08 00 01 00 00 00 01   ................
                           00 00 00 07 05 81 03 08 00 0A 00 00 00 00         ..............

        --------------- Connection Information V2 -------------
Connection Index         : 0x07 (7)
Length                   : 0x10 (16 bytes)
SupportedUsbProtocols    : 0x03
 Usb110                  : 1 (yes)
 Usb200                  : 1 (yes)
 Usb300                  : 0 (no)
 ReservedMBZ             : 0x00
Flags                    : 0x00
 DevIsOpAtSsOrHigher     : 0 (Is not operating at SuperSpeed or higher)
 DevIsSsCapOrHigher      : 0 (Is not SuperSpeed capable or higher)
 DevIsOpAtSsPlusOrHigher : 0 (Is not operating at SuperSpeedPlus or higher)
 DevIsSsPlusCapOrHigher  : 0 (Is not SuperSpeedPlus capable or higher)
 ReservedMBZ             : 0x00
Data (HexDump)           : 07 00 00 00 10 00 00 00 03 00 00 00 00 00 00 00   ................

    ---------------------- Device Descriptor ----------------------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x01 (Device Descriptor)
bcdUSB                   : 0x110 (USB Version 1.10)
bDeviceClass             : 0x00 (defined by the interface descriptors)
bDeviceSubClass          : 0x00
bDeviceProtocol          : 0x00
bMaxPacketSize0          : 0x08 (8 bytes)
idVendor                 : 0x03EB (Atmel Corporation)
idProduct                : 0x2042
bcdDevice                : 0x0000
iManufacturer            : 0x01 (String Descriptor 1)
 Language 0x0409         : "Arduino"
iProduct                 : 0x02 (String Descriptor 2)
 Language 0x0409         : "Keyboard"
iSerialNumber            : 0x00 (No String Descriptor)
bNumConfigurations       : 0x01 (1 Configuration)
Data (HexDump)           : 12 01 10 01 00 00 00 08 EB 03 42 20 00 00 01 02   ..........B ....
                           00 01                                             ..

    ------------------ Configuration Descriptor -------------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x02 (Configuration Descriptor)
wTotalLength             : 0x0022 (34 bytes)
bNumInterfaces           : 0x01 (1 Interface)
bConfigurationValue      : 0x01 (Configuration 1)
iConfiguration           : 0x00 (No String Descriptor)
bmAttributes             : 0xC0
 D7: Reserved, set 1     : 0x01
 D6: Self Powered        : 0x01 (yes)
 D5: Remote Wakeup       : 0x00 (no)
 D4..0: Reserved, set 0  : 0x00
MaxPower                 : 0x32 (100 mA)
Data (HexDump)           : 09 02 22 00 01 01 00 C0 32 09 04 00 00 01 03 01   ..".....2.......
                           01 00 09 21 11 01 00 01 22 40 00 07 05 81 03 08   ...!...."@......
                           00 0A                                             ..

        ---------------- Interface Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x04 (Interface Descriptor)
bInterfaceNumber         : 0x00
bAlternateSetting        : 0x00
bNumEndpoints            : 0x01 (1 Endpoint)
bInterfaceClass          : 0x03 (HID - Human Interface Device)
bInterfaceSubClass       : 0x01 (Boot Interface)
bInterfaceProtocol       : 0x01 (Keyboard)
iInterface               : 0x00 (No String Descriptor)
Data (HexDump)           : 09 04 00 00 01 03 01 01 00                        .........

        ------------------- HID Descriptor --------------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x21 (HID Descriptor)
bcdHID                   : 0x0111 (HID Version 1.11)
bCountryCode             : 0x00 (00 = not localized)
bNumDescriptors          : 0x01
Data (HexDump)           : 09 21 11 01 00 01 22 40 00                        .!...."@.
Descriptor 1:
bDescriptorType          : 0x22 (Class=Report)
wDescriptorLength        : 0x0040 (64 bytes)
Error reading descriptor : ERROR_INVALID_PARAMETER

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x81 (Direction=IN EndpointID=1)
bmAttributes             : 0x03 (TransferType=Interrupt)
wMaxPacketSize           : 0x0008 (8 bytes)
bInterval                : 0x0A (10 ms)
Data (HexDump)           : 07 05 81 03 08 00 0A                              .......

      -------------------- String Descriptors -------------------
             ------ String Descriptor 0 ------
bLength                  : 0x04 (4 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language ID[0]           : 0x0409 (English - United States)
Data (HexDump)           : 04 03 09 04                                       ....
             ------ String Descriptor 1 ------
bLength                  : 0x10 (16 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language 0x0409          : "Arduino"
Data (HexDump)           : 10 03 41 00 72 00 64 00 75 00 69 00 6E 00 6F 00   ..A.r.d.u.i.n.o.
             ------ String Descriptor 2 ------
bLength                  : 0x12 (18 bytes)
bDescriptorType          : 0x03 (String Descriptor)
Language 0x0409          : "Keyboard"
Data (HexDump)           : 12 03 4B 00 65 00 79 00 62 00 6F 00 61 00 72 00   ..K.e.y.b.o.a.r.
                           64 00                                             d.

参考情報がだらだら長引いてしまいました。

 

Zoomは転送データ量が他のネット会議ツールよりも少なく安定しています。Wifi経由でないスマホからの出席者にとってもよいことですね。私は一昨年から遠隔会議に使ってきましたが、最近は乱入防止のために待機室を使うなど簡単な対策もそろってきましたし、この便利なツールにはとても感謝しています。

ネット会議の需要はまだまだ当分続くことでしょうし、広がる一方でしょう。なのでこの簡単操作ボタンの出番は半永久的?次は全体が一番小さいのを作っておこうかと考え始め、今になって結局Arduino Micro系の基板を注文しておきました。あれっ^^; 

小さいのをそちらで作った際には、またここの記事でご報告するつもりです。ただ、記事はなにせ勝手なマイペースですから、途中で他の記事になったりして・・

 

©2020 Akira Tominaga, All rights reserved.