Sunday, January 31, 2016

Wi-Fi and OLED Upgrade for MightyOhm Geiger Counter

In this post I will show you how to add Wi-Fi connectivity and an OLED screen to the MightyOhm Geiger Counter kit. Lots of fun!

MightyOhm Geiger Counter kit with Wi-Fi and OLED!


I assembled my Geiger counter kit from MightyOhm some time ago. It's a very fun kit and the finished counter looks awesome. Oh, that Geiger-Muller tube sitting on that yellow PCB! I've always wanted to modify it somehow and add functionality. Today I realized that an Adafruit Feather sits PERFECTLY where the AAA battery holder normally goes. Doesn't it look like they belong together? I modified the counter, added a Feather HUZZAH ESP8266 with OLED FeatherWing, and whipped up some code. I'm very happy with the end result. Want to do the same to your kit? Let's get on with the tutorial.

Parts List

Here's what you need to complete this mod:

Code for this Project: Shared on Github


NOTE: Please read through this entire tutorial before starting the assembly. There are some important things to be aware of regarding power and program uploading.

First, solder headers to the Feather HUZZAH and OLED FeatherWing. Test those together with Adafruit's example program. If you are unfamiliar with the Adafruit Feather or OLED, I recommend checking out their tutorials. They can be found by clicking on the product links in the parts list above.

Next, assemble your MightyOhm Geiger counter kit. That is a full tutorial by itself. There is just one modification to the instructions. Do not attach the AAA battery holder. We have other plans for that space on the board. You can tack on some wires in its place to test the counter before you continue. If you bought the case, don't put it on yet.

If your kit is already assembled, you need to remove the battery holder. It doesn't require any special tools beyond a soldering iron. First take the case off if you have one. You might also want to remove the tube and put it in a safe place, it is fragile! Remove the nut holding the battery holder, then heat each contact pin one at a time while gently wiggling it back out.

We don't need the battery holder anymore. The Feather will provide 3V to the counter.

Now take a look at my example program. It will display information on the OLED screen, and also publish the radiation count data to your Adafruit IO account over Wi-Fi! You need to modify the program with your Adafruit IO account info, feed names, secret key, and router name/password. See the Adafruit MQTT tutorial for more information about this. Once you have modified the program, upload it to the Feather.

Next, a minimum of three wires need to be tacked onto the OLED FeatherWing. These will connect power and serial from the Feather it sits on to the counter. Look at the Feather HUZZAH's pinout and the pins on the FeatherWing. Find where 3V, Ground, and digital pin #13 would line up. Now cut and strip one end off of each jumper wire, leaving a Female end still attached to each. Solder the wires on the underside of the FeatherWing to the three pads just mentioned. Angle them so they will exit near the JST connector when attached to the Feather. See the next two images for clarification.

If you will want to add a DC jack to this project, also affix a fourth wire to the "USB" pin position. This is where 5V from USB normally goes. I used the JST connection to power the Feather so I did not attach this wire.

The red wire is 3V, the black wire is Ground, and green is pin #13.

Attach the FeatherWing to the Feather HUZZAH, being careful not to crush the wires. Test fit the assembly on the counter board to see where we are headed.

Looking good so far.

Before going any further, you need to know that the USB port will be obstructed once you finish mounting the Feather on the counter. Make sure you are happy with the loaded program before continuing.

Were you wondering why I said to use Female jumper wires instead of normal hookup wire? This is why. I highly recommend testing the program before finalizing assembly to make sure everything works, including your Adafruit IO info. At this point you can connect the Feather to the J6 and J7 headers on the counter. Connect to them as shown below with the wires you attached to the FeatherWing, power up the Feather with a USB cable, and test the assembly. This is also a good time to modify the program as you like.

Header connections on the Geiger counter for testing.

Everything working? Great, let's finish this up. Cut the female ends off of the three wires, strip them, and tin them. Put a piece of double-sided tape on the underside of the Feather HUZZAH and get ready to affix it in place.

Getting ready to attach the Feather assembly to the counter board.

You can use the top cover of the case to make sure the Feather is perfectly positioned. But it fits exactly where the AAA battery holder normally goes. Center it in that black box, and it will be positioned correctly with the case on. Peel off the backing on the double-sided tape and affix the Feather to the counter.

Now flip the board over. We have three connections that need to be made on the back. 3.3V and Ground will attach where the battery holder pins normally go. Also, the serial connection will attach to the Tx pin on J7 that we used earlier for testing.

Wiring on the back of the Geiger counter board. Pretty simple!

