Monday, January 11, 2016

Helping Your Feathers Flock Together

This post is about the Adafruit Feather line of microcontroller development boards. It will serve as a guide to cross-Feather compatibility when designing both hardware add-on circuits and software to work with all of the Feather variants.

Left to right: Feather 32U4 Adalogger, my GPS FeatherWing, Feather M0, and Feather HUZZAH.

Introduction

Occasionally I see a new product or microcontroller development board that really sparks my interest. That's what happened with the Adafruit Feather line of boards. They pack a lot of punch into a small footprint, especially when you consider the fact that LiPo charging is built-in, as well as Wi-Fi, Bluetooth, or an SD card on some of the variants. Adafruit is also releasing expansion boards called FeatherWings, which are like Arduino shields or Beaglebone Black capes. I immediately had a project idea involving GPS and data logging, but the GPS FeatherWing wasn't out yet. So, I fired up Eagle and designed my own.

Compatibility Issues

I designed a FeatherWing using the U-Blox NEO-6M GPS module. I've used it many times before in other projects, and it's very easy to work with. It fit perfectly on the board along with it's supporting circuitry. I had some space left over, so I decided to add a sensor. On one version of my board I had a simple temperature sensor, and on the latest version I have a 3-axis accelerometer. When I designed this board, the Feather 32U4 (basically a smaller Arduino Leonardo) was the only one out, and not a single FeatherWing had yet been released. I had to make some guesses about compatibility in the pinout. Well, my board works great with the Feather 32U4 and it's Adalogger cousin.

But... I have had to make some changes to support the recently released Feather M0 and Feather HUZZAH (ESP8266). It's clear that Adafruit had to make compromises to fit so much hardware on such a small board, and this is very apparent when you start looking at the pinouts. Not all of the standard Arduino digital pins are broken out, and some have dual functions. The HUZZAH in particular has several pins that have to be used in certain ways or avoided all-together to prevent bootloader problems. Below, I will document what I discovered and list my recommended pin usage for your projects that will work with any of the currently-released Feather boards. It's an important consideration when soldering your proto-board connections or designing your own PCB that will of course have a fixed physical pin arrangement.

UARTs

Serial communication on the Feather 32U4 is pretty simple, and your Arduino projects can probably transfer straight over. You have the hardware UART on pins D0 and D1. Also, you can use SoftwareSerial in the IDE to turn other digital pins into serial pins. On the M0, things are a little different. SoftwareSerial is not (currently) supported. However, you have several SERCOMs available that can act as hardware UARTs. They are somewhat documented in this post on the Arduino forum. Great! Right? ...

Unfortunately the SERCOM pins don't line up well with the usable pins in SoftwareSerial for the Feather 32U4 (basically a Leonardo in the IDE). For example, SERCOM1 uses pin D12 as RX, but that is not a possible RX pin in SoftwareSerial on the 32U4.

Serial communication is once again different on the HUZZAH. You do have the hardware UART that lines up with pins D0 and D1 on the M0/32U4, but you should really (really) leave that one alone. It's connected to the serial bridge, and you don't want USB traffic interfering with your serial-connected device or vice versa. There is a second hardware UART in the ESP8266. It's documents on the github ESP8266/Arduino page, but you can see just the relevant part in this post on the ESP8266 forum. That UART would work fine with a 32U4-compatible pinout, but doesn't work with the SERCOM pinout on the M0.

