Creating a USB Device (or is Serial Better?)

Hi Everyone!

First off, I hope everyone here has been doing well.

I’ve thought of an idea that would be a lot of fun to work on, but it’s a little out of my depth as it includes communicating over Serial or USB. I thought that USB would be fun, but that’s opening a whole world of things I’m not sure where to start with.

The idea was to create an LED board that is computer controlled. Either via USB/Serial and a terminal program (with a gui later) or directly via the ARGB headers my computer has (ideally both?). From my understanding ARGB headers are just the neopixel protocol, so that part is easily taken care of.

But I’m stuck on the communication side and I’m not sure how I should best go about starting this. I was targeting Atmel chips, both because I can start with Arduino and ideally move to a normal chip later. Also, I already have an AVR programmer.

Does anyone have experience with V-USB or USB directly via hardware? Or is Serial the better way of going? Lastly, tutorials??? Which ones are good for someone who has fairly limited experience with programming, but kinda understands how it works. Mostly my issue is understanding how to set up the build environments.

Thanks!

The USB stack is a complex beast. Google “USB in a Nutshell” and you’ll see what I mean.

Most times I’ve ever implemented USB, I’ve started from a vendor example, and modified very lightly to suit my purposes. (At the lower levels/guts of the implementation, I haven’t modified it at all. There be dragons.)

Virtual Com Port or Communications Device Class are the Serial-over-USB protocols you’re referring to, for additional googling. :slight_smile:

Native USB is nice to reduce production costs (no need for a USB to serial chip) and for better throughput (no UART bottleneck). USB is a 12Mbps checksum’d protocol so it ensures integrity and delivery of packets.

Without the above constraints, it will be easier to just use a USB to serial chip that handles the complexity for you.

a lot of the serial usb implementations don’t have or implement handshaking so it comes down to software, so if you’re streaming a lot of data back and forth and it can get swamped consider that.

also USB HID is quite straightforward and you get a few more benefits of USB, and there are a lot of examples of it.

alternatively again if you use libusb then the usb comms is pretty straightforward and all you have to do is implement endpoints. https://github.com/libusb/libusb/tree/master/examples

@nrc.reilly yeah, that’s what made me want to make a post here. I was doing some reading up on USB and I just felt the eyes glossing over and was wondering if it was worth pushing through or if I should abandon the attempt for something more sensible.

And since my goal isn’t a keyboard or other HID, I’m sure I’d be into the realm of writing some of my own drivers and honestly that sounds way out of the scope of what is feasible for me.

What’s a good USB to Serial chip then? From my understanding, there’s basically only FTDI and the CH341. Or is there something better to use.

@tyler I was initially thinking of using the Atmega16u2 for this reason, but when looking at how the USB software stack looks, it sounds complex for me.
So this is where I’m not sure how to proceed. Since I’m not sure what’s involved in USB direct or USB to serial in terms of the software stack.

@charliex Humm. You certainly aren’t selling USB haha. Which is fine. it’s a learning experience, but I don’t want to spend all my time writing software. I’ll give libusb a read though!

Nothin’ wrong with FTDI! They’ve always worked great for me.

FWIW - I always think it’s nicer using non-USB-serial to avoid the driver install issue. If you’re talking to somewhere where serial makes sense (console, etc) it’s good.

But if you are shoveling data back & forth IMO it’s easier to do this with a USB micro I think… although it does normally mean you’re using a non-arduino device & IDE to do it.

I had some old demos & project examples at https://colinoflynn.com/2015/06/esc-sv-2015-usssssb-talking-usb-from-python/ if helpful along those lines.

HID isn’t just for keyboards/input devices you can use it for a lot of different things. i have a mini one button keyboard that uses hid for the keyboard but also for the rgb leds, also for the macro programming i use that to send the macro sequence to the keyboard.

it is handy like cdc usb since the os is more or less built in drivers

for libusb once you’ve added endpoints on the atmel side its really just a init/open/send/recv/close setup.

CDC serial is definitely the easiest to deal with, but does have limitations, it is possible to add hardware flow control with chips like FTDI, ive also had issues with high rates of streaming over a long time on CDC serial, usually driver related, and on some OSs reconnect is a pita if the IF is lost.

CP2101 by Silicon Labs is another one.

If the project is a one-off, you can also use a Raspberry Pi Zero as a USB device, with suitable configuration. Not associated with OLPC, but part of the ecosystem, we have a repair specialist who figured out how to add a Zero and attach as a network device so they could run the Chrome browser in a co-processor arrangement.

In addition to the FTDI FT232 family and the Nanjing Qinheng Micro CH340 family, ST has their CP2102 family.

The easiest path is probably to take a look at existing dev board designs that use these chips and just copy-and-paste their designs.

