Permission Denied When Programming Arduino Micro/SparkFun Pro Micro

I recently started having trouble with Arduino 1.6.x not being able to program Arduino Micro or SparkFun Pro Micro, with avrdude complaining about permission denied when trying to open /dev/ACM0.

The usual solutions to this is to add oneself to the dialup group, or mess around in /etc/udev/rules.d/99-arduino.rules.

None of these worked for me. However Arduino is able to program the micros fine if I run it as root, which clued me into that fact that there is some finite time between the kernel creating /dev/ttyACM0 and udev rules having effect. Specifically, udevd is a userspace daemon, and therefore necessary runs sometime after the kernel as created the relevant device node.

The problem is thus: Arduino IDE opens /dev/ttyACM0 at 1200bps and immediately closes it. This is causes the ATmega32u4 to reset itself, causing the serial port to disappear. When the bootloader runs, it presents itself as a usb-serial device, and /dev/ttyACM0 appears again. Reappearance of /dev/ttyACM0 causes the Arduino IDE to launch avrdude, which immediately tries to open /dev/ttyACM0 and fails because udev hasn't had time to process all the rules and assign the correct permissions etc.

The solution then is to introduce a delay before running avrdude, or even better, let udev let us known when it is done, which is much more robust. This can be done using

udevadm settle -t 1

Which waits for the udev to "settle", and the -t 1 specifies a maximum wait time of 1 second.

I hit upon the idea of wrapping avrdude in a shellscript and then adding the above line before avrdude, and that was when I discovered that hardware/tools/avr/bin/avrdude is already a shellscript! This made things much easier. 

My Arduino IDE's avrdude script now looks like:

$ cat hardware/tools/avr/bin/avrdude

udevadm settle -t 1

export LD_LIBRARY_PATH="`dirname "$0"`/../lib/"
exec -a "$0" "`dirname "$0"`/avrdude_bin" "$@"

Programming of Arduino Micro and SparkFun Pro Mini is now flawless under Xubuntu 15.10.


Thinkpad Mute Buttons and Xubuntu

I recently acquired a used Lenovo X220 for use as a linux laptop, and needed the following in my openbox configuration XML to make the hardware speaker and mic mute buttons work:

  <!-- Modified for X220 -->
  <keybind key="XF86AudioMute">
    <action name="Execute">
      <command>pactl set-sink-mute 0 toggle</command>
  <keybind key="XF86AudioMicMute">
    <action name="Execute">
      <command>pactl set-source-mute 1 toggle</command>

Sources and sinks can be discovered using:

pactl list sources
pactl list sinks

For me there was only one sink, and two sources, the first of which is some kind of virtual source that monitors the microphone, while the second source is the microphone itself.

Something that is interesting is that both speaker and mic mute buttons have a central light that lights up when mute is active, and this seems tied to the hardware. This makes me trust that when the mute buttons are used they actually do something.

Hope this helps some people.


Notes on Migrating a Linux Install

Some issues I ran into when trying to move a Linux install from a 500 GB drive to a smaller 120 G SSD:

  • When duplicating the filesystem, make sure that /proc exists, otherwise when you boot the new drive the kernel will complaint that /proc is missing and it can't create the virtual file system
  • In grub-rescue, (hd0,msdos2) is /dev/sda2, and (hd0,msdos1) is /dev/sda1
  • When specifying initrd be sure not to accidentally select the vmlinuz image again
  • After you have fixed grub and find that booting is taking longer than expected, check that the UUID in /etc/initramfs-tools/conf.d/resume is the UUID of your swap partition. Check using sudo blkid