24

As far as my understanding of computer ports goes,

  1. A serial port is a 9 pin plug such as the one showed here and it is also called a COM port.
  2. USB ports are a different standard from serial ports.

Why then do I often see USB ports called "serial ports" and, for instance in the Arduino IDE, USB ports are identified by the COM prefix? Also why is a virtual COM port sometimes needed if there aren't any serial ports involved? (Example: Prologix GPIB-USB adapter.)

This use of the same name for describing two different things I think can be a bit confusing.

Screenshot from the Arduino IDE, menu command Tools → Serial Port → COM14 shown

mickkk
  • 975

5 Answers5

36

These aren't USB ports referred to as serial ports. In your example, the Arduino has a USB-to-serial device (either in the form of a second microcontroller, or an FTDI chip). This will use USB to communicate with the computer and form an actual serial port to the outside world - similar to USB Wi-Fi dongles, or USB LAN adapters, USB SATA adapters, etc.

The key is that in many cases, the serial port is not available directly to the user, as it is "hard wired" in the device (in this case, connected directly to the microcontroller you are programming).

In strict theory, any port using serial communications (almost any modern bus - including USB, which stands for "Universal Serial Bus", if my memory serves me) is a "serial port". However, in most cases, when people refer to "the serial port", they actually refer to a port that complies to RS-232.

23

It's confusing because Windows COM: ports come from a naming system defined back in MS-DOS (b. 1980). This was pretty-much copied from CP/M (b. 1974) with some ideas taken from Unix. They didn't anticipate the addition of an intermediate 'transport' bus like USB.

Quite a few things in Windows are survivors from the CP/M->MS-DOS evolution, such as letter-named disk drives, 3-letter filename extensions, .EXE and .COM files and the Command Prompt command interface.

Another is device names: generally three letters, always ending in a colon. COM: is a serial 'communications port', LPT: a 'line printer' (usually hanging off a Centronics port), NUL: dumps whatever's sent to it, CON: is the 'console' (keyboard and screen). Some that you could have several of get numbered to differentiate between them. COM: ports do, as do LPT: ports, becoming COM1: and LPT1: and so on.

A COM: port is an 'endpoint': the far end of the communications link from a Windows PC's point of view. Like many things in computing, the bridge there is ignored and it's the far end component you're thinking about, not USB. This is also true of a PC keyboard (linked as CPU-PCIe-USB-kbd) or a network drive (linked as CPU-PCIe-LAN-LAN-PCIe-CPU-PCIe-SATA or similar).

USB also uses the idea of endpoints. A USB controller can connect a host PC to all sorts of hardware and provide them to it as resources. So when you see the hardware attached by USB, you see these endpoints. A virtual COM: port in a USB device is simply a serial port coming out of that USB slave device as an endpoint. Windows will give it a number (COM1:, COM27: etc.) and that serial port can be recognised and used by any program using the standard Windows API for COM: ports.

Some USB-attached hardware might prefer to impersonate a serial port because it makes the development of the Windows software for it easier. No device driver needs to be written, which save a lot of work - the USB device tell Windows that it is a serial port. From the PC's point of view, this is fine if it behaves like a serial port (bytes are sent and received in an endless serial stream which is always open). So there are benefits for the developer.

TonyM
  • 363
9

Your understanding of the difference between COM port and USB port is correct.

Short answer you your question, why some USB ports are mapped by OS as "COM" ports, is: there are USB devices that implement USB CDC (Communication Device Class). These devices provide a bridge from awfully complicated USB interface to a standard UART/RS-232 type interface. For transparency for users, operating system loads USB drivers that mimic the transport layer as COM port, a virtual COM port. Some historical details and justification for this approach follow.

The COM port uses DB-9/DB-15 (aka RS-232 serial, or UART) connectors, and controllers for these ports are physically mapped into PC hardware, to specific addresses in I/O space. This COM controller is getting obsolete in modern PCs, and goes extinct.

At the same time many MCU still use the RS-232 serial communication as main means to communicate with peripheral world. The reason is that the hardware (and software) for this kind of link is very simple and easy to implement. More, all modern Android development/debug communication is done in COM-port style. Also, many "communication" devices (as modems, including 4G LTE and above), still use the UART-style interface with ASCII-type control protocol over several "COM" ports.

Now developers have a dilemma, how to communicate with such micro-controllers if the host development PC has no COM ports? The solution was to use USB ports and special USB devices that bridge the USB protocol with COM-port RS-232 interface. There are dedicated USB device as FTDI chips, and many others (Cypress, Microchip, etc.) make devices that perform this bridge function.

Now, all native communication to these MCUs is still expressed in terms of RS-232 protocol, and most application examples assume the use of some Terminal application (TeraTerm, HyperTerminal, etc.) to use the link. For user convenience, the USB-to-UART bridges are provided with drivers that represent the port as a virtual COM port. All modern software uses virtualization of COM hardware, which provides smooth transition to "COM-less" PCs. It becomes a common practice to either add a dedicated FTDI bridge to UART ports on a MCU development platform (and use FTDI drivers on host PC to make the USB port look like COM port), or embed proper bridge code into the MCU itself (if it has native USB functionality).

