10 years, 10 months ago.

Send UP_ARROW with USB Keyboard

Hello

I try to find the right way to sent the arrow key with the USB Keyboard. When I send the arrow command with 0.01s space on Metal Slug 3 the character move sometime, I think that the game see sometime the arrow key. If I send the key as fast as possible, the game freeze until i stop to press the arrow key

have you an idea? I use the KL25z board .

thank you

Sorry for my english I am french.

1 Answer

10 years, 10 months ago.

Are you sure the issue is your code, and not the game? Sending a command 100 times per second is just slightly outside the normal range. 10 times per second is already not humanly possible.

Accepted Answer

I fond the solution. The USB Keyboard send automatically the press and release command:

the original function in USBKeyboard.cpp

bool USBKeyboard::keyCode(uint8_t key, uint8_t modifier) {
    // Send a simulated keyboard keypress. Returns true if successful.
    HID_REPORT report;

    report.data[0] = REPORT_ID_KEYBOARD;
    report.data[1] = modifier;
    report.data[2] = 0;
    report.data[3] = keymap[key].usage;
    report.data[4] = 0;
    report.data[5] = 0;
    report.data[6] = 0;
    report.data[7] = 0;
    report.data[8] = 0;

    report.length = 9;

    if (!send(&report)) {
        return false;
    }

    report.data[1] = 0;
    report.data[3] = 0;

    if (!send(&report)) {
        return false;
    }

    return true;

}

So the second send(&report)

stop key code

    if (!send(&report)) {
        return false;
    }

Stop automatically the command sent before. Just comment this code and add a new function to send manually the release event

stop key code final in USBKeyboard.cpp

bool USBKeyboard::keyCode(uint8_t key, uint8_t modifier) {
    // Send a simulated keyboard keypress. Returns true if successful.
    HID_REPORT report;

    report.data[0] = REPORT_ID_KEYBOARD;
    report.data[1] = modifier;
    report.data[2] = 0;
    report.data[3] = keymap[key].usage;
    report.data[4] = 0;
    report.data[5] = 0;
    report.data[6] = 0;
    report.data[7] = 0;
    report.data[8] = 0;

    report.length = 9;

    if (!send(&report)) {
        return false;
    }

    report.data[1] = 0;
    report.data[3] = 0;

    /*if (!send(&report)) {
        return false;
    }*/

    return true;

}

bool USBKeyboard::keyCode_off() {
    // Send a simulated keyboard keypress. Returns true if successful.
    HID_REPORT report;

    report.data[0] = REPORT_ID_KEYBOARD;
    report.data[1] = 0;
    report.data[2] = 0;
    report.data[3] = 0;
    report.data[4] = 0;
    report.data[5] = 0;
    report.data[6] = 0;
    report.data[7] = 0;
    report.data[8] = 0;

    report.length = 9;

    if (!send(&report)) {
        return false;
    }


    return true;

}

The main code is

stop key code final in main.cpp

#include "mbed.h"
#include "USBKeyboard.h"
 
//LED1: NUM_LOCK
//LED2: CAPS_LOCK
//LED3: SCROLL_LOCK
BusOut leds(LED2, LED2, LED3);

DigitalOut led(LED1);

DigitalIn Up(PTC12);  
DigitalIn Down(PTC13);
DigitalIn Left(PTC16);
DigitalIn Right(PTC17);

DigitalIn Right(PTC17);
DigitalIn Right(PTC17);
DigitalIn Right(PTC17);
DigitalIn Right(PTC17);

//USBKeyboard
USBKeyboard keyboard;
 
int main(void) {
    int verou1 = 0;
    int verou2 = 0;
    int verou3 = 0;
    int verou4 = 0;
    
    Up.mode(PullUp);
    Down.mode(PullUp);
    Left.mode(PullUp);
    Right.mode(PullUp);
    
    while (1) {
        if(Up==0)
        {
            verou1 = 0;
            keyboard.keyCode(UP_ARROW, 0);
        }
        else if(verou1 == 0)
        {
            led =! led;
            verou1 = 1;
            keyboard.keyCode_off();
        }
            
            
        if(Down==0)
        {
            verou2 = 0;
            keyboard._putc(DOWN_ARROW);
        }
        else if(verou2 == 0)
        {
            verou2 = 1;
            keyboard.keyCode(0, 0);
        }
        
        if(Left==0)
        {
            verou3 = 0;
            keyboard._putc(LEFT_ARROW);
        }
        else if(verou3 == 0)
        {
            verou3 = 1;
            keyboard.keyCode_off();
        }
        if(Right==0)
        {
            verou4 = 0;
            keyboard._putc(RIGHT_ARROW);
        }
        else if(verou4 == 0)
        {
            verou4 = 1;
            keyboard.keyCode(0, 0);
        }
            
        wait(0.05);
        
        //leds = keyboard.lockStatus();
    }
}

the "verou" variable is use to avoid a continuous stop commend if my stick arcade is not used. Use "keyboard._putc()" or "keyboard.keyCode()" in this case do the same thing.

PS:

If you want to send several key at the same time use this function:

send several key at the same time : USBKeyboard.cpp

bool USBKeyboard::keyCode_ATH(uint8_t key_1, uint8_t key_2, uint8_t key_3, uint8_t key_4, uint8_t key_5, uint8_t key_6, uint8_t modifier) {
    // Send a simulated keyboard keypress. Returns true if successful.
    HID_REPORT report;

    report.data[0] = REPORT_ID_KEYBOARD;
    report.data[1] = modifier;
    report.data[2] = 0;
    report.data[3] = keymap[key_1].usage;
    report.data[4] = keymap[key_2].usage;
    report.data[5] = keymap[key_3].usage;
    report.data[6] = keymap[key_4].usage;
    report.data[7] = keymap[key_5].usage;
    report.data[8] = keymap[key_6].usage;

    report.length = 9;

    if (!send(&report)) {
        return false;
    }

    return true;

}
posted by Adrien Thiers 07 Dec 2014

Great explanation Adrien Thiers!! This helps me a lot!

posted by Julio Ryuuzaki 30 Dec 2016