Now flip the board over and attach your Li-Po battery or alternate means of powering the Feather. The Feather will power up immediately. Flip the power switch on the counter to ON (yes it still works). After several seconds you should be up and running. The radiation count data will be displayed by default. Press the C button to check Wi-Fi status. If the Feather is not receiving serial data from the counter, it will warn you.


Large text counts-per-minute display. Get to this mode by pressing the B button.

The program will warn you if it is not receiving serial strings from the counter.

The data is streamed to your Adafruit IO account.

Reassemble the Geiger counter and case. You are done.


Using the modified Geiger counter with the example program is very easy. As long as you are in range of your Wi-Fi router, the Feather HUZZAH will automatically connect to Adafruit IO and publish data every five seconds. Press the C button on the OLED FeatherWing to see your Wi-Fi status and IP address.

The default view on the screen shows counts-per-second (CPS), counts-per-minute (CPM), and microSieverts per hour (uS/hr). This is the same data that is normally sent by the Geiger counter over serial. You can get back to this view later by pressing Button A.

Button B takes you to a display that only shows CPM in large digits. This is more readable if you want to see the count at a distance.

The Feather HUZZAH echoes the serial string from the counter across USB. This basically adds USB-to-Serial functionality to the counter, which would normally require an FTDI adapter. If you can find a way to squeeze a USB cable into the port when the Feather is mounted, that would be a great option for powering the Feather and doing PC logging. You might be able to use a USB cable with a right angle connector. I didn't have one to test.

Power Options

There are lots of ways to power the modified Geiger counter:
  • USB as just mentioned, IF you can fit a cable into the Feather
  • Li-Po battery through the JST connector on the Feather
  • Fit a DC jack to the project. It would only require adding a fourth wire to feed 5V to the "USB" pin on the Feather as described above. The regulator on the Feather will feed 3.3V to the counter.
  • Provide 3.3V and Ground to the J6 connector on the counter we used for testing. 

Mods to the Mod

You can modify the provided example program to do...anything you want. Adafruit has excellent libraries to help you design fancy display visuals and publish data online. The brains of the Feather HUZZAH is of course an ESP8266, so the options are nearly limitless.

If you just want the OLED display and not Wi-Fi, you can use a Feather M0 or Feather 32U4 instead and modify the example program.

If you want Bluetooth instead of Wi-Fi, use a Feather Bluefruit LE.

That's it! Please post any comments and corrections below. Good luck modifying your MightyOhm Geiger counter kit.

Thanks for reading.

- Dan W.

Friday, January 29, 2016

Arduino 32-bit Speed Test Shootout!

I benchmarked some Arduino 32-bit boards, including an Arduino 101, Arduino Due, Arduino Zero clone, and a chipKIT Uno32. I threw an Arduino Uno into the mix for comparison. Here are the results.

Spoiler: The chipKIT Uno32 won. :)

Test Setup

To benchmark these boards, I used an excerpt from the Arduino Show Info program. The sketch includes several speed tests that examine GPIO manipulation speed and raw computational speed. While each of the 32-bit boards tested is very fast, optimization in the IDE also comes into play when measuring performance. Even a 84MHz processor won't make up for poor code structure and inefficient register manipulation in the libraries. So instead of just comparing specs, let's put each board through tests that measure completion time of commonly used program functions.

For the Arduino boards, I used Arduino IDE 1.6.7. For the chipKIT Uno32, I used Mpide 0023.

Benchmarking Program Download: Shared on Github

Please examine this program to see exactly how each  test is structured.


Here are the benchmarking results. Each data point is the time to completion of the test in microseconds. Faster is better. The fastest board in each test is highlighted in green. I also highlighted two concerning results. Two of the tests could not be run on two of the boards due to compilation problems, as indicated.

The results of the speed tests.


The Arduino Due and chipKIT Uno32 were the clear winners here. Despite the release of newer Arduino boards, the Due can still hold its own in raw computational speed. There is no doubt that it will be relevant for some time to come with its SAM3X8E microcontroller and large number of GPIO. The dark horse in the test, the chipKIT Uno32, did extremely well. In fact, I have to say it was the winner. It had very fast and consistent GPIO manipulation speed, awesome floating point performance, and it was nearly the equal of the Due in integer math. How much of this is due to the microcontroller versus IDE optimization? I cannot say. But hats off to the creators of that nice little board. It seems to be discontinued, but you can still find it for sale at about $15 cheaper than a Due!

