# CircuitPython POV Bike Wheel

## Overview

https://youtu.be/Q_NKRBHHIpg

Light up your bike for festival season or nighttime Critical Mass rides. Stand out from the crowd with a custom persistence-of-vision bike wheel display, and upload dozens of your own images to create the ride you’ve always dreamed of.

Persistence of vision is the effect that happens when your eyes briefly retain an image after it disappears. By flashing LEDs in carefully timed patterns as the bike wheel spins, those individual points of light appear to blend together into a complete floating image.

This guide shows you how to build a three-spoke, double-sided bike wheel display. There’s some tricky soldering required to get everything wired neatly and securely in place, so this is not a beginner build.

Sample CircuitPython code and images are included, and it’s easy to swap in your own artwork or adapt the layout for your particular wheel and LED setup.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/963/medium800/sensors_pov_bike_wheel_hero.jpeg?1787941790)

## Parts
Featured
### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
![Angled shot of black rectangular microcontroller "Feather RP2040"](https://cdn-shop.adafruit.com/640x480/4884-04.jpg)

### Adafruit DotStar Digital LED Strip - White 144 LED/m - One Meter

quantity: 2
[Adafruit DotStar Digital LED Strip - White 144 LED/m - One Meter](https://www.adafruit.com/product/2242)
Move over NeoPixels, there's a new LED strip in town! These fancy new DotStar LED strips are a great upgrade for people who have loved and used NeoPixel strips for a few years but want something even better. DotStar LEDs use generic 2-wire SPI, so you can push data much faster than with...

In Stock
[Buy Now](https://www.adafruit.com/product/2242)
[Related Guides to the Product](https://learn.adafruit.com/products/2242/guides)
![Shot of lightly coiled LED strip glowing rainbow colors.](https://cdn-shop.adafruit.com/product-videos/640x480/2242-09.jpg)

### Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer

[Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer](https://www.adafruit.com/product/6490)
The **Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer Breakout** is a low-power linear 3D Hall-effect sensor designed for a wide range of industrial and personal electronics applications. It&nbsp;integrates three independent Hall-effect magnetometer sensors in the X, Y, and Z...

In Stock
[Buy Now](https://www.adafruit.com/product/6490)
[Related Guides to the Product](https://learn.adafruit.com/products/6490/guides)
![Angled shot of 3D magnetometer sensor breakout.](https://cdn-shop.adafruit.com/640x480/6490-00.jpg)

### High-strength 'rare earth' magnet

[High-strength 'rare earth' magnet](https://www.adafruit.com/product/9)
Yow! These things are super powerful. .47" diameter and .18" thick discs. Great for use with your SpokePOV Kit. If you have an aluminium frame, use tape/foam sticky tape to attach it.

In Stock
[Buy Now](https://www.adafruit.com/product/9)
[Related Guides to the Product](https://learn.adafruit.com/products/9/guides)
![Angled Shot of the High-strength 'rare earth' magnet.](https://cdn-shop.adafruit.com/640x480/9-04.jpg)

### STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long](https://www.adafruit.com/product/4399)
This 4-wire cable is&nbsp;50mm / 1.9" long and fitted with JST SH female 4-pin connectors on both ends. Compared with the chunkier JST PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4399)
[Related Guides to the Product](https://learn.adafruit.com/products/4399/guides)
![Angled of of JST SH 4-Pin Cable.](https://cdn-shop.adafruit.com/640x480/4399-00.jpg)

### Adafruit USB Type C Plug Breakout

[Adafruit USB Type C Plug Breakout](https://www.adafruit.com/product/5978)
Throw out all those Mini and Micro B USB cables you have in a plastic bin - the next generation of USB connectors is here with&nbsp; **USB C**! You've seen these connectors pop up on all sorts of devices, as the industry moves from micro B or lightning to the new standard....

In Stock
[Buy Now](https://www.adafruit.com/product/5978)
[Related Guides to the Product](https://learn.adafruit.com/products/5978/guides)
![Angled shot of USB type C breakout.](https://cdn-shop.adafruit.com/640x480/5978-00.jpg)

### USB C to USB C Cable - USB 3.1 Gen 4 with E-Mark - 6" long

[USB C to USB C Cable - USB 3.1 Gen 4 with E-Mark - 6" long](https://www.adafruit.com/product/4198)
As technology changes and adapts, so does Adafruit! Rather than the regular USB A, this cable has&nbsp; **USB C to USB C** &nbsp;plugs!

USB C is the latest industry-standard connector for transmitting data&nbsp;_and_&nbsp;power. Like Lightning and MagSafe cables, USB C...

In Stock
[Buy Now](https://www.adafruit.com/product/4198)
[Related Guides to the Product](https://learn.adafruit.com/products/4198/guides)
![USB C to USB C cable. USB 3.1 gen 4 with E-Mark. 6" long](https://cdn-shop.adafruit.com/640x480/4198-01.jpg)

This is my favorite wire for projects that will flex and move a lot. Get 4 different colors: I used black, red, green, and yellow.

### Silicone Cover Stranded-Core Wire - 2m 26AWG Black

quantity: 4
[Silicone Cover Stranded-Core Wire - 2m 26AWG Black](https://www.adafruit.com/product/1881)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

In Stock
[Buy Now](https://www.adafruit.com/product/1881)
[Related Guides to the Product](https://learn.adafruit.com/products/1881/guides)
![Black Silicone Cover Stranded-Core Wie](https://cdn-shop.adafruit.com/640x480/1881-01.jpg)

### 3-pin JST SM Plug + Receptacle Cable Set

[3-pin JST SM Plug + Receptacle Cable Set](https://www.adafruit.com/product/1663)
These 3-wire cables are 163mm (6.4") long and come as a set. One cable has a JST SM type connector plug on the end. The other cable has a matching JST SM type receptacle connector. They are good for whenever you have 3 wires you want to be able to plug and unplug. We like the solid and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1663)
[Related Guides to the Product](https://learn.adafruit.com/products/1663/guides)
![Angled shot of 2 3-pin JST SM Plug + Receptacle Cable.](https://cdn-shop.adafruit.com/640x480/1663-00.jpg)

### 2-pin JST SM Plug + Receptacle Cable Set

[2-pin JST SM Plug + Receptacle Cable Set](https://www.adafruit.com/product/2880)
These 2-wire cables&nbsp;are 16cm long and come as a set. &nbsp;One side has a 2-pin JST SM type connector plug on the end. &nbsp;The other side has a matching 2-pin JST SM type receptacle connector. &nbsp;They are good for whenever you have 2 wires you want to be able to plug and unplug....

In Stock
[Buy Now](https://www.adafruit.com/product/2880)
[Related Guides to the Product](https://learn.adafruit.com/products/2880/guides)
![Angled Shot of the 2-pin JST SM Plug + Receptacle Cable Set.](https://cdn-shop.adafruit.com/640x480/2880-11.jpg)

### You'll Also Need

- [Clear self-fusing silicone tape](https://a.co/d/0aWQeUSz)
- [Clear 1/2" heat shrink tubing](https://a.co/d/0hoQ7RpM)
- Hot glue gun & sticks
- Heat gun
- Zip ties
- Soldering iron & accessories

# CircuitPython POV Bike Wheel

## Wiring Diagram

![](https://cdn-learn.adafruit.com/assets/assets/000/145/901/medium800/sensors_wiring2_bb.jpg?1787768889)

The wiring for this project is fairly complex.

For a double-sided wheel, use six LED strips arranged in pairs.&nbsp;The two strips in each pair are wired identically, so the left and right sides of your bike will show the same image. Treat these like one double-sided strip once they're connected.

Working from the **IN** end of all strips (arrows pointing away from your solder joints:)

- **VCC** (red wires) connect all together and to **VBUS** on the USB breakout
- **GND** (black wires) connect all together and to **GND** on the USB breakout, and also to **G** on the Feather
- **CI** (yellow wires) connect all together and to **SCK** on the Feather
- **DI** (green wires) connect in pairs, then the pairs are connected to **A1** , **A2** , and **A3** on the Feather

Use either Stemma port on the hall effect sensor to plug into the Feather's Stemma port.&nbsp;

# CircuitPython POV Bike Wheel

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_feather_rp2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/102/705/medium800/adafruit_products_FeatherRP_buttons_highlighted.jpg?1623167565)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/145/511/original/nuke_universal.uf2?1786537992)
# CircuitPython POV Bike Wheel

## Test Code

This code will light up the three pairs of LED strips in red, green, and blue. Use this code during the build to make sure all the strips are working and to help keep the strips together in the correct order during assembly.

You can access the code and necessary libraries by downloading the Project Bundle.

To do this, click on the **Download Project Bundle** button in the window below. It will download to your computer as a zipped folder.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CircuitPython_Bike_Wheel_POV/test/code.py

## Upload the Code and Libraries to the RP2040 Prop-Maker Feather

After downloading the Project Bundle, plug your RP2040 Prop-Maker Feather into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called **CIRCUITPY**. Unzip the folder and copy the following items to the RP2040 Prop-Maker Feather's **CIRCUITPY** drive.

- **lib** folder
- **code.py**

Your RP2040 Prop-Maker Feather **CIRCUITPY** drive should look like this after copying the **lib** folder,&nbsp;and the **code.py** file.

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/CircuitPython_Bike_Wheel_POV_test.png )

If your strips have a different number of pixels than 36, or if you soldered to different pins, change the code here.

```auto
NUM_PIXELS = 36

CLOCK_PIN = board.SCK
DATA_PINS = (board.A1, board.A2, board.A3)
```

# CircuitPython POV Bike Wheel

## Electronics Assembly

My bike has 27.5 inch wheels, and each spoke fits 36 pixels.&nbsp;

Figure out the length you want for your bike and cut 6 strips to that length. When cutting, leave the full width of the copper pads on the IN end of the cut-off strip. This will make soldering the strips a whole lot easier - these pads are tiny so do yourself a favor here and keep them intact.

Slip some clear heat shrink on to both cut ends of the strips. Don't shrink it down until you're done testing, but it's good to put it on now so you don't forget later.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/905/medium640/sensors_cutstrips.jpeg?1787770356)

The 6 clock pins (CI) on the LED strips will all connect to the same pin on the Feather: SCK.

Cut three yellow wires to about 5-6" long. Find the center, and carefully cut through the shielding on the silicone wires with your fingernail or a pair of wire strippers to expose a little bit of the wire in the middle.&nbsp;

Twist the three wires together so the exposed wires all snuggle together. You want a good solid connection of the metal here. Now you have six wires all neatly joined together. These six wires will connect to the CI pins on your six strips.

Cut one more 3-4" piece of yellow wire -- this one will connect all these wires to the Feather. Wrap it around the metal connection point so you have a seven wire bundle. Solder the connection thoroughly so all the wires have good connectivity. Cover the joint with heat shrink.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/902/medium640/sensors_01wire_separate.jpeg?1787769539)

![](https://cdn-learn.adafruit.com/assets/assets/000/145/903/medium640/sensors_02wire_twist.jpeg?1787770117)

![](https://cdn-learn.adafruit.com/assets/assets/000/145/904/medium640/sensors_03wire_seven.jpeg?1787770147)

Repeat this process with the red wires - you want a 7-wire bundle there too. The 7th wire will connect to VCC on the USB breakout.

For the black wires, use the same technique but end up with 8 wires (so, 4 twisted pairs). The ground wires need to go to both the Feather G and the USB breakout G so we need one more in the black bundle.

For the green (data) wires: each LED pair will connect to a different data pin, so we need to keep them separate and not bundle them all up.

Make three 3-wire splice junctions. One wire from each set will go to the Feather (pins **A1** , **A2** , and **A3** ) and the others will go to the **DI** pins on the LED strips.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/906/medium640/sensors_green.jpeg?1787771264)

Solder the wires onto the LED strips, making sure you're soldering to the IN end:

- Red \> VCC
- Yellow \> CI
- Green \> DI
- Black \> G

You should be left with three green wires, two black wires, one red wire and one yellow wire left unconnected.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/907/medium640/sensors_04_wired.jpeg?1787771536)

Solder the red wire and one of the black wires to the USB breakout:

- Red \> VBUS
- Black \> G

Slide on some heat shrink, but again, don't seal anything yet.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/908/medium640/sensors_05_usb_brekaout.jpeg?1787771681)

Solder JST connectors onto the remaining wires: Black and yellow to the 2-pin connector, and the 3 green wires to the 3-pin connector.&nbsp;

I also ended up extending the wires leading to the USB breakout a bit just to give myself more wiggle room during installation.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/145/909/medium640/sensors_07wired.jpeg?1787771848)

Connect the other sides of the JST connectors to the Feather:

- 3-pin connector to A1, A2, and A3
- 2-pin connector to G and SCK

The order isn't too important for the 3 pin connector. We'll sort them out during installation. But make sure you get the G wire and SCK wire consistent with the LED wiring for the 2-pin connector.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/145/910/medium640/sensors_08controller_wired.jpeg?1787772001)

The hall effect sensor plugs into the Feather via the Stemma port.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/913/medium640/sensors_stemma.png?1787772914)

Be sure you've uploaded the test code from the software page.

Plug the 3-pin and 2-pin connectors from the Feather into the LED strips. Plug the USB breakout into the battery. Also plug the Feather's USB port&nbsp;into the battery using a short USB cable.

If all goes well, your lights will turn on in red, green, and blue. Sort them out so the pairs are together.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/912/medium640/sensors_09lit.jpeg?1787772721)

## Troubleshooting

This is a devilishly complicated wiring job. If all your lights come on in the right colors on the first try, I'd love to shake your hand! Mine sure didn't. If yours didn't either, here are some things to try:

- Look closely at the solder connections on the LED strips. These pads are SO tiny and SO close together that it's easy to bridge the solder, or have a stray wire from one pad touching another pad. With the power turned OFF, run a utility knife gently between the pads of the offending strip to see if there are any tiny stray wires.
- Make sure you soldered to the IN end of all the strips. If one is soldered on the OUT end (arrows pointing toward the solder joints), flip the strip around.
- If you had a hard time soldering, and the solder pads are burned or unsalvageable and you want to start again, cut off one LED from the front of the strip. If one or two of these strips have 35 instead of 36 in the length, the bike will still look great.
- Check all your connections again. Follow each wire through the connectors to make sure it goes where you think it goes. Some connectors have different color-coding order from other connectors and it's easy to accidentally plug the red wire into the black wire port on a connector from a different lot.
- Try re-uploading the test code. Open your serial monitor in Mu (or your favorite code editor) and see if the code is running correctly.
- Make sure both the USB breakout and the Feather are plugged into power, and that your battery is capable of running two ports at once. Try plugging them into a USB hub or wall socket to determine whether the battery is the problem.

## Seal Your Connections. And Then Seal Them Some More.

I brought my bike to Burning Man on a very dusty and rainy year, and my project did not completely survive. Two of the strips started flickering on and off intermittently, and one of the silicone sleeves got torn somehow, either through riding or during transport - probably because I was too aggressive when tightening the zip tie.&nbsp;

When I pulled the JST connectors apart, there was playa dust inside both of them making the electrical connections much weaker. I also didn't seal the USB ports on either the battery or the controller. The bike did work for the first couple days of the festival but by the end I was experiencing problems.&nbsp;

This build will survive normal city use and forest or beach festivals, but for windy, dusty, muddy desert festivals I recommend adding a LOT more sealing.&nbsp;

### Sealing Ideas

- Use a second layer of heat shrink over all wire connections. Squirt some hot glue inside the heat shrink before shrinking it down, or use [heat shrink with adhesive already inside](amazon.com/TKDMR-530-Pcs-Shrink-Adhesive/dp/B0GSW28K44/ref=sr_1_2_sspa?dib=eyJ2IjoiMSJ9.49LfqXCa8YGCwHVnsw-shEg_jKJF6URA-UFR5T-2kuSvK7NIVi1fmD0VD4EbFHgX8sYBJ5_jLSJC6Jgpsd2Vu51ctZT57ThV-jjNBD1ndShgRhdQV8KUFgW6pQRFfpsNjKHX9XfLLfnxD2rLWto5_a710WMRjDMPkKzEMAqEE05ZhMsapEZi0KRa8_on5iqunYuN5OF-IA8UIjkraGInUT-kj82M9ciOSj-WatNVUGg.L_jr9IXuM-2yZXovH6zCj96hOv_9fWIul0_8mnvMQBM&dib_tag=se&keywords=wiring+heat+shrink+glue&qid=1789578379&sr=8-2-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1).
- Use a lot of self-sealing silicone tape. Bring an extra roll and really pile it on over the USB battery port connections. You'll need to cut it off to charge the battery, but your electronics will work a lot longer. All the connections I covered with this stuff DID survive!
- Wrap the JST connectors in self-sealing silicone tape as well to keep the dust out
- Be sure to seal up both ends of the LED strips. Two of my strips had exposed wire on the OUT end that I hadn't noticed during the build, and those were definitely giving me trouble after the burn.
- Be careful when attaching the strips to the bike! I got a zip tie too tight and it rubbed its way right through the silicone sleeve.&nbsp;

# CircuitPython POV Bike Wheel

## Bike Assembly

Decide if you want the POV display on the front or back wheel. If you're using the back wheel, make sure there's plenty of room for the gear selector to move without hitting the strips or electronic components.

Once you're sure everything's working, seal up all the electronics to keep water and dust out.

Use hot glue and 3/4" clear heat shrink to seal both ends of all your LED strips.&nbsp;

Use 1" heat shrink and/or self-sealing silicone tape to enclose the Feather and hall effect sensor together into a little plastic-coated bundle, with the two JST connectors sticking out the end. Fill that end of the heat shrink bundle with a little more hot glue. Seal it up as much as you can while still keeping the USB port accessible.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/145/931/medium640/sensors_controller_bundle.jpeg?1787871518)

![](https://cdn-learn.adafruit.com/assets/assets/000/145/932/medium640/sensors_controller2.jpeg?1787871588)

![](https://cdn-learn.adafruit.com/assets/assets/000/145/933/medium640/sensors_06heatshrink_hg.jpeg?1787871637)

Select three spokes that are placed at equidistant angles around the wheel. Use zip ties and clear silicone self-sealing tape to secure the three pairs of strips back-to-back along the spokes, in the order shown and matching colors in the back-to-back placement.

Manage the wires around the hub of the wheel with more zip ties. If these wires catch on the gear mechanism or get out of line in any way, they'll very likely break. Spend a little time doing some wire management for safety.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/934/medium640/sensors_10spokes.jpeg?1787871881)

Use some strong zip ties to secure the controller to the battery, and the battery to two spokes. Tighten the zip tie just below a spot where the spokes cross, so the centrifugal force pulling the battery out toward the rim of the wheel as you ride pulls the zip tie against the widening spokes and keeps the battery firmly in place.

Make sure you can reach the USB ports and the on/off switch on the battery easily.

If you're taking this to a dusty, muddy desert, add self-sealing silicone tape around the USB port connection to seal it up once you're done testing.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/935/medium640/sensors_controller2_%281%29.jpeg?1787872108)

Use 5 minute epoxy or another strong adhesive to glue the rare earth magnet to the inside of the frame, at the location where the magnet sensor will pass directly by it as the wheel turns.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/941/medium640/sensors_IMG_7916.jpeg?1787879250)

Plug in the two JST connectors connecting the strips to the Feather. Plug the USB-C breakout into the USB-C port on the battery, and connect the Feather's USB port to another of the battery ports using a short USB cable.&nbsp;

Use the self-sealing silicone tape or more zip ties wherever needed to hold everything in place.&nbsp;

# CircuitPython POV Bike Wheel

## Code the POV Wheel

You can access the code and necessary libraries by downloading the Project Bundle.

Click the **Download Project Bundle** button in the code window below. This will download a zipped folder containing the CircuitPython code, libraries, and sample images for the project.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CircuitPython_Bike_Wheel_POV/final/code.py

After downloading the bundle, plug the Feather RP2040 into your computer with a known good USB data+power cable. A drive named **CIRCUITPY** should appear in Finder or File Explorer.

Copy the following items to the CIRCUITPY drive:

- **/lib** folder
- **code.py**
- create a folder called **/img** and put all images inside

The **/img** folder contains the artwork displayed by the wheel. Add your own images to this folder to customize the artwork that shows.

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/CircuitPython_Bike_Wheel_POV_final.png )

The code watches the Hall effect sensor to determine how quickly the wheel is turning, then adjusts the LED timing to keep the persistence-of-vision images looking consistent as your speed changes. The three spokes work together to draw different sections of the same image around the wheel.

## Configuration

The main settings are gathered near the top of **code.py** so you can customize the display without digging through the rest of the program.

```auto
NUM_LEDS = 36
IMAGE_FOLDER = "/img"
IMAGE_SECONDS = 8.0

SCANLINES_PER_REVOLUTION = 144
MIN_SCANLINES_PER_SECOND = 400.0

STABILIZATION_STRENGTH = 1.0
PATTERN_ROTATION_DEGREES = 30.0

DOTSTAR_BRIGHTNESS = 10
```

`NUM_LEDS` should match the number of DotStar LEDs on each spoke. This build uses 36 LEDs per strip.

`IMAGE_SECONDS` controls how long each image is displayed before the next image in the **/img** folder is loaded.

`DOTSTAR_BRIGHTNESS` controls the overall LED brightness. DotStars use a global brightness value from `0` to `31`. Lower values save power and can actually make POV images easier to photograph at night.

## Image Size and Repeats

All images must be exactly **36 pixels high** to match the 36 LEDs running from the hub toward the rim.

The image width can vary.

```auto
SCANLINES_PER_REVOLUTION = 144
```

This setting determines approximately how much image data is drawn during one wheel revolution. Shorter images automatically repeat around the wheel.

```auto
36 pixels wide  = about 4 repeats
72 pixels wide  = about 2 repeats
144 pixels wide = about 1 repeat
```

Narrow geometric patterns tend to work especially well for POV. Wider images can display more complex artwork, but very long images may be harder to read clearly while riding.

Add your own `.bmp` or `.gif` files to the **/img** folder. The code will cycle through the files alphabetically.

If an image cannot be loaded — for example, if it is the wrong height or is too large to fit in memory — the code will skip it and continue to the next image.

## Wheel Speed

The Hall effect sensor measures each wheel revolution and uses that timing to adjust the image playback speed.

```auto
MIN_SCANLINES_PER_SECOND = 400.0
```

This sets the minimum playback speed. At very slow wheel speeds, allowing the LEDs to update too slowly can make the image look incomplete or broken up. The default value of `400` keeps the animation moving fast enough to maintain a convincing POV effect.

For this build, I found the default value worked well and generally wouldn't recommend changing it unless you're experimenting with a different wheel size or LED layout.

## Image Position

The Hall sensor also gives the code a reference point for the wheel position.

```auto
STABILIZATION_STRENGTH = 1.0
PATTERN_ROTATION_DEGREES = 30.0
```

`STABILIZATION_STRENGTH` controls how strongly the image timing corrects itself relative to the Hall sensor. A value of `1.0` works well for this build.

`PATTERN_ROTATION_DEGREES` rotates the displayed artwork around the wheel relative to the magnet. Change this value if your images consistently appear in an awkward part of the wheel.

Try values such as:

```auto
PATTERN_ROTATION_DEGREES = 0.0
PATTERN_ROTATION_DEGREES = 30.0
PATTERN_ROTATION_DEGREES = 90.0
```

This does not rotate the bitmap itself. It shifts where the repeating POV pattern appears around the wheel.

## Hall Sensor Settings

The Hall effect sensor settings are also near the top of the file:

```auto
MAG_TRIGGER = 800.0
MAG_RELEASE = 450.0
```

These values determine when the code recognizes that the wheel magnet has passed the sensor.

The defaults were tuned for the magnet and sensor placement used in this build. You probably won't need to change them unless you're using a different magnet or mounting the sensor farther away.

The LEDs remain off while the wheel is stationary. After the code detects two valid magnet passes, the POV display starts automatically. When the wheel stops, the LEDs turn off again.

I think that’s about the right level for this guide: enough for someone to confidently change the artwork, timing, brightness, and image position, without forcing them through the PIO packing or Hall-state logic.

# CircuitPython POV Bike Wheel

## Create Images

![](https://cdn-learn.adafruit.com/assets/assets/000/145/943/medium800/sensors_icons.jpg?1787889050)

The code bundle includes around 30 starter images. If you want to add your own artwork, here are the specs:

- .gif or .bmp format - be sure .gif images are still, not animated, and .bmp images are saved as 8-bit files
- Images should have a height equal to the number of pixels in your strip, so mine are 36 pixels high
- Image width can vary, but images look best if the width is fairly narrow. Images that are 36 or 72 pixels wide will lay out beautifully on the wheel. Images that are narrower than 36 pixels also look great. For the most precise looking images, scale down in factors of 36 (18, 3, 6, etc).

36 pixels is not very many pixels! Your images will look tiny on your computer screen. There's an art to getting small images to look clear. Think of an icon - they're pixelated when you zoom in but clear from a distance. Icons or geometric shapes look great.&nbsp;

It's also effective to use the same shape but color-shifted into different hues. That gives a cohesive look to your bike.

If you want to play them in a certain order, use a naming convention that sorts them numerically or alphabetically. 00\_adafruit.bmp plays first since it's listed first in the **/img** folder.

![](https://cdn-learn.adafruit.com/assets/assets/000/145/964/medium800/sensors_bikewheel2.jpeg?1787942010)


## Guide Products

### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
### Adafruit DotStar Digital LED Strip - White 144 LED/m - One Meter

[Adafruit DotStar Digital LED Strip - White 144 LED/m - One Meter](https://www.adafruit.com/product/2242)
Move over NeoPixels, there's a new LED strip in town! These fancy new DotStar LED strips are a great upgrade for people who have loved and used NeoPixel strips for a few years but want something even better. DotStar LEDs use generic 2-wire SPI, so you can push data much faster than with...

In Stock
[Buy Now](https://www.adafruit.com/product/2242)
[Related Guides to the Product](https://learn.adafruit.com/products/2242/guides)
### Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer

[Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer](https://www.adafruit.com/product/6490)
The **Adafruit TMAG5273 (A2) 3D Hall Effect Magnetometer Breakout** is a low-power linear 3D Hall-effect sensor designed for a wide range of industrial and personal electronics applications. It&nbsp;integrates three independent Hall-effect magnetometer sensors in the X, Y, and Z...

In Stock
[Buy Now](https://www.adafruit.com/product/6490)
[Related Guides to the Product](https://learn.adafruit.com/products/6490/guides)
### High-strength 'rare earth' magnet

[High-strength 'rare earth' magnet](https://www.adafruit.com/product/9)
Yow! These things are super powerful. .47" diameter and .18" thick discs. Great for use with your SpokePOV Kit. If you have an aluminium frame, use tape/foam sticky tape to attach it.

In Stock
[Buy Now](https://www.adafruit.com/product/9)
[Related Guides to the Product](https://learn.adafruit.com/products/9/guides)
### STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long

[STEMMA QT / Qwiic JST SH 4-Pin Cable - 50mm Long](https://www.adafruit.com/product/4399)
This 4-wire cable is&nbsp;50mm / 1.9" long and fitted with JST SH female 4-pin connectors on both ends. Compared with the chunkier JST PH these are 1mm pitch instead of 2mm, but still have a nice latching feel, while being easy to insert and remove.

<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4399)
[Related Guides to the Product](https://learn.adafruit.com/products/4399/guides)
### Adafruit USB Type C Plug Breakout

[Adafruit USB Type C Plug Breakout](https://www.adafruit.com/product/5978)
Throw out all those Mini and Micro B USB cables you have in a plastic bin - the next generation of USB connectors is here with&nbsp; **USB C**! You've seen these connectors pop up on all sorts of devices, as the industry moves from micro B or lightning to the new standard....

In Stock
[Buy Now](https://www.adafruit.com/product/5978)
[Related Guides to the Product](https://learn.adafruit.com/products/5978/guides)
### USB C to USB C Cable - USB 3.1 Gen 4 with E-Mark - 6" long

[USB C to USB C Cable - USB 3.1 Gen 4 with E-Mark - 6" long](https://www.adafruit.com/product/4198)
As technology changes and adapts, so does Adafruit! Rather than the regular USB A, this cable has&nbsp; **USB C to USB C** &nbsp;plugs!

USB C is the latest industry-standard connector for transmitting data&nbsp;_and_&nbsp;power. Like Lightning and MagSafe cables, USB C...

In Stock
[Buy Now](https://www.adafruit.com/product/4198)
[Related Guides to the Product](https://learn.adafruit.com/products/4198/guides)
### Silicone Cover Stranded-Core Wire - 2m 26AWG Black

[Silicone Cover Stranded-Core Wire - 2m 26AWG Black](https://www.adafruit.com/product/1881)
Silicone-sheathing wire is super-flexible and soft, and its also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness has to...

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

## Related Guides

- [Introducing Adafruit Feather RP2040](https://learn.adafruit.com/adafruit-feather-rp2040-pico.md)
- [Adafruit TMAG5273 3D Hall Effect Magnetometer Breakout](https://learn.adafruit.com/adafruit-tmag5273-3d-hall-effect-magnetometer-breakout.md)
- [Pico W PiCowBell Case](https://learn.adafruit.com/pico-w-picowbell-case.md)
- [Neon LED Signs](https://learn.adafruit.com/led-neon-signs.md)
- [Attachécade](https://learn.adafruit.com/attache-arcade.md)
- [Ever-Burning Flame Painting](https://learn.adafruit.com/ever-burning-flame-painting.md)
- [Touch Deck: DIY Customizable TFT Control Pad](https://learn.adafruit.com/touch-deck-diy-tft-customized-control-pad.md)
- [Tiny LED WiFi Companion Cube](https://learn.adafruit.com/tiny-led-wifi-cube.md)
- [Toddler Timer](https://learn.adafruit.com/toddler-timer.md)
- [CYBERDECK Expansion Plate](https://learn.adafruit.com/cyberdeck-plate.md)
- [Magic Mirror with Glowing Secret Messages](https://learn.adafruit.com/magic-mirror-with-glowing-secret-messages.md)
- [Desk Calculator with CircuitPython](https://learn.adafruit.com/desk-calculator-with-circuitpython.md)
- [Adafruit QT Py ESP32-C3 WiFi Dev Board](https://learn.adafruit.com/adafruit-qt-py-esp32-c3-wifi-dev-board.md)
- [Which CircuitPython Board is Right for You?](https://learn.adafruit.com/choose-your-circuitpython-board.md)
- [Digital Clock with CircuitPython](https://learn.adafruit.com/digital-clock-with-circuitpython.md)
- [Adafruit DS3502 I2C Digital Potentiometer](https://learn.adafruit.com/ds3502-i2c-potentiometer.md)
- [LED Rocket Lamp](https://learn.adafruit.com/led-rocket-lamp.md)
