Serial Port Troubleshooting on Linux

Date: — by Slatian

A serial port (i.e. for programming a microcontroller) can have multiple resons why it is not working. This guide is based on my experince and will try to cover most cases, FAQ style.


It is always a good idea to try to look up the problem in your distributions wiki/documentation first!

You can manually connect to a serial port using screen /dev/tty<name>. Quit with Ctrl+a and pressing k after that.

Is your Serial device showing up?

Use ls /dev/tty* to get a list of terminal devices on your Linux machine. If you find a ttyUSBn or a ttyACMn (where n is a number) that appears when you plug your device in and disappears when unplugging (yes that's the easiest way) that is your device with hardware and drivers working, skip this section.

Note: Builtin serial ports are sometimes also called /dev/Sn.

Is the Hardware recognized?

Try running lsusb, it will give you a list of connected USB devices, if your device is not among them you either have a bad cable, a bad microcontroller or (for some micros) the controller is not in programming mode.

If the device shows up in lsusb but there is no serial port, your harware is working but there is a driver problem. (or the hardware doesn't provide a serial port.)

Would a reboot fix the problem?

This only the case if there has been a system update since the last reboot.

(Depending on your definition of a shortcut: just reboot)

If you are not using a very uncommon setup check if /lib/modules (the directory kernel modules (drivers) are in) contains a directory called the same as the output of uname -r (the version of the currently running kernel).

If that is not the case your package manager has cleaned up the old modules during an update and you have not rebooted yet (still running the old kernel). The solution in this case is a reboot, then the hardware management will be able to find the modules the kernel needs because the running version matches the version of the modules in the filesystem.

Missing Package or Driver Error

If a reboot did not or would not fix your problem try searching for a driver package (usually the package name contains ftdi for USB to serial adaptors).

If you find the neccessary packe already installed, running dmesg -w as root and then plugging in the device is also worth a look at this point. dmesg prints logs from your kernel, including potential information and errors from relevant drivers.

Do you have permission for accessing serial ports?

Run ls -l /dev/tty*, this will tell you who owns the device files, file permissions apply like with regular files.

An example output line, the file belongs to the root user and the dialout group, both are allowed to read and write.
crw-rw---- 1 root dialout 4, 67  5. Sep 12:25 /dev/ttyS0
#^  ^ The 2 rw here indicate that owner and group may read from and write to this device.

By default on many distributions the hardware management comes preconfigured in a way that only permits users in the dialout group to use serial ports. Check if are a member of that group using the groups command.

Note: the dialout group may have a different name on some distributions if the ls -l didn't indicate that the serial port belongs to the dialout group this is the case for you. (look up serial ports in the distributions wiki).

Note on Arch derived Distributions: On Archlinux and derived distributions the relevant group is called uucp instead of dialout. (UUCP stands for Unix-to-Unix Copy which was common to be used over a serial link.)

You can give a user permission by running sudo usermod -a -G dialout <username> and logging out and back in after that.

In case your system looks completely different you may want to investigate udev and udev rules.

Is something else using the port?

Since a program doesn't really know what is on the other side of a serial port some programs simply connect and try to find out. This may interfere with whatever you are trying to do.

One of these programs is brltty which is preconfigured by most big distributions. It tries very hard to make sure plugging a braille display into an USB port will make it immedeately available. (which is very good, your little Arduino isn't nearly as important!) Unfortunately it has to open every serial device taht connects to the system to find out wheter it is a braille display or not.

To fix that behaviour either configure the "offending" program or stop (and disable) the service it belongs to if you don't need it.

Example of how to disable and stop the brltty service on most systemd based distributions.
Do not do this if you rely on a working braille display!
sudo systemctl disable --now brltty

Did that fix it?

If this guide helped you please consider sharing it.

In case you found a mistake or ended up in a dead end, don't hesitate to contact me.