まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

Keyboard

Arduinoで任意のUSBコードを送る 解決編

 Arduino Leonardo/MicroはUSBキーボードとして使えるが、Usageコードが101より大きいものは無視されるという問題があった。
PS/2キーボード変換器の製作(18) USBキーボードの無視されるキーについて
対策箇所はわかっていたが、当時はバイナリにパッチするという手段しか思いつかず強引にやっていた。
PS/2キーボード変換器の製作(19) HEXファイルにパッチを当てる
 この後、Arduino IDEのフォルダ内にあるソースをいじると反映されることを知った。Arduino IDEは毎回ソースから全部ビルドしてたのか!コアな部分はコンパイル済と勝手に思っていた。
Turning an Arduino Leonardo into a joystick.(Imarginary Industries)
 この記事ではUSBAPI.h、HID.cppを修正することによりジョイスティックのUSB-HIDを追加している。ということはArduino IDEにあるHID.cppのHID Report Descripterを修正することで日本語キーボードの機種で¥マークなどを入力できるようになるはずだ。
MacOSXだと修正対象のソースはContents/Resources/Java/hardware/arduino/cores/arduino/以下にある。
https://gist.github.com/houmei/2ad9f7a713f46149e72f

HID.cppを差し替え、ライブラリを組み込む。このライブラリはHID.cpp/USBAPI.hと一体化もできると思うが以前作ったのをそのまま流用しているのでこうなっている。

2014shot1
 これはDavinciにArduino Microのファームウェアを書き込んだもの。pin4にスイッチを付けてフリスクの大きめのケースに入れてみた。たったこれだけ。日本語キーボードがついてるものがWindowsXPの古いノートPCしかなかったのでそれに接続して¥マークが入力できることを確認した。

https://gist.github.com/houmei/0ac6873618caa02f22b4

 USBキーボードのUsageコードについては以下からどうぞ。注意点としてUSキーボードのレイアウトが基準。
USB HID to PS/2 Scan Code Translation Table

 ああ、これで数年悩んでた問題が解決だ。変なバイナリパッチ作った時点で誰も突っ込んでくれないのね。


 ついでにPrint ScreenのUsageコード(0x46)を設定して最近話題のエビデンス画面スクリーンショット用ボタンにしてみた。これでハードコピー取り放題よ。
2014shot2

 

PS/2キーボード変換器の製作(10) 整理

・PS/2キーボード→USB接続、US配列を日本語配列に変換する。工程整理。

■開発環境とマイコンは確定
・ArduinoIDE1.0.1とArduino Leonardo(互換品)で作成。オープンソース。再現性高い。
・送り返して書きなおしたりしなくても、先方でアップデート可能

☆印は優先、これらが出来れば最低限動作

□ハードウェア
□マイコン選定(AVR ATmega32U4搭載 Arduino Leonard互換ボード、複数の選択肢があることは重要)
 ※sparkfun ATmega32U4モジュール 今回は使わない http://www.switch-science.com/products/detail.php?product_id=982
☆PS/2ポートのPullUp抵抗無くせるか 設定確認
□ケース組み込み

□ソフトウェア
■構造
 ■PS/2キーボード入出力はArduinoのライブラリとして構成 → arduino.cc playgroundのps2keyboard/ps2keyboardext2を参考
 ■USB HIDキーボード出力はArduinoIDE1.0.1の機能を利用
 ■スキャンコード→USBのコードへの変換はスケッチで行う

・ライブラリ
□PS/2キーボード入力
 ■PS/2キーボードのスキャンコード Type2決め打ちでOK(Type1は古い機種、Type3は特殊で使われない)
 ☆スキャンコードを直接扱うrawread()を追加→作成済、未確認
 ☆スキャンコードをFIFOに入れる→キー取りこぼし対策
 ☆PrintScreen/Alt+PrintScreen
 □Pause(ただしPrintScreenができればたいしたことはない)
 □NumLock時挙動 キーパッド部分
□PS/2キーボード出力
 □コマンド送出 キーボード本体のLED制御
 □コマンド送出 キーボードリピート設定

・スケッチ
☆スキャンコード PS/2-US→USB-HID変換
□スキャンコード マルチメディア系の追加キー
☆make/release制御 USBは同時押し6個まで、PS/2は無制限 この調整

