Teensy for beginners – playing with keyboard

Photo by: Jeroen Bennink

We have Teensy and know how to program it. So its time to do write some code that allow us to… write something 😉 Good place to start would be usb_keyboard example from official Teensy website. There is some simple API for using keyboard that we can later modify for our needs.

Basically to press key from Teens you have to call function:

int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);

where first argument is number of key (like A or 5), and second one is modifier (like Shift or Ctrl). To get key number, you can check usb_keyboard.h file, where all keys are defined as KEY*. There is also lower level functions, that allow you to, for example, to keep pressed Ctrl while pressing other keys. But I didn’t need it, so lets leave it alone.

To press Win+R key combination the call could look like:

usb_keyboard_press(KEY_R, KEY_GUI);

and to type some text we could write something like that:

usb_keyboard_press(KEY_D, KEY_LEFT_SHIFT);
usb_keyboard_press(KEY_E, 0);
usb_keyboard_press(KEY_M, 0);
usb_keyboard_press(KEY_O, 0);

But if you want to type longer text, calling usb_keyboard_press for each letter is not something lazy programmer would do. So I’ve created function that will convert char array into array of keys with modifiers:

void convertStrningToKeys(char* text, uint8_t* keys, int size)
{
    for(int i = 0; i < size; i++)
    {

        if(text[i] >= 97 && text[i] <= 122)//a-z
        {
            assignKey(keys, i, text[i] - 93, 0);
        }
        else if(text[i] >= 65 && text[i] <= 90)//A-Z
        {
            assignKey(keys, i, text[i] - 61, KEY_LEFT_SHIFT);
        }
        else if(text[i] >= 49 && text[i] <= 57)//1-9
        {
            assignKey(keys, i, text[i] - 19, 0);
        }
        else{
            switch(text[i]){
                case 10:
                    assignKey(keys, i, KEYPAD_ENTER, 0);
                    break;
                case 32: //space
                    assignKey(keys, i, KEY_SPACE, 0);
                    break;
        (...)
                case 126: // ~
                    assignKey(keys, i, KEY_TILDE, KEY_LEFT_SHIFT);
                    break;
                default:
                    assignKey(keys, i, KEY_L, KEY_LEFT_ALT);
                    break;
            }
        }
    }
}

having such function we can then type all text with other helper function:

void writeKeys(uint8_t* keys, int textSize)
{
	for(int i = 0; i < textSize; i++){
		usb_keyboard_press(keys[i*2], keys[i*2+1]);
		_delay_ms(40);
	}
}

and usage example use might look like:

const int textLength = 13;
uint8_t keysToPress[26];
char textToType[] = "Text\nt0\ntype.";
convertStrningToKeys(textToType, keysToPress, textLength);
writeKeys(keysToPress, textLength);

Notice that I’ve hardcoded length of string and then doubled it in definition of keysToPress.

Now we can easily define text we want to type with our small device. There is another problem – what and why we would like to type?

I’ve pulled full code of that example to GitHub.