TrinketKeyboardで日本語キーボード109で正しく表示する方法
この解決方法については、Toramin10さんが公開されていて、
DigiKeyboardのライブラリーを使っている場合は、ここの通りに実施すればよさそうだが、ATtinyCoreを使っている場合、TrinketKeyboardの組み合わせでないと、うまく動作しなかった事から、TrinketKeyboardで同じように、正しく表示する事を行った記録。
【スケッチの準備】
で作ったものを改変する。
#include <TrinketKeyboard.h>
// Attiny85
// PB5(reset)-| |-VCC
// PB3-| |-PB2
// PB4-| |-PB1
// GND-| |-PB0
const int PB0pin = 0;
const int PB1pin = 1;
const int PB2pin = 2;
const int PB5pin = 5;
bool outputState = true;
void setup() {
pinMode (PB0pin, INPUT_PULLUP);
pinMode (PB1pin, INPUT_PULLUP);
pinMode (PB2pin, INPUT_PULLUP);
pinMode (PB5pin, INPUT_PULLUP);
TrinketKeyboard.begin(); //start USB stuff
}
void loop() {
TrinketKeyboard.poll();
if (digitalRead(PB0pin) == LOW)
{
// type out a string using the Print class
TrinketKeyboard.print("1234567890-^\\");
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
// this releases the key
delay(100);
}
if (digitalRead(PB1pin) == LOW)
{
// type out a string using the Print class
TrinketKeyboard.print("!\"#$%&'()=~|");
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
//TrinketKeyboard.pressKey(0,KEYCODE_TAB);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
// this releases the key
delay(100);
}
if (digitalRead(PB2pin) == LOW)
{
// type out a string using the Print class
TrinketKeyboard.print("@[;:],./\\ `{+*}<>?_");
delay(100);
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
// this releases the key
}
if (digitalRead(PB5pin) == LOW)
{
// type out a string using the Print class
//TrinketKeyboard.pressKey(0,KEYCODE_INTERNATIONAL3);
//TrinketKeyboard.pressKey(KEYCODE_MOD_LEFT_SHIFT,KEYCODE_INTERNATIONAL1);//_
//TrinketKeyboard.pressKey(KEYCODE_MOD_LEFT_SHIFT,KEYCODE_INTERNATIONAL3);//|
delay(100);
TrinketKeyboard.pressKey(0,KEYCODE_ENTER);
// this should push enter key
TrinketKeyboard.pressKey(0, 0);
// this releases the key
}
delay(1);
}
一つ目のボタン:キーボードの一番上の行を左の1から順に押していった場合
2つ目のボタン:シフトを押しながら一番上の行を押した場合
3つ目のボタン:キーボードの上から2行目以降の記号
4つ目のボタン:この時点ではコメントアウトしてありEnterで改行だけされる。
TrinketKeyboard.print("@[;:],./\\ `{+*}<>?_");
\の文字を入れたい時は、\\二回かさねる。(上ではバックスラッシュ2回のところ)
あと”ダブルクォーテーションを入れる時も¥”と前に¥をつける。
これをボタンを押してメモ帳で確認すると
1234567890-&]
!*#$%':)^}
"@;+[,./] ‘~({<>?=
最後の行に至っては、途中で全角になり正しく表示されない。
例えば1234567890-&]は本来は、
1234567890-^\
と表示してほしい。これはキーボードが109になっていないから割り当てが異なるので違うキーコードを送っているから生じる
D:\Users\<ユーザー名>\Documents\Arduino\libraries\TrinketKeyboard
にライブラリーが入っているのでいくつかのファイルの編集をする。
【TrinketKeyboard.cpp】
このファイルに、
ASCII_to_keycode
という関数があるのでこここの関数を編集する。
一番最初だけ解説
if (ascii >= 'A' && ascii <= 'Z')
{
*keycode = 4 + ascii - 'A'; // set letter
if (bit_is_set(ledState, 1)) // if caps is on
{
*modifier = 0x00; // no shift
}
else
{
*modifier = _BV(1); // hold shift // hold shift
}
}
例えば”B”
アスキーコードは10進数で66 この66に4を足して、Aのアスキーコード65を引くと”5”になりHIDコード、つまりUSB経由で、PCに繰り込まれるキーコードに変換している。
といった具合に、アスキーコードから、HIDのキーコードに変換する関数.
A-Zや、小文字のa-zまた数字なんかは、連続しているので計算しやすしので一つ一つ書き出してもよいけどif文で書いている。
数字やアルファベットは問題にならず、問題になるのは、記号。
1234567890-^\
が
1234567890-&]
と出力される事からここのキーのアサインが異なっている。
”^”の所を見てみる。
case '^':
*modifier = _BV(1); // hold shift
*keycode = 29 + 6;
break;
^を押すと、キーコードの35が送り込まれる。
日本語キーボードの35は”6”のキーでシフトを押しながら、”6”を押すので、”&”が出力される結果になる。
これを正しく”^”を出力するのには、本来のキーコード”46”でシフトなしに編集する。
case '^':
//*modifier = _BV(1); // hold shift
//*keycode = 29 + 6;
*keycode = 46;
break;
すべてのキー、特に記号は、すべてのキーについて見直して編集する。
Toramin10さんが日本語キーボードの絵に、番号を記載してくれているのでそれを見ながら編集すると簡単にできる。
このWEBサイトはキーコードを表示してくれるので、それを見て編集する。
Toramin10さんのテクニックを使わせてもらって、後々問題となるアスキーコードで
の3つについては、135や137ではなく、104、105,106を割り当てる。
全部書き換えたASCII_to_keycodeの関数が以下。
表示の都合で、”¥”が””と表示されているが、このままコピーして問題ない。
void ASCII_to_keycode(uint8_t ascii, uint8_t ledState, uint8_t* modifier, uint8_t* keycode)
{
*keycode = 0x00;
*modifier = 0x00;
// see scancode.doc appendix C
if (ascii >= 'A' && ascii <= 'Z')
{
*keycode = 4 + ascii - 'A'; // set letter
if (bit_is_set(ledState, 1)) // if caps is on
{
*modifier = 0x00; // no shift
}
else
{
*modifier = _BV(1); // hold shift // hold shift
}
}
else if (ascii >= 'a' && ascii <= 'z')
{
*keycode = 4 + ascii - 'a'; // set letter
if (bit_is_set(ledState, 1)) // if caps is on
{
*modifier = _BV(1); // hold shift // hold shift
}
else
{
*modifier = 0x00; // no shift
}
}
else if (ascii >= '0' && ascii <= '9')
{
*modifier = 0x00;
if (ascii == '0')
{
*keycode = 0x27;
}
else
{
*keycode = 30 + ascii - '1';
}
}
else
{
switch (ascii) // convert ascii to keycode according to documentation
//ASCII code 92:\ 95:| 124:_ are assigned to 104,105,106
{
case '!':
*modifier = _BV(1); // hold shift
*keycode = 29 + 1;
break;
case '@':
//*modifier = _BV(1); // hold shift
//*keycode = 29 + 2;
*keycode = 47;
break;
case '#':
*modifier = _BV(1); // hold shift
*keycode = 29 + 3;
break;
case '$':
*modifier = _BV(1); // hold shift
*keycode = 29 + 4;
break;
case '%':
*modifier = _BV(1); // hold shift
*keycode = 29 + 5;
break;
case '^':
//*modifier = _BV(1); // hold shift
//*keycode = 29 + 6;
*keycode = 46;
break;
case '&':
*modifier = _BV(1); // hold shift
//*keycode = 29 + 7;
*keycode = 35;
break;
case '*':
*modifier = _BV(1); // hold shift
//*keycode = 29 + 8;
*keycode = 52;
break;
case '(':
*modifier = _BV(1); // hold shift
//*keycode = 29 + 9;
*keycode = 37;
break;
case ')':
*modifier = _BV(1); // hold shift
//*keycode = 0x27;
*keycode = 38;
break;
case '~':
*modifier = _BV(1); // hold shift
*keycode = 46;
// fall through
break;
case '`':
*modifier = _BV(1); // hold shift //add on original
*keycode = 47;
break;
case '_':
*modifier = _BV(1); // hold shift
// fall through
//keycode = 135;
*keycode = 105;
break;
case '-':
//*keycode = 0x2D;
*keycode = 45;
break;
case '+':
//*modifier = _BV(1); // hold shift
// fall through
*keycode = 0x57;
break;
case '=':
//*keycode = 0x2E;
*modifier = _BV(1); // hold shift
*keycode = 45;
break;
case '{':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 48;
break;
case '[':
//*keycode = 0x2F;
*keycode = 48;
break;
case '}':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 49;
break;
case ']':
//*keycode = 0x30;
*keycode = 49;
break;
case '|':
*modifier = _BV(1); // hold shift
// fall through
// keycode = 137;
*keycode = 106;
break;
case '\\'://"\" mark
//*keycode = 0x31;
//keycode = 137;
*keycode = 104;
break;
case ':':
//*modifier = _BV(1); // hold shift
// fall through
*keycode =52;
break;
case ';':
*keycode = 0x33;
break;
case '"':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 0x1F;
break;
case '\''://single quotation
*modifier = _BV(1); // hold shift
*keycode = 0x24;
break;
case '<':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 54;
break;
case ',':
//*keycode = 0x36;
*keycode = 54;
break;
case '>':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 55;
break;
case '.':
//*keycode = 0x37;
*keycode = 55;
break;
case '?':
*modifier = _BV(1); // hold shift
// fall through
*keycode = 56;
break;
case '/':
//*keycode = 0x38;
*keycode = 56;
break;
case ' ':
*keycode = 0x2C;
break;
case '\t':
*keycode = 0x2B;
break;
case '\n':
*keycode = 0x28;
break;
}
}
}
ここまで関数を変更すると、
1234567890-^
!"#$%&'()=~
@[;:],./ `{+*}<>?
と表示されるようになる。しかしエンターキーの左上、バックスペースの左のキー”¥”と?の右隣、これも”¥”が表示されていない。
これは、そもそもUSキーボードには、これらのキーがないから。次にその対処。
【HIDのレポートディスクリプタ】
Toramin10さんがこの対処についても記載してくれている。
TrinketKeyboardでは、
TrinketKeyboardC.c
というにファイルにHIDのレポートディスクリプタの記載がある。
const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xA1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes)
0x19, 0xE0, // USAGE_MINIMUM (Keyboard LeftControl)(224)
0x29, 0xE7, // USAGE_MAXIMUM (Keyboard Right GUI)(231)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs) ; Modifier byte
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs) ; Reserved byte
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs) ; LED report
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs) ; LED report padding
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))(0)
// 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)(101)
0x29, 0x8c, // USAGE_MAXIMUM (Keyboard Application)(109)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xC0 // END_COLLECTION
};
下から3行目をコメントアウトして
0x29, 0x8c, // USAGE_MAXIMUM (Keyboard Application)(109)
に置き換える。
また、Toramin10さんを見習って、TrinketKeyboard.cppの中にある
typeCharという関数を以下に編集する。
void Trinket_Keyboard::typeChar(uint8_t ascii)
{
uint8_t modifier, keycode;
ASCII_to_keycode(ascii, getLEDstate(), &modifier, &keycode);
switch (keycode) {
case 104:
pressKey(modifier, 135);
break;
case 105:
pressKey(KEYCODE_MOD_LEFT_SHIFT, 135);
break;
case 106:
pressKey(KEYCODE_MOD_LEFT_SHIFT, 137);
break;
default:
pressKey(modifier, keycode);
pressKey(0, 0); // immediately release the key after
}
}
ここまでできると、
1234567890-^\
!"#$%&'()=~|
@[;:],./\ `{+*}<>?_
と正しく表示されるようになる。
【TrinketKeyboard.h】
文字列で正しく送り込みはできるが、他の単キーについてはも対応するためTrinketKeyboard.h
を編集する。
// some more keycodes
#define KEYCODE_LEFT_CONTROL 0xE0
#define KEYCODE_LEFT_SHIFT 0xE1
#define KEYCODE_LEFT_ALT 0xE2
#define KEYCODE_LEFT_GUI 0xE3
#define KEYCODE_RIGHT_CONTROL 0xE4
#define KEYCODE_RIGHT_SHIFT 0xE5
#define KEYCODE_RIGHT_ALT 0xE6
#define KEYCODE_RIGHT_GUI 0xE7
#define KEYCODE_1 0x1E
#define KEYCODE_2 0x1F
#define KEYCODE_3 0x20
#define KEYCODE_4 0x21
#define KEYCODE_5 0x22
#define KEYCODE_6 0x23
#define KEYCODE_7 0x24
#define KEYCODE_8 0x25
#define KEYCODE_9 0x26
#define KEYCODE_0 0x27
#define KEYCODE_A 0x04
#define KEYCODE_B 0x05
#define KEYCODE_C 0x06
#define KEYCODE_D 0x07
#define KEYCODE_E 0x08
#define KEYCODE_F 0x09
#define KEYCODE_G 0x0A
#define KEYCODE_H 0x0B
#define KEYCODE_I 0x0C
#define KEYCODE_J 0x0D
#define KEYCODE_K 0x0E
#define KEYCODE_L 0x0F
#define KEYCODE_M 0x10
#define KEYCODE_N 0x11
#define KEYCODE_O 0x12
#define KEYCODE_P 0x13
#define KEYCODE_Q 0x14
#define KEYCODE_R 0x15
#define KEYCODE_S 0x16
#define KEYCODE_T 0x17
#define KEYCODE_U 0x18
#define KEYCODE_V 0x19
#define KEYCODE_W 0x1A
#define KEYCODE_X 0x1B
#define KEYCODE_Y 0x1C
#define KEYCODE_Z 0x1D
#define KEYCODE_COMMA 0x36//
#define KEYCODE_PERIOD 0x37//
//^
#define KEYCODE_CARET 0x2E//46
//-
#define KEYCODE_MINUS 0x2D//45
//#define KEYCODE_BACKSLASH 0x31//
#define KEYCODE_INTERNATIONAL1 0x87 //135 One left of the right shift key
#define KEYCODE_INTERNATIONAL3 0x89 //137 \ key above enter key
//@
#define KEYCODE_ATMARK 0x2F //47
//#define KEYCODE_SQBRAK_LEFT 0x2F // [
#define KEYCODE_SQBRAK_LEFT 0x30 //48
//#define KEYCODE_SQBRAK_RIGHT 0x30 // ]
#define KEYCODE_SQBRAK_RIGHT 0x31 //49
//;
#define KEYCODE_SEMICOLON 0x33 //51
//:
#define KEYCODE_COLON 0x34 //52
// /
#define KEYCODE_SLASH 0x38 //56
#define KEYCODE_F1 0x3A
#define KEYCODE_F2 0x3B
#define KEYCODE_F3 0x3C
#define KEYCODE_F4 0x3D
#define KEYCODE_F5 0x3E
#define KEYCODE_F6 0x3F
#define KEYCODE_F7 0x40
#define KEYCODE_F8 0x41
#define KEYCODE_F9 0x42
#define KEYCODE_F10 0x43
#define KEYCODE_F11 0x44
#define KEYCODE_F12 0x45
#define KEYCODE_APP 0x65
#define KEYCODE_ENTER 0x28//
#define KEYCODE_BACKSPACE 0x2A//
#define KEYCODE_ESC 0x29//
#define KEYCODE_TAB 0x2B//
#define KEYCODE_SPACE 0x2C//
#define KEYCODE_INSERT 0x49//
#define KEYCODE_HOME 0x4A//
#define KEYCODE_PAGE_UP 0x4B//
#define KEYCODE_DELETE 0x4C//
#define KEYCODE_END 0x4D//
#define KEYCODE_PAGE_DOWN 0x4E//
#define KEYCODE_PRINTSCREEN 0x46//
#define KEYCODE_ARROW_RIGHT 0x4F//
#define KEYCODE_ARROW_LEFT 0x50//
#define KEYCODE_ARROW_DOWN 0x51//
#define KEYCODE_ARROW_UP 0x52//
#define KEYCODE_PAUSE 0x48// add pause key
使っているスケッチのコメントアウトしていた部分をはずして確認する。
1234567890-^\
!"#$%&'()=~|
@[;:],./\ `{+*}<>?_
\_|
"\","_","|"といった記号までちゃんと表示されるようになる。
コメント
コメントを投稿