The developer's resource for computer interfacing, especially USB, serial (COM) ports, mass storage, and embedded networking. (Formerly

Home > Articles > USB for Projects on a Budget

USB for Projects on a Budget

Jan Axelson

This article originally appeared in Nuts & Volts.

If you have an idea for a device that communicates with PCs, the chances are good that the device will connect to the PC via the Universal Serial Bus (USB). You’re probably well acquainted with USB as the interface used by mice, keyboards, drives, cameras, and other mass-market peripherals. But USB is also versatile enough for use in specialized devices produced in single or small quantities.

Adding a USB interface to a device can seem a daunting task. Every USB device must contain device-controller hardware and must have a software driver in the PC. Many options exist for device controllers and drivers, and the right choices can make a big difference in how quickly you get a project up and running.

This article shows three ways to add USB to devices. Each takes a different approach, but all are suitable for devices built in small quantities and on limited budgets.

USB in Brief

Here are some essential facts for anyone who is designing a device that uses a USB port.

Hosts and Devices

Every USB communication is between a host and a device. A USB host is a PC or another computer that contains USB host-controller hardware and software. The host controls communications on the bus. A USB device contains USB device-controller hardware and program code, often called device firmware. The device responds to communications from the host.

On power up or device attachment, the host computer requests information from the device in a process called enumeration. The device sends a series of data structures called descriptors, which tell the host about the device and its capabilities.

A Windows host compares the contents of the descriptors with the information in the PC’s INF files. The file with the best match tells the host what class driver or device driver to assign to the device. (Other operating systems use similar methods to select a driver.) The driver is software that manages communications between applications and the lower-level drivers that access the USB hardware.

Windows includes drivers for popular device classes, including human-interface devices (mice, keyboards, game controllers), mass storage (drives), audio and video devices, printers, cameras, and more.

Device Controllers

The device controller is hardware that can be embedded in a microcontroller chip or in a separate chip that interfaces to a microcontroller or other CPU. Microcontrollers with embedded USB controllers are available from many sources, including Microchip Technology, Atmel Corporation, Silicon Laboratories, and Cypress Semiconductor. Chips that interface to a microcontroller or CPU are available from Philips Semiconductors, National Semiconductor, and others.

Every USB device must have the intelligence to understand and respond to received requests and other events on the bus. Controller chips vary in how much firmware support they require for handling the low-level USB protocols. Most chip vendors provide example firmware that you can adapt for a specific application.

Transferring Data

For every communication, the host specifies an endpoint address in the device. The endpoint address is typically a buffer or register that holds received data or data waiting to transmit.

USB supports three bus speeds. Low speed can guarantee bandwidth of only 800 bytes/sec. per endpoint address but is useful for some inexpensive devices such as keyboards and mice. Full speed can transfer data to or from an endpoint address at up to 1.2 Megabytes/sec. For devices that need more speed, a high-speed endpoint can transfer data at over 30 Megabytes/sec.

USB uses four transfer types that provide options to fit the needs of any device.

Transfer Type Control Bulk Inter­rupt Isochro­nous
Required by all devices yes no no no
Allowed at low speed yes no yes no
Supports error checking yes yes yes no
Guaranteed transfer rate no no no yes
Guaranteed latency* no no yes yes

latency = maximum time between transfer attempts

Typical uses for each type include enumeration for control transfers, printer and scanner data for bulk transfers, mouse and keyboard data for interrupt transfers, and real-time audio and video for isochronous transfers.

USB Virtual COM Port

For years, every PC came with one or more RS-232 serial ports. Software accesses these ports as numbered COM ports (COM1, COM2, and so on up). But not every COM port has an RS-232 interface. Some devices with USB ports can function as virtual COM ports.

Applications access virtual COM ports in the same way as RS-232 ports. Users can communicate using terminal-emulator software such as Windows Hyperterminal. Programmers can use the SerialPort class in Microsoft’s .NET Framework. The only difference is that the hardware interface is USB instead of RS-232. Lower-level drivers handle the details of accessing the hardware.

