Home > Arduino, Bluetooth, TKJ Electronics, USB > Bluetooth HID devices now supported by the USB Host library

Bluetooth HID devices now supported by the USB Host library

I am glad to announce that Bluetooth HID devices are now supported by the USB Host library. The library already supports PS3 and Wiimote controllers, but now it also supports more general devices, like Bluetooth keyboard and mice.

An example is available at the following link: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/BTHID/BTHID.ino.

First time you run the code, you will have to pair with your device, this is done by creating the instance like so:

BTHID bthid(&Btd, PAIR, "0000");

You can of course set the pin to anything you like.

Now you should enable discovery of your device and it should automatically detect any mouse or keyboard present and then connect to them. On Bluetooth mice there is no need to enter any pin, but on a keyboard you should enter the pin on the keyboard and then afterwards press enter.

So in this example you should press 0 four times on the keyboard and then press enter afterwards.

After you have paired with the device, you can simply create the instance like so:

BTHID bthid(&Btd);

When you press any button on your device it will automatically connect to the last paired device i.e. your Arduino.

By default it uses the “Boot Protocol Mode”, but since only basic functionality is available in “Boot Protocol Mode”, I have made it easy to change it.
Simply call this in your setup:

bthid.setProtocolMode(HID_RPT_PROTOCOL);

Since it do not read the HID descriptor of your device, you might find that some of the buttons etc. might not work on your device. Unfortunately you will have to modify the parser, but it should not be that difficult.

Simply uncomment:

#define PRINTREPORT

In BTHID.cpp to see the incoming data and then modify the parser for your needs – the standard parser can be found in hidboot.cpp.

I have currently tested the code with a PS3 keyboard (see image below) and it works perfectly fine, but I had to change it to use “Report Protocol Mode” as described above. A nice thing about the PS3 keyboard is that it features both a keyboard and a mouse, as the keyboard is touch sensitive and can therefore be used as a trackpad.

Furthermore I have tested it with my Apple Wireless Keyboard, Apple Wireless Trackpad and an old Bluetooth mouse from Microsoft that I have and all of them worked fine as well.

ps3_controller_keyboard_01

This is all for now. Fell free to leave a comment below if you have any questions or problems with a specific device.

