I've had this exact problem, and had to write my own solution. Unfortunately, I changed something which caused my changed files to be deleted. Luckily, I had one of them open, so I was able to copy and paste into a new file. That said, I still need to re-write the header file. I've posted my code below in sections for ease of viewing. The whole file is also added as an attachment to this post.
2 important things to note:
- I was using an older mbed_os library, so your file may be slightly different
- Note that I wanted to be able to press and send more than 6 keys (which is the default max); I'm using an array size of 10. So the comments in my code tend to that mention that (believe it or not, I write comments in my code even if I don't plan on sharing it). To increase the length of the report you'll need to modify line 407 or so (the first line of the section before Media Controls) to read:
REPORT_COUNT(1), 0x0A, // Allows up to 10 keys.
The first problem is that the keyboard library doesn't allow multiple button presses to be sent in a report. This gives rise to the second problem: there's no press and release.
First we need to create an array to store the key values we want to send, I put this in the header file at the bottom, but I forget if I had it above the protected section, or in the private section.
uint8_t _keys_pressed[10];
Now that we have a place to store the key presses, we need a function to do that. This is based on the press() function in the regular keyboard library.
void USBKeyboard::press_button(uint8_t c)
{
if(_keys_pressed[0] != c && _keys_pressed[1] != c &&
_keys_pressed[2] != c && _keys_pressed[3] != c &&
_keys_pressed[4] != c && _keys_pressed[5] != c &&
_keys_pressed[6] != c && _keys_pressed[7] != c &&
_keys_pressed[8] != c && _keys_pressed[9] != c)
{
for(int i = 0; i < 10 ; i++)
{
if(_keys_pressed[i] == 0)
{
_keys_pressed[i] = c;
//////////////////////////////////////////////////////////
// If we don't break, it'll loop through and put the //
// character in all 10 slots, since we've already //
// checked if it was in the array *BEFORE* starting the //
// loop. //
//////////////////////////////////////////////////////////
break;
}
}
}
}
Now we need a function to send the keys. This is a modified version of the key_code() function already present in the file.
bool USBKeyboard::sendReleaseAll()
{
_mutex.lock();
// Testing with hardcoded values of array size 10, and
// report size 13.
// Send simulated keyboard buttons, and empty the button pressed buffer.
// Returns true if successful.
HID_REPORT report;
report.data[0] = REPORT_ID_KEYBOARD;
report.data[1] = 0;
report.data[2] = 0;
for(int i = 3; i < 13; i++)
{
report.data[i] = keymap[_keys_pressed[i-3]].usage;
}
report.length = 13;
if (!send(&report)) {
_mutex.unlock();
return false;
}
for(int i = 3; i < 13; i++)
{
report.data[i] = 0;
}
emptyButtonBuffer();
if (!send(&report)) {
_mutex.unlock();
return false;
}
_mutex.unlock();
return true;
}
You will need to modify the key_code() function they give by adding a few lines to the array, and changing the report length. This is important because: if your reports don't list the correct length, the function won't work, and nothing will be sent.
report.data[9] = 0;
report.data[10] = 0;
report.data[11] = 0;
report.data[12] = 0;
report.length = 13;
You may have noticed, but I used a function called emptyButtonBuffer() to clear the _keys_pressed array.
void USBKeyboard::emptyButtonBuffer()
{
// Using hard-coded value of 10 for keys pressed array for testing.
// Empties the pressed buttons buffer.
// Buffer is 10 (0 through 9) long.
for(int i = 0; i < 10; i++)
{
_keys_pressed[i] = 0;
}
}
These are the basic changes. There is more that can be done, but this is what I had, and it was working properly. If you decide to use my file, you'll need to fix the filename which I left as untitled to avoid any unintended overwrites. I suggest either using my functions as templates, or only copying sections you want into your keyboard.cpp file, since a newer keyboard.cpp file may reference newer changes in the mbed_os library (I'll be doing this myself in the next week or two).
Untitled-1.cpp (23.7 KB)