Virtual COM ports provide a way to transfer data for just about any purpose. If you’re familiar with COM-port programming or have existing COM-port code you want to re-use, a virtual COM port can be a good choice. The COM-port data travels in USB’s bulk transfers, so transfers are fast on a bus that isn’t busy.

A virtual COM-port device can use a generic USB-capable controller chip or a special-purpose controller designed for use as a virtual COM port.

A popular special-purpose controller is FTDI Chip’s FT232BM USB UART. The chip is a USB/asynchronous serial converter that manages all USB communications in hardware. You don’t have to know anything about USB protocols to use this chip. For experimenting, DLP Design offers DIP adapter modules that each contain a controller chip, USB connector, and related components.

You can interface the USB UART to just about any microcontroller or other CPU that has a UART or USART for asynchronous serial communications (Figure 1). On enumeration, the PC assigns FTDI Chip’s (free) drivers to the chip. The drivers cause the chip to appear as a COM port on the PC. You can set the baud rate and other parameters for the chip’s asynchronous port just as you would for an RS-232 port.

When a PC application writes a byte to the virtual COM port, the USB UART receives the byte at the chip’s USB port and passes the byte to the chip’s asynchronous serial port using the selected port parameters. A microcontroller that connects to the serial port can read the received byte. In the other direction, when the microcontroller writes a byte to its serial port, the USB UART receives the byte as serial data and passes the byte to the PC via USB. COM-port software on the PC can retrieve the received byte.

If you prefer a parallel interface to your microcontroller, FTDI Chip’s FT245BM USB FIFO chip has a bidirectional parallel interface instead of a serial interface. PC applications can access the chip as a COM port and exchange data with the chip’s parallel port. (The baud rate and other serial-port parameters don’t apply.)

Rather than using a special-purpose USB controller and drivers, another option is to use a general-purpose controller and the USB COM-port driver included with Windows. With this approach, the microcontroller and USB controller can reside on the same chip.

Because of performance and other problems with earlier driver editions, it’s best to use the included USB COM-port drivers only with Windows XP Service Pack 2 (SP2) or later Windows editions. Microchip Technology and Atmel Corporation provide complete example firmware for USB COM-port devices that use the built-in Windows drivers.

Generic Human Interface Device

If you want to use drivers included with Windows, another option for USB devices is the Human Interface Device (HID) class. Keyboards, mice, and game controllers are HIDs, but you can also design generic HIDs that transfer data for any purpose.

PC applications communicate with HIDs using Windows API functions such as CreateFile, ReadFile, and WriteFile as well as APIs that are specific to HIDs. The .NET Framework doesn’t provide a HID class, but .NET applications can call API functions. The HIDmaker software from Trace Systems, Inc. can automate much of the task of writing PC software for any HID and writing code for Microchip controllers.

All HID data travels in structures called reports. A report descriptor in the device defines the size and direction of each report. This HID report descriptor defines three 2-byte reports:

0x06 0xFFA0 Usage Page (vendor defined)
0x09 0x01 Usage (vendor defined)

0xA1 0x01 Collection (Application)

The Input report

0x09 0x03 Usage (vendor defined)
0x15 0x00 Logical Minimum (0)
0x26 0x00FF Logical Maximum (255)
0x95 0x02 Report Count (2)
0x75 0x08 Report Size (8 bits)
0x81 0x02 Input (Data, Variable, Absolute)

The Output report

0x09 0x04 Usage (vendor defined)
0x15 0x00 Logical Minimum (0)
0x26 0x00FF Logical Maximum (255)
0x75 0x08 Report Size (8 bits)
0x95 0x02 Report Count (2)
0x91 0x02 Output (Data, Variable, Absolute)

The Feature report