The Arduino 101 did pretty well considering the lower clock speed. It is not a "Due killer" and was never intended to be. While the raw computational speed isn't as fast as I was hoping for, we may see improvements for this board as the IDE is optimized and we get access to the RTOS under the hood. Also, keep in mind that speed is only part of the story. Do any of the other boards have Bluetooth and an accelerometer on board? No. As a potential Arduino Uno successor, the Arduino 101 is a good addition to the lineup.

Speaking of an Arduino Uno successor, the Arduino Zero has been billed as just such a board. I don't have an official Zero, but I did test Sparkfun's take on it, their SAMD21 Dev Board. Sadly, I was a bit disappointed. Sure the SAMD21 chip turned in some good numbers, but I feel that the Arduino Zero is too expensive for what it offers. It is slightly more expensive than a Due with lower performance and less GPIO. With the Arduino 101 out at $25 less in price, where does the Zero fit in? Less expensive Zero-compatible boards might be good alternatives if you want to explore the Cortex M0+ SAMD21 microcontroller.

The Arduino Uno rocked it! Well, ok, it looks pretty slow compared to the other boards. However, remember that it is extremely unfair to pit an 8-bit microcontroller against modern 32-bit devices in speed tests. The Uno still has enough processing power for the majority of hobbyist projects. It is a classic board that will be around for years to come.

There were two concerning results that I highlighted on the table. Analog read performance on the Arduino Zero clone is abysmal! There has to be something wrong in the IDE there. Nearly half a millisecond to read an analog pin is unacceptable. Hopefully it will be fixed in the near future. Also, dstostrf() speed on the Arduino 101 was far too slow. Once again, this has to be due to optimization problems in the IDE. That is not a commonly used function so I doubt many people will notice.


That's it! I hope you found this shootout useful. Download the sketch above and benchmark your own boards and microcontrollers, it's a lot of fun.

If you would like to see a similar shootout with small AVR, PIC and ARM microcontrollers, such as the ATtiny and STM32F030 devices, please post in the comments below. Also post any comments and corrections.

Thanks for reading!

- Dan W.

Monday, January 25, 2016

MultiNav FeatherWing for Adafruit Feather

This post will serve as documentation for the MultiNav FeatherWing for Adafruit Feather.

GPS + 9DOF for your Adafruit Feather!


The MultiNav FeatherWing is an add-on board for Adafruit Feather. It incorporates a U-Blox NEO-6M GPS module as well as an InvenSense MPU-9250 9 Degrees of Freedom (9DOF) sensor.

The board includes the following additional features:
  • Micro USB connector to connect to the U-Blox GPS. It is accessible using the free U-blox u-center application for configuration and monitoring.
  • u.FL connector for the GPS antenna (supports active antennas, 3.3V or 5V)
  • EEPROM for storing U-Blox configuration between power cycles
  • Power and GPS Pulse-per-second (PPS) LEDs
  • Interrupts broken out for GPS PPS and MPU-9250 interrupt pin


The MultiNav FeatherWing is compatible with Feather M0, 32U4, and HUZZAH. However, the MPU-9250 interrupt pin and GPS PPS interrupt are only accessible with Feather M0 as hardware interrupts.

This FeatherWing may be compatible with other official FeatherWing boards that only use the I2C bus. The MPU-9250 uses I2C with the fixed address 0x68. For FeatherWings that also use GPIO, check the pin usage on the schematic of both FeatherWings to determine compatibility.

For example, the OLED FeatherWing is compatible for simultaneous use with the MultiNav FeatherWing as long as the interrupt solder jumpers are left disconnected.

Shared Files

OSHPark Shared Project - Order PCBs!

Eagle Files: Shared on Github
MultiNav FeatherWing Schematic

MultiNav FeatherWing Board Layout


Assembling the MultiNav FeatherWing will require good SMT soldering skills, including having to solder a fine-pitched QFN and castellations.

All part values are shown on the schematic. Most of the passives are 0603. The only exception is L1, which is an 0402 inductor. A handful of parts have specific requirements:
  • GPS Module: U-Blox NEO-6M (Should also be compatible with NEO-7M, but I have not tested this yet)
  • 9DOF: InvenSense MPU-9250 
  • EEPROM: MicroChip 24AA32ASN 8-SOIC or ST M24C32 8-SOIC
  • L1 Inductor: Murata LQG15HS27NJ02D (any substitute must have similar specs)
  • Micro USB: FCI 10103594-0001LF



