Keyboard Reprogram not working

Hello,

the Leonardo example Sketch did not write the right letters, I think it's the wrong keyboard layout or something is wrong, but I can't change it. I don't know what layout is used in the IDE files my layout is swiss-german and the reprogramm sketch is typing some very stange things.

Did someone has an solution?

BR.

Markus

The translation table (from ASCII characters to key codes) is in hardware/arduino/cores/arduino/HID.cpp. It's implemented only for the US keyboard but you're free to change it to your needs.

pylon:
The translation table (from ASCII characters to key codes) is in hardware/arduino/cores/arduino/HID.cpp. It's implemented only for the US keyboard but you're free to change it to your needs.

Ah thanks for the hint, I looked at it

const uint8_t _asciimap[128] =...

is realy confusing i don't understand what is going on there, at the same time I looked at the keylayouts.c/.h from the teensy but I have no idea how to merge them useful. On the Teensy its allready done for many layouts. but I don't understand how the guy who wrote the HID.ccp and the USBAPI.h manage to send the key with the right ASCII-Value.

BR.

Markus

The ASCII values (index into the array _asciimap) are translated into key codes. A key code is a position on the keyboard. Most characters (a-z) are the same on the US and the Swiss keyboard, just Y and Z are swapped. If an ASCII value is entered on the keyboard by pressing it together with the shift key, the key code in the array is orred with the shift value. I guess you have the Swiss-German keyboard in front of you, so you should be able to fill the complete array with values for your mapping.

pylon:
The ASCII values (index into the array _asciimap) are translated into key codes. A key code is a position on the keyboard. Most characters (a-z) are the same on the US and the Swiss keyboard, just Y and Z are swapped. If an ASCII value is entered on the keyboard by pressing it together with the shift key, the key code in the array is orred with the shift value. I guess you have the Swiss-German keyboard in front of you, so you should be able to fill the complete array with values for your mapping.

Some clouds are gone, but i've looking at this paper www.usb.org/developers/devclass_docs/Hut1_12v2.pdf and some keys have different Usage ID like Key_return at USBAPI.h xB0 and in the paper x28 or Caps Lock xC1 and x39.

Strange at all

The translation table is not in USBAPI.h but in HID.cpp and there the character line feed (10) is translated into 0x28.

The definitions you found are especially for this code and are translated in the press method:

	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		_keyReport.modifiers |= (1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);

0xB0 - 136 = 0x28

so this makes sense.

Edit: corrected LF code.

pylon:
The translation table is not in USBAPI.h but in HID.cpp and there the character line feed (10) is translated into 0x28.

The definitions you found are especially for this code and are translated in the press method:

	if (k >= 136) {			// it's a non-printing key (not a modifier)
	k = k - 136;
} else if (k >= 128) {	// it's a modifier key
	_keyReport.modifiers |= (1<<(k-128));
	k = 0;
} else {				// it's a printing key
	k = pgm_read_byte(_asciimap + k);



0xB0 - 136 = 0x28

so this makes sense.

Edit: corrected LF code.

Hmmm.

I changed some key but nothing happend, the IDE recompilied it i think, tested for sure slashed some keys out and i get some errors

Can you get a bit more specific? Show us your code and the output you get (including the errors).

There it comes:

Some define parts are double from the USBAPI.h I merged some parts from the keylayouts.h for better testing, if I uncomment some lines I get an not declared message.

Insert in the HID.ccp at line 281

Part1

#define SHIFT     0x80

#define ASCII_00	0x00             // NUL
#define ASCII_01	0x00             // SOH
#define ASCII_02	0x00             // STX
#define ASCII_03	0x00             // ETX
#define ASCII_04	0x00             // EOT
#define ASCII_05	0x00             // ENQ
#define ASCII_06	0x00             // ACK  
#define ASCII_07	0x00             // BEL
#define ASCII_08	0x2a        		 // BS	Backspace
#define ASCII_09	0x2b		         // TAB	Tab
#define ASCII_0A	0x28		         // LF	Enter
#define ASCII_0B	0x00             // VT 
#define ASCII_0C	0x00             // FF 
#define ASCII_0D	0x00             // CR 
#define ASCII_0E	0x00             // SO 
#define ASCII_0F	0x00             // SI 
#define ASCII_10	0x00             // DEL
#define ASCII_11	0x00             // DC1
#define ASCII_12	0x00             // DC2
#define ASCII_13	0x00             // DC3
#define ASCII_14	0x00             // DC4
#define ASCII_15	0x00             // NAK
#define ASCII_16	0x00             // SYN
#define ASCII_17	0x00             // ETB
#define ASCII_18	0x00             // CAN
#define ASCII_19	0x00             // EM 
#define ASCII_1A	0x00             // SUB
#define ASCII_1B	0x00             // ESC
#define ASCII_1C	0x00             // FS 
#define ASCII_1D	0x00             // GS 
#define ASCII_1E	0x00             // RS 
#define ASCII_1F	0x00             // US 

#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_A                    0x04
#define KEY_B                    0x05
#define KEY_C                    0x06
#define KEY_D                    0x07
#define KEY_E                    0x08
#define KEY_F                    0x09
#define KEY_G                    0x0A
#define KEY_H                    0x0B
#define KEY_I                    0x0C
#define KEY_J                    0x0D
#define KEY_K                    0x0E
#define KEY_L                    0x0F
#define KEY_M                    0x10
#define KEY_N                    0x11
#define KEY_O                    0x12
#define KEY_P                    0x13
#define KEY_Q                    0x14
#define KEY_R                    0x15
#define KEY_S                    0x16
#define KEY_T                    0x17
#define KEY_U                    0x18
#define KEY_V                    0x19
#define KEY_W                    0x1A
#define KEY_X                    0x1B
//#define KEY_Y                    0x1C
#define KEY_Y                    0x04
//#define KEY_Z                    0x1D
#define KEY_Z                    0x04
#define KEY_1                    0x1E
#define KEY_2                    0x1F
#define KEY_3                    0x20
#define KEY_4                    0x21
#define KEY_5                    0x22
#define KEY_6                    0x23
#define KEY_7                    0x24
#define KEY_8                    0x25
#define KEY_9                    0x26
#define KEY_0                    0x27
#define KEY_RETURN               0xB0
#define KEY_ESC                  0xB1
#define KEY_BACKSPACE            0xB2
#define KEY_TAB                  0xB3
#define KEY_SPACE                0x2C
#define KEY_MINUS                0x2D
#define KEY_EQUAL                0x2E
#define KEY_LEFT_BRACE           0x2F
#define KEY_RIGHT_BRACE          0x30
#define KEY_BACKSLASH            0x31
//#define KEY_NON_US_NUM  50
#define KEY_SEMICOLON            0x33
#define KEY_QUOTE                0x34
#define KEY_TILDE                0x35
#define KEY_COMMA                0x36
#define KEY_PERIOD               0x37
#define KEY_SLASH                0x38
#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
//#define KEY_PRINTSCREEN 70
//#define KEY_SCROLL_LOCK 71
//#define KEY_PAUSE       72
#define KEY_INSERT               0xD1
#define KEY_HOME                 0xD2
#define KEY_PAGE_UP              0xD3
#define KEY_DELETE               0xD1
#define KEY_END                  0xD5
#define KEY_PAGE_DOWN            0xD6
#define KEY_RIGHT_ARROW          0xD7
#define KEY_LEFT_ARROW           0xD8
#define KEY_DOWN_ARROW           0xD9
#define KEY_UP_ARROW             0xDA

#define ASCII_20	KEY_SPACE				 // 32  
#define ASCII_21	KEY_1 | SHIFT			// 33 !
#define ASCII_22	KEY_2 | SHIFT			// 34 "
#define ASCII_23	KEY_3 | SHIFT 		// 35 #		??
#define ASCII_24	KEY_4 | SHIFT			// 36 $
#define ASCII_25	KEY_5 | SHIFT			// 37 %
#define ASCII_26	KEY_7 | SHIFT			// 38 &
#define ASCII_27	KEY_QUOTE      		// 39 '  
#define ASCII_28	KEY_9 | SHIFT			// 40 ( 
#define ASCII_29	KEY_0 | SHIFT			// 41 )
#define ASCII_2A	KEY_8 | SHIFT		// 42 *
#define ASCII_2B	KEY_EQUAL | SHIFT					// 43 +
#define ASCII_2C	KEY_COMMA				// 44 ,
#define ASCII_2D	KEY_MINUS				// 45 -
#define ASCII_2E	KEY_PERIOD				// 46 .
#define ASCII_2F	KEY_SLASH  		// 47 /
#define ASCII_30	KEY_0					// 48 0
#define ASCII_31	KEY_1					// 49 1
#define ASCII_32	KEY_2					// 50 2
#define ASCII_33	KEY_3					// 51 3
#define ASCII_34	KEY_4					// 52 4
#define ASCII_35	KEY_5					// 53 5
#define ASCII_36	KEY_6					// 54 6
#define ASCII_37	KEY_7					// 55 7
#define ASCII_38	KEY_8					// 55 8
#define ASCII_39	KEY_9					// 57 9
#define ASCII_3A	KEY_SEMICOLON | SHIFT			// 58 :
#define ASCII_3B	KEY_SEMICOLON			// 59 ;
#define ASCII_3C	KEY_COMMA				// 60 <
#define ASCII_3D	KEY_EQUAL			// 61 =
#define ASCII_3E	KEY_PERIOD | SHIFT		// 62 >
#define ASCII_3F	KEY_SLASH | SHIFT			// 63 ?
#define ASCII_40	KEY_2 | SHIFT			// 64 @
#define ASCII_41	KEY_A | SHIFT			// 65 A
#define ASCII_42	KEY_B | SHIFT			// 66 B
#define ASCII_43	KEY_C | SHIFT			// 67 C
#define ASCII_44	KEY_D | SHIFT			// 68 D
#define ASCII_45	KEY_E | SHIFT			// 69 E
#define ASCII_46	KEY_F | SHIFT			// 70 F
#define ASCII_47	KEY_G | SHIFT			// 71 G
#define ASCII_48	KEY_H | SHIFT			// 72 H
#define ASCII_49	KEY_I | SHIFT			// 73 I
#define ASCII_4A	KEY_J | SHIFT			// 74 J
#define ASCII_4B	KEY_K | SHIFT			// 75 K
#define ASCII_4C	KEY_L | SHIFT			// 76 L
#define ASCII_4D	KEY_M | SHIFT			// 77 M
#define ASCII_4E	KEY_N | SHIFT			// 78 N
#define ASCII_4F	KEY_O | SHIFT			// 79 O
#define ASCII_50	KEY_P | SHIFT			// 80 P
#define ASCII_51	KEY_Q | SHIFT			// 81 Q
#define ASCII_52	KEY_R | SHIFT			// 82 R
#define ASCII_53	KEY_S | SHIFT			// 83 S
#define ASCII_54	KEY_T | SHIFT			// 84 T
#define ASCII_55	KEY_U | SHIFT			// 85 U
#define ASCII_56	KEY_V | SHIFT			// 86 V
#define ASCII_57	KEY_W | SHIFT			// 87 W
#define ASCII_58	KEY_X | SHIFT			// 88 X
#define ASCII_59	KEY_Y | SHIFT			// 89 Y
#define ASCII_5A	KEY_Z | SHIFT			// 90 Z
#define ASCII_5B	KEY_LEFT_BRACE			// 91 [
#define ASCII_5C	KEY_BACKSLASH			// 92 
#define ASCII_5D	KEY_RIGHT_BRACE			// 93 ]
#define ASCII_5E	KEY_0 | SHIFT		// 94 ^
#define ASCII_5F	KEY_MINUS | SHIFT			// 95 _
#define ASCII_60	KEY_TILDE		// 96 `
#define ASCII_61	KEY_A					// 97 a
#define ASCII_62	KEY_B					// 98 b
#define ASCII_63	KEY_C					// 99 c
#define ASCII_64	KEY_D					// 100 d
#define ASCII_65	KEY_E					// 101 e
#define ASCII_66	KEY_F					// 102 f
#define ASCII_67	KEY_G					// 103 g
#define ASCII_68	KEY_H					// 104 h
#define ASCII_69	KEY_I					// 105 i
#define ASCII_6A	KEY_J					// 106 j
#define ASCII_6B	KEY_K					// 107 k
#define ASCII_6C	KEY_L					// 108 l
#define ASCII_6D	KEY_M					// 109 m
#define ASCII_6E	KEY_N					// 110 n
#define ASCII_6F	KEY_O					// 111 o
#define ASCII_70	KEY_P					// 112 p
#define ASCII_71	KEY_Q					// 113 q
#define ASCII_72	KEY_R					// 114 r
#define ASCII_73	KEY_S					// 115 s
#define ASCII_74	KEY_T					// 116 t
#define ASCII_75	KEY_U					// 117 u
#define ASCII_76	KEY_V					// 118 v
#define ASCII_77	KEY_W					// 119 w
#define ASCII_78	KEY_X					// 120 x
#define ASCII_79	KEY_Y					// 121 y
#define ASCII_7A	KEY_Z					// 122 z
#define ASCII_7B	KEY_LEFT_BRACE | SHIFT			// 123 {
#define ASCII_7C	KEY_BACKSLASH | SHIFT		// 124 |
#define ASCII_7D	KEY_RIGHT_BRACE | SHIFT			// 125 }
#define ASCII_7E	KEY_TILDE	| SHIFT	// 126 ~
#define ASCII_7F	KEY_BACKSPACE				// 127

Part 2

extern
const uint8_t _asciimap[128] PROGMEM;

const uint8_t _asciimap[128] = {
        ASCII_00, ASCII_01, ASCII_02, ASCII_03,
        ASCII_04, ASCII_05, ASCII_06, ASCII_07,
        ASCII_08, ASCII_09, ASCII_0A, ASCII_0B,
        ASCII_0C, ASCII_0D, ASCII_0E, ASCII_0F,
        ASCII_10, ASCII_11, ASCII_12, ASCII_13,
        ASCII_14, ASCII_15, ASCII_16, ASCII_17,
        ASCII_18, ASCII_19, ASCII_1A, ASCII_1B,
        ASCII_1C, ASCII_1D, ASCII_1E, ASCII_1F,
        ASCII_20, ASCII_21, ASCII_22, ASCII_23,
        ASCII_24, ASCII_25, ASCII_26, ASCII_27,
        ASCII_28, ASCII_29, ASCII_2A, ASCII_2B,
        ASCII_2C, ASCII_2D, ASCII_2E, ASCII_2F,
        ASCII_30, ASCII_31, ASCII_32, ASCII_33,
        ASCII_34, ASCII_35, ASCII_36, ASCII_37,
        ASCII_38, ASCII_39, ASCII_3A, ASCII_3B,
        ASCII_3C, ASCII_3D, ASCII_3E, ASCII_3F,
        ASCII_40, ASCII_41, ASCII_42, ASCII_43,
        ASCII_44, ASCII_45, ASCII_46, ASCII_47,
        ASCII_48, ASCII_49, ASCII_4A, ASCII_4B,
        ASCII_4C, ASCII_4D, ASCII_4E, ASCII_4F,
        ASCII_50, ASCII_51, ASCII_52, ASCII_53,
        ASCII_54, ASCII_55, ASCII_56, ASCII_57,
        ASCII_58, ASCII_59, ASCII_5A, ASCII_5B,
        ASCII_5C, ASCII_5D, ASCII_5E, ASCII_5F,
        ASCII_60, ASCII_61, ASCII_62, ASCII_63,
        ASCII_64, ASCII_65, ASCII_66, ASCII_67,
        ASCII_68, ASCII_69, ASCII_6A, ASCII_6B,
        ASCII_6C, ASCII_6D, ASCII_6E, ASCII_6F,
        ASCII_70, ASCII_71, ASCII_72, ASCII_73,
        ASCII_74, ASCII_75, ASCII_76, ASCII_77,
        ASCII_78, ASCII_79, ASCII_7A, ASCII_7B,
        ASCII_7C, ASCII_7D, ASCII_7E, ASCII_7F
};

And what do you get? Show us the code your trying with and what the output on the PC is.

For single test I use the Keyboardserial

void setup() {
  // open the serial port:
Serial.begin(9600);
  // initialize control over the keyboard:
  Keyboard.begin();
}

void loop() {
  // check for incoming serial data:
  if (Serial.available() > 0) {
    // read incoming serial data:
    char inChar = Serial.read();
    // Type the next ASCII value from what you received:
    Keyboard.write(inChar);
  }  
}

I send an Z and get an Y

How can I forced an recompile of the lib's? on the IDE 1.0.1

Why are you sending key code 0x04 for a 'Z' and for a 'Y'? Do you really try with the code you posted? Keep in mind that the Swiss keyboard swaps the two keys, so you must send 0x1d for a 'Y' and 0x1c for a 'Z'.

pylon:
Why are you sending key code 0x04 for a 'Z' and for a 'Y'? Do you really try with the code you posted? Keep in mind that the Swiss keyboard swaps the two keys, so you must send 0x1d for a 'Y' and 0x1c for a 'Z'.

Yes I tryed to see if it works, I have also swapped the define to change the send ID

Does everything work now? What's the output for different character inputs?

No

So can you provide the output you get for different input characters?

pylon:
The translation table is not in USBAPI.h but in HID.cpp and there the character line feed (10) is translated into 0x28.

The definitions you found are especially for this code and are translated in the press method:

	if (k >= 136) {			// it's a non-printing key (not a modifier)
	k = k - 136;
} else if (k >= 128) {	// it's a modifier key
	_keyReport.modifiers |= (1<<(k-128));
	k = 0;
} else {				// it's a printing key
	k = pgm_read_byte(_asciimap + k);



0xB0 - 136 = 0x28

so this makes sense.

Edit: corrected LF code.

Yes that makes sens

pylon:
So can you provide the output you get for different input characters?

So I get managed it to work, with help of this i've getting it to work

From http://geekhack.org/showwiki.php?title=Scan+Codes

Scan Code set for USB Keyboard

Set4 AKA USB HID
Many manufacturers move the key that is in either the 5C or 53 position to the 5D position,
while having it retain its old scan code, (AT keyboard layout) Set4 was designed for the 101-key keyboard.


 ---     ---------------   ---------------   ---------------   -----------
| 29|   | 3A| 3B| 3C| 3D| | 3E| 3F| 40| 41| | 42| 43| 44| 45| | 46| 47| 48|
 ---     ---------------   ---------------   ---------------   -----------

 -----------------------------------------------------------   -----------   ---------------
| 35| 1E| 1F| 30| 21| 22| 23| 24| 25| 26| 27| 2D| 2E|(5C) 2A| | 49| 4A| 61| | 53| 54| 55| 56|
|-----------------------------------------------------------| |-----------| |---------------|
|   2B| 14| 1A| 08| 15| 17| 1C| 18| 0C| 12| 13| 2F| 30| (31)| | 4C| 4D| 4E| | 5F| 60| 61|   |
|-----------------------------------------------------------|  -----------  |-----------| 57|
|    39| 04| 16| 07| 09| 0A| 0B| 0D| 0E| 0F| 33| 34|(53)  28|               | 5C| 5D| 5E|   |
|-----------------------------------------------------------|      ---      |---------------|
| E1 (64)| 1D| 1B| 06| 19| 05| 11| 10| 36| 37| 38|(87)    E5|     | 52|     | 59| 5A| 5B|   |
|-----------------------------------------------------------|  -----------  |-----------| 58|
|   E0|   |   E2|  (8B)|    2C|  (8A)|  (88)|   E6|   |   E4| | 50| 51| 4F| |     62| 63|   |
 -----     ---------------------------------------     -----   -----------   ---------------

This shows the Keyboardlayout for an USB Keyboard and with it I set the ASCII-Code to the Scan-Code where the Key is.

but there is the problem now there are some Keys like € it has the ASCII-Code 80 its already used by SHIFT in the HID.ccp and the Modifiere Keys are placed in range of some special Letters on the ISO-8859-1.

At this point I have no idea how to merge it with the Letters and I looking for an option to make an connection for the ALT GR Key some ASCII-Codes on my Layout are on the 3rd Layer like { or ] or @ so I thinking how to merge it usefully...

Modified Code will follow after I cleaned the mess in the HID.ccp I arranged.

EDIT:
Files added!

HID.cpp (17.5 KB)

keylayout.h (11.2 KB)