Detecting LabHackers’ Serial Port Addresses using Python

First posted February 26, 2019

LabHackers’ MilliKey and USB2TTL8 devices have a USB Serial interface that is assigned a unique address by the operating system the first time the device is connected to a computer. The LabHackers’ Device Manager application can be used to view the serial port address assigned to a device.

However, the same LabHackers’ device will likely be assigned a different serial port address when it is connected to a different computer, so it is also useful to be able to identify LabHackers’ device serial port addresses from within your Python script.

Finding all Serial Ports

If we want to connect to a LabHackers’ device USB Serial interface, but do not know the device’s serial port address, the first thing we need to do is find it.

Lets start by finding the serial port address for all serial devices connected to the computer.

import serial
import os

def get_serial_ports():
    """
    Return list of serial port addresses that have be openned.
    """
    if os.name == 'nt':  # Windows
        available = []
        for i in range(1, 512):
            try:
                sport = 'COM%d'%(i)
                s = serial.Serial(sport, baudrate=128000)
                available.append(sport)
                s.close()
            except (serial.SerialException, ValueError):
                pass
        return available
    else:  # macOS and Linux
        from serial.tools import list_ports
        return [port[0] for port in list_ports.comports()]

get_serial_ports() returns a list of all serial port addresses on the computer that have a device connected to them. For example:

serial_ports = get_serial_ports()
print(serial_ports)

run on a Windows computer with two connected serial ports, will return something like:

 ['COM2', 'COM9']

Note: get_serial_ports() returns all the serial devices connected to the computer.

Detecting LabHackers’ device Serial ports

Next we need to find which, if any, of the serial addresses are connected to a LabHackers’ MilliKey or USB2TTL8 device. Building on get_serial_ports() , we can get a list of the LabHackers’ ports by checking the responds of each serial port when “PING\n” is sent.

def get_labhackers_ports():
    """
    Return list of connected LabHackers' device serial port addresses.
    """
    devices = []
    for p in get_serial_ports():
        s = serial.Serial(p, baudrate=128000, timeout=0.1)
        s.write(b"PING\n")
        rx = s.readline()
        if rx:
            rx = str(rx)
            if rx.find('MilliKey')>=0 or rx.find('USB2TTL8')>=0:
                devices.append(p)
        s.close()
    return devices

For example:

labhacker_ports = get_labhackers_ports()
print(labhacker_ports)

run on a Windows computer with one LabHackers’ device connected will return one serial port address:

['COM9']

Putting it together

Here is a complete version of the code.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function

import serial
import os

def get_serial_ports():
    """
    Return list of serial port addresses that have be openned.
    """
    if os.name == 'nt':  # Windows
        available = []
        for i in range(1, 512):
            try:
                sport = 'COM%d'%(i)
                s = serial.Serial(sport, baudrate=128000)
                available.append(sport)
                s.close()
            except (serial.SerialException, ValueError):
                pass
        return available
    else:  # macOS and Linux
        from serial.tools import list_ports
        return [port[0] for port in list_ports.comports()]

def get_labhackers_ports():
    """
    Return list of connected LabHackers' device serial port addresses.
    """
    devices = []
    for p in get_serial_ports():
        s = serial.Serial(p, baudrate=128000, timeout=0.1)
        s.write(b"PING\n")
        rx = s.readline()
        if rx:
            rx = str(rx)
            if rx.find('MilliKey')>=0 or rx.find('USB2TTL8')>=0:
                devices.append(p)
        s.close()
    return devices

if __name__ == '__main__':
    print(get_labhackers_ports())

Happy Hacking!