The U-Blox GPS on the MultiNav FeatherWing is accessible via UART serial. Before use, you must configure solder jumper JP3 on the underside of the board based on your chosen Feather.

  • For 32U4, bridge Option A and use Software Serial. Pin D10 is Tx, and Pin D11 is Rx.
  • For HUZZAH, bridge Option A and use SoftwareSerial. Pin D10 is Tx, and Pin D12 is Rx.
    • Note: SoftwareSerial for ESP8266 is still largely under development. Here's a good library I used, but it is Receive only.
  • For M0, bridge Option B and use SERCOM1 as shown in the provided example program.

The MPU-9250 is accessible via I2C. It uses the standard SDA and SCL pins, so it is usable on any Feather board. Pull-up resistors for I2C are included in the design of this board.

Two interrupt signals are available when using this board with Feather M0:
  • The interrupt pin from the MPU-9250 goes to pin D5 on M0. If you want to use this interrupt, you must bridge the JP1 solder jumper on the underside of the board. Unfortunately, this pin is not usable with attachInterrupt on the 32U4 and HUZZAH. For HUZZAH, leave JP1 disconnected to prevent boot loading issues.
  • The GPS PPS goes to pin D6 on M0. If you want to use this interrupt, you must bridge the JP2 solder jumper on the underside of the board. Unfortunately, this pin is not usable with attachInterrupt on the 32U4 and HUZZAH. For HUZZAH, leave JP2 disconnected to prevent boot loading issues.

  • The PPS LED will blink at the beginning of each UTC second. This signal is generated by the U-Blox GPS module. It's a good way to know when you have GPS signal, as the LED will not blink when signal is lost, or the GPS module is still acquiring satellites. Because this signal is also available as an interrupt on M0, it is a very powerful feature for synchronized and time-critical tasks.
  • An EEPROM is provided on the board for storing U-Blox configuration between power cycles. No backup battery is available on the MultiNav FeatherWing, as the Feather boards have built-in Li-Po battery connections and charging.
  • The USB connector on the MultiNav FeatherWing will also provide power to the Feather (VBUS).
  • The orientations of the various axes on the MPU-9250 are printed in the silk screen of the board.
  • The I2C address of the MPU-9250 is fixed as 0x68.

The MultiNav FeatherWing is released as Open Source Hardware (OSHW) under Creative Commons 2.5 Share-Alike / Attribution license. The same license as Adafruit Feather. Build it, modify it, use it and enjoy!

Thanks for reading!

- Dan W.

Tuesday, January 19, 2016

Exploring the I/O Performance of the Arduino 101

In this post I will explore the hardware input/output (I/O) performance of the recently-released Arduino 101.

The new, yet somehow familiar, Arduino 101.


Though many of my personal projects have moved beyond the Arduino eco-system, I still enjoy keeping up with the Arduino line of boards. The newly-available Arduino 101 is a very intriguing addition to the line-up. It packs an Intel Curie system-on-chip (SoC), Bluetooth Low Energy (BLE), and a six-axis accelerometer and gyroscope. Despite these new features, it only costs $30 USD and is surprisingly familiar to hold in the hand. The pinout is similar to an Arduino Uno, with power, digital I/O, and analog inputs in the usual places.

The Quark microcontroller inside the Curie SoC runs the ViperOS real-time operating system (RTOS), which Intel is promising to open-source at some point. That will present some intriguing options for advanced hobbyists and developers to extract maximum performance from the board. For now, we can program it using the Arduino IDE. As I understand it, you don't really "flash" an Arduino 101, but rather upload a new sketch for the RTOS to execute itself.

Though the Arduino IDE makes developing code for projects very easy, it also imposes performance penalties. This is especially noticeable when you are trying to stretch the limits of the I/O. I just unpacked my new Arduino 101. Before delving into the example projects for the board or attempting to port some of my previous projects over, I thought I'd have a look at the performance of the board's I/O lines.

5V Tolerant?

Here's the big question many will ask: Are the I/O pins 5V tolerant? Well, yes they are. Arduino says that the I/O lines on the 101 are 3.3V, but will not be damaged by 5V inputs. Clearly the Curie itself (a modern SoC) is not going to be a 5V device, so let's examine the schematic for the Arduino 101 and see how they accomplish this.

