# USB: what are the advantages (or disadvantages) or using HID over serial-over-USB?

Disclaimer: I'm a novice at electronics and even more so to working with USB, please bear with me if I misunderstand some of the essentials behind how USB works. Any correction welcome!

The scenario: with a group of friends we are building a robotic sailing boat. We are managing all the on-board sensors through a µC (AVR) but the sailing AI is done on an embedded linux system. The electronics is connected to the the AI hardware via USB, and I am looking for advice on what protocol to use for the transmission.

We already tried both the serial-over-USB and using HID, and both worked good enough™ in our short, near-coast tests but before settling for one or the other, I'd like to know if there is some non-trivial but nevertheless important differences between the two that I missed to consider. For our project the most important characteristics are:

• Reliability: our robot is due to sail autonomously for a few days. Is either of the two protocol inherently "safer" / with better error handling / self-recovery functionality?
• Throughput: although in normal operating situations our throughput could well be under 1Kb/s, under certain conditions we will need to harvest data nearly real-time. Serial is limited to 115Kb/s, does HID have a speed limit other than the 1500Kb/s of the USB 1.0 protocol?

...but as I said: I'm pretty new to electronics/USB, so if you feel I am missing a key parameter, I'll be glad to hear.

To determine what solution will be best for throughput, you need to find the bottleneck and improve that until it's no longer the bottleneck until you can't remove anything anymore.

1. Your AVR has a fixed maximum frequency, aim to make its (optimized) processing routines the limiting factor. If your communications protocol can handle this speed, then there's nothing more you can do.
2. USB at 1.5Mbps represents moving 1 byte every 160 clocks. That's quite a lot of time. to do processing, and if you're triple-buffering your data or sending out full blocks you'll want this to be even faster. At 12 Mbps, you get 13 clock cycles per byte, which is much more difficult to achieve, and would be a reasonable goal.
3. The interface between USB (and even USB itself) will carry some overhead. Sending ASCII data over an asynchronous serial interface is a big overhead. A parallel FIFO USB interface chip will be much faster. A micro with built-in USB peripheral will be better yet.

To get more reliability, you need to stick with what works and what you know best. Relax the specs. Here, a tried-and-true serial interface is a fine choice.

How does "serial over USB" work in your application?

If it's a software driver on the embedded Linux device, and a USB <-> parallel IC (or software serial port on a USB-enabled AVR, which sounds likely since you've tried HID mode), then you'll have no problems with higher bit rates.

However, true USB <-> serial ICs do exist and are popular (the FTDI232R on older Arduinos comes to mind...) which turn USB into logic-level serial RS232 communication. You don't need or want this layer for your application. It will reduce your throughput and add an additional asynchronous delay section into your application.

I did a project that required a USB interface (using PIC micro) a couple of years ago, I looked at both but HID is superior I feel:

HID has automatic detection and buffering of packets by windoze as opposed to keep having to 'reconnect' the serial port on each plug-in (and to a port number that is dependant upon the usb port used each time (LAME)) --programming VB for HID is simples!

Max throughput is lower for HID, i think its 64bytes (max hid buffer size) both ways every 10ms for USB 1.1 or 1ms for USB 2.0.

• Do you know any good instructional examples for vb.net and/or hardware programming of an HID using an ST Micro STM32L151? If I could get a PC-side version working, I might find it easier to figure out what's going on with the ST's demo. – supercat Mar 1 '12 at 19:35
• FYI: If you don't want 'virtual COM port roulette', make sure your CDC device has a serial number descriptor. If the device has a S/N descriptor, Windows assigns a unique com port to that VID-PID-S/N, and you can move it to whichever USB port you like - the VCP will stay the same. If you don't have a S/N descritpor, Windows substitutes in a field representing the physical USB port - this is why the virtual COM port changes when you move the device. – Adam Lawrence Jun 27 '15 at 14:39

1) As for reliability I would prefer lower-level protocols like hardware serial with manual error handling. USB device might just disappear if controller does not like something, and if you won't reinitialize it - you won't see it again. So you need to learn to reinit USB.

2) As for speed - serial-over-USB is not limited to 115Kb/s in general, in bust be seeing limitation in one of our implementations. In general I would expect 'serial-over-USB' to be more efficient than HID, as HID should have more 'decoration' burden. Even faster is 'parralel-over-USB' which is used to pump at speeds close to USB throughput.

It's not the serial profile that's limited to 115200bps - in fact, it's rarely even the serial port nowadays. If you use something like an FT245 you can reach much higher speeds than that. The problem with standard asynchronous (RS-232 style) transfer is that you need to have gaps occasionally to have a chance to synchronise on bytes (or alternatively, send 0xff from time to time).

As for the difference between HID and USB serial, serial is bulk while HID is control and interrupt. That's fundamental for USB, and means HID has (potentially) lower latency but serial has higher capacity. There's not much more to it than that, neither is more reliable, and you'll want a way to reset your circuitry when things go wrong.

... by the way, this sounds familiar. Hi Mac! Pardon my absence from Abbenay yesterday.

• Lol, hi Yann! So it seems the World IS a small place! :) Back onto the question: so the fact that with the serial if I unplug & replug the device I need to manually re-initialise the connection, while with HID I don't is purely a software difference in the libraries I am using (i.e. in the HID case the library does that without me knowing it)? Can you articulate on the 0xFF byte "synchronise on bytes" issues? Thanks! – mac Oct 27 '11 at 9:28
• FF is a trick. Basically a frame on RS232 looks like 0ddddddddp1, where 0 is the start bit and 1 is the stop bit. Sending all data and parity bits high ensures the next start bit is the first 0 for a while, so it can be used to synchronize. As for unplugging the USB device; for the serial port, it disappears, so you need to open the new one instead. For the HID case, you may be listening to the combined input stream? I don't know. Either way, you can use udev to start things when you plug a device in. – Yann Vernier Oct 27 '11 at 16:39
• As you note, any byte which follows an FF will be received correctly, regardless of previous framing errors; depending upon the UART design, the same may also be true of FE, FC, F8, F0, E0, C0, 80, and 00. This can make that set of characters useful for synchronization if the receiving UART will wait for a falling edge on the data line following a framing error (some will; some won't). – supercat Jan 25 '12 at 15:30