So what to do if you need a second non-USB UART? My recommendation is to use pin D10 on the 32U4 and M0 (pin #15 on HUZZAH) as a second serial RX. That will work with the M0 SERCOM and 32U4 SoftwareSerial, and there are some SoftwareSerial-like libraries out there for the ESP8266 (1, 2, probably more...) that should work for your project. For the TX line, I recommend implementing a jumper in your circuit to select between pins D11 and D12 (pins #12 and #13 on HUZZAH). Select the pin D11 jumper to use the SERCOM on the M0, and select the other jumper for 32U4 and HUZZAH.

Interrupts

For using the AttachInterrupt routine in the Arduino IDE, the possible pins on the 32U4 and M0 are documented on the Arduino AttachInterrupt page. (Look for "Leonardo" and "Zero" respectively in the table). For the ESP8266, they are pretty much documented here (along with a ton of other information). What is not frequently mentioned in the resources I saw is that pin #16 on the ESP8266 is not usable with AttachInterrupt.

You really can't find a common interrupt pin that will work on all of the Feathers. That is kind of a bummer. If you need interrupts, I recommend designing around the M0 or HUZZAH. As a fall-back if you hook your circuit up to a 32U4 Feather, you can use a while loop in the main loop to watch for the pin level to change. That's far less useful than an interrupt, but it might get you by for your project.

Analog Input

Analog input on the 32U4 and M0 is super easy. You have the standard A0 through A5 pins we are all familiar with from the Arduino boards. (A0 on the M0 board is also the DAC output!) There are other analog inputs possible on some digital pins. The HUZZAH is very different though. There is only a single analog input (at the A0 pin position), and very importantly, it has a MAXIMUM input voltage of about 1 Volt. That limits it's usefulness when designing for cross-Feather compatibility. You could use a voltage divider to drop the input voltage to a safe level, but that will likely limit your resolution on the 32U4 and M0 boards unless you can tolerate a different analog reference voltage (AREF).

Digital I/O

There are some things to be aware of on the digital pins of the Feather boards. Pin D9 on the 32U4 and M0 should be avoided, because it is connected to a resistor divider to read the battery voltage. Also, pins D2 and D3 on the 32U4 board are in the same positions as pins 20 and 21 on the M0 board. That's because they are the I2C pins. I would suggest reserving those pins for I2C instead of wasting them on digital I/O. There seem to be lots of cool official FeatherWings coming out that use I2C exclusively to add functionality.

Digital I/O on the HUZZAH is once again very different. The pin numbering is different from the 32U4 and M0 boards, so it makes it difficult to refer to particular pins between the variants. Some of the pins are used in the bootloading process. You can read more about it in the official Adafruit tutorial. Long story short, just avoid pins 0, 2, and 15 if possible. You can use them as outputs as suggested in the guide, but you also need to consider the state of the pins on initial boot-up. I noticed some very strange behavior on my FeatherWing board when trying to use those pins, and certain connections would completely prevent programming or booting of the board. Three good digital I/O pins to use are #14, #13, and #12. However, those are also used for hardware SPI (and connected to the SPI pins on the opposite header). You might have to sacrifice SPI in order to get some "clean" digital pins for your project on the HUZZAH.

What does it all mean?

Wow, that was a lot of information. If you examined all of the links I posted, you'll see why I hit so many roadblocks in finding a good cross-compatible pinout for my FeatherWing board.

My over-arching recommendation is to pick one Feather and design around it. That will help you extract the most from the available pinout. However, the point of this article is finding a cross-Feather-compatible pinout so you can swap your circuit or custom FeatherWing between boards.

So, let's summarize the key points and mention some other tidbits:
  • Reserve the I2C pins in your project and don't waste them on regular digital I/O. I2C seems to be the primary way to add functionality to the Feathers due to the limited pin availability.
  • For a second UART, I recommend using pin D10 (#15 on HUZZAH) as serial RX and implementing a jumper to choose between pin D12 for the M0 and D11 (#13 on HUZZAH) for TX. Your sketches will be different for all three in order to set up the necessary configurations or libraries.
  • You are pretty much out of luck for a common interrupt pin between all three boards (assuming you have the requirement that the main UART and I2C pins be left alone). I have found pin D5 (#2 on HUZZAH) to be a possible option. It works with AttachInterrupt for both M0 and HUZZAH. However, it does have a pull-up resistor and LED attached to it on the HUZZAH. Make sure that your circuit won't pull it low on boot-up, and can tolerate the pull-up. For the 32U4, you would have to check the level in your code (not a true interrupt).
  • Analog inputs: If you only need a single analog input, you can put a voltage divider on it to knock the MAX input level down to 1V and connect it to A0. This will work on all three boards, but potentially with reduced resolution on the M0 and 32U4. Also, you sacrifice the DAC functionality on Feather M0 (it uses pin A0). If you need more than one analog input, you might have to consider adding an ADC chip to your circuit that talks to the microcontroller over I2C for the HUZZAH.
  • If you are designing a custom FeatherWing specifically for M0 and 32U4 and plan to use 3.3V analog inputs, use pins A1 through A5 only. This prevents the situation where someone connects the FeatherWing to a Feather HUZZAH and a signal above 1 Volt on A0 damages the ESP8266 module.
  • Be very cautious when selecting your digital I/O. The HUZZAH in particular has multiple pins that affect the bootloading process and have LEDs/pull-ups connected to them. Pins #14, #12, and #13 (D13, D12, and D11 on M0/32U4) are good options as long as you don't need to use SPI.
  • About pin D13... It is connected directly to an LED and resistor on the Feather M0 and 32U4. You need to keep that in mind when attempting to use it as a digital I/O pin (especially as an input). On the HUZZAH, it is a "clean" pin (the LEDs are on pins #0 and #2).
  • If you want to design your own FeatherWing, watch out for the pin next to D0 and D1 on the M0 and 32U4 boards (labeled as a Ground pin). On the Feather HUZZAH, driving that pin low will hold the ESP8266 processor in reset! Therefore, that pin needs to be treated as a No Connect. There is a primary Ground pin next to the AREF pin.
  • The Feather boards do not have I2C pull-up resistors on-board. Remember to add them to your own circuit if you are using I2C.
Summary

I hope the information I have presented here is useful for finding a pinout for your project that will work across all three Feather boards. Again, I would not suggest going that route if you can avoid it. Pick one Feather and design around it to get the most from the I/O pins. However, if you really want a circuit or custom FeatherWing that works on all three AND uses several types of I/O, there are a lot of things to watch out for.

As always, the official Adafruit documentation about Feather should be your main resource. Please post any comments and corrections below.

Thanks for reading!

- Dan W.



2 comments:

  1. Thanks for the Feather information, Dan, and as usual, great job with your own FeatherWing. I have another friend (named Dan, BTW) who has recently started using Feather boards for his projects.

    ReplyDelete
    Replies
    1. Thanks. Yeah, these are very powerful little boards with a lot of cool features. Great for projects.

      Delete