skip to Main Content

In windows 10 I am trying to read the output of an attached serial device.

Using hterm I am able to see the data on serial port COM5. So the serial port works fine.

Now using WSL2 (Ubuntu 20.04.3) I am running the following python script

import serial

ser = serial.Serial("COM5", baudrate=115200)

which fails with the error

Traceback (most recent call last):
  File "test1.py", line 6, in <module>
    ser = serial.Serial("COM5", baudrate=115200)
  File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 240, in __init__
    self.open()
  File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 268, in open
    raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))
serial.serialutil.SerialException: [Errno 2] could not open port COM5: [Errno 2] No such file or directory: 'COM5'

I also tried to use the suggestions posted in this article at attach the USB port on which the serial device is connected to, to WSL.

The command usbipd wsl list in a windows powershell shows then

8-3    0403:6001  USB Serial Converter                                          Attached - Ubuntu-20.04

But when then running the same python code in WSL2 gives the same error.

So how to fix this problem so I am able to just read all data from the serial port with python?

4

Answers


  1. [EDIT] Code updated and tested as per locking remarks[/EDIT]

    I generally use a solution where I just identify the port name from USB VID:PID data.
    This allows me to not hard code any com port name.

    You must begin searching for the port name corresponding to your USB device (see find_device() below).

    You should also use locks on your serial port while reading so you don’t get multiple concurrent accesses, which especially on Windows will create permission errors. See with LOCK context manager for locking the serial reads.

    Code has been tested from Python 2.7 to 3.11 on both Windows and Linux.

    Of course you can adapt the serial port settings and perhaps the size of read bytes and/or timeout.

    import serial.tools.list_ports
    import serial
    from threading import Lock
    
    # Your USB SERIAL DEVICE identification
    USB_VID = "0x0403"
    USB_PID = "0x6001"
    
    SERIAL_SETTINGS = {
        "baudrate": 115200,
        "bytesize": 8,
        "parity": "N",
        "stopbits": 1,
    }
    
    LOCK = Lock()
    
    
    def find_devices():
        # type: () -> List[str]
        """
        Find all COM ports corresponding to your USB device
        """
        _device_ports = []
        for port in serial.tools.list_ports.comports():
            if port.vid == int(USB_VID, 16) and port.pid == int(USB_PID, 16):
                _device_ports.append(port.device)
        return _device_ports
    
    def read_device(device) -> str:
        # type: (str) -> str
        try:
            with LOCK:
                with serial.Serial(device_port, timeout=1, **SERIAL_SETTINGS) as ser:
                    result = ser.read(size=64).decode('utf-8')
                    if len(result) == 0:
                        return None
                    else:
                        return result.strip("rn")
                    return result
        except serial.SerialException as exc:
            error_message = "Cannot read serial port {}: {}".format(device_port, exc)
            print(error_message)  # or log it
            raise OSerror(error_message)
    
    
    for port in find_devices():
        data = read_device(port)
        print(data)
    

    Hope this helps.
    More examples of serial reading can be found in a library I wrote for reading USB temperature sensors, see this

    Login or Signup to reply.
  2. You could try using the following script.

    import serial
    
    ser = serial.Serial("COM5", baudrate=115200, timeout=1)`
    while True:
       data = ser.readline()
       print(data)
    
    Login or Signup to reply.
  3. I personally would get this to work in Ubuntu 20.04.3 first.

    Just download a Virtual Machine of Ubuntu, install it (in a VM environment (or real machine if you have one spare) ) and test.

    WSLx is really good but it still has some teething problems.

    If you know it passes in a real (or VM) Ubuntu install then you are most of the way there.

    I always do this as WSLx can have some weird quirks I have found. It shouldn’t for note but it does, especially when it comes down to external hardware.

    Login or Signup to reply.
  4. Since you are using Ubuntu, you can’t use the Port-Names used by Windows. In Ubuntu Port names usually are in the format of dev/ttyUSB followed by the number of the port (dev/ttyUSB0).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search