Level Translation on the Arduino 101. (Source:

The board uses three Texas Instruments LSF0108 level translators to accommodate all of the I/O lines (including the analog inputs). This is an interesting part. It's not really a level "shifter", and it's not a buffer. The Curie is still sourcing and sinking current to the pins, but the voltage levels are clamped at 3.3V on the Curie's side of the chip. In this regard it's kind of like a fancy analog switch. The on resistance of each signal path is in the neighborhood of 10 ohms.

The fact that the Curie sources and sinks current to the I/O pins is important to keep in mind. The original specs released for the Arduino 101 claimed a max current per pin of 4 mA. That is quite low, especially when you consider the fact that many Arduino tutorials show circuits that would easily exceed the limit. However, it seems that the maximum current per pin is actually 20 mA, based on a post in the Arduino forum and the now-updated product page. I would still like to see more information on current limits, including any limits for I/O banks and the SoC overall limit.

Digital Output Signals

Enough talk, let's look at some signals. For a first test, I programmed the board to toggle digital pin 12 as fast as possible with the standard digitalWrite() routine. The main loop was free-running with no delays. The Arduino 101 was able to produce a 114kHz square wave with this routine. I measured the rise-time at about 13ns on my scope. We aren't going to set the world on fire with the Arduino digitalWrite routine, but at least we know what we can expect as an upper limit. Knowing these performance limits might be important until we get lower-level access to the I/O.

The output transitions looked very clean with almost no ringing. It's possible the small on resistance of the level translator combined with the capacitance of my scope probe (a low-pass filter) helped in this regard. I'd like to explore the characteristics of the LSF0108 more in the future.

Toggling D12  on the Arduino 101 with a free-running main loop.

Rise time on D12 digital output on the Arduino 101.

For comparison, the free-running loop test on an Arduino Uno generated a square wave with a frequency of about 85.5 kHz. Clearly the processing speed of the Curie will be seen when doing complex mathematical operations, not when twiddling I/O pins.

Toggling D12 on an Arduino Uno with a free-running main loop.

Digital Input Logic Transitions

I applied a DC voltage to pin D7 and varied it up and down while the Arduino 101 reported the logic state in the serial monitor. This was done in order to discover the logic transition levels. Going from high to low, it returned a low state after crossing 1.26V. Going from low to high, however, the transition occurred at 1.55V.

Digital Output Voltage Level Under Load

For the next test, I set pin D7 high and connected it to a variable DC load. I checked the output voltage level at different output currents. With no load, the output voltage was 3.27V. With a 1 mA load, it was 3.18V. At 4 mA, it dropped to 3.04V. Seeing this droop, I didn't proceed to test the rated 20 mA of pin current. The on resistance of the level translator would have made a small contribution to this, but I do suspect that the Curie's output drivers are not extremely robust. I would keep pin currents as low as possible when using the Arduino 101's I/O pins.

Pulse-Width Modulation (PWM)

The Arduino 101 has four PWM outputs (digital pins 3, 5, 6, and 9). This is slightly disappointing, as we have come to expect nearly every pin to be PWM capable on modern 32-bit microcontrollers. I couldn't find documentation on the PWM frequencies used, so let's measure them.

PWM Output on Pin D6.

I found that pins D3 and D9 produced PWM signals with frequencies of 490 Hz. Pins D5 and D6 produced PWM signals with frequencies of 980 Hz. This coincidently matches the PWM frequencies used on the Arduino Uno. I suspect this was only done for compatibility, and presumably an option can be added in the future to change these frequencies. (I wouldn't even be surprised if the RTOS is just toggling these pins at the prescribed frequency and duty cycle to mimic PWM).

Analog Input Linearity

Next I tested the analog inputs. I was curious if the level translators affect the accuracy of the readings. I applied a DC voltage on pin A5, starting at 0V and increasing to 3.3V in 100 mV steps. At each step, I recorded the 10-bit analog-to-digital (ADC) readings reported by the Arduino 101. I then created a graph of the data, which is shown below. As you can see, the results are pretty linear across the entire input range. Spot-checking a few values, I found that there might have been a +20mV bias on the readings at the top end of the scale. However, I would have to tighten up my test setup to verify that. I plan to explore it more in the future.

A graph of analog input voltages versus reported ADC readings.


My initial impressions of the Arduino 101 are very positive. Besides the good test results shown above, the board is very easy to program and work with. The integration with the IDE is seamless, as you would expect from the Arduino eco-system. Uploads are very fast (a couple of seconds) and go the first time. No hitting upload two or three times like on many of the newer 32-bit boards.

There are hundreds of additional tests that could be performed, including benchmarking of real-time code execution. If you would like to see any additional tests in a follow-up post, post them below. Also, please post any comments and corrections.

Thanks for reading!

- Dan W.

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.


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.


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.


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.

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.