USB keyboard problems..

Status
Not open for further replies.

UnaClocker

Active member
I'm getting errors trying to use "usb_keyboard_press" as explained here: http://www.pjrc.com/teensy/usb_keyboard.html
It's Arduino 1.03, latest Teensyduino applied, Teensy 2.0, on the latest Mac OSX
The compiler window lists complaints:
"error: 'usb_keyboard_press' was not declared in this scope"
Why not? It's in the documentation, was it removed? Renamed?

Here's code that won't work:
Code:
#include <usb_keyboard.h>

void setup() {
  pinMode(11, OUTPUT);
}

void loop() {
  delay(5000);
  digitalWrite(11, HIGH);
  usb_keyboard_press(KEY_D);
  delay(1000);
  digitalWrite(11, LOW);
}
 
The function takes two arguments: the second is the modifier key (or 0 if no modifier).

Compiling with that change, without the #include, and with board set to Teensy 3.0 and USB set to keyboard+mouse+joystick works for me. Like you, changing to Teensy 2.0 gives an error "error: 'usb_keyboard_press' was not declared in this scope".

Working code (Teensy 3.0)
Code:
void setup() {
  pinMode(11, OUTPUT);
}

void loop() {
  delay(5000);
  digitalWrite(11, HIGH);
  usb_keyboard_press(KEY_D, 0);
  delay(1000);
  digitalWrite(11, LOW);
}
 
Searching the forum, I reported a problem in Teensy beta8 and it was fixed in beta 9. But apparently, only for Teensy 3.0 and not Teensy 2.0/++2.0. And then the thread goes cold, with Paul commenting on media keys (an entirely separate issue) and worrying, oddly, that all other keys in the USB standard won't work on Windows.

The following modification of your code, adding the mising function and adding an include to get the #defines, compiles on 1.0.3+Teensyduino 112. Obviously it would be better if the function was defined in the library, as it is for Teensy 3.0.

Code:
#include "keylayouts.h"

void setup() {
  pinMode(11, OUTPUT);
}

void loop() {
  delay(5000);
  digitalWrite(11, HIGH);
  usb_keyboard_press(KEY_D, 0);
  delay(1000);
  digitalWrite(11, LOW);
}

void usb_keyboard_press(int key, int modifier) {
  // press one key with up to one modifier, then release
  Keyboard.set_modifier(modifier);
  Keyboard.set_key1(key);
  Keyboard.set_key2(0);
  Keyboard.set_key3(0);
  Keyboard.set_key4(0);
  Keyboard.set_key5(0);
  Keyboard.set_key6(0);
  Keyboard.send_now();
  delay(1);
  Keyboard.set_key1(0); 
  Keyboard.send_now();
}
 
Many years ago, in the early days of Teensy 1.0, there was only the C example code. Serial-only Arduino support came next, and after several months, I ported the keyboard and mouse code over to Teensyduino.

Later, other USB types were implemented in Teensyduino, and improvements to the Keyboard support were made for Arduino. This new stuff never made its way back to the original C code.

For Teensy 3.0, I'm trying a new approach, aiming for better long-term maintenance. The implementation is basically all C-only, with a C++ class that calls the C functions. The C code aims for compatibility with the original pre-Teensyduino C examples for the AVR-based boards.

Eventually, I'll probably rework the AVR-based code to use this approach, bringing the newer features (like international keyboard layouts) to the C-only code. But I hope you can understand how this is a pretty low priority.

You can use the C-only functions on Teensy 3.0 (their only documentation is the source code or header files)... but I don't consider their absence on Teensy 2.0 a bug. It's more a byproduct of the fact I couldn't predict exactly how all this stuff would work out over the years. The C functions really aren't an official API when running Arduino.

Likewise, on the media keys, it turned out to be a learning experience. I followed the published HID usage table spec (the actual standard published on www.usb.org by the USB-IF). It works perfectly on Linux and Mac. Little did I know about Microsoft's silly limitations for Windows. That's yet another little thing I learned along the way.

I'm planning to write a new, Windows-compatible media keys implementation on Teensy 3.0. It'll be substantially better than the limited 8-key attempt I made on Teensy 2.0. In time, after it's well tested on 3.0, I'll probably back-port than approach to 2.0.... but there will be a period of time where the media keys work great on 3.0, but 2.0 still has the limited media keys support it has now.
 
Last edited:
Also, both Teensy 2.0 and 3.0 have an undocumented function Keyboard.press(key) and Keyboard.release(key). That's probably the function you want.

It's also on the list of many things I'm going to document on the website soon....
 
Ok, I'll use Keyboard.press and release. I assume I'll need some what of a delay in there.. 10ms? Thanks for the feedback.
edit: I had also used keyboard_keys[x]=keys;, and that doesn't work either (didn't show in my example, because the compiler wasn't complaining about it yet).. Guess I'll have to find a way to use this other method with that.
 
Last edited:
Status
Not open for further replies.
Back
Top