0x09 0x05 Usage (vendor defined)
0x15 0x00 Logical Minimum (0)
0x26 0x00FF Logical Maximum (255)
0x75 0x08 Report Size (8 bits)
0x95 0x02 Report Count (2)
0xB1 0x02 Feature (Data, Variable, Absolute)

0xC0 End Collection

An Input report travels from the device to the PC. An Output report travels from the PC to the device. A Feature report can travel in either direction. The reports can contain data for any purpose.

HIDs use USB’s control and interrupt transfers. The maximum guaranteed bandwidth using the Windows drivers is 64 kilobytes/sec. per endpoint. Even at high speed, the default interface should request no more than 64 kilobytes/sec., and supporting an alternate interface would require a custom driver.

Many device manufacturers provide HID examples. A mouse or keyboard example can provide a good head start for creating a generic HID.

Using a Generic Driver

A third option that can be useful for any specialized device is using a generic driver. The driver defines functions that enable PC applications to exchange data with the device. The down side to using a generic driver is that you’re likely to be dependent on the driver’s provider to fix any problems.

Although you can write your own driver, Windows driver writing isn’t an easy task and thus isn’t worth pursuing for most small-quantity projects. Fortunately, generic drivers are available from a variety of sources.

Drivers from device manufacturers include the Microchip General Purpose USB Windows Driver, Cypress Semiconductor’s CY4604 USB Developer's uStudio, and the Silicon Labs USBXpress host library. FTDI Chip offers the D2XX Direct Driver, which applications can use to access FTDI Chip’s controllers using vendor-specific functions instead of COM-port programming. Some development boards come with drivers that you can use to access the controller on the board. Other drivers, such as Tetradyne Software, Inc.’s DriverX USB, are for use with any controller chip.

If you’re switching to Windows Vista, you can use the operating system’s WinUSB driver. The driver provides functions for accessing any device that doesn’t use Windows class drivers or isochronous transfers.

The Vendor ID Dilemma

Every USB device must contain a device descriptor with a Vendor ID and Product ID that identify the device:

Device Descriptor

0x12 Descriptor size in bytes
0x01 Descriptor type (Device)
0x0200 USB Specification release number (BCD) (2.00)
0x00 Class Code
0x00 Subclass code
0x00 Protocol code
0x08 Endpoint 0 maximum packet size
0x0925 Vendor ID (Lakeview Research, assigned by
0x1234 Product ID (assigned by vendor)
0x0100 Device release number (BCD)
0x01 Manufacturer string index
0x02 Product string index
0x03 Device serial number string index
0x01 Number of configurations

The host requests these 16-bit values from the device during enumeration and uses the values to help in selecting a driver for the device.

The owner of the Vendor ID assigns a Product ID to each product released by the vendor. Every device with the same Vendor ID/Product ID pair should communicate in the same way with the PC. If two devices with different communication requirements contain the same Vendor ID/Product ID pair, one or both devices are likely to fail to perform as intended.

The rights to use a Vendor ID cost $1500 from the USB Implementers Forum. If you don’t have a Vendor ID and your budget doesn’t allow obtaining one, several options are available.

Users of FTDI Chip’s controllers can use the Vendor ID and Product ID programmed into each controller. Because the controllers handle the USB communications entirely in hardware, the controllers appear identical to the host computer. The controllers may connect to circuits that perform different functions, but the host PC doesn’t have to know or care about anything that happens beyond the USB interface.

Some chip manufacturers provide free blocks of Product IDs for customers. You can use the manufacturer’s Vendor ID and the provided Product IDs in products that you develop using the manufacturer’s controllers. Microchip is one manufacturer that offers Product IDs. FTDI Chip also has this option for those who want a unique Product ID.

Some development boards that come with a driver have a Vendor ID and Product ID that you can use in products that use the driver.

Learning More

For many projects, one of the approaches described here can provide a way to add USB to a device with minimal expense and hassle. For more about USB developing, including links to the products mentioned in this article plus free example device firmware and host software, visit my USB pages at