まごころせいじつ堂

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

Leonardo

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 Leonardo USBキーの英語/日本語配列確認

Arduino Leonardoのkeyboard.press()でシフトキーを押した時の記号について。
以下のスケッチを使う。ピン2とGNDに繋いだスイッチを押すと[SHIFT]+[2]が出力される。


/*
 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_PULLUP);
  pinMode(keymacroPin, INPUT_PULLUP);

  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(KEY_LEFT_SHIFT);
      Keyboard.press('2');
    }
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
    Keyboard.release('2');
    Keyboard.release(KEY_LEFT_SHIFT);
  }
  delay(100);
}


 これを以下の環境で確認した。SHIFT+2では……
MacOSX Lion/PowerBookPro13インチ 日本語キーボード : @マーク
Windows7 32bit DELL PRECISION4300 英語キーボード : @マーク
WindowsXP DELL Latitude D630 日本語キーボード : ”マーク
 
 Windows環境では本体のキーボードを押すのと同じ様に入力された。
 MacOSXではLeonardoをUSBで接続した時にHIDキーボードの識別をする画面が出るが、これをキャンセルすると英語配列として扱うようだ。

ArduinoIDE1.0.1/Leonardoで足らないキーを追加する 続き

前回の続き。
 Arduino LeonardoではHID USB Keyboardとしてkey.press()でキーボードのように振る舞うことが出来る。これはArduino IDE1.0.1ソース中の
hardware/arduino/cores/arduino 以下にある
HID.cpp
USBAPI.h
で定義されている。

 USBAPI.hで定義されていないキーを、以下にまとめた。

参考:Universal Serial Bus(USB) HID Usage Tables
USBキーボードのコード 


#define KEY_PRINTSCREEN		0xCE
#define KEY_SCROLL_LOCK		0xCF
#define KEY_PAUSE			0xD0

#define KEYPAD_NUM_LOCK		0xDB
#define KEYPAD_SLASH		0xDC
#define KEYPAD_ASTERISK		0xDD
#define KEYPAD_MINUS		0xDE
#define KEYPAD_PLUS			0xDF
#define KEYPAD_ENTER		0xE0
#define KEYPAD_1			0xE1
#define KEYPAD_2			0xE2
#define KEYPAD_3			0xE3
#define KEYPAD_4			0xE4
#define KEYPAD_5			0xE5
#define KEYPAD_6			0xE6
#define KEYPAD_7			0xE7
#define KEYPAD_8			0xE8
#define KEYPAD_9			0xE9
#define KEYPAD_0			0xEA
#define KEYPAD_DOT			0xEB
#define KEYPAD_NONUS_BACKSLASH	0xEC
#define KEYPAD_APPRICATION	0xED
#define KEYPAD_POWER		0xEE
#define KEYPAD_EQUAL		0xEF
#define KEY_F13				0xF0
#define KEY_F14				0xF1
#define KEY_F15				0xF2
#define KEY_F16				0xF3
#define KEY_F17				0xF4
#define KEY_F18				0xF5
#define KEY_F19				0xF6
#define KEY_F20				0xF7
#define KEY_F21				0xF8
#define KEY_F22				0xF9
#define KEY_F23				0xFA
#define KEY_F24				0xFB
#define KEY_EXECUTE			0xFC
#define KEY_HELP			0xFD
#define KEY_MENU			0xFE
#define KEY_SELECT			0xFF
#define KEY_STOP			0x100
#define KEY_AGAIN			0x101
#define KEY_UNDO			0x102
#define KEY_CUT				0x103
#define KEY_COPY			0x104
#define KEY_PASTE			0x105
#define KEY_FIND			0x106
#define KEY_MUTE			0x107
#define KEY_VOLUP			0x108
#define KEY_VOLDOWN			0x109
#define KEY_LOCKING_CAPS_LOCK	0x10A
#define KEY_LOCKING_NUM_LOCK		0x10B
#define KEY_LOCKING_SCROLL_LOCK		0x10C
#define KEYPAD_COMMA		0x10D
#define KEYPAD_EQUALSIGN	0x10E
#define KEY_INTERNATIONAL1	0x10F
#define KEY_BACKSLASH	0x10F
#define KEY_INTERNATIONAL2	0x110
#define KEY_KANA	0x110
#define KEY_INTERNATIONAL3	0x111
#define KEY_YEN		0x111
#define KEY_INTERNATIONAL4	0x112
#define KEY_XFER	0x112
#define KEY_INTERNATIONAL5	0x113
#define KEY_NFER	0x113
#define KEY_INTERNATIONAL6	0x114
#define KEY_PC98_COMMA	0x114
#define KEY_INTERNATIONAL7	0x115
#define KEY_INTERNATIONAL8	0x116
#define KEY_INTERNATIONAL9	0x117
#define KEY_LANG1			0x118
#define KEY_LANG2			0x119
#define KEY_LANG3			0x11A
#define KEY_KATAKANA		0x11A
#define KEY_LANG4			0x11B
#define KEY_HIRAGANA		0x11B
#define KEY_LANG5			0x11C
#define KEY_ZENHAN			0x11C
#define KEY_LANG6			0x11D
#define KEY_LANG7			0x11E
#define KEY_LANG8			0x11F
#define KEY_LANG9			0x120
#define KEY_ALT_ERASE		0x121
#define KEY_SYSREQ			0x122
#define KEY_CANCEL			0x123
#define KEY_CLEAR			0x124
#define KEY_PRIOR			0x125
#define KEY_RETURN2			0x126
#define KEY_SEPARATOR		0x127
#define KEY_OUT				0x128
#define KEY_OPER			0x129
#define KEY_CLEAR_AGAIN		0x12A
#define KEY_CLRSEL			0x12B
#define KEY_EXSEL			0x12C

#define KEYPAD_00			0x138
#define KEYPAD_000			0x139
#define KEYPAD_THOUSANDS_SEPARATOR	0x13A
#define KEYPAD_DECIMAL_SEPARATOR	0x13B
#define KEYPAD_CURRENCY_UNIT	0x13C
#define KEYPAD_CURRENCY_SUBUNIT	0x13D
#define KEYPAD_LEFT_PAREN	0x13E
#define KEYPAD_RIGHT_PAREN	0x13F
#define KEYPAD_LEFT_BRACE	0x140
#define KEYPAD_RIGHT_BRACE	0x141
#define KEYPAD_TAB			0x142
#define KEYPAD_BACKSPACE	0x143
#define KEYPAD_A			0x144
#define KEYPAD_B			0x145
#define KEYPAD_C			0x146
#define KEYPAD_D			0x147
#define KEYPAD_E			0x148
#define KEYPAD_F			0x149
#define KEYPAD_XOR			0x14A
#define KEYPAD_CARET		0x14B
#define KEYPAD_PERCENT		0x14C
#define KEYPAD_LESSTHAN		0x14D
#define KEYPAD_GREATERTHAN	0x14E
#define KEYPAD_AND			0x14F
#define KEYPAD_LOGICAL_AND	0x150
#define KEYPAD_OR			0x151
#define KEYPAD_LOGICAL_OR	0x152
#define KEYPAD_COLON		0x153
#define KEYPAD_HASH			0x154
#define KEYPAD_SPACE		0x155
#define KEYPAD_ATMARK		0x156
#define KEYPAD_EXCLAMATION	0x157
#define KEYPAD_MS			0x158
#define KEYPAD_MR			0x159
#define KEYPAD_MC			0x15A
#define KEYPAD_MADD			0x15B
#define KEYPAD_MSUB			0x15C
#define KEYPAD_MMUL			0x15D
#define KEYPAD_MDIV			0x15E
#define KEYPAD_SIGN			0x15F
#define KEYPAD_CLEAR		0x160
#define KEYPAD_CLEARENTRY	0x161
#define KEYPAD_BIN			0x162
#define KEYPAD_OCT			0x163
#define KEYPAD_DEC			0x164
#define KEYPAD_HEX			0x165


問題点:0x100以上のコードは正しく扱われない。HID.cpp中のKeyboard_::press()が8bitの範囲内でしか扱っていないためと思われる。コードの修正も必要になる。

 MacOSXに接続して、Arduino Leonardoに繋いだボタンを押すとシャットダウン画面が出るものを作ってみた。また、pinmode(buttonPin,INPUT_PULLUP); で明示的なプルアップ指示をしてみた。これはArduino IDE 1.0.1からの機能。

/*
 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

#define KEY_PRINTSCREEN         0xCE
#define KEY_SCROLLLOCK          0xCF
#define KEY_PAUSE               0xD0
#define KEYPAD_POWER		0xEE
#define KEY_VOLUP			0x108
#define KEY_VOLDOWN			0x109

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

  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(KEYPAD_POWER);
    }
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
    Keyboard.release(KEYPAD_POWER);
  }
  delay(100);
}


Arduino Leonardo

Arduino LeonardoとATmega32U4搭載マイコンのピン接続表

Arduino Leonardoと32U4を搭載したマイコン基板の端子について調べた。

本家Arduino Leonardo
ATmega 32U4-Arduino Pin Mapping  ※2012/5/28現在、表にミスあり。32U4のpin30に対応するのはDigitalPin10。
ATmega32U4搭載マイコンボード[スイッチサイエンス] ※現行品はシルク印刷にミスあり。
ダ・ヴィンチ32U[ストロベリーリナックス]

 これらのマイコン基板の端子とATmega32U4のピン対応一覧をExcelにまとめた。
一応テスタを使ってよくわからない所は確認したが、使うときは自己責任でどうぞ。

32U4.xls[Google Drive]

 
32U4 pin# Pin Name Leonardo 32U4Breakout Davinci
1 PE6(INT.6/AIN0) Digital Pin7 14.E6 30.PE6
2 Uvcc +5V 6.VCC 2.+5V
3 D- RD- - -
4 D+ RD+ - -
5 UGND UGND - -
6 Ucap UCAP - -
7 VUSB Vbus - -
8 PB0(SS/PCINT0) RXLED 1.B0 22.PB0
9 PB1(PCINT1/SCLK) SCK 2.B1 23.PB1
10 PB2(PDI/PCINT2/MOSI) MOSI 3.B2 24.PB2
11 PB3(PDO/PCINT3/MISO) MISO 4.B3 25.PB3
12 PB7(PCINT7/OCA0/OC1C/#RTS) Digital Pin11(PWM) 18.B7 29.PB7
13 RESET RESET 5.RST 3.RST
14 Vcc +5V 6.VCC 2.+5V
15 GND GND 21.GND 1,17,32 GND
16 XTAL2 XTAL2 - -
17 XTAL1 XTAL1 - -
18 PD0(OC0B/SCL/INT0) Digital Pin3(SCL)(PWM) 10.D0 4.PD0
19 PD1(SDA/INT1) Digital Pin2(SDA) 9.D1 5.PD1
20 PD2(RXD1/AIN1/INT2) Digital Pin0(RX) 7.D2 6.PD2
21 PD3(TXD1/INT3) Digital Pin1(TX) 8.D3 7.PD3
22 PD5(XCK1/#CTS) TXLED (TXLED) 9.PD5
23 GND1 GND 21.GND 1,17,32 GND
24 AVCC AVCC 6.VCC 2.+5V
25 PD4(ICP1/ADC8) Digital Pin4 11.D4 8.PD4
26 PD6(T1/#OC4D/ADC9) Digital Pin12 19.D6 (シルク誤記D6) 10.PD6
27 PD7(T0/OC4D/ADC10) Digital Pin6(PWM) 13.D7 11.PD7
28 PB4(ADC11/PCINT4) Digital Pin8 15.B4 26.PB4
29 PB5(PCINT5/OC1A/#OC4B/ADC12) Digital Pin9(PWM) 16.B5 27.PB5
30 PB6(PCINT6/OC1B/OC4B/ADC13) Digital Pin10(PWM) 17.B6 28.PB6
31 PC6(OC3A/#OC4A) Digital Pin5(PWM) 12.C6 12.PC6
32 PC7(ICP3/CLK0/C4A) Digital Pin13 20.C7 13.PC7
33 PE2(#HWB) HWB HWB 16.HWB
34 Vcc1 +5V 6.VCC 2.+5V
35 GND2 GND 21.GND 1,17,32 GND
36 PF7(ADC7/TDI) Analog In 0 23.F7 21.PF7
37 PF6(ADC6/TDO) Analog In 1 24.F6 20.PF6
38 PF5(ADC5/TMS) Analog In 2 25.F5 19.PF5
39 PF4(ADC4/TCK) Analog In 3 26.F4 18.PF4
40 PF1(ADC1) Analog In 4 27.F1 15.PF1
41 PF0(ADC0) Analog In 5 28.F0 14.PF0
42 AREF AREF 22.AREF 31.REF
43 GND3 GND 21.GND 1,17,32 GND
44 AVCC1 AVCC 6.VCC 2.+5V

Arduino IDE1.0.1/Leonardで足らないUSBキーを追加する

Arduino IDE1.0.1とDavinciのLeonardo化の続き。
HID USBキーボードでどのキーが押されたかは、UsageIDというので与えられる。
http://www.usb.org/developers/devclass_docs/Hut1_11.pdf[pdf] のp.53〜 10 Keyboard/Keypad Page (0x07) 

表示不能な特殊キーとモディファイア(SHIFT,CTRL,ALT等)の番号を見ると、どうも違うのでソースを追ってみた。
特殊キーとモディファイアの定義は以下。
hardware/arduino/cores/arduino/USBAPI.h

keyboard.press()は以下。
hardware/arduino/cores/arduino/HID.cpp

 keyboard.press()では、与えられた数値が0x00〜0x7fを印字可能なキー、0x80〜0x87をモディファイアキー、0x88〜を表示不能な特殊キーとみなしている。
0x00〜0x7fは const uint8_t _asciimap[128] で定義されてあるテーブルで変換される。これはUSキー配列相当となっているので、日本語キーボード相当にしたければここをいじればよい。
0x88以上は、その値から0x88を引いた数値がUsageIDとしてUSB経由で送信される。つまり、ファンクションキーF7は #define KEY_F7 0xC8 と定義されているが、実際は0xC8ー0x88=0x40が送信される。

  ということで未定義のPrintScreenキーなどを追加してみた。

#define KEY_PRINTSCREEN                         0xCE
#define KEY_SCROLLLOCK                         0xCF
#define KEY_PAUSE                         0xD0

 といってもいきなりソースを修正するのは恐れ多いので、スケッチで実験してみる。

/* 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

#define KEY_PRINTSCREEN                         0xCE
#define KEY_SCROLLLOCK                         0xCF
#define KEY_PAUSE                         0xD0


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(KEY_PRINTSCREEN);
    }
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
    Keyboard.release(KEY_PRINTSCREEN);
  }
  delay(100);
}

 これは、Windowsマシンに接続してボタンを押すと画面のスナップショットをクリップボードにコピーする。定義されていないキーもこれで使用できた。

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キーボード相当の扱いだと思われます。
 

Davinci(Leonardo) マウスクリック

DavinciでUSBキーボードまわりを調べているけど、ちょっとわからないのでUSBマウスのほうで遊んでみた。
Mouse.press()で左ボタンを押した状態、Mouse.release()で離す。
 ソースはこちら。→https://gist.github.com/2651911

2012mouse
Davinciの5番ピン(D2)とGND間にキーを付ける。これがUSBマウスの左ボタンに対応する。
おまけで4番ピン(D3)を押すとモールスコードを発生するようにした。
Google日本語入力モールスバージョンで遊んでみよう。

あと、Arduino IDEでわかったこと。
pinMode(番号、INPUT) ; digitalWrite(番号,HIGH); でプルアップが指定できる。

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
が参考になる。
記事検索
プロフィール

hardyboy

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