Arduino IDE1.0.1とDavinciのLeonardo化

Arduino IDE 1.0.1がリリースされた。目玉はLeonardoの正式対応とマルチリンガル対応。MacOSXにインストールするとメニューが日本語化されていた。
 Leonardo正式対応ということで手持ちのDavinciを使ってUSB HID Keyboardのテストをやってみたが、コンパイルは通っても動作しない。これはDavinciのLeonardo相当ファームが古いのでは?と思い更新してみた。
 ファーム更新はAVR-ISP mkIIを使用する。Davinciにハンダ付けした6ピンのISP端子に写真の様に接続する。また、AVR-ISP mkIIでの書き込みでは別に電源が必要なため、DavinciにUSBケーブルを接続した。 また、Devinci上のショートプラグはショートしている。(写真右下にちょろっと見える)
2012isp
 
 書き込みはArduino-IDE1.0.1の[ツール]→[マイコンボード]でArduino Leonardoを選択。次に[ツール]→[書込装置]でAVRISPmkIIを選択。そして[ツール]→[ブートローダを書き込む]を実行。AVR-ISP mkII 装置のLEDがオレンジ色に光り、一分程で終了。
なぜか1回ではうまくいかず、DavinciをUSBケーブルでMac本体に接続してもシリアルポートを認識しなかった。2回目の書き込みでうまくいった。
ついでながら従来DavinciはWindows環境ではデバイスドライバをインストールできなかったのが、ファーム書き換えでArduino IDE1.0.1付属のデバイスドライバで認識できるようになった。まあLeonardoで書き換えられたんだからそうだろう。
 現在、発売されたばかりのArduino LeonardoとATmega32U4搭載マイコンボードを注文している。LeonardoのハードはほぼATmega32U4そのものなので、マイコンボードの方も書き換えられないかなあと思っている。

 HID-USB Keyboardのテストは以下。https://gist.github.com/2775713

/* Button for Keyboard (Arduino Leonardo only) */

/*
  Button
 
 Turns on and off a light emitting diode(LED) connected to digital  
 pin 13, when pressing a pushbutton attached to pin 2. 
 
 
 The circuit:
 * LED attached from pin 13 to ground 
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 
 * Note: on most Arduinos there is already an LED on the board
 attached to pin 13.
 
 
 created 2005
 by DojoDave 
 modified 30 Aug 2011
 by Tom Igoe
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/Button
 */

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int keymacroPin = 3;
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(keymacroPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  digitalWrite(keymacroPin, HIGH);

  Keyboard.begin();
}

void loop(){
  if (digitalRead(keymacroPin)==LOW) {
    // not implemented
  }

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == LOW) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH); 
    delay(30);
    while(buttonState == LOW){
      buttonState = digitalRead(buttonPin);
      // Keyboard.press(ctrlKey);
      Keyboard.press(' ');
    }
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
    Keyboard.release(' ');
  }
  delay(100);
}

2012mouse

 これは以前作ったマウスクリックと同じようなもので、今回はボタンを押すとスペースキーを押しっぱなしにしたのと同じような動作になる。Arduino-IDE 1.0非公式のやり方ではKeyboard.write()でUSBキーボードの文字を押した動作になるが、押しっぱなしにする機能はなかった。Arduino1.0.1からはKeyboard.press()とKeyboard.release()で指示できる。このため前回はGoogle日本語モールス入力がスペースキーでは出来なかったのでマウスクリックにしたが、今回はスペースキーでOKになった。また、モディファイア(CTRLキー、SHIFTキー)も指示できるようだ。

 Mouse&Keyboardライブラリの使い方。Mouse & Keyboard libraries[arduino.cc]

モディファイアの定義などは以下にある。
hardware/arduino/cores/arduino/USBAPI.h

ちょっと抜き出すと:

#define KEY_LEFT_CTRL           0x80
#define KEY_LEFT_SHIFT          0x81
#define KEY_LEFT_ALT            0x82
#define KEY_LEFT_GUI            0x83
#define KEY_RIGHT_CTRL          0x84
#define KEY_RIGHT_SHIFT         0x85
#define KEY_RIGHT_ALT           0x86
#define KEY_RIGHT_GUI           0x87

