Deciphering DigiKeyboard Scancodes

Hi all,

Firstly, apologies for my poor knowledge - I'm an old basic/perl/vbscript coder trying to find my way!!

One of the projects I'm trying to do is to create a UK version of the DigiKeyboard.h library so I can use some DigiSpark boards for fun stuff without constantly using workarounds for some characters (PIPE | is the main offender).

I've read everything I can find on the library and I believe it should be possible but I cannot work out what a key bit of code is doing so any help would be appreciated.

The DigiKeyboard.h file uses a file called scancode-ascii-table.h which builds an array of keyboard scancodes ordered by ASCII equivalent (so array [1]) is mapped to the keyboard scancode for that character.

HOWEVER, the scan codes listed are NOT the actual scan codes (as available on this great resource: https://kbdlayout.info/kbdusx/scancodes).

I believe it because some sort of binary arithmatic/manipulation is being done when the array is called by this function in DigiKeyboard.h:

  size_t write(uint8_t chr) {
    uint8_t data = pgm_read_byte_near(ascii_to_scan_code_table + (chr - 8));
    sendKeyStroke(data & 0b01111111, data >> 7 ? MOD_SHIFT_RIGHT : 0);
    return 1;
  }

But for all my experimenting with binary, I cannot work out what it's doing (and so I cannot work backwards to make a UK version).

Any pointer would be great!

Get a value from the translation table, indexed by chr - 8 (table starts with 8, not 0).

Send the keystroke that is stored in the lower 7 bits, using the topmost bit as SHIFT.

So it seems there is only support for 7-bit ASCII and a shift modifyer.

My keyboard uses AltGr '<' for the | symbol. It's a German keyboard layout.

Those are Window scan codes. You probably need USB scan codes.

(See: Page 53, Chapter 10, "Keyboard/Keypad Page (0x07)")

The table uses the top bit as a flag indicating the Shift modifier. If you have any keys that use the AltGraph shift you will need a separate flag for that.

Thanks Whandall! I tried converting the value to binary and ignoring the top highest (most significant bit) and I just can't see any correlation between the values and the scan codes.
I'll have another look tomorrow with more caffiene though! :slight_smile:

Thanks John,

I did look at that but the neither of the numbers (usage nor AT-101 position) marry up with what is in the ascii_to_scan_code_table.h file at the moment. As I say, unless there is some binary arithmatic being performed to get the resulting number in the ascii_to_scan_code_table file. WIthout knowing that however, I can't work backwords.

I can confirm that I've previously used that document as a reference to send 'problem' characters using (for example for the PIPE | symbol):

DigiKeyboard.sendKeyStroke (100,MOD_SHIFT_LEFT);

Which works fine but when I switched the reference for ASCII to:
/* ASCII: 124 */ 100,

I get a \ symbol

I assumed I needed to convert this to binary, add 1 to the most significant bit and then convert back to decimal but when I did this, I got a number in the 200s so I disregarded it. I've just gone ahead and tried it anyway and hey presto, it works!

Convert 100 to binary = 1100100
Append 1 to the number for the modifier (shift button) makes 11100100
Convert 11100100 back to 228

Now that I know its correct, I know I just need to add 128 in decimal to an character that needs the shift key!

Binary, decimal or hexadecimal are only representations of the same binary values,
there is no conversion involved.

Thanks Whandall, I know that :wink:
It was just clearer to manage the significant bit and as there was a binary value in code, I assume there was bitwise manipulation to be done (NOT, OR, XOR, etc) but I think I was overthinking it!
Really appreciate your input - it has all helped guide me to the solution!

That is a list of USB keycodes (with a SHIFT flag added) for ASCII characters from 0 to 126.

The "vertical bar" (a.k.a. "pipe") is the shifted state of the "reverse solidus" (a.k.a. "backlash") key. On the US and UK keyboards that is USB keycode 0x64 (decimal 100)

It looks like USB keycodes in ASCII order. Entry 97 (the ASCII code for 'a') maps to the USB code for the 'A' key (4) and entry 65 (ASCII code for 'A') also maps to the USB keycode for the 'A' key (4) but with 128 added (132) to indicate Shift-A.

Thanks John, figured it out in my last post with your help but any extra information is appreciated! I think fundamentally there still has to be an element of working backwards for some codes for the UK keyboards because in the reference, the @ symbol is 31 (so + 128 = 156 in the library file) but for a UK keyboard I need to use 34 (+128). I guess what I'm missing is a UK equivalent of the Hut1_12v2.pdf file!

I created a version of the DigiKeyboard library for the UK now - available here: GitHub - p0ep0e/DigiKeyboardUK: A modified version of the DigiKeyboard library configured to work with UK layout keyboards

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.