Wednesday, December 12, 2012

If you have ever used a USB to Serial adapter, you are probably familiar with the procedure: you plug the in adapter and then you have to start looking for the COM port (or tty number, if your'e on linux) assigned to it by the operating system. You have to open the control panel, browse through the list of serial ports and try to guess which of them is the correct port. Usually it's quite easy, because the adapter has a distinguishable name but occasionally it's not the case and you have to pull the device out, reconnect it and try to track the list while it gets refreshed. This annoyance becomes much worse when more than one of these plugs are connected to the computer, the list is longer and names has no real meaning.

The project I'm presenting for the WIG2012 contest grew up from this frustration. It's a serial to USB adapter with a small LCD display. When connected to a computer, the LCD shows the COM port number assigned to the device, plain and simple.

I've built a prototype to demonstrate how it works, which you can see in the following picture and video.

The prototype is fully functional, but it has some limitation - there is no RS-232 line driver, no baud rate control and only a single digit is driven in the LCD (due to I/O pin count limitation in the processor).

How does it work

The adapter is built using a PIC microcontroller (for the prototype, I used a UBW board from Sparkfun with PIC18F2553). The firmware on the microcontroller implements a composite USB device, that is a device that has two "heads". One "head" implements the CDC protocol. When Windows (or any other operating system) detects it, it creates a virtual serial port and attaches it to that interface. To the user, it looks like a regular serial port (it has a "COMxx" device name) which can be used as any other port.
The other "head" is uses a proprietary control protocol to set the number shown on the LCD. For ease of implementation, it uses the HID protocol, which makes it easy for user space program to communicate with it without requiring a special driver.
The last part is the host application. The host application runs on the PC and monitors the USB insertion and removal activity. Once it detects a device insertion, it scans through the list of USB devices, tries to find this specific type of devices (distinguished by their PID and VID numbers), determines what is the COM port number assigned to each of them and sends a command to show the number on the LCD screen.

Source code

The source code is, of course, fully open and available through a Github repository.
Two important precautions:

Every USB device must have a unique VID and PID, which must be bought from usb.org. Since this is only a demonstration prototype I haven't done this, and used the "prototype" VID. This means that theoretically, it's possible that other device use the same identifiers, which can lead to the wrong driver being loaded.

All the code is free and open source (under the GPL license) but it depends on the Microchip USB stack which can be freely used, but suffers from distribution limitations. The files from that stack are not included in the source code, they must be copied from Microchip distribution.

Finally, I would like to thank Wyolum for providing this opportunity and support for the development of open source hardware.