Linux and Python: auto-detect Arduino serial port


I have a problem automagically detecting my Arduino's serial port in Python, using Mac/Linux.

I know a working shell command to find the port; because Arduino serial ports almost always begin with tty.usbmodem, you can find the serial port with ls /dev | grep tty.usbmodem which should return something like tty.usbmodem262141.

However, I'm confused on how to call this shell command from my Python code. I've tried this:

p = "/dev/" + str(subprocess.Popen('ls /dev | grep tty.usbmodem', shell=True).stdout)

Which should make p become /dev/tty.usbmodem262141.

However, at the moment I get /dev/None.

How can I modify my shell script call to return the right string? I've tried to use several commands to call shell scripts, but none have worked.

5/23/2017 12:07:15 PM

Accepted Answer

First of all, if you're using a shell, you can use a glob (*), so your command would become ls /dev/tty.usbmodem*.

Next, you don't even have to call a shell command to use a glob in Python!

Consider the following code:

import glob

7/6/2012 3:16:35 PM

I wrote this to find out what dev the arduino was plugged into on osx 10.7.x : enjoy.

#!/usr/bin/env bash

# script name:
# author: Jerry Davis
# this little script determines what usb tty was just plugged in
# on osx especially, there is no utility that just displays what the usb
# ports are connected to each device.
# I named this script
# if run interactively, then it prompts you to connect the cable and either press enter or   it will timeout after 10 secs.
# if you set up an alias to have it run non-interactively, then it will just sleep for 10 secs.
# either way, this script gives you 10 seconds to plug in your device

# if run non interactively, a variable named MCPUTTY will be exported, this would be an advantage.
# it WAS an advantage to me, otherwise this would have been a 4 line script. :)
# to set up an alias to run non-interactively, do this:
#   osx: $ alias findtty='source',
#   or linux: $ alias findtty='.' (although source might still work)

\ls -1 /dev/tty* > before.tty.list

if [ -z "$PS1" ]; then
    read -s -n1 -t 10 -p "Connect cable, press Enter: " keypress
    sleep 10

\ls -1 /dev/tty* > after.tty.list

ftty=$(diff before.tty.list after.tty.list 2> /dev/null | grep '>' | sed 's/> //')
echo $ftty
rm -f before.tty.list after.tty.list
export MCPUTTY=$ftty                     # this will have no effect if running interactively

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow