# Raspberry Pi I2C Clock Stretching Fixes

## Overview

![clock](https://cdn-learn.adafruit.com/assets/assets/000/109/478/medium640/sensors_bitmap.png?1646433905 )

This guide covers various approaches for dealing with issues that arise when I2C devices use clock stretching on a Raspberry Pi.

## What Is Clock Stretching?

There is a good general overview of clock stretching in this guide:

[Clock Stretching](https://learn.adafruit.com/working-with-i2c-devices/clock-stretching)
Keep in mind that clock stretching is a feature of I2C. It's not unique to Raspberry Pi's. The issue is simply how Pi's handle (or don't) I2C clock stretching.

## Why Are Raspberry Pi's an Issue?

The same guide linked above discusses this. It's a known hardware issue with a lot of history. The articles referenced in that guide are linked again here for convenience:

- [Raspberry Pi I2C clock-stretching bug](https://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html) - Written in August, 2013, this blog post is the most often cited and linked. It contains lots of technical details.
- [RPI forums I2C clock stretching](https://forums.raspberrypi.com/viewtopic.php?f=44&t=13771) - Discussion circa 2012 about this issue. There are 70 posts to the thread!
- [I2C Broadcom bug workaround](https://github.com/raspberrypi/linux/issues/254) - An old issue thread from 2013. There are 73 posts to the thread!
- [I2C clock-stretching bug](https://github.com/raspberrypi/linux/issues/4884) - A more recent issue thread specific to the Pi 4. The saga continues!

# Raspberry Pi I2C Clock Stretching Fixes

## Example Issues

Let's start by demonstrating the general issue. There is a list of known troublesome chips here:

[Troublesome Chips](https://learn.adafruit.com/i2c-addresses/troublesome-chips)
The BNO55 and BNO085 sensors are used to demonstrate since these commonly come up as a source of problems.

## BNO055 Demonstration

The main guide for the BNO055 can be used as a starting point:

[BNO055 Python Setup](https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/python-circuitpython)
The wiring used here is identical to what is shown in that guide.

**NOTE:** There is a fair bit of initial software setup involved - mainly with the Blinka setup. Be sure to go through all of the required steps in the guide linked above.

Once [Blinka is installed and configured](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux) and you have [installed the BNO055 CircuitPython library](https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/python-circuitpython#python-installation-of-bno055-library-2998131), now to see if the BNO055 can be used on the Pi.

First double check the connections with a quick I2C scan:

```terminal
pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --
```

Cool! It's showing up at the expected I2C address of `0x28`. So the BNO055 is found. Try running the [simple example](https://github.com/adafruit/Adafruit_CircuitPython_BNO055/blob/main/examples/bno055_simpletest.py) from the library:

```terminal
pi@raspberrypi:~ $ python3 bno055_simpletest.py
Temperature: -106 degrees C
Accelerometer (m/s^2): (0.0, 0.0, 0.0)
Magnetometer (microteslas): (36.25, -29.5, -66.0)
Gyroscope (rad/sec): (0.0, -0.003272492347489368, 0.002181661564992912)
Euler angle: (0.0, 0.0, 0.0)
Quaternion: (0.0, 0.0, 0.0, 0.0)
Linear acceleration (m/s^2): (0.0, 0.0, 0.0)
Gravity (m/s^2): (0.0, 0.0, 0.0)

Temperature: -106 degrees C
Accelerometer (m/s^2): (0.16, -0.41000000000000003, 9.89)
Magnetometer (microteslas): (35.875, -29.0625, -64.1875)
Gyroscope (rad/sec): (0.0, 0.0, 0.001090830782496456)
Euler angle: (0.0, 0.8125, 2.4375)
Quaternion: (0.999755859375, -0.02154541015625, -0.00750732421875, 0.0)
Linear acceleration (m/s^2): (0.0, 0.0, 0.17)
Gravity (m/s^2): (0.14, -0.42, 9.790000000000001)
```

Well...it's running OK without any errors....but what's up with those sensor values? A temperature of -106 deg C? Something doesn't seem right. And it's not. Due to the poor handling of clock stretching, erroneous data is being read in.

## BNO085 Example

Now to try the [BNO085](https://www.adafruit.com/product/4754), which is similar to the BNO055. The main guide for the BNO085 covers how to get everything initially installed:

[BNO085 Python Setup](https://learn.adafruit.com/adafruit-9-dof-orientation-imu-fusion-breakout-bno085/python-circuitpython)
Once that is done, we again start with a quick I2C scan:

```terminal
pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- 4a -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --
```

Yep. That's the expected `0x4A` address for the BNO085.

Now to try running the [example from the library](https://github.com/adafruit/Adafruit_CircuitPython_BNO08x/blob/main/examples/bno08x_simpletest.py):

```terminal
pi@raspberrypi:~ $ python3 bno08x_simpletest.py
Acceleration:
X: 0.230469  Y: -0.039062 Z: 9.843750  m/s^2

Gyro:
X: 0.001953  Y: 0.001953 Z: 0.001953 rads/s

Magnetometer:
X: 22.187500  Y: 28.375000 Z: -47.750000 uT

Rotation Vector Quaternion:
I: 0.002136  J: -0.011108 K: 0.335449  Real: 0.942017

Acceleration:

Traceback (most recent call last):
  File "/home/pi/bno08x_simpletest.py", line 29, in &lt;module&gt;
    accel_x, accel_y, accel_z = bno.acceleration  # pylint:disable=no-member
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 594, in acceleration
    self._process_available_packets()
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 790, in _process_available_packets
    self._handle_packet(new_packet)
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 848, in _handle_packet
    raise error
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 843, in _handle_packet
    _separate_batch(packet, self._packet_slices)
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 358, in _separate_batch
    required_bytes = _report_length(report_id)
  File "/home/pi/blinka/lib/python3.9/site-packages/adafruit_bno08x/__init__.py", line 347, in _report_length
    return _AVAIL_SENSOR_REPORTS[report_id][2]
KeyError: 133
```

It gave a reading (or several) that look OK, then it exited with a cryptic error. What going on? It's clock stretching again.

# Raspberry Pi I2C Clock Stretching Fixes

## Change the Clock Speed

Changing the I2C clock speed is the first thing to try, since it allows continuing to use the existing hardware I2C peripheral on the Raspberry Pi. It also generally does not require any changes to user code. The changes are done using a system configuration file to directly alter that I2C hardware peripheral behavior.

Info: 

## Editing config.txt

Changing the I2C clock speed is done by adding a new line to the `config.txt` file. The location of this file has changed with time. For Raspberry Pi OS releases prior to bookworm, the file is at `/boot/config.txt`. Starting with bookworm, the location is `/boot/firmware/config.txt`. **Update the examples below to match the location for the OS release being used.**

[More info on config.txt](https://www.raspberrypi.com/documentation/computers/config_txt.html)
Log in to a terminal on your Pi and open that file in Nano, or your text editor of choice:

```auto
sudo nano /boot/config.txt
```

![](https://cdn-learn.adafruit.com/assets/assets/000/116/161/medium800/raspberry_pi_sensors_Screenshot-2018-08-14-13_06_24.png?1666640714)

Scroll down until you find a block like:

```auto
# Uncomment some of all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
dtparam=i2s=on
dtparam=spi=on
```

This block might vary depending on what you've enabled in&nbsp;`raspi-config`. Directly below it, add lines that looks like (the line starting with `#` is a comment):

```auto
# Set I2C Clock Speed
dtparam=i2c_arm_baudrate=REPLACE_WITH_VALUE
```

Replace `REPLACE_WITH_VALUE` with the desired clock speed value in Hz. **Picking a value is discussed in the following sections.**

Next, save the file and exit (in Nano, press&nbsp; **Ctrl-X** ,&nbsp; **y** for yes, and&nbsp; **Enter** ).

Now **reboot the Pi** for the setting to take effect:

```auto
sudo reboot
```

Danger: 

## Slow Down The Clock

This seems to be the most universal fix. The general idea is to slow down the clock enough that any clock stretching simply gets buried within a given clock cycle. That is - the stretching happens faster than the main clock itself, so it just gets missed and is never even seen.

The suggested starting value is 10000 Hz, so the line in `/boot/config.txt` would be:

```auto
# Clock stretching by slowing down to 10KHz
dtparam=i2c_arm_baudrate=10000
```

If you still get bad data, try slowing it down more, maybe to 5 KHz or 1 KHz rate. Reboot after each change.

## Speed Up The Clock

There are a few sensors, like the [BNO085](https://learn.adafruit.com/adafruit-9-dof-orientation-imu-fusion-breakout-bno085/python-circuitpython), for which this seems the better fix. This is done the same way as slowing down the clock, but the value is simply larger than the 100kHz default. I2C has various defined speed "ranges", and the next one above 100kHz is 400kHz, so the line in `/boot/config.txt` would be:

```auto
# Clock stretching by speeding up to 400kHz
dtparam=i2c_arm_baudrate=400000
```

Don't forget to reboot after saving the change.

# Raspberry Pi I2C Clock Stretching Fixes

## Example Fixes

Now to test the suggested fixes for slowing down / speeding up the I2C clock and see if it fixes the demonstrated issues with the BNO055 and BNO085.

## Clock Slow Down Fix for BNO055

With the line:

```auto
dtparam=i2c_arm_baudrate=10000
```

added to `/boot/config.txt` and the Pi rebooted, try again the same library example:

```terminal
pi@raspberrypi:~ $ python3 bno055_simpletest.py
Temperature: 22 degrees C
Accelerometer (m/s^2): (0.13, -0.33, 9.89)
Magnetometer (microteslas): (37.75, -27.6875, -65.25)
Gyroscope (rad/sec): (-0.001090830782496456, -0.003272492347489368, -0.001090830782496456)
Euler angle: (0.0, 0.0, 0.0)
Quaternion: (1.0, 0.0, 0.0, 0.0)
Linear acceleration (m/s^2): (0.15, -0.33, 0.06)
Gravity (m/s^2): (0.0, 0.0, 9.8)

Temperature: 22 degrees C
Accelerometer (m/s^2): (0.15, -0.34, 9.96)
Magnetometer (microteslas): (39.1875, -26.5625, -64.25)
Gyroscope (rad/sec): (-0.001090830782496456, 0.0, -0.001090830782496456)
Euler angle: (0.0, 0.8125, 1.875)
Quaternion: (0.99981689453125, -0.01666259765625, -0.00726318359375, 0.0)
Linear acceleration (m/s^2): (0.0, -0.01, 0.12)
Gravity (m/s^2): (0.14, -0.32, 9.8)

Temperature: 22 degrees C
Accelerometer (m/s^2): (0.13, -0.34, 9.99)
Magnetometer (microteslas): (38.75, -26.25, -64.6875)
Gyroscope (rad/sec): (0.0, 0.001090830782496456, -0.002181661564992912)
Euler angle: (0.0, 0.8125, 1.875)
Quaternion: (0.99981689453125, -0.01666259765625, -0.00726318359375, 0.0)
Linear acceleration (m/s^2): (0.0, 0.0, 0.15)
Gravity (m/s^2): (0.14, -0.32, 9.8)
```

Much better.

## Clock Speed Up Fix for BNO085

With the line:

```auto
dtparam=i2c_arm_baudrate=400000
```

added to `/boot/config.txt` and the Pi rebooted, try running the same library example:

```terminal
pi@raspberrypi:~ $ python3 bno08x_simpletest.py
Acceleration:
X: 0.574219  Y: -0.113281 Z: 10.000000  m/s^2

Gyro:
X: 0.000000  Y: 0.000000 Z: 0.000000 rads/s

Magnetometer:
X: 13.812500  Y: 22.375000 Z: -45.875000 uT

Rotation Vector Quaternion:
I: 0.003662  J: -0.025330 K: 0.294250  Real: 0.955383

Acceleration:
X: 0.613281  Y: -0.113281 Z: 10.031250  m/s^2

Gyro:
X: 0.000000  Y: 0.000000 Z: -0.001953 rads/s

Magnetometer:
X: 14.187500  Y: 23.125000 Z: -43.187500 uT

Rotation Vector Quaternion:
I: 0.003662  J: -0.028625 K: 0.316528  Real: 0.948120
```

And now it's working.

# Raspberry Pi I2C Clock Stretching Fixes

## Software I2C

Since the underlying issue with I2C clock stretching on a Raspberry Pi is the hardware I2C peripheral, another option is to simply not use it. Instead, use a software based implementation. On a Raspberry Pi, this is available via the **i2c-gpio device tree overlay**.

There is a little more work to be done with this approach. An additional library must be installed and some minor code changes need to be done to user code.

## The i2c-gpio Overlay

Information about the i2c-gpio overlay can be found in this README:

[Overlays README](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README)
The same information is also likely on the Pi itself under `/boot/overlays/README`. This is a large README that covers all of the overlays. Search for "i2c-gpio" to find the entry for the software I2C overlay. It should look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/116/173/medium800/raspberry_pi_i2c-gpio.png?1666718168)

This describes the general syntax used to enable the overlay (the Load: line) as well as the four parameters that can be used to customize the resulting behavior.

## Enabling the i2c-gpio Overlay

To enable the i2c-gpio overlay, the `/boot/config.txt` is updated to add a line that enables it and optionally configures settings.

To use the **defaults settings** , the line can simply be:

```auto
dtoverlay=i2c-gpio
```

To specify **specific pins** , for example `16` and `20`, use:

```auto
dtoverlay=i2c-gpio,i2c_gpio_sda=16,i2c_gpio_scl=20
```

 **After rebooting** , the resulting I2C interface will show up as a /dev/i2c\* entry. A number will automatically be assigned at boot time. To specify a specific **bus number** , for example `8`, use:

```auto
dtoverlay=i2c-gpio,bus=8
```

The parameters can be combined as needed. For example, to specify specific pins and a fixed bus number, use:

```auto
dtoverlay=i2c-gpio,i2c_gpio_sda=16,i2c_gpio_scl=20,bus=8
```

Danger: 

## Finding the I2C Port

After editing `/boot/config.txt` to add the i2c-gpio overlay, and rebooting, run the following command:

```terminal
ls /dev/i2c*
```

This will list all of the I2C buses created. Here is example output using the configuration from the previous section:

```terminal
pi@raspberrypi:~ $ ls /dev/i2c*
/dev/i2c-1  /dev/i2c-20  /dev/i2c-21  /dev/i2c-8
```

There are several entries shown. The `/dev/i2c-8` entry is the one created via the i2c-gpio overlay. The number `8` is a result of using the `bus=8` parameter.

## Extended Bus Library

This is the first bit of extra work that needs to be done to allow using the i2c-gpio overlay. The main Blinka installation works with known specific hardware I2C ports and pins. It's not aware of any additional I2C ports that may be setup using the i2c-gpio overlay. To access these, the following library is needed:

[Adafruit Python Extended Bus](https://github.com/adafruit/Adafruit_Python_Extended_Bus)
It can be installed like any other Python/CircuitPython library using pip:

```auto
pip3 install adafruit-extended-bus
```

## Update Code

The next bit of work needed is to modify code to use the [Python Extended Bus library](https://github.com/adafruit/Adafruit_Python_Extended_Bus) to access the software I2C port. The changes are limited to the initial setup part of the code. Once the I2C port has been created in code, it can be used in the same manner as the typical hardware I2C port.

Here is a brief summary of the two main lines needed:

```auto
# import the library
from adafruit_extended_bus import ExtendedI2C as I2C

# access the I2C port by bus number
i2c=I2C(8)
```

The library is imported and then the I2C bus is created. It is referenced using the bus number, `8` in this example. **This number may be different for different setups and should be changed as needed.** See previous section for details.

Now the `i2c` instance can be used in the same manner as the regular hardware i2c instance seen in most example code.

# Raspberry Pi I2C Clock Stretching Fixes

## Example Fixes

Let's look at some specific examples using the BNO055 and BNO085.

**NOTE:** These example assume the i2c-gpio overlay has been enabled and configured with the following line added to `/boot/config.txt`:

```auto
dtoverlay=i2c-gpio,i2c_gpio_sda=16,i2c_gpio_scl=20,bus=8
```

## Software I2C with BNO055

Let's try using the software I2C port with the BNO055.

Wiring used for BNO055 example. Note the pins used for SCL and SDA.

![raspberry_pi_BNO055_fritz_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/116/179/medium640/raspberry_pi_BNO055_fritz_bb.png?1666722707)

We again use the [example from the BNO055 library](https://github.com/adafruit/Adafruit_CircuitPython_BNO055/blob/main/examples/bno055_simpletest.py). However, we make the following modifications to use the software I2C port:

```auto
import time
import board
import adafruit_bno055
from adafruit_extended_bus import ExtendedI2C as I2C

i2c=I2C(8)
sensor = adafruit_bno055.BNO055_I2C(i2c)
```

 **Only the top part of the code listing is shown above. The remainder of the example code is unchanged.**

Now running the updated example:

```terminal
pi@raspberrypi:~ $ python3 bno055_simpletest.py 
Temperature: 23 degrees C
Accelerometer (m/s^2): (0.0, 0.0, 0.0)
Magnetometer (microteslas): (38.5, -27.6875, -67.0625)
Gyroscope (rad/sec): (-0.002181661564992912, -0.001090830782496456, 0.00545415391248228)
Euler angle: (0.0, 0.0, 0.0)
Quaternion: (0.0, 0.0, 0.0, 0.0)
Linear acceleration (m/s^2): (0.0, 0.0, 0.0)
Gravity (m/s^2): (0.0, 0.0, 0.0)

Temperature: 23 degrees C
Accelerometer (m/s^2): (0.15, -0.34, 10.0)
Magnetometer (microteslas): (39.1875, -26.25, -65.0625)
Gyroscope (rad/sec): (-0.001090830782496456, 0.0, 0.0)
Euler angle: (0.0, 0.8125, 2.0625)
Quaternion: (0.99981689453125, -0.018310546875, -0.0072021484375, 0.0)
Linear acceleration (m/s^2): (-0.01, 0.01, 0.14)
Gravity (m/s^2): (0.14, -0.35000000000000003, 9.790000000000001)

Temperature: 23 degrees C
Accelerometer (m/s^2): (0.15, -0.33, 9.92)
Magnetometer (microteslas): (39.5625, -26.5625, -64.375)
Gyroscope (rad/sec): (-0.001090830782496456, -0.001090830782496456, 0.0)
Euler angle: (0.0, 0.8125, 2.0625)
Quaternion: (0.99981689453125, -0.018310546875, -0.0072021484375, 0.0)
Linear acceleration (m/s^2): (0.01, 0.02, 0.17)
Gravity (m/s^2): (0.14, -0.35000000000000003, 9.790000000000001)
```

The readings look good.

## Software I2C with BNO085

Now to try using the software I2C port with the BNO085.

Wiring used for BNO085 example. Note the pins used for SCL and SDA.

![raspberry_pi_BNO085_fritz_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/116/180/medium640/raspberry_pi_BNO085_fritz_bb.png?1666722953)

Again to use the [example from the BNO085 library](https://github.com/adafruit/Adafruit_CircuitPython_BNO08x/blob/main/examples/bno08x_simpletest.py). However, make the following modifications to use the software I2C port:

```auto
import time
import board
import busio
from adafruit_bno08x import (
    BNO_REPORT_ACCELEROMETER,
    BNO_REPORT_GYROSCOPE,
    BNO_REPORT_MAGNETOMETER,
    BNO_REPORT_ROTATION_VECTOR,
)
from adafruit_bno08x.i2c import BNO08X_I2C
from adafruit_extended_bus import ExtendedI2C as I2C

i2c=I2C(8)
bno = BNO08X_I2C(i2c)
```

 **Only the top part of the code listing is shown above. The remainder of the example code is unchanged.**

Now running the updated example:

```terminal
pi@raspberrypi:~ $ python3 bno08x_simpletest.py
Acceleration:
X: 0.078125  Y: 0.078125 Z: 9.542969  m/s^2

Gyro:
X: -0.001953  Y: 0.000000 Z: 0.000000 rads/s

Magnetometer:
X: 18.250000  Y: 31.312500 Z: -51.437500 uT

Rotation Vector Quaternion:
I: 0.005066  J: -0.002808 K: 0.271362  Real: 0.962463

Acceleration:
X: 0.078125  Y: 0.078125 Z: 9.582031  m/s^2

Gyro:
X: 0.000000  Y: 0.000000 Z: -0.003906 rads/s

Magnetometer:
X: 18.687500  Y: 32.000000 Z: -51.500000 uT

Rotation Vector Quaternion:
I: 0.005554  J: -0.002014 K: 0.267334  Real: 0.963623
```

Readings look good and (hopefully) it should continue running without hitting any errors.


## Related Guides

- [Plantagotchi: PyBadge Plant Monitor](https://learn.adafruit.com/plantagotchi-pybadge-plant-monitor.md)
- [Adafruit QT Py RP2040](https://learn.adafruit.com/adafruit-qt-py-2040.md)
- [Adafruit PCF8591 Basic 4 x ADC + DAC Breakout](https://learn.adafruit.com/adafruit-pcf8591-adc-dac.md)
- [CLUE Vertical Garden Weather Visualizer](https://learn.adafruit.com/clue-vertical-garden-weather-visualizer.md)
- [MagTag Literary Quote Clock](https://learn.adafruit.com/magtag-literary-quote-clock.md)
- [Mystery Box: Haunted Radio](https://learn.adafruit.com/mystery-box-haunted-radio.md)
- [Custom HID Devices in CircuitPython](https://learn.adafruit.com/custom-hid-devices-in-circuitpython.md)
- [Make a Pi Trash Classifier with Machine Learning and Lobe](https://learn.adafruit.com/lobe-trash-classifier-machine-learning.md)
- [Python Edge Speech Recognition with Voice2JSON](https://learn.adafruit.com/edge-speech-recognition-with-voice2json.md)
- [Getting Started with HalloWing for Hackaday Supercon Attendees](https://learn.adafruit.com/getting-started-with-hallowing-for-hackaday-supercon-attendees.md)
- [PowerWash Simulator Nozzle Controller](https://learn.adafruit.com/powerwash-simulator-nozzle-controller.md)
- [Adafruit TLV320DAC3100 I2S DAC](https://learn.adafruit.com/adafruit-tlv320dac3100-i2s-dac.md)
- [How to Add a New Board to CircuitPython](https://learn.adafruit.com/how-to-add-a-new-board-to-circuitpython.md)
- [NeoPixel Menorah](https://learn.adafruit.com/neopixel-menorah.md)
- [MacroPad Summer Olympics Hotkeys](https://learn.adafruit.com/macropad-olympic-hotkeys.md)
