Code and Life

Programming, electronics and other cool tech stuff

Supported by

Supported by Picotech

Adafruit Trinket USB keyboard without Arduino

Happy New Year 2016! After a long hiatus in electronics, I have been quite busy in the last month or so. I have a bigger (USB MIDI related) project posting coming up, but just wanted share a small nugget already.

I ordered a big chunk of things recently from Adafruit shop and Sparkfun. Among them was the lovely Adafruit Trinket (which actually came as a free bonus because I spent way too much on black friday :).

Now I am planning a project which involves transforming the very compact, but already USB-enabled Trinket into a USB MIDI device. However, there are two problems:

  1. Adafruit examples for USB come in Arduino form
  2. There are no USB MIDI examples

I somewhat dislike the high-level Arduino environment in cases where low-level performance is needed (and the V-USB implementation is one of those places), and for my later MIDI part, I will need fine-grained control to juggle serial communication and USB. Also, all USB MIDI examples are on “bare metal”, so the Adafruit example Arduino code would require deeper knowledge of Arduino inner workings than I have.

Time to do some chopping!

Slimming Down the TrinketKeyboard Example

I decided to adapt the excellent base code in Adafruit Trinket USB GitHub repository, but trim the keyboard example to bare essentials (my next step will be to transform it into a USB MIDI device, so the less code I have to adapt, the better). Turns out this was quite simple to do:

  1. Rename TrinketKeyboardC.c to main.c (we’ll only have one .c file)
  2. Add 30 lines of code in the end — pressKey from the C++ part of the library and a simple main() method
  3. Remove everything else except the above file, usbconfig.h and usbdrv directory
  4. Add a Makefile

That was basically it! I did a few small tweaks, including a few pointer casts so the compiler would not complain, and remove some needless #includes. I made the code available to GitHub:

https://github.com/jokkebk/TrinketKeyboard

My minimal example does not toggle any LEDs and only has one button wired between pin #0 (PB0) and ground, which sends a string of capital A’s when pressed. If needed, it would be easy to bring over more utility functions from Adafruit’s library, but this will do for now:


// Above this code are the contents of TrinketKeyboardC.c

#define KEYCODE_MOD_LEFT_SHIFT 0x02
#define KEYCODE_A 0x04

// construct a keyboard report, follow the standard format as described
// this format is compatible with "boot protocol"
void pressKey(uint8_t modifiers, uint8_t keycode1) {
	report_buffer[0] = modifiers;
	report_buffer[1] = 0; // reserved
	report_buffer[2] = keycode1;
	report_buffer[3] = 0; //keycode2;
	report_buffer[4] = 0; //keycode3;
	report_buffer[5] = 0; //keycode4;
	report_buffer[6] = 0; //keycode5;
	report_buffer[7] = 0; //keycode6;
	usbReportSend();
}

int main() {
	usbBegin();
	PORTB |= _BV(PB0); // Pullup on button

    while(1) {
        usbPoll();

		if(!(PINB & _BV(PB0))) { // button pressed
            pressKey(KEYCODE_MOD_LEFT_SHIFT, KEYCODE_A); // press
            pressKey(0, 0); // release
        }
    }
	
    return 0;
}

Next I’ll be comparing my resulting code to Martin Homuth-Rosemann’s V-USB-MIDI project and see if I can transform this project into a working TrinketMIDI example. Stay tuned!

7 comments

rick:

This is a great writeup! I’ve been wanting to do something similar but cannot for the life of me get my Trinket to be recognized on my computer.

Also, in the IDE, are you selecting the Trinket as a board name or gemma or leonardo?

Joonas Pihlajamaa:

Thanks! In Arduino, I’m setting it to be Trinket, haven’t tried the others. I also have USBtiny ISP programmer drivers installed from the past, not sure if they help to get it working. I recall I used Adafruit’s instructions for installation and it Just Worked (thankfully).
https://learn.adafruit.com/adafruit-arduino-ide-setup/overview

SharpTek:

Hey,

Thanks – this is very great. I have tested it and works perfect.

How can I add some other Keys to this?

– SharpTek

Joonas Pihlajamaa:

You can find more key definitions from Adafruit’s Github repository (just search for those two I had), so you can easily add any keypress.

SharpTek:

I need for exemple the print method. How can I implement this?

Joonas Pihlajamaa:

I recall Adafruit code included that as well. And in any case, print method is just a for-loop sending individual characters, stop when you encounter a null byte (zero), so you can easily do such a method yourself.

Rich:

Hello,

Thanks. Your writing is very concise and easy to follow (which is fantastic as its easy to get lost in this area!). i’m just wondering if you have managed to crack the USB MIDI on trinket yet?… i appreciate it takes time to o and time to write/explain what you did…anyway i’m looking out for it and will have a go at it when i see how an expert such as yourself gets it going

cheers,

Rich