Bluetooth LE HID Keyboards
Bluetooth LE HID (Human Interface Devices) are things like Keyboards, Mice, and buttons. Puck.js can emulate these, so can simulate keys being pressed.
Note: You'll need at least firmware version 1v92 to pair on Windows (it needs the bonding functionality). Earlier firmwares can work as keyboards on Android, Mac OS and Chromebook, but we'd always recommend you're using the latest firmware.
Note: Bluetooth HID can't be enabled on an active connection. To make it work (if you're connected wirelessly) you need to upload the code, disconnect, and then reconnect with your Operating System's Pair
functionality. Sending HID keypresses without HID enabled will throw an exception.
BLE HID can be enabled by providing a HID Report to NRF.setServices, however we've provided common types of HID report in modules to make it easier:
Keyboards
Keyboard support is from the ble_hid_keyboard (About Modules) module. Using it
is as simple as calling NRF.setServices
with the HID report
provided by the module. You can then use the .tap
method to
send a key tap, or can use NRF.sendHIDReport
directly.
var kb = require("ble_hid_keyboard");
NRF.setServices(undefined, { hid : kb.report });
function btnPressed() {
// Send 'a'
kb.tap(kb.KEY.A, 0, function() {
// Followed by capital 'A'
kb.tap(kb.KEY.A, kb.MODIFY.SHIFT);
});
}
// trigger btnPressed whenever the button is pressed
setWatch(btnPressed, BTN, {edge:"rising",repeat:true,debounce:50});
// Add 'appearance' to advertising for Windows 11
NRF.setAdvertising([
{}, // include original Advertising packet
[ // second packet containing 'appearance'
2, 1, 6, // standard Bluetooth flags
3,3,0x12,0x18, // HID Service
3,0x19,0xc1,0x03 // Appearance: Keyboard
// 0xc2,0x03 : 0x03C2 Mouse
// 0xc3,0x03 : 0x03C3 Joystick
]
]);
As of around Sept 2023, Windows 11 has started filtering out any
Bluetooth LE device that does not include an Appearance
element in its Bluetooth LE
advertisement. To date, iOS, Android, Linux, Mac OS, Windows 10 all do not require it.
To allow pairing under Windows 11 you'll have to add a Bluetooth Appearance (0x19
) to the
advertisement, using this code:
NRF.setAdvertising([
{}, // include original Advertising packet
[ // second packet containing 'appearance'
2, 1, 6, // standard Bluetooth flags
3,3,0x12,0x18, // HID Service
3,0x19,0xc1,0x03 // Appearance: 0x03C1 Keyboard
// 0xc2,0x03 : 0x03C2 Mouse
// 0xc3,0x03 : 0x03C3 Joystick
]
]);
Valid appearance numbers can be found at https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Assigned_Numbers.pdf
under 2.6.3 Appearance Sub-category values
LEDs
When a Keyboard LED (Caps Lock, Num Lock, etc) should be lit, a message
is sent to Espruino and is provided via the NRF.on('HID', ...)
event.
- Bit 0: NUM lock
- Bit 1: CAPS lock
- Bit 2: SCROLL lock
- Bit 3: Compose
- Bit 4: Kana
For instance the following will light LED1 and LED2 depending on Num Lock and Caps Lock:
NRF.on('HID', function(v) {
LED1.write(v&1);
LED2.write(v&2);
});
This way you can send messages/data back to an Espruino device without any drivers or platform specific code, just by toggling the status of Caps Lock, Num Lock, and others.
Multimedia Keys
However, the multimedia keys on keyboards (play/stop/volume/etc) are treated as a completely separate device by USB and BLE.
Support for this is from the ble_hid_controls (About Modules) module.
var controls = require("ble_hid_controls");
NRF.setServices(undefined, { hid : controls.report });
// Play/stop music
controls.playpause();
// Send 'volume up' twice
controls.volumeUp(function() {
controls.volumeUp();
});
// Other options:
//controls.next();
//controls.prev();
//controls.stop();
//controls.mute();
//controls.volumeDown();
Mouse
You can also use the ble_hid_mouse (About Modules) module to emulate a mouse. For example:
var mouse = require("ble_hid_mouse");
NRF.setServices(undefined, { hid : mouse.report });
function btnPressed() {
mouse.send(0,0,mouse.BUTTONS.LEFT); // X movement, Y movement, buttons pressed
}
// trigger btnPressed whenever the button is pressed
setWatch(btnPressed, BTN, {edge:"rising",repeat:true,debounce:50});
Combination
If you find you require multiple HID defices at the same time (EG a keyboard and mouse combination) that is possible with more advanced custom HID reports. If you are looking for a quite complete keyboard and mouse combination implementation you can use the ble_hid_combo (About Modules) module.
var int = require("ble_hid_combo");
NRF.setServices(undefined, { hid : int.report });
function btnPressed() {
int.scroll(10); // Scroll down
int.moveMouse(30, 0); // Move mouse horizontally
int.tapKey(int.KEY.Y); // Also press the Y key
}
// trigger btnPressed whenever the button is pressed
setWatch(btnPressed, BTN, {edge:"rising",repeat:true,debounce:50});
Low Level control
You can emulate a wide variety of other devices by providing your own HID report:
report = new Uint8Array([
]);
NRF.setServices(undefined, { hid : report });
You can then call NRF.sendHIDReport
to send data. For Keyboards it must be an array of the form:
[modifier, reserved, key1, key2, key3, key4, key5, key6 ]
You can easily look up keyboard key codes, but for example
to send the 'a' key, send [0,0,4,0,0,0,0,0]
. To release
it, send [0,0,0,0,0,0,0,0]
Note: The modifiers are defined in require("ble_hid_keyboard").MODIFY
and
common keys are in require("ble_hid_keyboard").KEY
The modifiers are as follows:
1 : left control
2 : left shift
4 : left alt
8 : left GUI
16 : right control
32 : right shift
64 : right alt
128 : right GUI
So to send capital A
, send [2,0,4,0,0,0,0,0]
followed by [0,0,0,0,0,0,0,0]
.
NRF.sendHIDReport([2,0,4], function() {
NRF.sendHIDReport([0,0,0])
})
You can find key codes at https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf under the Keyboard/Keypad page
, but for quick reference:
a
...z
are 4..261
..9
are 30..380
is 39- Return is 40
- Space is 44
Uses
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.