This blog is now retired. Please visit our new blog here.

When I first started using them, I did have a little trouble uploading code to the Sparkfun Pro Micro, under Ubuntu 14.04LTS, using the Arduino IDE 1.6.8.

The Pro Micro board definitions were installed as detailed in the Sparkfun guide for linux but the board just gave the same error every time I tried to upload:

avrdude: ser_open(): can't open device "/dev/ttyACM0": Device or resource busy
avrdude: ser_send(): write error: Bad file descriptor

A little googling did suggest that modemmanager might be capturing that particular serial device and while I was unhappy with the idea of just uninstalling modemmanager as a way of solving it (I'm assuming that it's normally useful when using modems!), I did also find a suggested way of stopping modemmanager from interfering in specific arduino devices.

Although this didn't work directly, I did find enough information in checking if this was the problem to confirm that it was definitely modemmanager that was at fault.

By running: tail -f /var/log/syslog while plugging in the Pro-Micro, I could see the culprit capturing the device:

Mth DD hh:mm:ss hostname kernel: [90847.591711] usb 1-3.1: new full-speed USB device number 32 using ehci-pci
Mth DD hh:mm:ss hostname kernel: [90847.687856] usb 1-3.1: New USB device found, idVendor=1b4f, idProduct=9206
Mth DD hh:mm:ss hostname kernel: [90847.687862] usb 1-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Mth DD hh:mm:ss hostname kernel: [90847.687867] usb 1-3.1: Product: USB IO Board    
Mth DD hh:mm:ss hostname kernel: [90847.687871] usb 1-3.1: Manufacturer: Unknown    
Mth DD hh:mm:ss hostname kernel: [90847.688309] cdc_acm 1-3.1:1.0: This device cannot do calls on its own. It is not a modem.
Mth DD hh:mm:ss hostname kernel: [90847.688336] cdc_acm 1-3.1:1.0: ttyACM0: USB ACM device
Mth DD hh:mm:ss hostname kernel: [90847.690711] input: Unknown     USB IO Board     as /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3.1/1-3.1:1.2/input/input30
Mth DD hh:mm:ss hostname kernel: [90847.691280] hid-generic 0003:1B4F:9206.0016: input,hidraw4: USB HID v1.01 Mouse [Unknown     USB IO Board    ] on usb-0000:00:1a.7-3.1/input2
Mth DD hh:mm:ss hostname mtp-probe: checking bus 1, device 32: "/sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3.1"
Mth DD hh:mm:ss hostname mtp-probe: bus: 1, device: 32 was not an MTP device
Mth DD hh:mm:ss hostname ModemManager[815]: <info>  Creating modem with plugin 'Generic' and '1' ports
Mth DD hh:mm:ss hostname ModemManager[815]: <warn>  Could not grab port (tty/ttyACM0): 'Cannot add port 'tty/ttyACM0', unhandled serial type'
Mth DD hh:mm:ss hostname ModemManager[815]: <warn>  Couldn't create modem for device at '/sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3.1': Failed to find primary AT port

So although ModemManger was unable to understand the device, it was still happy to hold on to it, an keep the serial port busy.

Fortunately, the syslog nicely contains the idVendor required to tell ModemManger to ignore it, so adding the line: ATTRS{idVendor}=="1b4f", ENV{ID_MM_DEVICE_IGNORE}="1" in the correct position in the udev rules will do that.

1b4f is the vendor ID for Sparkfun, so this setting will apply to any USB device from them.

Run:

echo 'ATTRS{idVendor}=="1b4f", ENV{ID_MM_DEVICE_IGNORE}="1"' | sudo tee -a /etc/udev/rules.d/77-arduino.rules

to append that entry to the arduino.rules file (if it exists) and run:

sudo udevadm trigger

to re-read the rules.

Then plugging in the Sparkfun board and watching the syslog should show nothing beyond the mtp-probe lines, and specifically nothing from ModemManager. Job done.