Categories: Arduino, Bluetooth, TKJ Electronics, USB Tags:
  1. Kapil Saraswat
    December 27th, 2013 at 19:58 | #1

    Glade to hear. I want to know how I connect my android mobile phone with arduino mega adk via bluetooth? Any example?
    Regards

  2. December 27th, 2013 at 20:33 | #2

    @Kapil Saraswat
    First of all you should activate the mega ADK at explained here: https://github.com/felis/USB_Host_Shield_2.0#boards.

    Then upload the following code to the Arduino: https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/Bluetooth/SPP/SPP.ino. After that install the following application on your Android phone: https://play.google.com/store/apps/details?id=es.pymasde.blueterm.

    If you want to control a robot or something like that, then take a look at the Android app for the Balanduino: https://github.com/TKJElectronics/BalanduinoAndroidApp.

  3. ken
    January 10th, 2014 at 09:33 | #3

    Hi,
    PS3BT is too large for my board Atmega328 Duemilanove. Is this normal?
    If I need to buy a bigger size board, can I get Arduino MEGA 2560 R3?
    or it has to be first revision of Arduino MEGA 2560?

    thanks!

  4. January 10th, 2014 at 20:00 | #4

    @ken
    You can overcome this by simply removing some of the code from the example.
    You can start out by removing this: https://github.com/felis/USB_Host_Shield_2.0/blob/c11ca6c434a4482f60feac1df33a37368116dbd1/examples/Bluetooth/PS3BT/PS3BT.ino#L114 and this: https://github.com/felis/USB_Host_Shield_2.0/blob/c11ca6c434a4482f60feac1df33a37368116dbd1/examples/Bluetooth/PS3BT/PS3BT.ino#L128-L179. Then you should be able to compile.

    You can use any Arduino AVR board you like -- they are all supported. You can find more information here: https://github.com/felis/USB_Host_Shield_2.0#boards.

  5. Andy
    January 17th, 2014 at 17:15 | #5

    Firstly, thank you for your work.

    Second, are your libraries compatible and do you offer support for the iTead USB Host Shield? I’ve purchased this board and they direct me to here as they no longer offer support for their board.

    Basically I have downloaded the library and I am having issues connecting the PS3 controller. I’m troubleshooting now but just wanted to first make sure your library is compatible, I’m using the shield with the Arduino UNO R3 board with DIP ATmega328P. Or do I need to mod the iTead USB shield some way. I can provide more information if needed.

    Thank you

  6. January 17th, 2014 at 20:12 | #6

    @Andy
    I don’t support the iTead shield -- you should get help from iTead instead.
    You can take a look at the official schematic: http://www.circuitsathome.com/wp/wp-content/uploads/2011/02/UHS_20.pdf and compare it to the iTead shield: ftp://imall.iteadstudio.com/IM120417019_Arduino_USB_Host_Shield/SCH_IM120417019_ArduinoUSBHostShield.pdf.
    I just had a quick look and it looks like it will work without modifications.

  7. Michael Jacobsen
    March 28th, 2014 at 08:15 | #7

    Hi, Great Work!

    On a PC with CentOS and the ‘bluez’ libraries installed, I have a program that can ping Bluetooth addresses:

    static void ping(char *svr)
    {
    struct sigaction sa;
    struct sockaddr_l2 addr;
    socklen_t optlen;
    unsigned char *buf;
    char str[18];
    int i, sk, lost;
    uint8_t id;

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = stat;
    sigaction(SIGINT, &sa, NULL);

    buf = malloc(L2CAP_CMD_HDR_SIZE + size);
    if (!buf) {
    perror(“Can’t allocate buffer”);
    exit(1);
    }

    /* Create socket */
    sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
    if (sk < 0) {
    perror("Can't create socket");
    free(buf);
    exit(1);
    }

    /* Bind to local address */
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = AF_BLUETOOTH;
    bacpy(&addr.l2_bdaddr, &bdaddr);

    if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    perror("Can't bind socket");
    close(sk);
    free(buf);
    exit(1);
    }

    /* Connect to remote device */
    memset(&addr, 0, sizeof(addr));
    addr.l2_family = AF_BLUETOOTH;
    str2ba(svr, &addr.l2_bdaddr);

    if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    perror("Can't connect");
    close(sk);
    free(buf);
    exit(1);
    }

    /* Get local address */
    memset(&addr, 0, sizeof(addr));
    optlen = sizeof(addr);

    if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) {
    perror("Can't get local address");
    close(sk);
    free(buf);
    exit(1);
    }

    ba2str(&addr.l2_bdaddr, str);
    printf("Ping: %s from %s (data size %d) …\n", svr, str, size);

    /* Initialize buffer */
    for (i = 0; i 0) {
    struct timeval tv_send, tv_recv, tv_diff;
    l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf;

    /* Build command header */
    cmd->ident = id;
    cmd->len = htobs(size);

    if (reverse)
    cmd->code = L2CAP_ECHO_RSP;
    else
    cmd->code = L2CAP_ECHO_REQ;

    gettimeofday(&tv_send, NULL);

    /* Send Echo Command */
    if (send(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) {
    perror("Send failed");
    exit(1);
    }

    /* Wait for Echo Response */
    lost = 0;
    while (1) {
    struct pollfd pf[1];
    int err;

    pf[0].fd = sk;
    pf[0].events = POLLIN;

    if ((err = poll(pf, 1, timeout * 1000)) < 0) {
    perror("Poll failed");
    exit(1);
    }

    if (!err) {
    lost = 1;
    break;
    }

    if ((err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0)) len = btohs(cmd->len);

    /* Check for our id */
    if (cmd->ident != id)
    continue;

    /* Check type */
    if (!reverse && cmd->code == L2CAP_ECHO_RSP)
    break;

    if (cmd->code == L2CAP_COMMAND_REJ) {
    printf(“Peer doesn’t support Echo packets\n”);
    exit(1);
    }

    }
    sent_pkt++;

    if (!lost) {
    recv_pkt++;

    gettimeofday(&tv_recv, NULL);
    timersub(&tv_recv, &tv_send, &tv_diff);

    printf(“%d bytes from %s id %d time %.2fms\n”, cmd->len, svr, id -- ident, tv2fl(tv_diff));

    if (delay)
    sleep(delay);
    } else {
    printf(“no response from %s: id %d\n”, svr, id -- ident);
    }

    if (++id > 254)
    id = ident;
    }
    stat(0);
    }

    Do you think L2CAP_ECHO_REQ, L2CAP_ECHO_RSP, L2CAP_COMMAND_REJ can be implemented in the BTD library?

    /michael

  8. March 29th, 2014 at 12:28 | #8

    @Michael Jacobsen
    Why exactly do you want this capability? I might add it in the future, but to be honest it has very low priority.

  9. Bocar Ndiaye
    March 29th, 2014 at 12:40 | #9

    Hi.
    my aruino leonardo is already HID, how can I use leonardo keyboard and mouse sample code with a bleutooth dongle and usb hostshield and the bleutooth connection part of your code.
    thanks for any pointer.
    Bocar

  10. March 29th, 2014 at 13:09 | #10

    @Bocar Ndiaye
    You need the USB Host shield in order to use this code: http://shop.tkjelectronics.dk/product_info.php?products_id=43.

    Sorry but I think you misunderstood this blog post. This blog post is about how you can connect a Bluetooth HID device to your Arduino.

  11. Bocar Ndiaye
    March 29th, 2014 at 13:38 | #11

    Got it now. Thanks for the clarification.
    Bocar

  12. Michael Jacobsen
    March 31st, 2014 at 08:11 | #12

    A simple presence detector -- I already use it (on the PC) to detect if any of our phones are present. If none are present, I turn off all light…

    For the Arduino, I would like to move this functionality out to the drive-way so I can turn on lights out there if it’s dark and one of our phones are detected (by constantly ping’ing them).

    /michael

    @Lauszus

  13. March 31st, 2014 at 09:20 | #13

    @Michael Jacobsen
    Okay. You need to use the following command: https://github.com/felis/USB_Host_Shield_2.0/blob/b3b476af331e17f94ba6203eefd00869720a7478/BTD.cpp#L1020-L1032 and then check if it sees a device here: https://github.com/felis/USB_Host_Shield_2.0/blob/b3b476af331e17f94ba6203eefd00869720a7478/BTD.cpp#L430.

    You can just check if the number of responses it above zero, as you properly don’t care what type of device it is?

  14. Michael Jacobsen
    April 2nd, 2014 at 07:43 | #14

    @Lauszus
    Great! Thanks, I’ll give it a go. And yes, I don’t care about device type … :-)

    /michael

  15. NicoHood
    April 27th, 2014 at 13:38 | #15

    Hi!
    I think i finally found what i was searching for. You are my man. Ive got a few questions, it would be nice if you could answer me :)

    My goal was to connect my Wiiremote or Wiiu Pro Controller to my Arduino. I searched through alsmost every page that still exists (a lot of information got deleted). So well, we all know that youve got a solution with the shield, i will come to that later.

    I bought a HC-05 Bluetooth master. Not sure if you know this one. It can communicate as slave and as master with devices. I got it connected to my pc as a com port and also to my old k610 phone. But i wanted to connect it to my wiiremote (the old one). I got a respond from the remote with the address and the name. But pairing or linking didnt work. I am nor sure if i am doing something wrong or if the device just doesnt support HID usage. As far as i read i need to connect my remote to my arduino as hid. A question to that: is there a special master or slave role for hids? I found some other devices: the WT12 and the RN-42. Can you tell me if i can use them? I wanted to built something without usb if possible. I just have no idea how to connect them together. the actual communication with getting the buttons will be less complicated (i hope. at least the connection is there). If you have some information about that it would be nice to share it with me. Maybe i am just searching for the wrong keywords and you might know what page i could look up for good bluetooth information. If you can tell me how to link with the remote that would be nice.

    Well you might have no idea about the devices i want to use and cant help me with that. But you probably can help me with the usb host shield. If its the only solution (at least the only working solution i found yet) i will go this way. Ive got a arduino uno, mega, pro mini and pro micros. As far as i read the shield uses spi and two other pins of choice, is that right?

    I am wondering: Is there any difference between this shield (linked here) and the cheaper once from aliexpress? Will they also work? I would like to support the developers of that library if everything works fine too, but i am not sure if you have any profit from buying the original shield. Not sure if its worth spending that much money on the original shield, also because of shipping. I would rather buy it somewhere else and donate money here. So what is the different between the other shields?

    I also read that the mega adk is supported. I am not sure if its worth it to buy a mega adk just for this. It just isnt that fat with the shield, but its very expensive. Can I connect my Pro Controller there the same way, right? How slow/fast is the usb shield? Do i have time for other complex operations? Because a mega with a lot of ram but slow processor is no solution, then I would just connect more arduinos via uart or i2c.

    And one last question: Do you know if its possible to switch roles? Like emulating a pro controller and send information to the wii/wiiu and controll my games like that?
    Thanks for any help 
    Nico

  16. April 27th, 2014 at 16:02 | #16

    @NicoHood
    No you can not use the HC-05 Bluetooth module, as it doesn’t support Bluetooth HID. You will have to use the USB Host library.

    As far as i read the shield uses spi and two other pins of choice, is that right?

    Yes that is correct. It uses SCK, MISO, MOSI, SS and a pins for INT.

    I am wondering: Is there any difference between this shield (linked here) and the cheaper once from aliexpress? Will they also work? I would like to support the developers of that library if everything works fine too, but i am not sure if you have any profit from buying the original shield. Not sure if its worth spending that much money on the original shield, also because of shipping. I would rather buy it somewhere else and donate money here. So what is the different between the other shields?

    If you want to support me, then please buy it our shop: http://shop.tkjelectronics.dk/product_info.php?products_id=43, the cheap shield are just a copy of the official shield and often there a several flaws with them.

    I also read that the mega adk is supported. I am not sure if its worth it to buy a mega adk just for this. It just isnt that fat with the shield, but its very expensive. Can I connect my Pro Controller there the same way, right? How slow/fast is the usb shield? Do i have time for other complex operations? Because a mega with a lot of ram but slow processor is no solution, then I would just connect more arduinos via uart or i2c.

    If you write your code properly, then you can still do a lot of complex tasks.
    For instance the Balanduino uses the USB Host library, but still keeps standing upright.

    And one last question: Do you know if its possible to switch roles? Like emulating a pro controller and send information to the wii/wiiu and controll my games like that?

    Yes it’s possible, but no something I have implemented, so you will have to write the code yourself.

  17. NicoHood
    April 28th, 2014 at 12:46 | #17

    Thanks for your reply :)

    I just downloaded the Library and compiled the WiiuPro sketch. around 30kb is a lot, for only the basic usage. Is there a way to short this down? The library seems very komplex to me, i have no idea how hard it would be to implement my own solution. Because 30kb means for me i only can use the mega for usb projects, because i want to built other stuff around in my sketch. The goal is to get it working as a usb joystick on my pc, but then i have to get it under 28kb on a leonardo, and then that is everything i can do with that leonardo, no other functions. I made the expirience with the ir library that writing my own takes less flash, ram and is more relyable because i only support one device. In my case a wiiu pro controler. So is there stuff in the library that i could possibly short/reprogram and how hard is that to write the usb control?

    Lets say i want to read the controller every so often to use it as a pc controller. Then i have to send the information via Serial to another arduino that supports HID keyboards (leonardo) because 30kb is too much for a leonardo. But how fast is the access for a single bluetooth commant to get the new button states? Can i built a lot of stuff around or does the usb controll take a lot of time. Any benchmark for this?

    Is the mini version arduino pro micro compatibel? Because if its pro micro compatible and i can get the sketch under 28kb i would use the mini version. if the usb control is that processor expensive then i would also use a mini with a nano because i cant do anything else and a 328 is enough. But if there is no way to get it working under 28kb and the prcessor load is not that big i will use it with a mega. or probably buy an adk but i think the shield would be the better choose.

    You said its not possible to emulate a wiiremote, but is it possible to emulate normal keyboards and receive the pro controller at the same time? then i could built a bridge between my pc that converts the signals to a normal bluetooth controller.

    Thanks :)

  18. April 28th, 2014 at 14:53 | #18

    @NicoHood
    I know that the Arduino team is working on updating the AVR-GCC toolchain. It should be updated from Arduino 1.5.6.

    For now you can download it from one of the following links depending on your OS:
    http://downloads.arduino.cc/arduino-avr-toolchain-nightly-gcc-4.8.1-windows.zip
    http://downloads.arduino.cc/arduino-avr-toolchain-nightly-gcc-4.8.1-macosx.zip
    http://downloads.arduino.cc/arduino-avr-toolchain-nightly-gcc-4.8.1-linux32.tgz
    http://downloads.arduino.cc/arduino-avr-toolchain-nightly-gcc-4.8.1-linux64.tgz

    I just tried to compile the “WiiUProController” example for the Uno and the flash was reduced from 29,308 bytes to 26,270 bytes.

    You could reduce the code size removing all the content from: https://github.com/felis/USB_Host_Shield_2.0/blob/master/Wii.cpp that is related to the Wiimote and Nunchuck.

    Yes you could also use the Pro Mini 3.3V 8MHz version together with the mini version of the shield -- you could update the bootloader on the Pro Mini, so it only takes up 512 bytes instead of 2048 bytes.
    Then you should be able to get everything to fit on the Pro Mini if you use the updated toolchain.
    Yes the mini version of the shield is not pro micro compatible, but you will need to add your own logic level shifters.

    Have you thought about using a Sanguino: http://sanguino.cc/? I have written a hardware plugin for it as well: https://github.com/Lauszus/Sanguino since the Balanduino uses the same microcontroller.

    The update rate for the controller is approximately 1ms (1kHz) if you write your code efficient.

    You said its not possible to emulate a wiiremote, but is it possible to emulate normal keyboards and receive the pro controller at the same time? then i could built a bridge between my pc that converts the signals to a normal bluetooth controller.

    I never said that it wasn’t possible (everything is possible :) ), but it’s not something I will work on.
    Yes you should be able to both read the Wii U Pro controller and send keyboard events.

  19. NicoHood
    April 28th, 2014 at 17:12 | #19

    I need to get this working with my arduino pro micro/leonardo, this would be so awesome. I tried to compile it with the linked version and if i remove the Serial output i can get 28.620/28.672 kb (on a leonardo). Not much space to work with. I am wondering how you can blow up such a big library. I am not sure if removing stuff from the cpp would help that much because the compiler only compiles thes needed files. and the new version is even more clever it seems. I havent programmed the whole thing and havent looked through the code in detail. But maybe there are possibles to improve the code is this this usb thing just that complex?

    Oh and by the way: sparkfun sells pro micros with 3.3v and it seems that this would work then. its just expensive as hell and the sketch limit is reached very fast. If i have to use a mega and send the information to the pro micro which acts as usb keyboard then i could rather just try it with my raspberry.

    Where exactly did you get the latest arduino ide? The one i downloaded from the website (nightly) totally failed and compiled the sketch with 32kb.

  20. April 28th, 2014 at 21:10 | #20

    @NicoHood
    The only place where you can easily remove some code is in Wii.cpp! Simply remove all the code related to the Wiimote and Nunchuck as I told you in my previous comment.
    Due to the way the library is written the library doesn’t know which one is going to connect. This allows you to use the same library for all the Wii controllers.
    It might be better to split them up at some point, but I haven’t got time for that at the moment.

    Yes the USB and Bluetooth protocols are quite complex, so it’s not that easy to shrink it down.

    Have you considered using the one of the Teensy boards? They are all supported by the library and they can be used as a Keyboard as well -- or even a Joystick, Mouse, MIDI, External disk and flight simulator!

    It sounds very odd that it was that large!
    I just tried to compile the entire “WiiUProController” example for the Leonardo and that ended up at 28,898 bytes.
    Are you familiar with Git and have you ever compiled the Arduino IDE before?

  21. NicoHood
    April 28th, 2014 at 22:29 | #21

    as i said: i removed all serial functions and i think i added just a led functions instead. without any modification i get the same size. but thats too much for the leonardo.

    Splitting them seems a nice idea, but if you dont have time, i will have to do it on my own, no problem ;)

    using the teensy is a very nice idea. have to think about that. If i want to use it with a 5v arduino, do i have to use special logic level shifters or can i use simple resistors for all pins?

    Have you tried bluetooth with 3.3v, because it sais there can be problems for some devices?

    i used git to upload my own libraries but only for windows straight forward. and no i never compiled the ide before, because i never needed to do that. just asking where you got that link from so i can check out new updates too.

    Thanks so much for all your help and sorry for that many questions :S

  22. May 3rd, 2014 at 13:25 | #22

    @NicoHood
    Normally you would use mosfets for logic level conversion or even better you a dedicated IC, as there is on the 5V version of the shield. Take a look at the schematic: http://www.circuitsathome.com/wp/wp-content/uploads/2011/02/UHS_20.pdf.

    Yes I have. Some of the dongles I have works fine when VBUS is only 3.3V others doesn’t.

    If you are interrested in the development of the Arduino IDE then you should join the mailing list: https://groups.google.com/a/arduino.cc/forum/?fromgroups#!forum/developers, but please don’t ask any questions about Arduino, as it’s intended for development of the IDE!

    It would also be a good idea to “Watch” the Github repository: https://github.com/arduino/Arduino.

  23. September 5th, 2014 at 07:49 | #23

    Hey! I know this is kinda off topic but I was wondering
    which blog platform are you using for this site? I’m getting fed up of WordPress because I’ve had problems with hackers and I’m looking at options for another platform.
    I would be great if you could point me in the direction of a good platform.

  24. September 8th, 2014 at 06:20 | #24

    @cabinets
    We use WordPress as well with the plugin “Akismet” which catches most spammers!

  1. No trackbacks yet.