Introduction: NeoPixel Party Bike - Music Reactive Light Animations With Controller
I made my NeoPixel Party Bike for two reasons:
First, I've worked on a few simple NeoPixel projects in the past and it was like a "tease" that made me want to know more-more-more!
Second, I'm a member of BikeJC, a bicycle club in Jersey City that goes on rides at night throughout the summer. Most members light up their bikes with off-the-shelf bike lights - but I've been wanting to apply my hacker skills to my bike -- and make it epic!
I designed this project as my own personal "school" - my goal is to learn more about NeoPixels, music visualizations, and BLE. I already learned a lot and I'm happy to share it with you! I put in the time to make the physical hardware durable so that I can continue to deepen my knowledge of code, run tests, and try new skills on the same equipment - I think of it now as my "canvas for learning and testing"!
Here are some things I've found helpful along the way. If you have suggestions for tutorials, classes, blog posts, example code, or anything else I should check out (or add to this list) please comment below!
- 4 x 4 Matrix Array 16 Button Key Pad
- Not yet implemented, but soon to be! Adafruit NeoTrellis KeyPad with Silicone Button cover
- 2000 mAh Adafruit Lithium-Ion Battery (x2) (for the wheels)
- 10,000 mAh Battery Backup, similar to this (for the main controller)
- 3-Wire Cable (You could also use these LED strip connectors for connecting to the strips)
- 3 Pin Wire Connectors
- Heat Shrink (for all wire and led strip connections)
- 1 inch Black Heat Shrink (to go over plastic channels) - Home Depot
- Clear XL Heat Shrink(to protect Arduino Nano in Wheels)
- Panel Mount Stereo Audio Connector - Adafruit
- BUGANI M83 Speaker
- Audio Splitter with volume control
- Audio Cables(x2) (one for phone, one to connect to Arduino)
Enclosures & Mounting Supplies
- U-Shaped Mounting Channel
- Black Project Enclosure Box (Mine was from Radio Shack, R.I.P. )
- Industrial Strength Velcro
- Velcro Cable Ties
- Waterproof ID Holders (x2)
- Zip Tie Anchors & Zip Ties
- Soldering Iron & Solder
- Heat Gun
Step 1: Measure the Bike
First, I measured the bike to see how many LEDs I would need - I multiplied my measurements by 2 because I will have the lights on both sides of the bike! I chose to go with the 30LED/meter strands to cover the bike nicely without having too many LEDs that would drain the battery quickly. ( I was looking for about 3 hours of run time on this project, and I had a lot of pixels so I wanted to play it safe. You can learn more about powering NeoPixels in the Adafruit guide here. )
Step 2: Order Supplies
My system to connect the NeoPixel lights to my bike needed to be durable AND easy to remove (I park my bike outside in the city so I can't leave the lights attached to the bike at night). Here are some notes about the supplies I used and why I bought them. You can look at the "Supplies" section above for a more complete list.
- For my bike size and design, I ordered 10 meters (2 packs) of WS2812B LEDs from Amazon - I chose to go with the waterproof kind in case I get caught in the rain while riding.
- I also got some U-Shaped mounting channels from Home Depot to keep the lights straight. This not only will look more uniform but also allow me to attach and detach the lights easily without the light strips curling up into a ball of spaghetti between uses.
- I got some 3-wire cable to make joints in the LED strands.
- ( If available another solution with less soldering would be these LED strip connectors. )
- I also used 3-wire connectors wherever possible to make the project modular.
- And many sizes of heat shrink to protect all the joints.
- I got a huge pack of velcro cable ties to mount the LED sticks to the bike. These ended up being the perfect way to create a secure connection that is easy to remove.
Step 3: Make the 3 Strips With Joints
I chose to create three continuous strips per side (noted by color in my sketch), with two of the strips having joints made by cutting and soldering them back together with a flexible wire in between. The controller will go on the handlebars, so all the strips start at the top left.
I soldered the 3-wire cable to make the joints in the LED strands, then I added heat shrink around all of my joints to protect them.
Step 4: Keep It Together
Although the strips fit in the channels, they could fall out without some reinforcement.
- I added tiny bands of heat shrink about every 8 inches to keep the strips inside.
- I added a large piece of heat shrink over the ends.
- I also removed the red cover from the foam tape on the back and covered it with electrical tape. This was purely aesthetic - I thought that the red was distracting, and since the foam tape left behind a residue, it needed to be covered up.
If I had another form of long plastic sticks (other than the mounting channels) to keep the LEDs straight, I could have used the adhesive on the back of the strip to just adhere them to the stick. But even in this case, I think the heat shrink rings would be a good idea because adhesives are never THAT weatherproof. :p
Step 5: Attach With Velcro
I used the velcro cable ties to wrap around the strips about every 8 inches, and then placed the LED strips in place and wrapped the tails of the velcro around the bike frame and back around the strip. This worked as an easy and secure way to attach the lights - and it can also be removed fairly easily.
Step 6: Build the Test Circuit
I built the circuit as shown, connecting all the wires in a breadboard first.
I DID A WEIRD THING.
You'll notice in the diagram that I am powering the Arduino Nano 33 IOT from the USB port ( with a cable connected to a typical USB battery backup made for phones). And, that my power line for the NeoPixels is coming from the VIN pin.
I did not expect this to work. I think that it may even be incorrect. BUT - it does work, and it has been working all summer to run my 190 pixels off my battery pack. It appears that this pin is directly connected to the USB connector and is therefore powering the neopixels with 5V which is the voltage of the battery pack, and also powering the Arduino Nano at its 3.3V operating voltage without causing trouble. If you know more about this please comment on this step with more info!
Step 7: Testing 1-2-3!
I uploaded some of the examples from the Fast LED library and confirmed that my system was working. Now it was time to tame those crazy wires!
Step 8: Make Durable - Yet Removable - Connections
For the connections of the strips to the microcontroller, I added these wire connectors so that I could unplug the individual strips when taking them off the bike or troubleshooting/fixing them. Here's how the system works:
- Each strip has a "sister" strip on the other side of the bike. I labeled the female ends of the connectors with the number of the pin they go to (which is the same for the "sisters"), so there are two connectors with each of the pin numbers (4,6 and 8). I also added one more connector to add a single strip across the handlebars that does not have a "sister" (labeled 2 for pin 2).
- On the male ends of the connectors, I labeled them with their pin numbers plus SL or SR so that I put the system back together, in the same way, each time to make it easier to troubleshoot.
- Why "SL6?" "SL" stands for "Stage Left" - a quick way to remind me which version of "Left" I mean - this is borrowed from stage performers who refer to "stage right" or "stage left" as from the performers' point of view. In my case, I meant it as from the biker's point of view. :-)
Step 9: Make the Connections Changable
Because this is an ongoing project, I wanted to make sure I could keep changing the pin configuration without re-doing all of this wire management. So I used this mini perf board to solder all of the wire connections to. It sits perfectly in a breadboard but can be removed and repositioned as necessary.
Step 10: Make a Controller
I added a number pad to be able to change the lights on the go - and with the number pad, I have 16! It was fairly easy to set up. Here's the tutorial I followed to do so.
Making the number pad work with the animations:
I needed to be able to change the animation anytime - even in the middle of an animation sequence. I found this "Multi-tasking the Arduino" tutorial to be exactly what I needed. It's well explained and the full code is provided with an example circuit to try.
I modified the example to work with the KeyPad using the Adafruit Keypad library instead of the buttons. Then, I put everything in a project box, used mounting tape to adhere the number pad to the outside, and used a 10,000 mAh battery pack (typically sold to recharge your phone) to power the system. It was time to try it out!
Step 11: Ride the Bike! My Personal "user Testing"
I debuted the project at a BikeJC light-up ride, and this is what I learned from my own "user testing":
1) Power. The power usage was AMAZING. I rode for over 3 hours and used less than 25% of my 10,000mAh battery pack. After what I had read about needing to conserve power for the Neopixels, I was happy that it wasn't going to be an issue for this project. My bike frame has 190 Pixels.
2) Interaction. I originally thought that I wanted to use some of the buttons on the number pad to choose a pattern, and different buttons to choose a color scheme. (For example, I would need to press 2 buttons to set what I wanted - first the pattern, and then the color.) I ended up coding it so that each button press would set BOTH color and a pattern, and I saw how much of a necessity this was once I actually rode the bike. I need to be focusing on the road and not on manipulating the controls. For this project, changing lights needs to be a "one and done" sort of interaction - for safety's sake.
3) Modularity. It was really easy to take the lights off the bike after the ride - I simply unplugged the cables, unstuck the velcro, and wrapped the velcro strips around for storage. It was a lot of extra work to make the sticks so easy to add and remove, so I'm glad it paid off.
Step 12: Add Wheel Lights
I used the same technique to create light sticks for the wheels. I decided to make a 3 - piece lighting system because I thought it would look cool at both slow and fast speeds.
Each of the three sticks has 7 LEDs and is double-sided for a total of 14 LEDs. Both sides receive data at the center and mirror each other. After connecting both sides, the three sticks are connected together to the same power, ground, and signal connection with the same type of 3-wire connector that I used for the main controller. It was a LOT of wires to combine - you can see the map in the second photo!
Step 13: Connect Wheel Lights to Arduino Nanos
- I used the other side of the 3-wire connector to attach to the Nano. I added a resistor with heat shrink to the data line and added a female JST connector to power and ground so that I could connect a battery.
- I wrapped the connections together and soldered the three connections into the pin holes on the Nano.
Once one wheel was done, I made another! (2 wheels = twice the work!) You can see the Medusa-like pieces in the last photo! Don't worry - they look much cooler on the bike. :)
Step 14: Protection & Battery Power
- I used very large clear heat shrink and carefully shrunk a protective layer over the Nanos so that the fragile connections won't come undone. This heat shrink was great because it remained flexible after it shrunk so I could still press the reset button if needed.
- I added my 2000 mAh battery and tested the connection.
Step 15: Wheel Enclosures
- To protect the circuit and keep it safely attached to the wheels, I used two waterproof ID cases. Before I ordered the 2000 mAh batteries, I measured this case to be sure that the battery and nano would fit inside (and ordered the largest battery that would).
- I drilled a hole in the ID case that was large enough for the wires to escape but not too big as to keep it fairly water-resistant.
- I attached the ID cases to the spokes of the wheels with zip tie anchors and zip ties.
The great thing about this system is that I can just unlatch the ID holder and disconnect the battery and nano without taking the lights off of the bike. This is super handy for recharging and reprogramming the boards. And, If I want to ride without the lights, I can leave the ID holders in place.
Step 16: Wheel Test! Run Some Code
I tried it out! It looks pretty cool.
Step 17: Make It React to Music!
I considered using a microphone to listen to and interpret the music, but that would have been a bad idea. A microphone's greatest enemy - like the Achilles heel - of microphones is WIND - and I will be on a bike literally zipping through the wind. So bad idea.
I ended up creating a wired system using 3.5 mm audio cables and a splitter. The first video explains how I split the audio between the computer (or phone), the Arduino A0 pin, and the speaker.
The second and third videos show some examples of visualizations I've been playing with. In these examples, I am using the signal from the headphone jack as an analog input that is assigned to the value of different variables in the code.
Step 18: Big Plans - What's Next?
Like I said, my goals for this project are all about learning, and I'm excited to learn even more skills to bring back to this project.
Here are some ideas of what I'll do next:
- Upgrade the controller with a NeoTrellis button matrix with the silicone buttons so that I can have color-coded buttons that remind me of what the button does, and be able to change them in real-time.
- Add on/off switches to the controller and the wheels.
- Mount my boom box on the front of the bike, and run the controller off of its charging port.
- Add lights around the wheel rims
- I'm thinking of using regular RGB led string lights (the fairy light kind) for this because when the wheel is rotating, addressable LEDs don't have much advantage. Plus, I can weave them around the spokes and they will be visible from both sides.
Next big challenge: Use BLE to connect the wheels to the controller:
I'm almost there. I've been studying the ArduinoBLE library for a while and it's a big nut to crack. So far, I've successfully connected my Arduino Nano 33 IOT boards (that have BLE built-in) to each other but haven't yet found a way to keep a quick and reliable connection between all three that doesn't interfere with my animation and sensor code. I'm sure it's possible, and it will just take more experimenting, learning, and tweaking. :)
Once I have the system up and running, I need to remember to add a connection indicator light to the controller so that I can confirm that the wheels are receiving signals.
This is another huge place for expansion! Using the signal from an audio cable is just the tip of the iceberg for music visualization. I'm excited to explore ALL THE WAYS that makers are visualizing music with code. Do you know of resources I should know about? Please let me know in the comments!
I hope you enjoyed this instructable! Want to follow this project? I'll be posting updates on my blog here.
First Prize in the