I know that the FTDI has the VCP driver which most people use to get a virtual serial port connection. If you attach an EEPROM to the FTDI chip, you can store custom configurations which includes the ability to use the chip in alternate modes of operation with the D2XX and D3XX drivers for bit-banging and emulating a parallel MCU address/data bus interface. I actually used that on a product where there was actually not a MCU on the other end – just a bunch of I/O’s.

Okay, wow, there’s a lot here. And first off thank you everyone for your input. It’s really helpful. But I’m feeling a little overwhelmed by all of the talk and different options. Let’s see if I can sum this up and ask a more directed question. But first, more about the intended use.

The idea was to make a small little ARGB LED PCB, something like 20-30 LEDs, in two or three groups to light up a 120mm fan from the outer edge. Most of the time it will be playing one color or maybe doing some form of breathing effect for lack of a better term for it. The intent for ARGB control via a computer (either USB or Serial was just to add a bit of complexity and programming to the project to help me learn some more. I’m not a programming wiz, so I figured a simple terminal program would be a good place to start. But I would likely set one pattern, which would be saved to the microcontroller and leave it alone. So not much traffic is needed in either direction. It’s also just a personal project. In terms of variables, I was thinking a couple of RGB values and a timer for how long the light should be on before moving to the next value.

I’ve never really looked into how communication with a microcontroller works for either USB or Serial. I know that COM ports exist and with the serial monitors in VS code/arduino, you can communicate with them and change settings that way.

So with that in mind. For Serial, I would need to implement something like this on the board and send the output of the FTDI (or other Serial chip) to the Atmel chip of my choice. I will have to do more digging on dev boards which provide this functionality. The software stack here is easier and drivers wouldn’t need to be written to handle any communication at all. In terms of Serial converter chips, there’s FTDI, CH340 Family, and CP2102 Family. And technically, the Serial could be done off board and just left to a programmer if I wanted. But that’s an option I have at that point.

For USB, I would need to get a USB chip (if I’m not using something that provides USB in hardware like the Atmega16u2) and I would have to contend with the USB software stack and overhead required to keep it working. If I use libusb, it sounds like some of that is abstracted away though and I’m left with an easier time, but I’m guessing I would still need to write drivers to be able to communicate to the unit via USB as I’m asking it to do a fairly limited thing??? I understand that HID is a deep category, but no buttons were planned for the unit, as it was just a static art piece mostly.

Is this a fair summation so far?

At this point, I’m much more inclined to go with serial as USB seems like a headache and a half. Maybe if I was going with a microprocessor it would make a bit more sense.

Yes, that’s fair. You’re asking a diverse group of people, so you will get responses that lean towards the tools each of us use.

Given the tools I’m familiar with, what you describe as your idea would happen in my lab like this;

  • grab an Arduino (atmega328), Teensy, or esp8266 board from my pile with a USB to serial chip already included,
  • wire up a few LEDs, APA102 or WS2812 depending on availability or how dim I wanted them to be,
  • using PlatformIO or something, write some C code for the microcontroller to read serial input and send the data to the LEDs,
  • on the computer, write some Python using the import serial module, to detect and open the serial device, and send sequences of animation,
  • capture the schematic,
  • design a PCB to hold roughly the same parts,
  • wait,
  • build, and test,
  • get bored and do something else. :grin:

TOO REAL! hahahhaha

But yes, what your described sounds like a good way to go about it really. And certainly the level of complexity I was thinking about for this part at least. I just needed to ask about the USB side of it since it seemed like something that -could- be interesting and fun to do. That being said, yeah it uhh, might be outside of what I’m really comfortable working on.

I enjoy that there is a large group of people. It provides context and ideas outside of what I would think of!

yep understanding what your needs and the problem is goes a long way to good recommendations.

usb serial is probably the best bet for you, since its easy to open and stream to it. i have some XMAS lights i made that use an ESP8266 and a PSOC4 that i just stream a buffer to them to display the results on a chain of LEDs, its wifi based since ESP but all it does is basically listen for the buffer and streams it out to the PSOC over the serial connection.

libusb is the driver, it abstracts all the hard parts away and you interface to it, so you write user mode code.

To clarify, in this context of USB serial, you mean a USB to serial chip like FTDI, etc, correct?

So then with libusb, that sounds pretty nice. is there a good (i.e. dumb) guide that I could read to see how to use it? I had a quick look, but man, my programming skills are baaaaaaaaaaaaaad.

Sounds like a fun project though!

USB-to-serial interfaces are great because you don’t even have to bother with libusb. They just look like serial terminal interfaces – just open up the port as a character device. Plenty of examples out there on how to talk to the serial port!

Yeah I’m leaning towards USB-to-serial for sure. I think it will make my life a little easier. And there are tons of examples! Sounds like a good idea.