#define KEY_UP_ARROW            0xDA
#define KEY_DOWN_ARROW          0xD9
#define KEY_LEFT_ARROW          0xD8
#define KEY_RIGHT_ARROW         0xD7
#define KEY_BACKSPACE           0xB2
#define KEY_TAB                         0xB3
#define KEY_RETURN                      0xB0
#define KEY_ESC                         0xB1
#define KEY_INSERT                      0xD1
#define KEY_DELETE                      0xD4
#define KEY_PAGE_UP                     0xD3
#define KEY_PAGE_DOWN           0xD6
#define KEY_HOME                        0xD2
#define KEY_END                         0xD5
#define KEY_CAPS_LOCK           0xC1
#define KEY_F1                          0xC2
#define KEY_F2                          0xC3
#define KEY_F3                          0xC4
#define KEY_F4                          0xC5
#define KEY_F5                          0xC6
#define KEY_F6                          0xC7
#define KEY_F7                          0xC8
#define KEY_F8                          0xC9
#define KEY_F9                          0xCA
#define KEY_F10                         0xCB
#define KEY_F11                         0xCC
#define KEY_F12                         0xCD




 うれしかったのは(1)Windowsでのデバイス認識、(2)USB-HIDキーボードの正式サポート。これであれがやっとできる!

参考:
2012/5/22 Arduino-1.0.1リリース[Arduino Wiki]
Arduino Leonardoへのガイド[スイッチサイエンス]

追記:モディファイアの設定も効いた。
      Keyboard.press(ctrlKey);
      Keyboard.press('a');
で全選択ができる(WindowsでCTRL+A)。
なお、ArduinoIDE1.0.1のMacOSX版では、Arduino(Leonardo)のシリアルポートがUSBケーブルの挿し直しなどで番号が変わってしまった場合にエラーとなる。ArduinoIDE1.0では接続すべきポートをサジェストしてくれていた。

ctrlaltdel.ino WindowsXPでこれを接続してボタンを押すとタスクマネージャが起動します。 

追記:
      Keyboard.press(shiftKey);
      Keyboard.press('2');
で表示されたのは'@'でした。つまりUSキーボード相当の扱いだと思われます。
 

Arduino Leonardo(Davinci)でHID-Keyboard動作確認

TETRASTYLEさんの記事を参考に実験しました。

開発環境:MacBookPro/MacOSX Lion/Arduino IDE 1.0
※自分の環境ではWindowsではDavinciのドライバをインストールできなかった(認識しない)
→ Arduinoメモ

Leonardo っぽいので紹介されているArduino Leonardoの互換品、DavinciでHIDキーボードの動作確認。

2012davinci
配線はこんな感じで、ワイアを2本付けます(D2とGND)。ワイアをショートさせるとHIDキーボードからキー入力されます。
 
実験結果:MacOSX、WindowsXP、Windows7(32bit)、Windows7(64bit)でOK

MacOSXでのデバイス認識
2012davinci_usb
 
WindowsXPでのデバイス認識(Davinci自体は?になってるがHID標準キーボード、HID標準マウスが見える)
davinci

こちらからはArduino IDE 1.0rc2のソースが取得できる→http://code.google.com/p/arduino/wiki/Arduino1

展開したあと、arduino-1.0-rc2/hardware/arduino/cores/arduino/ の中にある
USBAPI.h
HID.cpp
が参考になる。

USB HID Keyboard作例メモ

メモ。 Arduino/AVRでUSBデバイス(HID Keyboard)を実現するには、32U4を使った内蔵USB I/Fで行うものと、V-USBと言ってソフト制御のみで行うものがあるらしい。

Beating Level 1-4 in Bit.Trip runner with no hands!
iPadにArduinoをつなぎ,Webブラウザ上でProcessingを使ってセンサデータを可視化
How to bulid iPad with Arduino + Processing.js
Project Log : Arduino USB


V-USB Reference Projects
おなかすいたwiki V-USB
Virtual USB Keyboard
サブキーボード

 キーボード変換I/FではPS/2入力とUSB Bポートがあればいいので、ピンはたくさんはいらない。

これ、本命っぽい
Arduino®-Leonardo USB HID Keyboard & Mouse Tutorial and Advanced Serial Port Examples
 

Newton Keyboard to USB Converter
記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