Keyboard Media Keys, now (hopefully) Windows compatible

Maybe you tested with Tools > USB Type set to "Serial + Keyboard + Mouse + Joystick"? Teensy 2.0 doesn't have enough USB endpoints to also do media keys with that combination.

Try with "Keyboard + Mouse + Joystick". Media keys should work in this mode.
 
Maybe you tested with Tools > USB Type set to "Serial + Keyboard + Mouse + Joystick"? Teensy 2.0 doesn't have enough USB endpoints to also do media keys with that combination.

Try with "Keyboard + Mouse + Joystick". Media keys should work in this mode.

Yes! Working like a charm now. Thanks!
 
I've never even seen such a keyboard!

Near the end of that instructable page you can see lots of unique keyboards people have added. The process of adding another would be similar. Generally speaking, you would do it in 2 steps. First you need to experimentally figure out which 2 pins get connected when that particular key is pressed. Then you would need to figure out which HID key code you want to transmit for that key. That's simple if you just want it to act like a "#" on a regular keyboard. But if it's a special key, maybe you want to send something else (perhaps a combination of them). This too can take some experimentation if the answer isn't immediately clear from looking at the long list of possible key codes.
 
I've been working on improved media keys support which can work with Windows. It's ready for initial testing. Hopefully there's still interest in this feature?

Code for Teensy LC & 3.x is on github now.

https://github.com/PaulStoffregen/cores

If you'd like to try this, download the cores repository and replace your hardware/teensy/avr/cores folder with its contents. On a Mac, control-click Arduino, then "Show Package Contents", and replace Contents/Java/hardware/teensy/avr/cores with the files from github.

I'm planning to back-port this to Teensy 2.0, after some testing. As you can see on the github commit log, this changed quite a lot of the USB keyboard code. I could really use some help with testing, especially on various Windows systems, and *especially* with the many non-US layouts. So far, I've done only initial testing on Windows 10, and only with "US English" keyboard layout.

The new media key support is intended to be used with Keyboard.press() and Keyboard.release(). Here's an example:

Code:
/* Buttons to USB Keyboard Example - Special Media Player Keys

   You must select Keyboard from the "Tools > USB Type" menu

   This example code is in the public domain.
*/

#include <Bounce.h>

// Create Bounce objects for each button.  The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
Bounce button0 = Bounce(0, 10);
Bounce button1 = Bounce(1, 10);  // 10 ms debounce time is appropriate
Bounce button2 = Bounce(2, 10);  // for most mechanical pushbuttons
// TODO: fix pin 3 button on my testing board....
Bounce button3 = Bounce(4, 10);
Bounce button4 = Bounce(5, 10);  // if a button is too "sensitive"
Bounce button5 = Bounce(6, 10);  // you can increase this time.

void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  button0.update();
  button1.update();
  button2.update();
  button3.update();
  button4.update();
  button5.update();

  // Check each button for "falling" edge.
  // falling = high (not pressed - voltage from pullup resistor)
  //           to low (pressed - button connects pin to ground)
  if (button0.fallingEdge()) {
    Keyboard.press(KEY_MEDIA_PREV_TRACK);
    Keyboard.release(KEY_MEDIA_PREV_TRACK);
  }
  if (button1.fallingEdge()) {
    Keyboard.press(KEY_MEDIA_PLAY_PAUSE);
    Keyboard.release(KEY_MEDIA_PLAY_PAUSE);
  }
  if (button2.fallingEdge()) {
    Keyboard.press(KEY_MEDIA_NEXT_TRACK);
    Keyboard.release(KEY_MEDIA_NEXT_TRACK);
  }
  if (button3.fallingEdge()) {
    Keyboard.press(KEY_MEDIA_VOLUME_DEC);
    Keyboard.release(KEY_MEDIA_VOLUME_DEC);
  }
  if (button4.fallingEdge()) {
    Keyboard.press(KEY_MEDIA_VOLUME_INC);
    Keyboard.release(KEY_MEDIA_VOLUME_INC);
  }
  if (button5.fallingEdge()) {
    Keyboard.press(KEY_SYSTEM_POWER_DOWN);
    Keyboard.release(KEY_SYSTEM_POWER_DOWN);
    //Keyboard.press(KEY_MEDIA_EJECT);
    //delay(300);  // Mac OS-X will not recognize a very short eject press
    //Keyboard.release(KEY_MEDIA_EJECT);
  }
}

So far, these are the keys defined in keylayouts.h:

Code:
KEY_MEDIA_PLAY         
KEY_MEDIA_PAUSE        
KEY_MEDIA_RECORD       
KEY_MEDIA_FAST_FORWARD 
KEY_MEDIA_REWIND       
KEY_MEDIA_NEXT_TRACK   
KEY_MEDIA_PREV_TRACK   
KEY_MEDIA_STOP         
KEY_MEDIA_EJECT        
KEY_MEDIA_RANDOM_PLAY  
KEY_MEDIA_PLAY_PAUSE   
KEY_MEDIA_PLAY_SKIP    
KEY_MEDIA_MUTE         
KEY_MEDIA_VOLUME_INC   
KEY_MEDIA_VOLUME_DEC   
KEY_SYSTEM_POWER_DOWN
KEY_SYSTEM_SLEEP
KEY_SYSTEM_WAKE_UP

Unlike the old code, which was limited to only 8 keys (which only worked on Mac & Linux), this new way is intended to be able to support all the media (aka HID Consumer Usage Page) key definitions, and all the system control keys too.

The Keyboard.press() and Keyboard.release() functions are meant to accept ASCII, and Unicode up to 0xC1FF (of course, each layout implements only a small fraction of the huge Unicode space), and non-ascii characters, and the many KEY_XYZ constants which map directly to HID usage numbers. Much of this code got reworked... and it seems to be functioning, but I haven't yet tested on non-US layouts. I could really use help testing from anyone using Teensy as a non-US keyboard.

If you find anything not working, please be sure to post a complete program and specify which layout and OS you're using, so I can try to reproduce and fix the problem.
It’s great to see the progress on the improved media keys support for Windows! I’m sure many will find this feature valuable, especially those who use Teensy boards for custom keyboard projects. The step-by-step instructions for testing the new code are clear and well-documented. It’s awesome to see the broad support for media and system control keys this is definitely an upgrade from the old, more limited functionality. I’d love to see how this works with non-US keyboard layouts, as this is often a pain point for many users. It would be helpful if you could provide a bit more guidance on testing with different layouts or any troubleshooting tips for users unfamiliar with compiling code or modifying their Teensy setup.

As for testing, I think reaching out to the community could definitely help catch any potential issues with various systems, especially with different Windows versions and non-US layouts. Keep up the great work!
 
Back
Top