Automatically find a Teensy Board with Python and PySerial

hexodin

Active member
Hi!

I'm currently implementing a program in Python to send files to an EEPROM and came across the problem of automatically detecting the board.

In this topic, I will show how to solve the problem using Python Programming Language and PySerial Library.

So if you connect a Teensy to PC and launch this code:
Code:
from serial.tools import list_ports
list(list_ports.comports())

You'll return:
Code:
[('COM5', 'Teensy USB Serial (PJRC.COM) (COM5)', 'USB VID:PID=16C0:0483 SNR=12345')]

This is the base of this function:
Code:
def getTeensyPort():
	"""Discover where is Teensy."""
	ports_avaiable = list(list_ports.comports())
	teensy_port = tuple()
	for port in ports_avaiable:
		if port[1].startswith("Teensy"):
			teensy_port = port
	if teensy_port:
		return teensy_port

So I created a little example to do the basis:
Code:
import sys
import serial
from serial.tools import list_ports

class TeensySerial:
    def __init__(self, baudrate):
        self.teensy_port = self.getTeensyPort()
        self.teensy = serial.Serial(self.teensy_port[0], baudrate)

    def getTeensyPort(self):
        """Discover where is Teensy."""
        ports_avaiable = list(list_ports.comports())
        teensy_port = tuple()
        for port in ports_avaiable:
            if port[1].startswith("Teensy"):
                teensy_port = port
        if teensy_port:
            return teensy_port

    def close(self):
        if self.teensy.isOpen():
            self.teensy.close()

if __name__ == "__main__":
    print "Welcome to Example: Autodetect Teensy!"
    try:
        teensy = TeensySerial(115200)
        print "Connected to: %s" % teensy.teensy_port[1]
        teensy.close()
    except TypeError:
        print "Cannot find a Teensy board connected..."

Teensy not founded:
teensynotok.png

Teensy founded:
teensyok.png

This code works on Windows but I don't know the effects in others Operational Systems... I'm not so good at programming, so... if you have suggestions/corrections feel free to interact. I'm glad this code can help you with your projects!

Bye!
 
Last edited:
This is a simplified code that will use VID, PID and serial number to detect the device and return the serial port. More efficient than using the driver name (which can vary depending of driver version) :
Code:
import sys, serial
from serial.tools import list_ports

# Teensy USB serial microcontroller program id data:
VENDOR_ID = "16C0"
PRODUCT_ID = "0483"
SERIAL_NUMBER = "12345"

def getTeensyPort():
	for port in list(list_ports.comports()):
		if port[2] == "USB VID:PID=%s:%s SNR=%s"%(VENDOR_ID, PRODUCT_ID, SERIAL_NUMBER):
			return port[0]

if __name__ == "__main__":
	TeensyPort = getTeensyPort()
	if TeensyPort:
		print "Teensy found on port %s"%TeensyPort
	else:
		print "No compatible Teensy found. Aborting."
		sys.exit(1)


Note:
You can define a custom serial number into the usb.serial.c of your avr program:
Code:
#define STR_SERIAL_NUMBER	L"[COLOR="#0000FF"]MY_PROGRAM_V1[/COLOR]"
will return:
Code:
[('COM5', 'Teensy USB Serial (PJRC.COM) (COM5)', 'USB VID:PID=16C0:0483 SNR=[COLOR="#0000FF"]MY_PROGRAM_V1[/COLOR]')]

and using the above script, with
Code:
SERIAL_NUMBER = "[COLOR="#0000FF"]MY_PROGRAM_V1[/COLOR]"
Then, if port is detected, the device + the program loaded into the microcontroller is the good one.
 
I can run the python code without errors, but the teensy is never found on my windows 10 machine.
None of the above examples find my teensy, by TyCommander finds it just fine. :(
 
DJB, here is another example. Replace teensy_sn = "7644400" with the serial number you are looking for.
regards

Code:
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
teensy_vid = "16C0"
teensy_sn = "7644400"  #replace with the serial number you are looking for 
port_to_open = ""
found = 0


for port, desc, hwid in sorted(ports):
        print("{}: {} [{}]".format(port, desc, hwid))
        print(port)
        print(desc)
        print(hwid)
        #Look for the Teensy VID
        if  teensy_vid in hwid:
                print ("******************************************")
                print("Found a Teensy on port")
                print(port)
                if teensy_sn in hwid:
                    found = 1
                    port_to_open = port
                print ("******************************************")

                
print ("******************************************")
if found ==1:
        print("Device Found On Port : " + port_to_open)
else:
        print("Device not found")
 
Running @macrosii python code on windows 10 resulted in this.

COM1: Communications Port (COM1) [ACPI\PNP0501\0]
COM1
Communications Port (COM1)
ACPI\PNP0501\0
******************************************
Device not found

It must be noted that the teensy LC is configured as USB: MIDI
I know, it's not serial, but no other "serial" emulator needs the "USB : Serial" setting to communicate with the teensy (i.e. using built in serial comms with Arduino IDE or TyCommander)
I thought I had something using basic HID device identification and comms, but I'm in over my head with USB given my current knowledge. https://github.com/rene-aguirre/pywinusb
 
DJB, yes pyserial is for serial ports, either harware UART on the PC or virtual serial via USB. I am only using this to detect the Teensy and communicate via the USB:serial interface for Python front end GUI.
I do use HID for keyboard and mouse emulation but leave serial enabled for the Python GUI
 
DJB, yes pyserial is for serial ports, either harware UART on the PC or virtual serial via USB. I am only using this to detect the Teensy and communicate via the USB:serial interface for Python front end GUI.
I do use HID for keyboard and mouse emulation but leave serial enabled for the Python GUI

Yeah, so I may just have to leave my USB config setting to be "Serial + MIDI" do just that and running your code again finds the teensy.
Why tyCommander and the Arduino IDE don't need that to find and communicate with the teensy is above my current pay grade. :)
Thank you!

COM1: Communications Port (COM1) [ACPI\PNP0501\0]
COM1
Communications Port (COM1)
ACPI\PNP0501\0
COM6: USB Serial Device (COM6) [USB VID:pID=16C0:0489 SER=9370980 LOCATION=1-9:x.0]
COM6
USB Serial Device (COM6)
USB VID:pID=16C0:0489 SER=9370980 LOCATION=1-9:x.0
******************************************
Found a Teensy on port
COM6
******************************************
******************************************
Device Found On Port : COM6
 
Back
Top