The straight approach is to use an external USB-to-UART board and wire the UART to the MCU under development. Or, if a board already has the DB-9 connector, there are USB dongles that can be connected directly to it.

In all cases the native UART control of MCU will appear on host side as a virtual COM port, skipping all intermediate signal/protocol transformations. That's why people nowadays often skip the distinction between USB-to-UART bridges and COM ports.

Ale..chenski
  • 13,235
7

To add to Joren Vaes's answer: be aware that some software apps (like Arduino IDE) install a Windows driver that creates "virtual COM" ports. When those ports are activated, the operating systems tells the programs that there is a COM port available, which looks like a standard serial port [*], to which programs (like Arduino IDE, but also any other) can send and receive bits like to any serial port. Under the hood, however, those bits are sent to a USB cable. Inside the Arduino board something analogous occurs.

[*] And, by "standard serial port" here we mean RS-232 protocol, the kind that was traditionally trasmitted via DB-9 or DB-25 connector. In our context it does not matter at all that USB is also "serial".

leonbloy
  • 695
3

It is very confusing, but you don't need to worry about it. First off, think of a UART which itself is a generic term, but think of one that produces a protocol with a start bit, one or two stop bits, 7 or 8 usually data bits, and sometimes parity which is even or odd; it can vary from there which makes it that much worse.

The UART is at TTL levels, whatever that means. It used to be 5 V and now 3.3 V, 1.8 V or whatever; perhaps TTL is the wrong term. THEN you had/have RS-232, RS-422, etc. These are VOLTAGE AND PIN standards, not protocol standards. It is incorrect to mix the terms and say RS-232 when you mean some sort of UART.

Back in the day your UART was on your motherboards and you desired some sort of connector to the outside world with voltage levels that at the time made sense and some sort of standard pinout/cable. So a popular 25 and 9 pin standard was often found for various peripherals, and in the Wintel PC world this was called a COMmunication port or sometimes serial port.

Sure, a port that carries serial data can and is called a serial port, SPI, I²C, MDIO, UART, HDLC, SDLC, etc., and perhaps even USB and SCSI; you could go crazy with this. Usually a serial port means some pins you can get at a UART.

The Unix/Linux world says tty instead of com/serial/uart, but it is the same thing.

Now there is the IMPLEMENTATION. You can buy some UART chip with some interface on it (yep, you can have a SPI UART, which is serial on both ends, or I²C UART or some dedicated bus or USB, etc.). Even back in the day the UART had some bus on one side that ultimately the CPU was communicating through. Today we have FTDI and other vendors that make nice USB UART solutions, doesn't make it any different some layers of interface between the software and the UART and then the other side of the UART has some interface, be it TTL/chip level or RS-232C or RS-422, etc.

Early Arduinos you often used an FTDI USB-to-UART board that also provided power to the Arduino. Some have that USB power and serial/UART on the Arduino board itself and then that is hooked up across the board to the UART on the AVR chip (same deal some processor with some layers of buses to allow software to communicate with a UART which has some interface on the other side of it, in this case the pins on the edge of the AVR, at chip voltage levels, TTL).

Since the UART functionality has not changed in decades, why should the software terminology or even software applications change at the application level? Write a Linux/Unix TTY application 10-15 years ago against a UART chip on your motherboard, and there is a good chance it still works today with a USB to TTL level or USB to RS-232C level or RS-422 or whatever pin/level definition. The same goes for Windows, and I have code that old that still works on both. In the Windows world the term COM is used.

I have not used the Arduino sandbox in a while and if so would have been on Linux, but I wouldn't be surprised if that program which is Java, if I remember right, is generic and uses the system name so ttyS2 on Linux and COM2 on windows.

Re-reading your question this can go much further, taking advantage of the already existing amount of software that uses these API calls. Again for decades there is no reason why you can't create a virtual port in software that carries this bidirectional data down pretty much anything you can think of. UART to Ethernet is a very common one, and in server rooms where servers still very much use COM/TTY/RS-232 ports, you can have a terminal server which has a number of interfaces which you can connect to a number of servers, then Ethernet on the other side, then if you choose not to telnet in, you can install a virtual COM port driver.

Then your application on your computer thinks it is talking to a COM port, but in fact that stream of bytes is hopping onto Ethernet then hitting the terminal server, THEN, to a UART to RS-232C level (but not necessarily pinout) cables to the server and back the same way.

Sometimes there is no reason to actually make it to a real UART, for whatever reason virtualize a COM port so that software that was written for those API calls can still work. You could perhaps think about the ancient banking software we still use that has a dumb terminal to a UART interface that perhaps back in the day was hardwired or went into a modem to eventually a server. You can make it so that software still works, through various amounts of emulation including a virtual COM port that today likely just goes down Ethernet to the server as a serial stream (TCP/IP for example).

old_timer
  • 180