Keyboard emulation on native USB is not a keyboard

Hi,

For our thesis we are working with an Arduino Due. We bought it especially for the 2nd USB port which can emulate a keyboard.
The intention was to take over the characters sent by a keyboard towards a game on PC. Instead of playing the game on the keyboard
the Arduino should collect data from other devices (like potmeters and switches) and sent the proper characters towards the game.

Unfortunally our game does not recognize the Native USB interface as a full compliant keyboard.
However other programs are accepting fine the characters sent by the Arduino Due.

I don't know that much of an USB interface but with USBlyzer I managed to detect some differences.
My keyboard has 2 interfaces (keyboard and Mouse)
The binterfaceClass/binterfaceSubClass/binterfaceProtocol is keyboard: 03_01_01 and mouse 03_01_02

For the native USB interface however, I see it is defined as a CDC device with 4 pipes. (??)
The last "Interface Descriptor" has a similar binterfaceClass/binterfaceSubClass/binterfaceProtocol : 03_00_00.
The others are CDC descriptors.(Communication Device Class)

Does anyone has a solution or a workaround for this problem?

Depends how the Game read from the keyboard, does it takes only the final characters or in raw mode how long the key is/was pressed ?

Just a single character:

usb_keyboard_press(KEY_A, 0);

Beginn:

keyboard_keys[0] = KEY_LEFT;   usb_keyboard_send();

End:

keyboard_keys[0] = 0;
usb_keyboard_send();

I had this issue with a Flight Simulator, steering right/left was unusable but navigating through Menus worked well. (Also in a Texteditor, but not in the Sim)

Hi Transwarp,

I am not aware of the above used usb instructions.

I use a very simplified piece of code with the keyboard.xxxx instructions defined for the Arduino Due:

//  Arduino code example modified to test game interface
//  With the Arduino Due Native USB 
// A breadboard with a push button, just temporarily touch pin D22 to +3V3 to toggle the input

// Make sure to open a blank Notepad window or similar to avoid messing up your sketch!

/* 
 Keyboard Button test
 Sends a character 'n' when a button is pressed.
 The circuit:
 - pushbutton attached from pin 22 with resistor of 1k to 3V3
 created 24 Dec 2012
 by Yougo
*/

const int buttonPin = 22;          // input pin for pushbutton
int previousButtonState = HIGH;    // for checking the state of a pushButton

void setup() 
{
  // make the pushButton pin an input:
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  Serial.println("Hello World");
  Keyboard.begin();

}

void loop() {
  
  // Read pin22
  int buttonState = digitalRead(buttonPin);
  
  // if the button state has changed, 
  if ((buttonState != previousButtonState) && (buttonState == HIGH))    // and it's currently pressed:
    {  Keyboard.write(110);                // type "n"
    }
  // save the current button state for comparison next time:
  previousButtonState = buttonState; 
}

Oh, in the Tutorial http://www.arduino.cc/en/Tutorial/KeyboardReprogram , with came with IDE 1.5.1 it's:

Keyboard.press('n');
delay(100);
Keyboard.releaseAll();

The Point is, not to send a Key but an condition (pressed or not pressed, that's the question XD )
In the Tutorial a delay ist used, for the game use Keyboard.press when it's pressed and then Keyboard.releaseAll when it's no longer pressed.

Yes, yes, yes. It works!!!
We are very grateful. TransWarp, you saved the project!!!

But please explain what the exact difference is between sending a character
and keep it pressed for the game.
I can imaging that, when the game is just polling every x miliseconds that
it is missing characters which are sent at 9600baud (~1ms)

So I tried to determ x. And below a delay(25); it started to fail once a while (the lower the more of course)
tnx again
Yougo

Woo hoo !

Polling is very inefficient in large Systems (it's very easy if you have just a few items like 2 Sensors and a Servo),
so it's done by Interrupts.

Very short:
Polling:

loop forever
  check if key is pressed - do something when it happened
  wait

Interrupt:

Main Program does something;

The Interrupt-Logic waits till a key is pressed, then --> Interrupts the Main Program, tell a Key is pressed (Send a Signal) and the Main Program does something and continue at that point when the interrupt came (maybe with changed Values).

The Interrupt-Logic waits till the key is released, then --> Interrupts the Main Program again, send the Key Released-Signal and the Main Program does something and continue at that point when the interrupt came.

The Main Program does not waste time with waiting (there is no x), the Interrupt-Controller waits independent and sends only Signals to the Main Program.
Then it depends on the programmer, how he want to deal with those Signals.

Working with Interrupts is a complete different way of programing, due the separation from the code sequence into Hardeware (it can happen at any time), the Compiler can't test all possibilities.
If you know what you're doing, it's fast and cool. 8)

I know that polling is a very inefficient way of programming and reacting.(Always the polling delay)
But in this case it is the game on the PC which is doing it in the polling way. I was not expecting that.
So therefore I was puzzled and came not to the idea to use the pressed key functionality
in the Arduino Due.

I will take your advice into account when I got to program someything similar on the Arduino.

Thanks a lot
BR
Yougo