USB HID Support on Pico!

Posted on
of 4
/ 4
Last Next
  • What type of HID device are you having problems with?

    My understanding is that something like Windows will load drivers for one reported interface even if it doesn't know anything about the other one. It's definitely been the case with other products (like the Nucleo boards, where even without drivers you still get the mass storage interface).

    But you're saying that even if you install the ST drivers that'll handle the virtual COM port, the second you enable HID as well, VCP stops working too?

    It could potentially be some issue with Espruino's Device Qualifier. At the moment it seems to do the totally standard thing of saying 'each interface defines what it is', but I guess it's possible that for no-driver operation it should instead be saying 'I'm a mouse'.

    It's a hard one - if you can find out what needs changing I can have a go at implementing it, but I have a lot of work on at the moment so I can't spend days implementing stuff just because it might save you a bit of time.

    You can always compile your own version of the NEW_USB branch - instructions are on GitHub. Once you're doing that you can tweak the device descriptors just by changing this file - to the point where you could even pull out the USB CDC interface.

  • Hm, well, same problem here. USB is just too much to do in between other work.
    But thanks for the links, that might save some time at some point.

    so I can't spend days implementing stuff just because it might save you a bit of time.

    Well's it's a forum, so it's just my need posted. If that's something others are interested,too... the attractiveness of a tool is always measured by the amount of time and energy it saves. If it's just mine, you're right, of course.

  • Hi Gordon, i did try to get this HID example up and running but it does not work for me.
    I can toggle the LED if i press the button but the mouse cursor does not move.

    var mouse = require("USBMouse");
    function toggle() {
      on = !on;
      digitalWrite(LED1, on);
    setWatch(function() {
      mouse.send(20, 20, mouse.BUTTONS.NONE);
    }, BTN, {debounce:100, repeat:true, edge:"rising"});

    Maybe i am missing something here? Should the pico show up as a mouse device in my system USB device tree?

    ioreg -p IOUSB -w0 | sed 's/[^o]*o //; s/@.*$//' | grep -v '^Root.*'

    The only relevant device i can find with this call is the STM32 Virtual ComPort.
    I am using OS X 10.10.4 and Espruino 1v80

  • You'd have to send the code, save() it, then unplug and re-plug - did you do that?

    Espruino can only add new USB devices when it connects to USB - but after it's done that then you can dynamically change the code as usual.

    (It also works without save() if you just keep Espruino powered with something like a battery)

    I finally merged the USB code into the master branch, so for an up to date build you can just use one of the latest builds, like this one. The build you have should still work though.

  • Yes i did uploaded the code, called save() and re-pluged it. It did not work. I tried several times. Today i restarted my Mac with the still connected pico and suddenly it worked. Exactly 3 times. After that the pico did not respond anymore. (No LED on|off toggle) After opening the WEB-IDE i did get this message.

    >Loading from flash...
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
    WARNING: Expecting a number or something iterable, got undefined
  • OK. I did some more test. My Mac recognises the pico HID mouse only at reboot. If i re-plug the pico the magic is gone.

  • And you're using the updated firmware from my last post, and the code that you posted above?

    Because I tried that just now and it works great. Just booted a mac up and it works on that too.

  • @gordon: Good news. I updated / downgraded ? my pico from 1v80 to 1v79.210 and it seems to work very well now. Thanks a lot. Great work.

    @all: Is somebody already working on a USBMidi module?

  • @loopMasta upgraded :) I changed the version numbering so 1vXX is a main release (or an old one!) and 1vXX.YY is Y git commits after the release of version 1vXX

    I'm not personally doing USB Midi right now, but if you can find the magic USB descriptor for it, it should be pretty easy to get working.

  • Actually just took a quick look at this, and it seems that USB MIDI isn't a HID device after all (at least looking at this code), which means a report descriptor may not be enough.

    If that's the case I'm afraid you might be out of luck - it'd require changes to Espruino to let you specify the whole config descriptor. I hadn't done that because it's actually very device specific (setting endpoints and suchlike) and it also contains stuff to do with the USB com port as well.

  • Oh no. I really wanted to replace my HiDuino based project with the pico. It would have been so much more fun with all its javascript goodness. :-)

  • You might know more about this than me then - is MIDI actually a HID device? It looks a lot like it's a special (non-HID) device type.

    While actually letting people specify custom descriptors isn't that difficult, I think realistically it's not going to be very useful. I think you'd need far more than a passing knowledge of USB to do anything with it...

  • Your question 'is MIDI actually a HID device' took me by surprise. I searched the web for more information to make sure that i use the proper terminology (Midi , USBMidi, HIDMidi, Midi over USB, etc.) and among others i found this interesting post by Paul Stoffregen.­?f=51&t=51683&p=262051#p262017

  • Hmm, interesting... So I'd actually have to provide a way to change the endpoint type as well. I'm afraid that's probably not going to get done any time soon.

    However I can point you at the bits you'd have to change in the firmware to compile you own version. That itself isn't too hard - it's the making it available from JS that takes the time :)

  • OK. I'll try that. It's better than complaining all the time. :-) Where should i start?

  • Ok, try looking on GitHub and getting a version of Espruino compiled and running on your board. Actually using a Linux PC or VM is probably the easiest way to build right now.

    Then, have a look at usbd_cdc_hid.c and usb_desc.c.

    You should be able to tweak the descriptors in those to report back that it's a MIDI device. Finally I think you need to change the endpoint type to BULK here.

    Hopefully you can specify in the descriptor that it's an audio device with just the IN endpoint. Actually trying to do the other endpoints could be a pain as it seems like pot luck trying to update the USB buffer sizes such that you can get enough working endpoints for USB CDC and something else.

  • @Gordon I'm having mixed success with the HID code here, using your simple Keyboard Hello World with the firmware from 15th July.

    It doesn't work at all on Windows 8.1 64-bit. I never see any characters appear. Tried a variety of hubs and directly plugged in.

    On OSX, it acted very strangely with context menus popping up randomly, until I removed the setModifiers calls. Now it works every few button presses but also sends the last character repeatedly on many attempts.

    However I'm thrilled to get some code running which turns the Pico into a OTP Fob and successfully generates the same codes as Google Authenticator for one of my logins. If the USB HID code worked every time, then the Pico would be as good as a YubiKey :-)

  • Hi @conor,

    Thanks for checking it out! Can you try this build? I made some changes for @Stev that seem to have fixed the mouse issue on Mac.

    I guess it might also help on Windows.

    At the moment, if you send commands too quickly they can get lost (why there are lots of timeouts in the USBKeyboard module). I really need to add a better way to handle that (with callbacks I guess), but if the HID command gets lost then the PC might think the key is held down, and will auto-repeat.

    Maybe you could post your code? If you're sending commands one after the other (without using the callback function), that could be causing you problems.

  • Thanks Gordon.

    No behaviour change on that latest firmware.

    I'll see if I have any ST drivers installed and will uninstall.

    On MBP, it works fine the first time but repeats last character the second time and I have to pull the Pico to stop it.

    Code here:­a68d073f80f

  • Ok, interesting - so by last character you don't mean Enter, but actually the last character of the password?

  • yep, exactly that.

  • Actually I just found the problem - it was with the USBKeyboard module, not USB HID itself.

    If you try uploading your code again now it should probably work fine.

  • Still no joy on Windows (not even appearing as a COM Port).

    OSX now failing too "USBF: The IOUSBFamily was not able to enumerate a device"

  • What changed between times?

    If you were using the firmware I posted above both times, it shouldn't have affected the way Espruino enumerates (just what happens when you press the button).

  • Changed nothing on my side. I suspect sometimes save() makes things go a bit screwy and I have to reflash the Pico to get it recognised again by Windows. Just happened twice in succession.

    Hmm, updated to Chrome 44 in between things working and not working. I'll try flashing on MBP now.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

USB HID Support on Pico!

Posted by Avatar for Gordon @Gordon