# ulab: Crunch Numbers fast in CircuitPython

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/088/977/medium800thumb/sensors_5e62c7536ec82980387928.jpg?1583531951)

## What is ulab

ulab (pronounced "micro lab") lets you perform number crunching tasks in CircuitPython more quickly, often around 10x as fast. This can be very handy when dealing with sensor data, as we'll see below.

Make sure you have CircuitPython 5.1.0 or newer, and any Adafruit CircuitPython board with an M4 or higher processor, including most SAMD51 and nRF boards.

It's a "built-in module", meaning that it is installed when you install CircuitPython, it's not a file or a set of files in a project bundle or installable via circup. Check the "Built-in modules available" list for a particular board on circuitpython.org to find out if it's available, or just run `import ulab` at the repl to find out for yourself immediately. If the result is an **ImportError** , then ulab is not available on that board.

ulab is modeled after [`numpy`](https://numpy.org/), but is not entirely compatible; so after the examples there are guidelines to help you move between numpy and ulab.

ulab is not available in Blinka, Adafruit's Single Board Computer layer for CircuitPython - for those boards we recommend using plain numpy since it's available! If your code needs to run on both CircuitPython and Blinka, you'll probably either need to use conditional code or forego the use of ulab altogether.

Warning: 

## The ulab API

ulab makes things faster by operating on entire arrays of values in one operation.&nbsp; For example, when you have two _numbers_ `a` and `b`, `a+b` adds them together, returning a new _number_.&nbsp; When you have two ulab _arrays_ `a` and `b`, `a+b` adds the corresponding numbers in `a` to the corresponding numbers in `b`, returning a new _array_.&nbsp; Want to double every number in an array?&nbsp; That's `a*2`.&nbsp; Compute its sine?&nbsp; `ulab.numpy.sin(a)`.&nbsp; It also has special versions of functions like `sum` that act on a whole array and return a single number.&nbsp; [Documentation for all functions in ulab](https://circuitpython.readthedocs.io/en/latest/shared-bindings/ulab/) are on readthedocs.

These examples only cover a portion of the functions available in ulab.&nbsp; The items below are beyond the scope of this gude:

- Matrix functions in `ulab.numpy.linalg`, such as determinant, inverse, and eigenvectors of a matrix
- Creating vectors with&nbsp;`ulab.numpy.linspace`, which is sort of like `range()` but for arrays
- Statistical functions such as standard deviation, `ulab.numpy.std` and others
- Functions for working with polynomials in `ulab.numpy.polyfit` and&nbsp;`ulab.numpy.polyval`
- Slicing arrays with `arr[lo:hi:step]`

## Parts
Featured
### Adafruit CLUE - nRF52840 Express with Bluetooth® LE

[Adafruit CLUE - nRF52840 Express with Bluetooth® LE](https://www.adafruit.com/product/4500)
Do you feel like you just don't have a CLUE? Well, we can help with that - get a CLUE here at Adafruit by picking up this sensor-packed development board. We wanted to build some projects that have a small screen and a lot of sensors. To make it compatible with existing projects, we made...

In Stock
[Buy Now](https://www.adafruit.com/product/4500)
[Related Guides to the Product](https://learn.adafruit.com/products/4500/guides)
![Animated GIF showing CLUE board  displaying data from the many on-board sensors.](https://cdn-shop.adafruit.com/product-videos/640x480/4500-04.jpg)

Featured
### Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor

[Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor](https://www.adafruit.com/product/3595)
This breakout is chock full o' sensors! Add basic gesture sensing, RGB color sensing, proximity sensing, or ambient light sensing to your project with the&nbsp; **Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor**. When connected to your microcontroller (running our...

In Stock
[Buy Now](https://www.adafruit.com/product/3595)
[Related Guides to the Product](https://learn.adafruit.com/products/3595/guides)
![Angled shot of a Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor.](https://cdn-shop.adafruit.com/640x480/3595-06.jpg)

Featured
### Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor

[Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor](https://www.adafruit.com/product/2651)
Bosch has stepped up their game with their new BMP280 sensor, an environmental sensor with temperature, barometric pressure that is the next generation upgrade to the BMP085/BMP180/BMP183. This sensor is great for all sorts of weather sensing and can even be used in both I2C and...

In Stock
[Buy Now](https://www.adafruit.com/product/2651)
[Related Guides to the Product](https://learn.adafruit.com/products/2651/guides)
![Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor - STEMMA QT](https://cdn-shop.adafruit.com/640x480/2651-08.jpg)

Featured
### Flexible Silicone Neon-like Skinny NeoPixel LED Strip

[Flexible Silicone Neon-like Skinny NeoPixel LED Strip](https://www.adafruit.com/product/4310)
You love NeoPixels, and you love silicone diffusion? Peep this&nbsp; **Flexible Silicone Neon-like Skinny NeoPixel LED Strip**! OK it's a bit of a mouthful, but check out the beautiful footage! It&nbsp;_looks_&nbsp;a lot like a slim strip of neon, but without the need...

In Stock
[Buy Now](https://www.adafruit.com/product/4310)
[Related Guides to the Product](https://learn.adafruit.com/products/4310/guides)
![Demo Video of hands squeezing and unraveling the illuminated Flexible Silicone Neon-like Skinny NeoPixel LED Strip.](https://cdn-shop.adafruit.com/product-videos/640x480/4310-00.jpg)

Featured
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
![USB cable - USB A to Micro-B - 3 foot long](https://cdn-shop.adafruit.com/640x480/592-01.jpg)

# ulab: Crunch Numbers fast in CircuitPython

## A Simple Benchmark

In this simple benchmark, we compare two ways of finding the amplitude of a signal.&nbsp;&nbsp; `normalized_rms` computes it in a traditional way, handling each number one by one in Python code.&nbsp; `normalized_rms_ulab` computes more quickly by working on groups of numbers in a ulab array at the same time.&nbsp; `ulab.numpy.std` computes most quickly by moving all operations from Python to ulab.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ulab_Crunch_Numbers_Fast/benchmark/code.py

On my Metro M4, the ulab code computes almost exactly the same value, **but over 40 times faster.** Take care if running this on a board with an LCD display such as the CLUE, printing the results on the display takes a lot longer than the computation itself, and completely distorts the results.

```none
traditional               :    2.951ms [result=3535.843611]
ulab, algorithm in python :    0.251ms [result=3535.853624]
ulab only, with list      :    0.336ms [result=3535.854340]
ulab only, with ndarray   :    0.068ms [result=3535.854340]
```

# ulab: Crunch Numbers fast in CircuitPython

## FFT Example: Waterfall Spectrum Analyzer

Use the microphone on your Adafruit CLUE to measure the different frequencies that are present in sound, and display it on the LCD display. This shows the author whistling up and down a musical scale.

![sensors_vlcsnap-2020-03-06-16h00m29s064.jpg](https://cdn-learn.adafruit.com/assets/assets/000/088/980/medium640/sensors_vlcsnap-2020-03-06-16h00m29s064.jpg?1583533892)

The program is below.&nbsp; The program samples audio for a short time and then computes the [fast Fourier transform (FFT)](https://en.wikipedia.org/wiki/Fast_Fourier_transform "Fast Fourier transform on wikipedia") of the audio data.&nbsp; FFT is a way of turning a series of samples over time into a list of the relative intensity of each frequency in a range.

While running the demo, here are some things you might like to try:

- Sing or whistle a musical scale
- Look at the difference between saying "ah", "th", and "sss"
- See how your favorite music looks when you transform it by FFT

(Note that because the program alternates between recording sound and doing computations, it can miss registering short sounds like claps)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ulab_Crunch_Numbers_Fast/waterfall/code.py

# ulab: Crunch Numbers fast in CircuitPython

## Example: NeoPixel Wave Simulation

Create an ever varying rainbow pattern on NeoPixel LED strips using the equation for "[1D wave simulation](https://en.wikipedia.org/wiki/Wave_equation)".

It is possible to create numeric simulations of waves which resemble ocean waves or ripples on a pond.&nbsp; [Here is an example](https://web.archive.org/web/20221006120137/https://bl.ocks.org/curran/raw/9e035dcae9c8178ae649/) as a web demo. In this case, instead of the simulation values representing heights of a liquid wave, they represent colors on the color wheel, which are shown on a neon-like NeoPixel strip.&nbsp; By changing a few parameters in the Python source code, you can create a relaxed experience or an almost stroboscopic effect

This demo, heavily adapted from [an answer on Stack Overflow](https://stackoverflow.com/questions/10081942/python-writing-a-program-to-simulate-1d-wave-motion-along-a-string), is designed for a neon-like NeoPixel strip and I ran it using an Adafruit Feather nRF52840.&nbsp; However, you can adapt it to a wide range of CircuitPython devices and NeoPixel strip types.

![sensors_spiral1.gif](https://cdn-learn.adafruit.com/assets/assets/000/088/981/medium640thumb/sensors_spiral1.jpg?1583534561)

Wire the neopixels to the feather, as shown below.&nbsp; If you need to use a different pin than D5, or the number of neopixels you have is not 96, you'll&nbsp; need to change some things in the code.

![](https://cdn-learn.adafruit.com/assets/assets/000/088/960/medium800/sensors_leds_FeatherM0_NeoPixel_bb.jpg?1583429660)

You'll need to manually install the necessary libraries from the bundle:

- **neopixel.mpy**

Next, copy the code below to **code.py** on the **CIRCUITPY** drive.

Many of the parameters can be tinkered with to give different effects. Some are pretty, some are boring, and a few will even cause errors because they give a result of infinity!

The elements of `f` that are nonzero indicate places where energy is added to the wave. The main function randomly assigns one element of `f` to be nonzero, every once in awhile.

`dx`, `dt`, and `c` control how quickly the wave reacts, but in slightly different ways. `dx`&nbsp;is how far apart the sampled points are, `dt`&nbsp;is how far apart in time the calculated instants are, and `c` is the maximum speed of a wave in distance per time.&nbsp; These are all in arbitrary units; they don't have anything to do with the physical distance between NeoPixels or the time between updates of the strip, which always goes as fast as possible.

The number 0.99 which is used as a multiplier of u and um within the main loop is a damping factor. 0.99 damps a very small amount.&nbsp; Values closer to 0 dampen the wave more.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ulab_Crunch_Numbers_Fast/ledwave/code.py

Featured
### Flexible Silicone Neon-like Skinny NeoPixel LED Strip

[Flexible Silicone Neon-like Skinny NeoPixel LED Strip](https://www.adafruit.com/product/4310)
You love NeoPixels, and you love silicone diffusion? Peep this&nbsp; **Flexible Silicone Neon-like Skinny NeoPixel LED Strip**! OK it's a bit of a mouthful, but check out the beautiful footage! It&nbsp;_looks_&nbsp;a lot like a slim strip of neon, but without the need...

In Stock
[Buy Now](https://www.adafruit.com/product/4310)
[Related Guides to the Product](https://learn.adafruit.com/products/4310/guides)
![Demo Video of hands squeezing and unraveling the illuminated Flexible Silicone Neon-like Skinny NeoPixel LED Strip.](https://cdn-shop.adafruit.com/product-videos/640x480/4310-00.jpg)

Featured
### Adafruit Feather nRF52840 Express

[Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
The **Adafruit Feather nRF52840 Express** is the new Feather family member with Bluetooth® Low Energy and _native USB support_ featuring the nRF52840!&nbsp; It's our take on an 'all-in-one' Arduino-compatible + Bluetooth® Low Energy with built-in USB...

In Stock
[Buy Now](https://www.adafruit.com/product/4062)
[Related Guides to the Product](https://learn.adafruit.com/products/4062/guides)
![Angled shot of a Adafruit Feather nRF52840 Express. ](https://cdn-shop.adafruit.com/640x480/4062-02.jpg)

# ulab: Crunch Numbers fast in CircuitPython

## Filter Example: Pulse Rate Estimation

Sensor data is often noisy or contains slowly varying DC offsets.&nbsp; Here we will see how to use Finite Impulse Response Filters (FIRs) to get just the part of the signal that is of interest.

Designing the "taps" of a filter is somewhat of an art.&nbsp; Websites like [https://fiiir.com/](https://fiiir.com/) can ease the task and even provide the filter values as a Python list ready to paste into your program.&nbsp; As a rule of thumb, doubling the number of taps in your filter doubles the computation time, so a smaller filter is much faster than a larger one.&nbsp; (Also, before the data coming out of a filter is valid, the number of data points must be at least the number of taps.&nbsp; This is why the pulse waveform takes about 2 seconds to start displaying)

## High pass filtering: Measuring pulse with CLUE's APDS

The gesture sensor on the CLUE, APDS9960, can be used as a crude pulse sensor.&nbsp; You can also use other CircuitPython boards together with the APDS9960 breakout board.&nbsp; As your heart pumps blood, the amount of light that is transmitted through your skin changes very slightly.&nbsp; In this demo, a high-pass FIR filter is used to exclude the parts of the signal that change at less than .5Hz (equivalent of a 30bpm heart rate) and preserve higher frequencies up to 4Hz (equivalent to a 240bpm heart rate).

Make sure the following libraries from the bundle are installed:

- **adafruit\_apds9960**
- **adafruit\_bus\_device**
- **adafruit\_register**

Next, copy **code.py** (below) to the **CIRCUITPY** drive.&nbsp; Open up [the Mu editor](https://learn.adafruit.com/adafruit-clue/installing-mu-editor) and its plotter window. Press your finger firmly on the sensor just above the CLUE's screen.&nbsp; When your finger is registered, the white LEDs will turn on.&nbsp; After a few seconds, a graph of the recorded pulse data will begin to display.&nbsp; Shortly after that, an estimated pulse rate will be displayed too.&nbsp; When you remove your finger, the plot will stop and the LEDs will turn back off.

During the demo, the CLUE's screen is blank to preserve processing power for the script.

Depending on your individual body, this demo may work well or not at all. It worked very well for the author, but not at all for a spouse - don't press too hard and try first finger and also thumb.

Of coures, this is just a toy, not medical diagnostic equipment!

![sensors_IMG_20200305_102041.jpg](https://cdn-learn.adafruit.com/assets/assets/000/088/957/medium640/sensors_IMG_20200305_102041.jpg?1583426706)

Here's what you will see in mu if the sensor is picking up your pulse: a somewhat irregular waveform in blue, and an estimated pulse rate in green.&nbsp; The values shown at the left represent the current filtered light value and the estimated pulse in beats per minute.

![sensors_pulse-and-rate.png](https://cdn-learn.adafruit.com/assets/assets/000/088/971/medium640/sensors_pulse-and-rate.png?1583524866)

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ulab_Crunch_Numbers_Fast/cluepulse/code.py

# ulab: Crunch Numbers fast in CircuitPython

## Filter Example: Measuring barometric pressure

## Low pass filtering: Measuring barometric Pressure with a BMP280

In the pulse rate estimation example, we used a filter to remove the low frequency (slowly changing) part of a signal and preserve the high frequency part.&nbsp; This is known as a high pass filter.

To measure barometric pressure, we instead want to preserve the slowly changing part of the signal and exclude the quickly changing part, AKA noise.&nbsp; This is known as a low-pass filter.

This example is designed for CLUE or Feather Sense, but can be adapted to other supported boards with the BMP280 breakout.

The image below shows a typical plot in Mu.&nbsp; The green trace is unfiltered, the blue is filtered.&nbsp; Notice how the blue trace is smoother than the green, but is also moved further to the right.&nbsp; This represents the _phase shift_ of the filter, which is about 10 seconds.

![](https://cdn-learn.adafruit.com/assets/assets/000/088/956/medium800/sensors_image2.png?1583426461)

You'll need to manually install the necessary libraries from the bundle:

- **adafruit\_bmp280.mpy**
- **adafruit\_bus\_device**

Before continuing make sure your board's lib folder or root filesystem has the&nbsp; **adafruit\_bmp280.mpy,** and **adafruit\_bus\_device**** &nbsp; **files and folders** &nbsp; **copied over.&nbsp; Put the following Python code into** code.py** and then open the Mu plotter window.&nbsp; In the plot, you will see a noisy, unfiltered trace and a smooth filtered trace.

Note that the barometric pressure value is offset by 980, which happened to be the local barometric pressure when this example was written.&nbsp; This is to move the values closer to the center of the Mu plot, which accentuates the variation in the value.&nbsp; You can remove the subtraction so that you are dealing with absolute, not relative, values.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/ulab_Crunch_Numbers_Fast/cluebarometer/code.py

# ulab: Crunch Numbers fast in CircuitPython

## Writing code for ulab and numpy

## Importing ulab

The ulab module is split into two main parts `ulab.numpy` and `ulab.scipy` each of which provide similar functionality to their respective CPython library counterpart. You can rename `ulab.numpy` when you import it to use the shorthand name np. `from ulab import numpy as np` then in your code you can call the functions like `np.sum()` etc. Many existing CPython numpy examples are written to use this shorthand name.

## Working with CircuitPython and Blinka

Where possible, if a ulab function and a numpy function have the same name, ulab's functionality is a subset of numpy.

```python
try:
  import ulab.numpy as np
except ImportError:
  import numpy as np

u = np.array([1,2,3,4])
v = np.array([1,-2,1])
print(np.convolve(u, v))
```

## Numpy/ulab differences

Many ulab functions do not support all the same arguments as numpy.&nbsp; For instance, `numpy.convolve` supports several ways of controlling how the boundary conditions are handled, using the `mode=` named parameter.&nbsp; However, `ulab.numpy.convolve` always acts like numpy's `mode='full'`.

In a few cases, numpy accepts a positional argument but ulab requires a named parameter.&nbsp; This is true of `ulab.numpy.linspace`'s `num=` argument, for instance.

ulab does not support complex numbers.&nbsp; Because of this, ulab's fft returns a pair of arrays, where the first array holds the real part of the fft and the second array holds the imaginary part.&nbsp; Instead of using fft directly, consider whether to use&nbsp;`ulab.scipy.signal.spectrogram` instead.&nbsp; For compatibility with both CircuitPython and Blinka, spectrum can be implemented as follows:

```python
try:
  from ulab import numpy as np
except ImportError:
  import numpy as np
  
try:
  from ulab.scipy.signal import spectrogram
except ImportError:
  def spectrogram(arr):
    return abs(np.fft.fft(arr))

data = np.array([1,2,1,4])
print(spectrogram(data))
```


## Guide Products

### Adafruit CLUE - nRF52840 Express with Bluetooth® LE

[Adafruit CLUE - nRF52840 Express with Bluetooth® LE](https://www.adafruit.com/product/4500)
Do you feel like you just don't have a CLUE? Well, we can help with that - get a CLUE here at Adafruit by picking up this sensor-packed development board. We wanted to build some projects that have a small screen and a lot of sensors. To make it compatible with existing projects, we made...

In Stock
[Buy Now](https://www.adafruit.com/product/4500)
[Related Guides to the Product](https://learn.adafruit.com/products/4500/guides)
### Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor

[Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor](https://www.adafruit.com/product/3595)
This breakout is chock full o' sensors! Add basic gesture sensing, RGB color sensing, proximity sensing, or ambient light sensing to your project with the&nbsp; **Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor**. When connected to your microcontroller (running our...

In Stock
[Buy Now](https://www.adafruit.com/product/3595)
[Related Guides to the Product](https://learn.adafruit.com/products/3595/guides)
### Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor

[Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor](https://www.adafruit.com/product/2651)
Bosch has stepped up their game with their new BMP280 sensor, an environmental sensor with temperature, barometric pressure that is the next generation upgrade to the BMP085/BMP180/BMP183. This sensor is great for all sorts of weather sensing and can even be used in both I2C and...

In Stock
[Buy Now](https://www.adafruit.com/product/2651)
[Related Guides to the Product](https://learn.adafruit.com/products/2651/guides)
### Flexible Silicone Neon-like Skinny NeoPixel LED Strip

[Flexible Silicone Neon-like Skinny NeoPixel LED Strip](https://www.adafruit.com/product/4310)
You love NeoPixels, and you love silicone diffusion? Peep this&nbsp; **Flexible Silicone Neon-like Skinny NeoPixel LED Strip**! OK it's a bit of a mouthful, but check out the beautiful footage! It&nbsp;_looks_&nbsp;a lot like a slim strip of neon, but without the need...

In Stock
[Buy Now](https://www.adafruit.com/product/4310)
[Related Guides to the Product](https://learn.adafruit.com/products/4310/guides)
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

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

[Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
The **Adafruit Feather nRF52840 Express** is the new Feather family member with Bluetooth® Low Energy and _native USB support_ featuring the nRF52840!&nbsp; It's our take on an 'all-in-one' Arduino-compatible + Bluetooth® Low Energy with built-in USB...

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

## Related Guides

- [Adafruit BMP280 Barometric Pressure + Temperature Sensor Breakout](https://learn.adafruit.com/adafruit-bmp280-barometric-pressure-plus-temperature-sensor-breakout.md)
- [Introducing the Adafruit nRF52840 Feather](https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather.md)
- [Introducing Adafruit CLUE](https://learn.adafruit.com/adafruit-clue.md)
- [NeoPixel Run LED Arcade Game](https://learn.adafruit.com/pixel-chase-game.md)
- [Professor Bubbleton’s Breathing Head in a Jar](https://learn.adafruit.com/professor-bubbleton-s-breathing-head-in-a-jar.md)
- [Remote Control Tree Ornament with Circuit Playground Express](https://learn.adafruit.com/remote-control-tree-ornament-with-circuit-playground-express.md)
- [Tappy Robotic Hand](https://learn.adafruit.com/robotic-tapping-hand-with-cpx.md)
- [Watchmen's Sister Night NeoPixel Goggles](https://learn.adafruit.com/watchmen-sister-night-circuitpython-neopixel-goggles.md)
- [Archimedes' Boat](https://learn.adafruit.com/archimedes-boat.md)
- [Flashing LED Strand with MakeCode](https://learn.adafruit.com/flashing-led-strand-with-makecode.md)
- [Halloween Sentry-Bot with CRICKIT for CPX](https://learn.adafruit.com/halloween-sentry-bot.md)
- [Where's My Friend? A Location-Aware Display with PyPortal and ItsASnap](https://learn.adafruit.com/where-s-my-friend-a-location-display-frame-with-pyportal.md)
- [LED Neon Signs with NeoPixels](https://learn.adafruit.com/led-neon-signs-with-neopixels.md)
- [BLE Sniffer with nRF52840](https://learn.adafruit.com/ble-sniffer-with-nrf52840.md)
- [NeoTrellis M4 Noisy Grains of Sand](https://learn.adafruit.com/neotrellism4sand.md)
- [Circuit Playground + CircuitPython Quickstart Guide](https://learn.adafruit.com/circuit-playground-express-circuitpython-5-minute-guide.md)
- [Metronome CLUE](https://learn.adafruit.com/metronome-clue.md)
- [Cardboard Window Skull With Animated LED Eyes](https://learn.adafruit.com/cardboard-window-skull-animated-led-eyes.md)
