Fun with Flora

It’s been a while since I’ve played with AVR microcontrollers:

http://www.matthewarcus.org.uk/avr-ntp/

but I couldn’t resist getting myself an Adafruit Flora:

http://www.adafruit.com/products/659

The tutorials etc. on the Adafruit website mainly cover using Windows and Apple development platforms, though there is much useful information in their forums on using Linux – I suppose we are meant to be able to work these things out for ourselves (actually, I suspect the real reason is that there is too much variation across different distributions to be able to give a single consistent set of instructions). Anyway, this is what worked for me to get everything working nicely on Ubuntu 12.10.

Firstly, set up your IDE. The standard 1.0.4 installation is what is recommended by Adafruit, so we’ll start there (see later for 1.5.2). We need a Flora entry in the boards.txt file, and a board specific header file, to go in variants/flora, telling the compiler where the pins etc. are. These files can be extracted from the “official” Adafruit Arduino IDE for the Flora, or the excellent kkolbo has put them in a handy zip file, referenced here:

http://adafruit.com/forums/viewtopic.php?f=22&t=39012

Now we have a Flora entry on the Tools/Board menu and we can try downloading a “sketch”, as Arduino programs apparently are called. My Flora already has a blinkenlights program on it, so we’ll be wanting to change the timing or something so we can see that we really are running a new program. So, here we have the “Hello, world” of the embedded world (sketch taken directly from Adafruit tutorial):

// Pin D7 has an LED connected on FLORA.
// give it a name:
int led = 7;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on
  delay(1500);
  digitalWrite(led, LOW);    // turn the LED off
  delay(500);
}

Nice, a little way from a Stratum-1 NTP server, but it’s a start.

To get our sketch running on the Flora, we must bear some things in mind. First thing (this held me up for a while), you upload with “Upload” and not with “Upload Using Programmer” – I suppose you only do that if you have an actual Programmer, pretty obvious really, secondly there is a “modem-manager” program, part of the Linux network manager that sometimes does strange things to the USB-pretending-to-be-a-serial-port that we are attempting to program over, and thirdly, you must, of course, have the right permissions to access said USB/serial device – for a serial over USB link, you will be looking for a device called /dev/ttyACMx and this should appear in the “Tools/Serial Ports” menu item – if no port is shown there but a suitable device exists in /dev then you probably have a permissions problem. Make sure you have the port selected too, with a tick next it. You can run the IDE as root or fiddle with group membership, but the proper way of dealing with this is with the udev device manager (which also allows us to tell modem-manager to keep its hands off).

Like the Leonardo, the Flora has one USB port, used both by the program, and for programming and it seems that the device reports different USB product ids depending on what mode it’s in – just after a reset, it reports product id 0004, then after going to “normal” mode, the product id becomes 8004 (and some of the USB properties change), and we need to set udev rules for both. (“lsusb” and “udevadm info -a -n /dev/ttyACMx” are useful here to find out what is going on).

The upshot is that we need two udev lines, for the different states of the USB connection and the different idProducts that are reported:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="239a", ATTRS{idProduct}=="0004", MODE="0660", GROUP="plugdev", ENV{ID_MM_DEVICE_IGNORE}="1"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="239a", ATTRS{idProduct}=="8004", MODE="0660", GROUP="plugdev", ENV{ID_MM_DEVICE_IGNORE}="1"

The group setting ensures normal users (which Ubuntu adds to the plugdev group) can access the port, and the ID_MM_DEVICE_IGNORE tells modem-manager to ignore this device, so we no longer need to disable modem-manager while programming. There are some suggestions on the internet of using a SYMLINK+=”ttyACM%n” entry too, but that doesn’t seem to be necessary for our purposes (actually, adding “SYMLINK+=ttyUSB0” gives us a means of adding a consistent device name that is recognized by the Arduino IDE, but doesn’t clash with the kernel assigned ACM names). Add these lines into, say, /etc/udev/rules/90-flora.rules, restart udev with service udev restart and reconnect or reset your Flora. You should see something like:

$ ls -l /dev/ttyACM*
crw-rw---- 1 root plugdev 166, 1 May 18 15:59 /dev/ttyACM1

and programming should now work just fine as a normal user (assuming they are in the plugdev group). Sometimes the soft reset that the programmer does to initiate upload doesn’t work and you have to do a hard reset, but that seems to be a standard problem with Leonardo/Flora. Most of the time it seems to work just fine with the software reset.

A couple of observations: when programming, the software reset of the serial port fails if the port isn’t selected in the Serial Port menu, though programming after a hard reset will still suceed. Also sometimes if the upload fails, the avrdude process isn’t shut down properly and keeps the serial port device open, so when the USB connection is reestablished, the device minor number goes up (ie. we now have /dev/ttyACM1 rather than /dev/ttyACM0). If this happens, “killall avrdude” will restore the status quo.

Finally, I had originally tried using an Arduino 1.5.2 installation I set up when I was thinking of having a play with the ARM-based Arduino Due. Initially this didn’t work too well for the Flora, but after sorting out the USB device problems as above and copying the relevant seeming lines from the Leonardo section of the boards.txt file to the Flora section (and copying the variants/flora directory), it was just fine:

flora.name=Adafruit Flora
flora.upload.tool=avrdude
flora.upload.protocol=avr109
flora.upload.maximum_size=28672
flora.upload.speed=57600
flora.upload.disable_flushing=true
flora.upload.use_1200bps_touch=true
flora.upload.wait_for_upload_port=true
flora.bootloader.tool=avrdude
flora.bootloader.low_fuses=0xff
flora.bootloader.high_fuses=0xd8
flora.bootloader.extended_fuses=0xcb
flora.bootloader.path=caterina
flora.bootloader.file=Caterina-Flora.hex
flora.bootloader.unlock_bits=0x3F
flora.bootloader.lock_bits=0x2F
flora.build.mcu=atmega32u4
flora.build.f_cpu=8000000L
flora.build.vid=0x239A
flora.build.pid=0x8004
flora.build.core=arduino
flora.build.variant=flora
flora.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid}

(I’m not sure that I’ve got that bootloader, but I don’t need it at the moment).

Anyway, a nice bit of kit, good work from Limor Fried and all at Adafruit, and now I can make the LED flash just as I like, time to think of some more interesting applications. Watch this space…