More Digispark stuff:
-
USBRQ_HID_SET_REPORT
supposedly has something to do with getting keyboard LED status. -
"Trinket Keyboard library" is also worth looking into. It has
getLEDstate()
. -
Some more stuff about Digispark and keyboard LEDs here: https://stackoverflow.com/a/40337245
-
Stuff about numeric keypad and key presses (i.e.
sendKeyPress
as opposed tosendKeyStroke
): https://digistump.com/board/index.php/topic,2839.0.html -- note that it appears "pressing" a key adds it to a reported set of keys that are currently down, so naturally we could call this only up to 6 times before we'd need to release some/all keys. -
00a-empty project determines minimum Digispark firmware size:
Sketch uses 302 bytes (5%) of program storage space. Maximum is 6012 bytes. Global variables use 9 bytes of dynamic memory.
-
00b-kblib project determines minimum size when
DigiKeyboard.h
is loaded:Sketch uses 2490 bytes (41%) of program storage space. Maximum is 6012 bytes. Global variables use 81 bytes of dynamic memory.
NOTE:
scancode-ascii-table.h
accounts for 812 program bytes, and 56 RAM bytes. The rest might be due tousbdrv.h
- The README has some good info, as does the guts ofusbdrv.h
. -
Read about
PROGMEM
-
01-kb1 does basic keyboard stuff, but suddenly adds a lot more code (I guess because a lot of the
DigiKeyboard
class methods now have to get linked):Sketch uses 3388 bytes (56%) of program storage space. Maximum is 6012 bytes. Global variables use 83 bytes of dynamic memory.
-
Micronucleus doing an upload to Digispark seems to be finicky on macOS: With my Mac, it was faulty when plugged into the keyboard's own USB socket. When plugged into the back of the Mac, it sometimes took too long to be recognised. It still worked after a couple of tries, though. I've noticed that both Mac and Windows look like they recognise the device faster if it gets plugged into a USB port that it has previously been used on.
-
For some reason,
KB.sendKeyStroke(KEY_CAPSLOCK);
seems to have no effect on my Mac. Maybe the Mac cares more about status LEDs? Actually, it might have something to do with howKB.print
works: It already specifies case in the string. I can't quite tell, then, why Windows behaves differently. -
Lots of USB key scan codes can be found here: https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
-
02-kb2 is meant to open Spotlight Search (CMD+Space) and do some stuff on a Mac. In order to make that initial key combo work (
KB.sendKeyStroke(KEY_SPACE, MOD_GUI_LEFT);
) I had to add this before it:KB.sendKeyStroke(0); KB.delay(100); KB.sendKeyStroke(0); KB.delay(100);
-
Other keyboard scancode stuff here: https://deskthority.net/wiki/Scancode -- and the Wiki itself might be interesting to learn more about HID.
-
Is it possible to do
KB.sendKeyStroke(0xe3)
to "tap" the Windows key and hence bring up the Windows menu, even though this key is normally a modifier? -
Someone's example code (which I've since cleaned up) for a "shortcut" keyboard adapter, including reading from a shift register:
#include "DigiKeyboard.h" int dataPin = 0; // Pin 0 of DigiSpark connected to Pin 3 of CD4021 int clockPin = 1; // Pin 1 of DigiSpark connected to Pin 10 of CD4021 int latchPin = 2; // Pin 2 of DigiSpark connected to Pin 9 of CD4021 byte RegisterValue = 0; void setup() { //define pins used to connect to the CD4021 Shift Register pinMode(dataPin, INPUT); pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); } void loop() { // Pulse CD4021 latch pin (high, then low) to latch data: digitalWrite(latchPin,1); delayMicroseconds(20); digitalWrite(latchPin,0); // Get CD4021 register data in byte variable: RegisterValue = shiftIn(dataPin, clockPin, MSBFIRST); switch (RegisterValue) { case 0b1: DigiKeyboard.sendKeyStroke(KEY_X, MOD_CONTROL_LEFT ); //CUT key SHORTCUT (ctrl+X) break; case 0b10: DigiKeyboard.sendKeyStroke(KEY_C, MOD_CONTROL_LEFT ); //COPY SHORTCUT (ctrl+c) break; case 0b100: DigiKeyboard.sendKeyStroke(KEY_V, MOD_CONTROL_LEFT ); //PASTE SHORTCUT (ctrl+v) break; case 0b1000: DigiKeyboard.sendKeyStroke(KEY_D,MOD_GUI_LEFT); // (WINDOWS+D) DigiKeyboard.delay(250); break; case 0b10000: DigiKeyboard.sendKeyStroke(KEY_F4,MOD_ALT_LEFT ); // Close shortcut key(alt+ F4) DigiKeyboard.delay(250); break; case 0b100000: DigiKeyboard.print("Hello"); // TO PRINT SOMETHING WITH A KEY PRESS DigiKeyboard.delay(250); break; } delay(250); }
-
03-kb3 - I tried
DigiKeyboard.sendKeyPress()
and it seems to work as expected:// Hold down 'A': DigiKeyboard.sendKeyPress(KEY_A); // Wait some amount of time, during which key repeat will probably kick in... DigiKeyboard.delay(2000); // Hold down A+SHIFT+B (i.e. add another pressed key to the mix, as well as SHIFT): DigiKeyboard.sendKeyPress(KEY_B, MOD_SHIFT_LEFT); // Again, wait for a while... DigiKeyboard.delay(2000); // Release all keys together: DigiKeyboard.sendKeyPress(0);
On Windows, we get key repeat for 'a', then 'B'. On macOS, for the Notes app, holding 'a' brings up foreign options for accented letter 'a', while holding 'B' does nothing special. This is normal, as far as I know.
NOTE: Strangely, my test with
KEY_CAPSLOCK
on the Mac still doesn't work, even when sending regular key presses. Maybe it really is something to do with getting/setting keyboard status lights?I also found that the Digispark was pretty flaky when plugging into my Windows 8.1 MS Surface 1. Often Windows would detect its bootloader, then as soon as the keyboard device started up, it would make a disconnection sound, and only half of the time kick in and start recognising it as a keyboard. Usually it would always eventually start working, but still seems inconsistent.
-
I next want to try the Trinket USB library, to set/get KB LEDs, but it's not clear from here what the correct way to install the TrinketHidCombo library is in Arduino IDE. I can see there's a
Sketch
=>Include Library...
menu, but not sure the right way to use it yet. Similarly there'sTools
=>Library Manager...
. Note also there's the TrinketKeyboard library. In any case, this might help and it just sounds like you maybe download a ZIP from GitHub, extract it, and either move the respective library folder into the Arduino "Libraries" folder (wherever that is), or you upload a ZIP of just the respective library folder into the Arduino IDE.