# Adafruit NeoPXL8 FeatherWing and Library

## Overview

 **NeoPixels** are magical things. It couldn’t be simpler…a _single data wire_ from the microcontroller, linking pixel to pixel for as long as you need.&nbsp;When NeoPixel projects get really large though…_hundreds_ of pixels or more…this simplicity starts to become a **bottleneck** …

- The standard NeoPixel data rate is a fixed **800 KHz** , or 30 microseconds per 24-bit pixel. As projects scale into the hundreds or thousands of pixels, the time spent issuing all that data reaches progressively larger fractions of a second; animation becomes **less smooth**.
- While this data is being transmitted, _all other processing_ on the microcontroller **stops** , including interrupts which keep track of time. This is why the millis() and micros() functions gradually drift in NeoPixel projects.

![](https://cdn-learn.adafruit.com/assets/assets/000/054/678/medium800/leds_banner.jpg?1527659513)

 **NeoPXL8** (pronounced “NeoPixelate”) is a hardware-and-software combo that works around these limitations to bring buttery **smooth animation** to **large-scale NeoPixel projects**.

NeoPXL8 splits the problem **8 ways** : rather than one long strand of, say, 1,000 pixels\*, eight strands of 125 pixels can operate concurrently in perfect sync. It’s like shoving two whole Kit Kats® in your mouth “the illegal way” instead of nibbling one bar at a time. Data transmission times are greatly reduced and animation can remain smooth.

![](https://cdn-learn.adafruit.com/assets/assets/000/088/737/medium800/leds_neopxl8-candy.png?1582779505)

\* Hypothetical situation, not an imposed limit. Depends on available RAM, but most “M0” (SAMD21) boards might handle upwards of 2,500 pixels, with “M4” (SAMD51) and RP2040 potentially up to 15,000…but in reality, you’ll want some _fraction_ of that, so your code has time to _compute_&nbsp;those pixels.

Additionally, NeoPXL8 uses **direct memory access (DMA)** to allow the CPU to **continue with other tasks** while these data transfers take place in the background. Your code could start processing the next frame of animation, or load data from an SD card. All interrupts and timekeeping functions operate normally, no drift.

**The NeoPXL8 code relies on features unique to the SAMD21, SAMD51, RP2040 and ESP32-S3 microcontrollers — it should work on any Adafruit “M0” or “M4” board, the Arduino Zero, most RP2040 boards like the Raspberry Pi Pico, and most ESP32-S3 boards (but _not_ S2, C3 or original ESP32). _It will not work on other architectures._**

The NeoPXL8 **FeatherWing** adapters provide&nbsp; **8 NeoPixel outputs** with **5-Volt logic level shifting** , and it stacks directly atop any of our **M0 or M4 Feather** boards — Basic Proto, Adalogger and so forth. _(Note there are different versions for Feather M0 vs M4, they are not interchangeable!)_ With a minor change, the M4 version can work with the **Feather RP2040**. _Either one_ works with **Feather ESP32-S3**.

The **NeoPXL8 Friend** breakout board provides similar functionality in a non-FeatherWing format, making it handy for use with boards like the Metro Express or ItsyBitsy M0 Express (and their respective M4 variants) or the Raspberry Pi Pico.

# Adafruit NeoPXL8 FeatherWing and Library

## NeoPXL8 FeatherWings

![](https://cdn-learn.adafruit.com/assets/assets/000/054/675/medium800/leds_neopxl8-kit-contents.jpg?1527643430)

For NeoPixel projects starting with one of our&nbsp; **Feather M0** or **M4** &nbsp;board variants, a **NeoPXL8 FeatherWing** &nbsp;can simplify and make sense of the wiring…the boards are designed to be stacked. **Some soldering and “maker skills” are required.**

**There are two distinct versions of the NeoPXL8 FeatherWing: one for M0 boards, the other for M4. The two are _not_ interchangeable.**

Warning: 

Warning: 

The **M4** version of the FeatherWing can also be used with the **Adafruit Feather RP2040** with just a small modification. Finish reading this page for general connection tips,&nbsp;then visit the “RP2040 Use” page for the fix.

_Either_ version of the FeatherWing can also work with the **Adafruit Feather ESP32-S3** without modification. But _only_ the S3; the ESP32-S2 and original ESP32 are _not_ supported.

# Connections: Two Types

The NeoPXL8 FeatherWing can be assembled **one of two ways** depending on your preferences and needs. You must&nbsp; **choose beforehand** what kind of connectors your project needs, as there’s **not enough room for both at once…**

Populating the **8x2** row header at the center of the board (16 pins total) provides a “ **Fadecandy-style** ” connection.

[Fadecandy](https://www.adafruit.com/product/1689) is a USB NeoPixel controller popular in large-scale LED installations. The 8x2 connector is fairly compact and low-profile. Assembled this way, the NeoPXL8 Feather-and-Wing combo could, with suitable Arduino code, function as a swap-in replacement in an existing Fadecandy project, or could make use of NeoPixels already wired for such.

![leds_3249-04.jpg](https://cdn-learn.adafruit.com/assets/assets/000/054/673/medium640/leds_3249-04.jpg?1527643306)

Populating the **two RJ45 connectors** &nbsp;at the board ends provides an “ **OctoWS2011-style** ” connection.

[OctoWS2811](https://www.adafruit.com/product/1779) is a similar hardware-and-software combo for large NeoPixel setups using the [PJRC Teensy 3.2](https://www.adafruit.com/product/2756) microcontroller. These connections are bulkier but latch into place and ensure a specific polarity. Assembled this way, the NeoPXL8 Feather-and-Wing combo could, with suitable Arduino code, function as a swap-in replacement in an existing OctoWS2811 project, or could make use of NeoPixels already wired for such.

![leds_3249-05.jpg](https://cdn-learn.adafruit.com/assets/assets/000/054/674/medium640/leds_3249-05.jpg?1527643330)

 **In either case, the NeoPixel headers mount on the _FLAT SIDE_ of the NeoPXL8 FeatherWing — the side with NO COMPONENTS — and are soldered on the _component side._ The Feather-stacking pins are done the OPPOSITE way — install from the component side, solder on the flat side.** See the photos above for reference.

**Additionally, you still need to build a _wiring harness_ between these connectors and your NeoPixel LEDs. The above is just a starting point.**

Adopting these two wiring schemes mean that **any&nbsp;existing tutorials** for wiring up Fadecandy or OctoWS2811 projects **are applicable to NeoPXL8** as well — it’s not starting over with a third incompatible standard.

[This tutorial shows some Fadecandy-style wiring harnesses being made](https://learn.adafruit.com/1500-neopixel-led-curtain-with-raspberry-pi-fadecandy/fadecandy-wiring-harness), using a ribbon cable and 8x2 IDC header, plus lots of soldering and heat-shrink. A multimeter with continuity beep is helpful in keeping track of data wires and grounds!

[The OctoWS2811 product page on the PJRC web site](https://www.pjrc.com/store/octo28_adaptor.html) shows RJ45 wiring harnesses being made by cutting open Ethernet cables.

**You will also need to safely distribute 5 Volt power to all of your NeoPixels.** This is **not** done through the NeoPXL8 board — it needs to be **part of your wiring harness**. [This tutorial explains](https://learn.adafruit.com/1500-neopixel-led-curtain-with-raspberry-pi-fadecandy/power-topology) some of the issues in powering large-scale NeoPixel installations.

# Pin Selection
Because we’re using hardware tricks, **NeoPXL8 output works only on specific pins**. Some are set in stone, others give _some_ control in that you can select an alternate pin. This may be helpful if using a Feather or Wing with its own peripheral pin constraints (wireless, perhaps)…sometimes you can re-route some signals and keep full functionality.

Depending on what additional hardware you’re interfacing, it’s possible that _neither_ selection will work…one peripheral or another absolutely requires that pin. In such cases, you can use NeoPXL8 with fewer than 8 outputs. We’ll elaborate further on the “Library” page.

 **Keep track of your selections. Write it down somewhere. You’ll need this information when writing Arduino sketches using the NeoPXL8 library.**

The pin selection is a little different between the M0 and M4 FeatherWings…

# For **M0** NeoPXL8 FeatherWing only…
![](https://cdn-learn.adafruit.com/assets/assets/000/054/676/medium800/leds_sudoku.jpg?1527649289)

Let’s refer to NeoPXL8’s eight outputs as “0” through “7,” sequentially. Outputs 3, 6 and 7 are fixed to specific Feather pins (13, A4, A3) and _cannot_ be changed, period. Outputs 0, 1, 2, 4 and 5 offer a “this” or “that” choice.

On the component side of the FeatherWing you’ll see several **solder pad** groups, labeled “N0”, “N1”, “N2”, “N5” and “N4”. Pay careful attention to those numbers…they are neither sequential nor contiguous (partly because three pins are fixed, partly because it was more practical to route the board this way).

Each of these five pins has a default assignment. To change a pin to an alternate setting, use a hobby knife or file to cut the trace between the center and default pads, then apply a solder bridge between the center and alternate pad.

# For **M4** NeoPXL8 FeatherWing only…

These rules apply only to the **Feather M4** board. For Feather RP2040, see the “RP2040 Use” page.

![](https://cdn-learn.adafruit.com/assets/assets/000/088/738/medium800/leds_neopxl8-m4.jpg?1582782874)

Let’s refer to NeoPXL8’s eight outputs as “0” through “7,” sequentially. Outputs 4, 5, 6 and 7 are fixed to specific Feather pins (13, 12, 11 and 10) and _cannot_ be changed, period. Outputs 0, 1, 2, and 3 offer a “this” or “that” choice.

On the component side of the FeatherWing you’ll see several **solder pad** groups, labeled “n0”, “n1”, “n2” and “n3”.

Each of these four pins has a default assignment. To change a pin to an alternate setting, use a hobby knife or file to cut the trace between the center and default pads, then apply a solder bridge between the center and alternate pad.

# Adafruit NeoPXL8 FeatherWing and Library

## NeoPXL8 Breakout Board

![](https://cdn-learn.adafruit.com/assets/assets/000/063/297/medium800/leds_3975-01.jpg?1539109946)

If you’re working on a solderless breadboard or aren’t using a Feather form-factor microcontroller, the [**Adafruit NeoPXL8 Friend**](https://www.adafruit.com/product/3975) provides similar utility to the NeoPXL8 FeatherWing but in a non-FeatherWing package.

The NeoPXL8 Friend breakout board provides logic level shifting from 3V devices to as many as eight NeoPixel strips, which can be connected one of two ways:

The&nbsp; **8x2** row header (16 pins total) provides a “ **Fadecandy-style** ” connection.

[Fadecandy](https://www.adafruit.com/product/1689) is a USB NeoPixel controller popular in large-scale LED installations. The 8x2 connector is fairly compact and low-profile. Assembled this way, the NeoPXL8 Friend could, with suitable Arduino code, function as a swap-in replacement in an existing Fadecandy project, or could make use of NeoPixels already wired for such.

The **two RJ45 connectors** &nbsp;provide an “ **OctoWS2011-style** ” connection.

[OctoWS2811](https://www.adafruit.com/product/1779) is a similar hardware-and-software combo for large NeoPixel setups using the [PJRC Teensy 3.2](https://www.adafruit.com/product/2756) microcontroller. These connections are bulkier but latch into place and ensure a specific polarity. Assembled this way, the NeoPXL8 Friend could, with suitable Arduino code, function as a swap-in replacement in an existing OctoWS2811 project, or could make use of NeoPixels already wired for such.

 **In either case, the NeoPixel headers mount on the _FLAT SIDE_ of the NeoPXL8 Friend — the side with NO COMPONENTS — and are soldered on the _component side._ The breadboarding pins are done the OPPOSITE way — install from the component side, solder on the flat side.**

![leds_3975-06.jpg](https://cdn-learn.adafruit.com/assets/assets/000/063/299/medium640/leds_3975-06.jpg?1539110710)

![leds_3975-04.jpg](https://cdn-learn.adafruit.com/assets/assets/000/063/300/medium640/leds_3975-04.jpg?1539110721)

 **Additionally, you still need to build a _wiring harness&nbsp;_between these connectors and your NeoPixel LEDs. The above is just a starting point.**

Adopting these two wiring schemes mean that **any&nbsp;existing tutorials** for wiring up Fadecandy or OctoWS2811 projects **are applicable to NeoPXL8** as well — it’s not starting over with a third incompatible standard.

[This tutorial shows some Fadecandy-style wiring harnesses being made](https://learn.adafruit.com/1500-neopixel-led-curtain-with-raspberry-pi-fadecandy/fadecandy-wiring-harness), using a ribbon cable and 8x2 IDC header, plus lots of soldering and heat-shrink. A multimeter with continuity beep is helpful in keeping track of data wires and grounds!

[The OctoWS2811 product page on the PJRC web site](https://www.pjrc.com/store/octo28_adaptor.html) shows RJ45 wiring harnesses being made by cutting open Ethernet cables.

**You will also need to safely distribute 5 Volt power to all of your NeoPixels.** This is **not** done through the NeoPXL8 board — it needs to be **part of your wiring harness**. [This tutorial explains](https://learn.adafruit.com/1500-neopixel-led-curtain-with-raspberry-pi-fadecandy/power-topology) some of the issues in powering large-scale NeoPixel installations.

A third option is to install header pins on the NeoPixel outputs, so both the “ins” and “outs” are breadboardable…this may be useful for certain prototyping tasks.

There isn’t clearance for the outputs on a regular-size breadboard, but linking two breadboards side-by-side is often done with wider devices like this.

![leds_3975-05.jpg](https://cdn-learn.adafruit.com/assets/assets/000/063/301/medium640/leds_3975-05.jpg?1539110819)

Unlike the FeatherWing, the NeoPXL8 Friend has space for _both_ an **8x2 row header** _and_ two **RJ45** connectors at the same time.

**HOWEVER** , if using the 8x2 connector, depending how one’s ribbon cable is crimped and strain-relieved, the RJ45 connectors may still be in the way…so you may want to leave those two connectors off unless you’re certain to need them.

![leds_3975-02.jpg](https://cdn-learn.adafruit.com/assets/assets/000/063/298/medium640/leds_3975-02.jpg?1539110173)

Because we’re using hardware tricks, **NeoPXL8 output works only on specific microcontroller pins**. The Arduino library examples explain in more detail. On boards like the Adafruit Metro Express or Arduino Zero, it’s conveniently on digital pins 0 through 7, so you can use an 8-pin ribbon cable to link directly to the NeoPXL8 Friend’s 8 inputs. In other situations, the pins may be strewn in different places around the board.

# Adafruit NeoPXL8 FeatherWing and Library

## NeoPXL8 Arduino Library

The **Adafruit\_NeoPXL8** library can be installed using the **Arduino Library Manager**. You will also need the **Adafruit\_NeoPixel** and **Adafruit\_ZeroDMA** libraries.

![](https://cdn-learn.adafruit.com/assets/assets/000/054/688/medium800/leds_libmanager.png?1527696471)

![](https://cdn-learn.adafruit.com/assets/assets/000/054/689/medium800/leds_neoplx8.png?1527696749)

Remember to install the correct&nbsp; **board support** package through the **Boards Manager:**

- **Adafruit SAMD** for Adafruit M0 and M4 boards
- **Arduino SAMD** for Arduino Zero and similar
- **Pico/RP2040 Earle F. Philhower III** for Feather RP2040 and SCORPIO
- **esp32** for Feather ESP32-S3

# Example Code

There is a single Adafruit\_NeoPXL8 example sketch called “strandtest,” and it’s pretty minimal. There’s _no need_ for a whole graphics demo, because **most NeoPXL8 functions are identical to their NeoPixel counterparts** , and there are plenty of NeoPixel examples around already. The differences mostly relate to pin assignments.

First, include Adafruit\_NeoPXL8.h instead of Adafruit\_NeoPixel.h:

```
#include &lt;Adafruit_NeoPXL8.h&gt;
```

Then declare an **Adafruit\_NeoPXL8** object (instead of an Adafruit\_NeoPixel object) — we’ll call our object “leds” in the example — passing up to three arguments:

```
Adafruit_NeoPXL8 leds(LENGTH, PINS, FORMAT);
```

The constructor’s&nbsp; **first argument** is the number of NeoPixels in **each** of the eight strands. In other words, the total number of NeoPixels will be **8 times** this value. If this value is set at 60, then the total number of NeoPixels is 480 (60 × 8).

The strands _don’t_ all need to be the same length. In that case, give the length of the _longest_ strand. But from the software’s point of view there’s still 8 times this many pixels…it’s going to require that much memory regardless and there will be gaps in how pixels are addressed. It’s _best and optimal_ if all 8 strands are in use and the same length, but not _required._

NeoPXL8 is a RAM hog, but on most M0 boards, depending on your code’s other needs, you can often get 250 RGB pixels per strand (2,000 pixels total). 300 (2,400 total) is starting to push things. Scale back for RGBW pixels, which require about 33% more RAM.

M4 boards have _six times_ the RAM and can handle absurd _thousands_ of pixels…but in reality, you might not want more than a couple thousand, tops, just to allow the CPU enough time to _compute_ all those pixels at a good frame rate. For an M0 project, maybe a few hundred to a thousand or so. There’s no hard limit, you just need to experiment what’s practical to compute.

The **second argument** is an 8-element int8\_t array indicating which pins to use for outputs 0 through 7.

**This is _extremely_ hardware-dependent** , and you’ll see in the strandtest sketch there are several different arrays given for different situations. For example, using a Feather M0, NeoPXL8 FeatherWing with the default pin assignments and the Fadecandy-style connector, it’s:

```
int8_t pins[8] = { PIN_SERIAL1_RX, PIN_SERIAL1_TX, MISO, 13, 5, SDA, A4, A3 };
Adafruit_NeoPXL8 leds(NUM_LED, pins, NEO_GRB);
```

As explained on the prior page, on the **Feather M0** , outputs 3, 6 and 7 are **not negotiable** — they _must_ go to pins 13, A4 and A3 (these can be _reordered_ — you can change which is considered output 3, 6 or 7 — but you cannot select completely different pins). For the remaining 5 outputs, there’s a limited ability to reassign things:

 **Feather M4** is a little different. There, outputs 4 through 7 are **not negotiable** — they _must_ go to pins 13 through 10 (though they can be _reordered_ within that series). For the other four outputs, there’s a limited ability to reassign things:

**Changing these assignments requires cutting and bridging pads on the component side of the FeatherWing board, plus _matching changes_ to the pins[] array.**

If _neither_ pin choice will work for your application, use a value of **-1** for that element of the pins[] array, as many as required. You will lose the corresponding NeoPixel output, and it will still take up RAM and pixel indices as if it were there, but the pin can then be used for normal GPIO.

 **Different boards will have different pinouts** , you’ll see this in the example code. The Metro M4 uses an entirely different set of pins. And on the Metro M0 (or Arduino Zero), things are super easy…if you want to use digital pins 0-7 as the eight NeoPixel outputs, just pass NULL instead of a pins[] array, or leave this argument off entirely. **RP2040** boards have their own rules, explained on the next page.

The **third argument** to the constructor is the NeoPixel data format or&nbsp; **color order**. Different manufacturers of “NeoPixel compatible” LEDs may use a different R/G/B (and sometimes W) byte order…and even among single manufacturers, different production runs may change the order as required for big customers or if they find it can economize the design. This is very similar to the last argument to the&nbsp;Adafruit\_NeoPixel constructor, except any&nbsp;NEO\_KHZ800 or&nbsp;NEO\_KHZ400 values are ignored (only 800 KHz is supported). You can leave this argument off to use the default&nbsp;NEO\_GRB color order.

All 8 strands must be the **same type and color order** ; e.g. you cannot mix RGB and RGBW NeoPixels.

 **From a coding perspective, the rest appears nearly identical to a regular NeoPixel sketch.**

Call the object’s begin() function to allocate memory and initialize the pin outputs:

```
  leds.begin();
```

You can check for a return value of “true” to confirm the allocation was successful.

Then `setPixelColor()` to modify individual pixel values and show() to issue data to the strands, just like a regular NeoPixel sketch.

For functions that take a pixel index (e.g. setPixelColor(), getPixelColor()), **all the pixels are treated as if one long continuous strand**. For example:

If the strand **length** was declared as **60** …that’s 480 pixels total…

- Pixels 0 – 59 are on strand 0
- Pixels 60 – 119 are on strand 1
- Pixels 120 – 179 are on strand 2
- Pixels 180 – 239 are on strand 3
- Pixels 240 – 299 are on strand 4
- Pixels 300 – 359 are on strand 5
- Pixels 360 – 419 are on strand 6
- Pixels 420 – 479 are on strand 7

This is true even if some strands are physically shorter, or if an element in the pins[] array is -1. The unused bits just vanish into the unknown, like that one light switch that doesn’t seem to control anything in the house.

One small difference from `Adafruit_NeoPixel` is that the `setBrightness()` function, in combination with `setPixelColor()` and `getPixelColor()`, work better here. The original color value assigned to a pixel using `setPixelColor()` will _always_ be accurately returned by `getPixelColor()`, regardless of the current brightness setting. In `Adafruit_NeoPixel` this is a “destructive” operation and only an approximation is returned.

That’s the vital stuff to know.

## [**Remaining functions and esoterica are documented on GitHub.**](https://adafruit.github.io/Adafruit_NeoPXL8/html/index.html)
 **Also maybe helpful:** if using other NeoPixel code as a starting point, [this blog post](https://blog.adafruit.com/2022/07/11/neopixel-arduino-library-best-practices/) discusses some&nbsp;out-of-favor techniques and how to write more modern NeoPixel code. If it’s using the `wheel()` function, it’s old!

# Adafruit NeoPXL8 FeatherWing and Library

## RP2040 and RP2350 Use

NeoPXL8 now also works on boards with the **RP2040** and&nbsp; **RP2350**  **microcontrollers** , such as the [Raspberry Pi Pico](https://www.adafruit.com/product/4864), [Raspberry Pi Pico 2](https://www.adafruit.com/product/6006), or [Adafruit Feather RP2040](https://www.adafruit.com/product/4884).

By and large it functions the same, with just some minor changes to the rules…

- Requires the **Earle Philhower RP2040** board support in Arduino, _not_ Mbed RP2040. If you don’t already have this installed, [the steps are documented in this guide.](https://learn.adafruit.com/rp2040-arduino-with-the-earlephilhower-core/installing-the-earlephilhower-core)
- The pin list passed to the constructor…rather than Arduino pin numbers (silkscreened on the top of some boards), this requires **GPIO bit numbers** , which aren’t always the same. On the Feather RP2040 and ItsyBitsy RP2040, GPIO bit numbers are silkscreened on the _bottom_ of the board. On Raspberry Pi Pico, the numbers are the same, and Pico guidelines such as avoiding GP15 apply.
- The 8 GPIO bits must be **contiguous** , e.g. GP00 through GP07. They do _not_ need to be _aligned_ to any particular boundary though, just _contiguous._ 1–8, 3–10 and so forth.
- It’s more efficient with RAM, requiring about 2X as much as the regular single-strand NeoPixel library, vs. 4X RAM on SAMD chips. And the RP2040 already has _lots_ of RAM!

## Hardware

Since RP2040 and **RP2350** are **3.3 Volt** devices, you’ll want to convert logic levels to the NeoPixel supply voltage ( **5V** typ.).

For most boards, our [**NeoPXL8 Friend**](https://www.adafruit.com/product/3975) does this nicely. It’s explained further on the “NeoPXL8 Breakout Board” page of this guide.

However…_if_ you’re using a [**Feather RP2040**](https://www.adafruit.com/product/4884), and _if_ you’re comfortable with some fine soldering, our [**NeoPXL8 FeatherWing M4**](https://www.adafruit.com/product/4537) (_not_&nbsp;the M0 version) can be adapted. Then you have a tidy package with less wiring!

If the work looks troublesome for your current soldering skill, no worries, you can still wire up a NeoPXL8 Friend. And to reiterate, this modification specifically requires the **M4** version of the FeatherWing.

Locate the **n0** selector pads on the FeatherWing and use an X-Acto knife or small file to **cut the trace** between n0 and SCK.

![leds_neopxl8-rp2040-trace-1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/104/746/medium640/leds_neopxl8-rp2040-trace-1.jpg?1631915548)

![leds_neopxl8-rp2040-trace-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/104/747/medium640/leds_neopxl8-rp2040-trace-2.jpg?1631915577)

Solder a short piece of insulated solid-core wire between the now-isolated **n0** &nbsp;surface pad and the last through-hole via in this row.

If you’ll be using the RJ-45 connections for pixels, make sure this wire clears the mounting hole in the board.

This step may take a few tries and some desoldering wick. Those pads are _designed_ for solder bridges, but now we want to keep n0 isolated.

Remember when installing the headers that these components are on the _bottom_ of the FeatherWing.

![leds_neopxl8-feather-mod-1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/104/749/medium640/leds_neopxl8-feather-mod-1.jpg?1631916677)

![leds_neopxl8-feather-mod-2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/104/750/medium640/leds_neopxl8-feather-mod-2.jpg?1631916689)

 **All other selectable pins — n1 through n3 — should be left in their default configurations.**

## Software

The strandtest Arduino sketch includes some processor-specific notes. You’ll need to set up the pins[] list and call the constructor like so:

```auto
int8_t pins[8] = { 6, 7, 9, 8, 13, 12, 11, 10 }; // GP## indices!
Adafruit_NeoPXL8 leds(NUM_LED, pins, NEO_GRB);
```

On the Feather RP2040, those correspond to digital pins&nbsp;4, 5, 9, 6, 13, 12, 11, and 10 on the top silkscreen. This is the only 8-pin list that works between NeoPXL8 and the Feather RP2040.

For other hardware, there’s usually more flexibility…just provide a list of eight contiguous GPIO bits. They don’t need to be in-order, merely contiguous.

And that’s it! Most existing NeoPXL8 sketches (which are very similar to regular NeoPixel sketches) will then carry right over. Some may need small changes…and that’s not always because of NeoPXL8, it’s sometimes unrelated hardware differences.

For example, the [**Ooze Master 3000**](https://learn.adafruit.com/ooze-master-3000-neopixel-simulated-liquid-physics) project can be adapted with just a couple code changes…

First, the pin list around line 23 should be modified…either the list given above (if using Feather RP2040 + NeoPXL8 FeatherWing M4), or a list of GPIO bits if using a different board with NeoPXL8 Friend.

Second, change the randomSeed() call (around line 68) to reference only pin A0, not A0 + A5. The RP2040 only has four analog inputs. Or you can just delete the line. The code is just using unconnected analog inputs to randomize things on startup, but it’s not vital.

```auto
randomSeed(analogRead(A0));
```

The code should then compile successfully for RP2040 and RP2350 boards.

![](https://cdn-learn.adafruit.com/assets/assets/000/104/755/medium800thumb/leds_oozemaster-thumb.jpg?1631918262)

# Adafruit NeoPXL8 FeatherWing and Library

## Feather RP2040 SCORPIO

![](https://cdn-learn.adafruit.com/assets/assets/000/117/245/medium800/leds_scorpio-oblique.jpg?1672259674)

The board-end 8x2 header on SCORPIO uses a different pin assignment than the regular Feather RP2040. No cutting, no jumpers, these pins _have one job:_

```cpp
int8_t pins[8] = { 16, 17, 18, 19, 20, 21, 22, 23 };
Adafruit_NeoPXL8 leds(NUM_LED, pins, NEO_GRB);
```

Other than this pin list change, most of what’s previously stated on the RP2040 page applies.&nbsp;More informative though, [the&nbsp;SCORPIO board has its own dedicated guide](https://learn.adafruit.com/introducing-feather-rp2040-scorpio)!

# Adafruit NeoPXL8 FeatherWing and Library

## ESP32-S3 Use

NeoPXL8 now also works on boards with the **ESP32-S3 microcontroller** , such as the [Feather ESP32-S3](https://www.adafruit.com/product/5323). Note that _only_ the **S3** chip is supported; **original ESP32, S2 and C3 are not compatible.**

## Hardware

Since ESP32-S3 is a **3.3 Volt** device, you’ll want to convert logic levels to the NeoPixel supply voltage ( **5V** typ.).

For most boards, our [**NeoPXL8 Friend**](https://www.adafruit.com/product/3975) does this nicely. It’s explained further on the “NeoPXL8 Breakout Board” page of this guide.

Or…if you’re using a [**Feather ESP32-S3**](https://www.adafruit.com/product/5323),&nbsp;our NeoPXL8 FeatherWings (either the [M0](https://www.adafruit.com/product/3249) or [M4](https://www.adafruit.com/product/4537) versions)&nbsp;work fine unmodified. Then you have a tidy package with less wiring!

## Software

The strandtest Arduino sketch includes some notes regarding pin selection.&nbsp;On the ESP32-S3, **any 8 pins** can be used for NeoPixel output.&nbsp;If using a NeoPXL8 FeatherWing,&nbsp;use one of the provided pinouts for the M0 or M4 ’wing, whichever you’ve got. And that’s it! Most existing NeoPXL8 sketches (which are very similar to regular NeoPixel sketches) will then carry right over. Some may need small changes…and that’s not always because of NeoPXL8, it’s sometimes unrelated hardware differences.

# Adafruit NeoPXL8 FeatherWing and Library

## NeoPXL8HDR

NeoPXL8 addresses the NeoPixel bandwidth issue, improving frame rates for large LED installations and freeing up more processor time for creating “next level” animation.&nbsp;With more potent microcontrollers now in the form of the RP2040 and ESP32-S3, suddenly we can go _next-_next-level. BEAST MODE!

The NeoPXL8 library includes an extra class called _ **NeoPXL8HDR** _&nbsp;(“high dynamic range”). You _don’t_ need to install an additional library for this, it tags along with the NeoPXL8 installation.

NeoPXL8HDR works a lot like NeoPXL8—in fact the same Arduino sketches can be used as a starting point—but then brings **bonus cake:**

- **_Temporal dithering_** provides more intermediate shades—_thousands_ of brightness levels rather than 256.
- **_16-bit color components_** for nuanced animation; each pixel now allows colors in 48-bit (RGB) or 64-bit (RGBW) formats.
- **_Gamma correction_** provides perceptually-linear brightness ramps from the pixels—it’s built into the library, you no longer need this in your code.
- **_Frame-to-frame blending_** creates smooth transitions even when animation frame rates are low.

**NeoPXL8HDR works best with a&nbsp;Feather RP2040 or ESP32-S3** (or other RP2040 or ESP32-S3 board, with suitable level shifting). With two processor cores, one can be dedicated fully to NeoPXL8HDR work. Though it _can_ run on an M4 board, the results are less satisfying (CPU time must be split between user code and the library). Other chips, even the M0 that works so well with “classic” NeoPXL8, are right out, the HDR additions are just too demanding.

## Tempering Expectations

NeoPixels still use 8-bit brightness levels, this doesn’t&nbsp;magically make them 16-bit.&nbsp;The illusion is done with _temporal dithering,_ quickly alternating the LEDs between two different levels. The effect _is_ noticeable, and one must ride a fine line between _just&nbsp;noticeable_ and _distracting._

Additionally, even the dithered output isn’t _fully_ 16-bit. It produces 12 bits by default, and with shorter pixel runs you might manage 13 bits. This is configurable so you can find a balance between precision and distraction. The important idea is that _to your code_ everything appears 16-bit. The last-step dither reduction is fully handled by the library and does not complicate your task.

If your project doesn’t _require_ HDR features, use the much-loved NeoPXL8 class!&nbsp;The HDR class consumes _inordinate_ RAM and resources, and it will _not_ automatically make anything look better; one must _specifically code to its strengths._&nbsp;Scrolling text? NeoPXL8. Super smooth plasma flame effects? NeoPXL8HDR.

NeoPXL8HDR relies on frequent refreshes to all the NeoPixel strips. There’s an associated bandwidth bottleneck to this, ultimately limiting how many pixels can be controlled while maintaining a sufficient refresh rate. This is subjective and there is no hard limit…but around 1,000 pixels (split 8 ways, and give or take a bit) is a sensible ballpark guideline.

## Basic Use

If you’ve never used _either_ class, read through the NeoPXL8 Arduino Library page first and play with the strandtest example. Get something working on actual hardware and familiarize yourself the concepts and constraints there.

Then, graduating to HDR, let’s look at the **strandtest\_hdr** example included with the NeoPXL8 library, comparing it against the simpler non-HDR&nbsp; **strandtest**. Open both side-by side in the Arduino IDE; we’ll just highlight certain sections here.

The two start out very similar. #include the header file, declare a list of pins. Even the constructor accepts the same arguments, it just has a different name for the HDR vs. traditional NeoPXL8 varieties.

```cpp
Adafruit_NeoPXL8HDR leds(NUM_LED, pins, NEO_GRB);
```

_Immediately_ things get strange in the HDR code, where you can see it compiles different code for RP2040 vs. ESP32-S3 vs. M4 (SAMD51) microcontrollers.

A new class function—`refresh()`—is introduced. In NeoPixel or NeoPXL8 code, you call the `show()` function to transmit new color data to the LEDs, done. In NeoPXL8HDR, `show()` hands off new color data to the library, _but doesn’t actually update the LEDs._ That’s now the task of `refresh()`, which must be called frequently to perform temporal dithering and all the other niceties.

On **RP2040** , we put a `refresh()` call inside the `loop1()` function, which runs again and again on the chip’s second core, as fast as it can go. _This requires installing the Earle Philhower RP2040 package in the Arduino Boards Manager, if you haven’t already._

On **ESP32-S3** , `refresh()` is called in a tight loop in the `loop0()` function, which the `setup()` code pins as a separate task on core 0. Arduino code…the animation logic in this case…always runs on core 1.

On the **M4** board, it’s necessary to set up a timer interrupt (via the Adafruit\_ZeroTimer library) to periodically call `refresh()`. You can see some extra steps needed both above and inside `setup()`.

If you _know for a fact_ that your own project will only ever use one chip or the other, you can trim the extraneous code. If sharing code with others as an open source project, it’s more neighborly to support all the different chips.

Once inside `setup()`, each class’ `begin()` function is a little different. NeoPXL8 accepts no arguments, it just runs one specific way. NeoPXL8HDR adds some _flair:_

```auto
bool status = leds.begin(true, 4, true);
```

The first argument selects whether **frame-to-frame** blending should be enabled. If you can’t generate frequent frames for animation, the library will provide some interpolation for you. This requires an extra 6 (RGB) or 8 (RGBW) bytes of RAM per pixel, atop the library’s already voracious needs. This 512-pixel example works fine with it, so it’s set `true`.

Second argument establishes the **temporal dithering** resolution. NeoPixels normally provide 256 brightness levels, or 8 bits. The `4` here bumps this up to 12 bits (effectively, but not actually, the extra being dithered). Long chains of NeoPixels are slow to update and _can’t_ use a lot of dithering…so you can dial this down (or up for short strips) to balance refresh rate with effective color range. Valid range is 0 (no dithering) to 8 (maximum dithering, but probably too infrequent to be useful).

Third argument is whether to enable **double-buffering** in the underlying NeoPXL8 library, freeing up the CPU to start on the next refresh sooner. Again, uses more RAM, but this 512-pixel demo is not a problem. _This argument is currently ignored on SAMD, only the RP2040 provides this, but it’s present for code compatibility._

`begin()` returns a status code: `true` if it was able to allocate the required RAM, `false` if not. The example sketch ignores this for brevity because we know it fits, but well-behaved neighborly code may want to respond appropriately (perhaps printing a message to the Serial console and/or blinking a board’s built-in LED).

Both examples then call `setBrightness()`, but NeoPXL8HDR works a little differently:

```auto
leds.setBrightness(65535 / 8, 2.6);
```

The first argument is a peak brightness level from 0 to 65535 (vs. 0–255 in NeoPixel and NeoPXL8). Everything sent to the LEDs will be scaled in proportion, this is just the top value. It’s set to `65535 / 8` here (instead of `8191`) just as a fancy and hopefully more readable way of saying “one eighth of the maximum brightness,” but the two are equivalent.

Second is a _gamma correction factor_ as a floating-point value. This is a topic extensively [covered in other guides](https://learn.adafruit.com/led-tricks-gamma-correction) already, but the basic idea is to make “in-between” colors more perceptually linear (because 50% duty cycle doesn’t look 50% as bright). A value of `2.6` has worked well for us over the years. It’s subjective though, you can try more or less.

**The default gamma value if left un-set is 1.0** ; linear brightness values have a linear effect on duty cycle, which is _not_ perceptually linear. This is on purpose and by design, so that any NeoPixel or NeoPXL8 code brought over to HDR doesn’t suddenly yield surprises; it will look more or less the same until you start adapting your code. Notice the NeoPXL8 _strandtest_ code performs its own gamma correction on every pixel, while _strandtest\_hdr_ doesn’t have to.

The remainder of these two examples—_strandtest_ and _strandtest\_hdr_—is then very similar, with the exception mentioned above that _hdr_ doesn’t need to gamma-correct every pixel, it’s done automatically. Both produce eight rows of colored “rain,” but the HDR version looks better especially among the lower brightness levels. Also they’re both using 8-bit color values despite HDR’s&nbsp;support for 16-bit. More on that later.

## Finer `setBrightness()` Details

First, please, I must reiterate a point from other NeoPixel projects and documentation: `setBrightness()` _never was and never will be intended as an animation effect in itself._ Configure it once at startup and leave it be…in fact you may get flickering in NeoPXL8HDR if using `setBrightness()` “live.” Animated fades should be rendered in code, perhaps with the NeoPixel `fill()` function.

If called with a single argument (no gamma value), `setBrightness()` works just like the original NeoPixel/NeoPXL8 version: the brightness value is **8-bit** (0-255) and the library will scale it up. This way, old code will work just as it did before. _Only when specifying a gamma value, or in more cases listed below, is the brightness level 16 bits._

“Brightness,” in the context of `setBrightness()`, is not a _perceptual_ brightness, but rather a _duty cycle._ So even if a gamma value is specified, _this doesn’t apply to the brightness value._ Requesting 32767 (or 127 for the 8-bit variant above) yields a peak brightness with about a 50% duty cycle, which will _appear_ more than half as bright. This is normal and by design, again for maintaining “classic” code behavior.

In addition to these two formats:

```auto
setBrightness(0-255);
setBrightness(0-65535, float gamma);
```

NeoPXL8HDR offers the ability to set peak red, green, blue and white (for RGBW pixels) independently, which can be used to improve color balance (folks often find that NeoPixels appear a bit blue-tinted when all elements are equally lit):

```auto
setBrightness(red, green, blue);
setBrightness(red, green, blue, gamma);
setBrightness(red, green, blue, white);
setBrightness(red, green, blue, white, gamma);
```

The red, green, blue (and white) values are _always_ **16-bit** &nbsp;(0-65535) with these syntaxes; there’s no 8-bit mode, no need for back-compatibility since classic NeoPixel doesn’t offer this. Gamma is _always_ floating-point, `1.0` is linear, and `2.6` works well in practice.

Another reason for defaulting to linear gamma (rather than imposing a value like 2.6) is that some users may want to provide their own more sophisticated color-correction functions. Leave gamma at 1.0 and then use the 16-bit pixel setting functions…

## Setting and Getting Pixel Colors

Your old NeoPixel code will work as before. There’s…

```auto
setPixelColor(pixel, r, g, b);
setPixelColor(pixel, 0xXXXXXXXX);
unsigned long x = getPixel(pixel);
```

…plus the `Color()` and `ColorHSV()` functions for “packing” RGB(W) values and working with HSV colors.

All of these functions work as before and use **8-bit** (0-255) brightness values. NeoPXL8HDR will upscale these numbers to the 16-bit range (or decimate back down to 8 bits in the `getPixel()` case).

To work with the full range of **16-bit** values, a different set of functions must be used…

```auto
set16(pixel, r, g, b);
set16(pixel, r, g, b, w);
get16(pixel, &amp;r, &amp;g, &amp;b, &amp;w);
```

In each case, `pixel` is a 16-bit pixel index (0–65535) just like before. For the two _set_ functions, r, g, b (and w if present) are now also 16-bit values (0–65535).&nbsp;There is no “packed” `set16()` function as we don’t have 64-bit types just yet.

The rgb(w) arguments to `get16()` are _pointers_ to 16-bit variables (`unsigned short` or `uint16_t`). w can be `NULL` if it’s not used, but the others _must_ point to valid destinations.

Adafruit\_NeoPixel provides a `getPixels()` function which returns a pointer straight into the buffer where 8-bit colors are stored. High-performance code can bypass `setPixelColor()` and work with the pixel buffer directly, with all the risks that entails.

The Adafruit\_NeoPXL8HDR class _also_ provides a `getPixels()` function, but the color values are 16-bit (function returns a `uint16_t *`). One perk is that the values here are _always_ in RGB or RGBW order, no need to reorder for different pixel vintages. Same risks still apply though, like anything with pointers, you can clobber things if you go out of range.

# Adafruit NeoPXL8 FeatherWing and Library

## Downloads

# Arduino Libraries

- Adafruit\_NeoPXL8 [code](https://github.com/adafruit/Adafruit_NeoPXL8) and [documentation](https://adafruit.github.io/Adafruit_NeoPXL8/html/index.html) on GitHub.
- Adafruit\_NeoPixel [code](https://github.com/adafruit/Adafruit_NeoPixel) on GitHub.
- Adafruit\_ZeroDMA [code](https://github.com/adafruit/Adafruit_ZeroDMA) on Github.

# Datasheets and Technical Information

- [ATSAMD21 datasheet](https://www.adafruit.com/images/product-files/2772/atmel-42181-sam-d21_datasheet.pdf) (main chip on Feather M0, Metro M0 and Arduino Zero)
- [ATSAMD51 information](https://www.microchip.com/wwwproducts/en/ATSAMD51J19A) (main chip on Feather M4, Metro M4 and Grand Central)

# Schematics & Fab Prints

[EagleCAD PCB files on GitHub](https://github.com/adafruit/Adafruit-NeoPXL8-PCBs)

NeoPXL8 FeatherWing **M0** (click to embiggen):

![](https://cdn-learn.adafruit.com/assets/assets/000/054/683/medium800/leds_neopxl8-wing-schematic.png?1527695475)

NeoPXL8 FeatherWing **M4** (click to embiggen):

![](https://cdn-learn.adafruit.com/assets/assets/000/088/739/medium800/leds_neopxl8-m4-schematic.png?1582784021)

NeoPXL8 **Friend** (click to embiggen):

![](https://cdn-learn.adafruit.com/assets/assets/000/063/302/medium800/leds_NeoPXL8-Friend-schematic.png?1539112383)

![](https://cdn-learn.adafruit.com/assets/assets/000/065/126/medium800/leds_fabprint.png?1541176683)

# Components for Fritzing App:

- [NeoPXL8 FeatherWing](https://github.com/adafruit/Fritzing-Library/raw/master/parts/Adafruit%20NeoPXL8%20FeatherWing.fzpz)
- [NeoPXL8 Friend breakout board](https://github.com/adafruit/Fritzing-Library/raw/master/parts/Adafruit%20NeoPXL8%20Friend.fzpz)


## Featured Products

### Adafruit NeoPXL8 FeatherWing for Feather M4 - 8 x DMA NeoPixels!

[Adafruit NeoPXL8 FeatherWing for Feather M4 - 8 x DMA NeoPixels!](https://www.adafruit.com/product/4537)
Since we first started carrying NeoPixels back in 2012, the chainable RGB LEDs have taken over the world. And a big part of that success is due to the simplicity of their wiring - just one data wire, no matter how many pixels you've got. So no surprise they're _everywhere_,...

In Stock
[Buy Now](https://www.adafruit.com/product/4537)
[Related Guides to the Product](https://learn.adafruit.com/products/4537/guides)
### Adafruit NeoPXL8 FeatherWing for Feather M0 - 8 x DMA NeoPixels!

[Adafruit NeoPXL8 FeatherWing for Feather M0 - 8 x DMA NeoPixels!](https://www.adafruit.com/product/3249)
Since we first started carrying NeoPixels back in 2012, the chainable RGB LEDs have taken over the world. And a big part of that success is due to the simplicity of their wiring - just one data wire, no matter how many pixels you've got. So no surprise they're _everywhere_,...

In Stock
[Buy Now](https://www.adafruit.com/product/3249)
[Related Guides to the Product](https://learn.adafruit.com/products/3249/guides)
### Adafruit NeoPXL8 Friend - 8 x Strands NeoPixel Level Shifter

[Adafruit NeoPXL8 Friend - 8 x Strands NeoPixel Level Shifter](https://www.adafruit.com/product/3975)
Since we first started carrying NeoPixels back in 2012, the chainable RGB LEDs have taken over the world. And a big part of that success is due to the simplicity of their wiring - just one data wire, no matter how many pixels you've got. So no surprise they're _everywhere_,...

In Stock
[Buy Now](https://www.adafruit.com/product/3975)
[Related Guides to the Product](https://learn.adafruit.com/products/3975/guides)
### Adafruit Feather M4 Express - Featuring ATSAMD51

[Adafruit Feather M4 Express - Featuring ATSAMD51](https://www.adafruit.com/product/3857)
It's what you've been waiting for, the Feather M4 Express featuring ATSAMD51. This Feather is fast like a swift, smart like an owl, strong like a ox-bird (it's half ox, half bird, OK?) This feather is powered by our new favorite chip, the **ATSAMD51J19** -&nbsp; with...

In Stock
[Buy Now](https://www.adafruit.com/product/3857)
[Related Guides to the Product](https://learn.adafruit.com/products/3857/guides)
### Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0

[Adafruit Feather M0 Basic Proto - ATSAMD21 Cortex M0](https://www.adafruit.com/product/2772)
Feather is the new development board from Adafruit, and like its namesake it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Feather M0 Basic Proto** ,&nbsp;it has a bunch of prototyping space...

In Stock
[Buy Now](https://www.adafruit.com/product/2772)
[Related Guides to the Product](https://learn.adafruit.com/products/2772/guides)
### Adafruit Feather M0 Adalogger

[Adafruit Feather M0 Adalogger](https://www.adafruit.com/product/2796)
Feather is the new development board from Adafruit, and like its namesake it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Adafruit Feather M0 Adalogger** &nbsp;- our take on an...

In Stock
[Buy Now](https://www.adafruit.com/product/2796)
[Related Guides to the Product](https://learn.adafruit.com/products/2796/guides)
### Adafruit Feather M0 Bluefruit LE

[Adafruit Feather M0 Bluefruit LE](https://www.adafruit.com/product/2995)
Feather is the new development board from Adafruit, and like its namesake, it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Adafruit Feather M0 Bluefruit LE** &nbsp;- our take on an...

In Stock
[Buy Now](https://www.adafruit.com/product/2995)
[Related Guides to the Product](https://learn.adafruit.com/products/2995/guides)
### Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500

[Adafruit Feather M0 WiFi - ATSAMD21 + ATWINC1500](https://www.adafruit.com/product/3010)
Feather is the new development board from Adafruit, and like its namesake it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores. This is the&nbsp; **Adafruit Feather M0 WiFi&nbsp;w/ATWINC1500** - our take on an...

In Stock
[Buy Now](https://www.adafruit.com/product/3010)
[Related Guides to the Product](https://learn.adafruit.com/products/3010/guides)

## Related Guides

- [Adafruit Feather M0 Adalogger](https://learn.adafruit.com/adafruit-feather-m0-adalogger.md)
- [Adafruit Feather M0 Bluefruit LE](https://learn.adafruit.com/adafruit-feather-m0-bluefruit-le.md)
- [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express.md)
- [Adafruit Feather M4 Express](https://learn.adafruit.com/adafruit-feather-m4-express-atsamd51.md)
- [Mini Commodore PET with Charlieplexed LED Matrix](https://learn.adafruit.com/mini-commodore-pet-with-charlieplexed-led-matrix.md)
- [Programming an M0 using an Arduino](https://learn.adafruit.com/programming-an-m0-using-an-arduino.md)
- [CircuitPython Hardware: PCA9685 PWM & Servo Driver](https://learn.adafruit.com/micropython-hardware-pca9685-pwm-and-servo-driver.md)
- [CircuitPython Hardware: MPR121 Capacitive Touch Breakout](https://learn.adafruit.com/circuitpython-hardware-mpr121-capacitive-touch-breakout.md)
- [Stand-alone programming AVRs using CircuitPython](https://learn.adafruit.com/stand-alone-programming-avrs-using-circuitpython.md)
- [OOZE MASTER 3000: NeoPixel Simulated Liquid Physics](https://learn.adafruit.com/ooze-master-3000-neopixel-simulated-liquid-physics.md)
- [Using LoraWAN and The Things Network with CircuitPython](https://learn.adafruit.com/using-lorawan-and-the-things-network-with-circuitpython.md)
- [Sketch Drawing Toy with CircuitPython](https://learn.adafruit.com/sketch-drawing-toy.md)
- [Welcome to CircuitPython!](https://learn.adafruit.com/welcome-to-circuitpython.md)
- [Introducing Adafruit Feather](https://learn.adafruit.com/adafruit-feather.md)
- [Using ATSAMD21 SERCOM for more SPI, I2C and Serial ports](https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports.md)
- [Dauntless Dotstar Gauntlets](https://learn.adafruit.com/dotstar-dauntless-gauntlets.md)
- [Adafruit Feather M0 Radio with RFM69 Packet Radio](https://learn.adafruit.com/adafruit-feather-m0-radio-with-rfm69-packet-radio.md)
- [CircuitPython Hardware: SSD1306 OLED Display](https://learn.adafruit.com/micropython-hardware-ssd1306-oled-display.md)
- [CircuitPython Hardware: ILI9341 TFT & FeatherWing](https://learn.adafruit.com/micropython-hardware-ili9341-tft-and-featherwing.md)
