Question

I'd like to write a Ruby program for OSX that communicates via USB with my Arduino. I am going to use the serialport gem for that purpose.

I found a sample code that says:

port_str = "/dev/ttyUSB0"  #may be different for you

How can I scan and find the Arduino, and know to what port I should connect to automatically? (I have OSX) Thanks!

Was it helpful?

Solution

This can be tricky to do in a general way, because Arduino devices appear as USB serial ports, making it hard to distinguish between Arduino and non-Arduino ports.

The brute-force approach is: enumerate the USB serial devices, open() each in turn, and see if your firmware boot header is sent on the other end. On OSX, the USB serial devices are at /dev/tty.*, but that may change with future OS updates. This method works, but can be slow and timing sensitive. I've found that a startup delay on the Arduino before sending a header helps, as well as a simple "hello, are you there?" command the host can use to bang for signs of life.

Also, you can save the last port found so that subsequent app launches try that port first.

A variant: if your app asks the user to plug in the Arduino at startup, you can list the USB ports in /dev, wait for user to confirm it's plugged in, and list the ports again. Any newly appearing device is likely your Arduino.

At the next level, you could look at the USB Vendor and Product IDs (VID & PID). However, these IDs are all over the map in Arduino-land. They differ by model, version, revision, Chinese clones, and the various Arduino-compatible devices. See this writeup at Adafruit.

If you're just trying to make things work with a very narrow hardware set (e.g. the one Arduino on your bench), you can use this OSX command to see the USB device details:

system_profiler SPUSBDataType

With my system, I get:

...
USB Bus:

  Host Controller Location: Built-in USB
  Host Controller Driver: AppleUSBUHCI
  PCI Device ID: 0x7fff000027c9 
  PCI Revision ID: 0x7fff00000002 
  PCI Vendor ID: 0x7fff00008086 
  Bus Number: 0x3d 

    Communication Device:

      Product ID: 0x0043
      Vendor ID: 0x2341
      Version: 0.01
      Serial Number: 75331313133351800000
      Speed: Up to 12 Mb/sec
      Manufacturer: Arduino (www.arduino.cc)
      Location ID: 0x3d100000 / 2
      Current Available (mA): 500
      Current Required (mA): 100

The location ID (0x3d100000 / 2) seems to match up with the device name: /dev/cu.usbmodem3d11

See this question for running command line commands from within a Ruby script.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top