Spanish Keyboard Layout - Wrong ASCII Characters

Hi there. I have also created this topic in the Spanish forum ( Codigos ASCII Incorrectos - Diseño del teclado en Español - Software - Arduino Forum ) but I thought I could have more advice here.

I just bought an Arduino Pro Micro, willing to learn something about this boards. I´m totally new into this kind of PCBs, but I do have programming knowledge.

As this board can be used as a keyboard, I´m trying to write some commands on Powershell (like an USB Rubber Ducky, but cheaper).

At this point I found two problems, one after another.

One of the commands I´m trying to make is this one, in powershell:

Keyboard.println("$usbPath = Get-WMIObject Win32_Volume | ? { $_.Label -eq 'ARDUINO' } | select name");

However, the output is this:

$usbPath ¡ Get'WMIObject Win32?Volume Ç _ ^$?.Label 'eq ÁRDUINO´* Ç select name

As you can see, the characters like equal, slash, or question mark, it prints in another way. After looking for this in Google, I saw that it could be because this Arduino just have the US keyboard layout. I did not find anyway of chaning to Spanish.

As I couldn´t achive the previus solution, I tried writing this characters in ASCII. For my surprise, the characters I´m displaying are totally different and wrong to what it should be ( Códigos ASCII - Tabla de caracteres y simbolos ascii ):

Code:

for (int i=0; i <= 128; i++){
      Keyboard.println(i);
      Keyboard.println("> ");
      Keyboard.write(i);
      delay(100);
      typeKey(KEY_RETURN);
} 
Keyboard.releaseAll();

Output:

0: 
1: 
2: 
3: 
4: 
5: 
6: 
7: 
8:
9: 	
10: 

11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32:  
33: !
34: ¨
35: ·
36: $
37: %
38: /
39: ´
40: )
41: =
42: (
43: ¿
44: ,
45: '
46: .
47: -
48: 0
49: 1
50: 2
51: 3
52: 4
53: 5
54: 6
55: 7
56: 8
57: 9
58: Ñ
59: ñ
60: ;
61: ¡
62: :
63: _
64: "
65: A
66: B
67: C
68: D
69: E
70: F
71: G
72: H
73: I
74: J
75: K
76: L
77: M
78: N
79: O
80: P
81: Q
82: R
83: S
84: T
85: U
86: V
87: W
88: X
89: Y
90: Z
91: `
92: ç
93: +
94: &
95: ?
96: º
97: a
98: b
99: c
100: d
101: e
102: f
103: g
104: h
105: i
106: j
107: k
108: l
109: m
110: n
111: o
112: p
113: q
114: r
115: s
116: t
117: u
118: v
119: w
120: x
121: y
122: z
123: ^
124: Ç
125: *
126: ª
127: 
128:

If we compare the results with the previus website, we will see that some of them they do match, but some others don´t. Also the pipe/vertical bar | is missing.

So, after this big text, my questions would be:

  • Anyway of changing the keyboard layout to Spanish?
  • Not being able to do that, writing the correct ASCII codes?

I hope I have explained myself correctly, and I would apreciate any kind of help. Thanks for all.

You could have a function that you call that will take the String with "English ASCII"(that does not mean much really, ASCII is American standard) but its only standard for the lower part - below 127.

The first 32 characters in the ASCII-table are unprintable control codes and are used to control peripherals such as printers

Codes 32-127 are common for all the different variations of the ASCII table, they are called printable characters, represent letters, digits, punctuation marks, and a few miscellaneous symbols. You will find almost every character on your keyboard.

What is byting you is The extended ASCII codes (character code 128-255) if you use them (| or = should not they are part of the standard)

There are several different variations of the 8-bit ASCII table such as ISO 8859-1 (also called ISO Latin-1).

So you need a transfer function that will take your extended ASCII values from the arduino world to the ones expected by your computer keyboard driver when you press keys.

See http://playground.arduino.cc/Main/Utf8ascii for an idea on this

Basically you could write a function scanning each byte of the arduino String and replacing those bytes with the new correct value expected by your computer and Serial.write that to serial.

Now you want to use keyboard that adds a different set of abstraction : your use of Keyboard.write is probably misleading you. When sending capital letters, Keyboard.write() sends a shift command plus the desired character, just as if typing on a keyboard. If sending a numeric type, it sends it as an ASCII character (ex. Keyboard.write(97) will send 'a').
Also it expects a char input not an int.

So if you use keyboard, you can modify the library to match your needs in what to send look at the const uint8_t _asciimap[128] =... array

And for | instead of sending 0x31|SHIFT, or for # 0x20|SHIFT, send what you really need in Spanish kbd

Thanks for your answer @J-M-L , I will check your links.

I haven´t been able to achieve this. Anyone alse can advise me? Thanks in advance.

What keys do you press on your Spanish keyboard to get the '|' character?
You need to be able to send the same sequence from your arduino

J-M-L:
What keys do you press on your Spanish keyboard to get the '|' character?
You need to be able to send the same sequence from your arduino

I press alt gr + 1.

How can I send those sequence with the arduino? Totally newbe in this.

The Keyboard functions translate the 128 ASCII characters (0-127) to USB keycodes that represent the correct key for the US-English keyboard. The OS then takes those keycodes and uses the currently selected keyboard layout. If that layout is not US-English the keycodes will be translated to whatever character the selected layout has on that key. You can fix some of the problems by using the character that is in the position you want on the US-English layout. For example to get the '=' try ')' (Shift-0 on the US-English layout). To get '-', try '/'.

The eight Key Modifiers are encoded as characters 128-135 and named in Keyboard.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

To get characters that use AltGr, press the keys in sequence. For example the vertical-bar (AltGr 1) would probably use:

  Keyboard.press(KEY_RIGHT_ALT);
  Keyboard.press('1');
  Keyboard.releaseAll();

If you need USB keycodes that are NOT on the US-English keyboard you can add 136 to the raw keycode value. You can find the keycodes here: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

If you are trying to write code that will work for any system you should look for a way to switch the keyboard layout of the terminal session.