Stay visible on bicycle at night with Arduino and Neopixel Strip

A BLB LaPiovra with the Cyclic project on its back.

Riding in the streets. Zigzagging up between the cars. At night, two little lights at the front and the back of the bike to see and be seen… But not bright enough, right? The Neopixel Strip comes to the rescue.

My goal was to use a brighter light on my bike, to be seen in the streets at night and be detected by any cars or bikers easier.

I wanted to use a light strip and control its colors by pushing a button while I was riding. I also wanted it to strip it out from the bike simply by pulling it when I parked, to avoid potential theft of my lights. And finally, I wanted this project to be adapted and be installed on any part of any bike.

1. Cyclic

I named this project “Cyclic”. You can see it on two different bikes at two different places in the video below:

The following article describes how I achieved it.

2. Materials

All components should be suitable and small enough to be setting up on a bike.

I chose the ItsyBitsy from Adafruit which is very small and really powerful. I already knew this microcontroller and liked working with it. It has much of the same capability as an Arduino UNO.
Even if I would only used a few GPIO, I like to keep my mind open, in case I want to add a Bluetooth controller or an accelerometer sensor later.

To power it, I obviously needed a portable battery, something that would be small and should work for a long time. I picked a cylindrical 2200mAh battery.
Despite the low power (3.7V) to charge the 5V ItsyBitsy, it was just fine and worked as expected.

However, when the battery is down, I do not want to open my case box every time and change it. Therefore, I added a LiPo charger to recharge it without opening the case.

Then, for the lights. I wanted a small strip, not a 1M long with 144 LED on it… This one below was perfect: a Neopixel Strip — 30cm with 30 LED.

Finally, for this project, I also used these items:

  • A switch as a relay between the micro-controller and the battery,
  • One push-button to change the pattern of the lights,
  • A 300 to 500 Ohm resistor between the Arduino pin and the strip,
  • Self-gripping adhesive strips (fasteners),
  • Some adhesive tape for hot surfaces (optionally around the battery),
  • And a bunch of wires.

3. Case Box

The case should be adapted for most of the bikes and mainly strapped into or stripped out to it easily. So I split the box in two parts: the first was the base, fixed on the bike, on which the second part, with the electronics, could be clipped.

The first part was designed to fit my bike’s fork with a 31.8mm diameter. Later, I made another model to fit another bike around its seat post with 27.2mm as diameter. There was a triangular hole to host the second part to clip in.
The second part contained all the electronics. It also had two holes on the bottom face to update the code or charge the battery without pulling out everything, and another one on the top to hold the push-button.

The goal was to adapt every part of a bike by just changing the fixed base, and not the whole case. The box should never change and should fit any other fixed base with a triangular hole. I tested on two bikes at two different places and it worked well.

4. Wiring

The wiring was simple: the push-button to the PINOUT 6, the strip to the PINOUT 8 — with a 300 to 500 Ohm resistor between them — and the LiPo charger to the BAT PIN via a switch.

The main thing was to keep all the wires as short as possible. I wanted to minimize the space between the components to fit inside a small case box:

5. Code

I wanted it to be clearly seen in the streets but also to be fun to watch. I created several patterns, which have unique colors and movements, and each time I pushed the button, while riding, it switched to the next pattern.

All patterns were in a separate file. This allowed me to set their own color patterns nicely. They all used a setup function to get the strip’s instance and the LED number.
In the mini-controller, the setup — for the push-button, the patterns and the strip — was as follows:

void setup() { 
pinMode(_button_pin, INPUT_PULLUP);

PatternK200.setup(_strip, NEOPIXEL_COUNT);
PatternTHUNDERBOLT.setup(_strip, NEOPIXEL_COUNT);
PatternFRENCH.setup(_strip, NEOPIXEL_COUNT);
...

_strip.begin();
...
}

Then, the loop checked every time the push-button state and shown the pattern accordingly:

void loop() {
bool shouldChange = isButtonPressed();
if (shouldChange) {
changePatternMode();
}
showPatternMode();
}

changePatternMode() was a simple switch to select the next pattern. And showPatternMode() called show() on the current one:

void showPatternMode() {
switch (_current_pattern) {
case K200:
PatternK2000.show();
break;
case THUNDERBOLT:
PatternTHUNDERBOLT.show();
break;
case FRENCH:
PatternFRENCH.show();
break;
...
}
}

For example, the PatternFRENCH which is a French flag had this show():

void show() {
// first 9 pixels to blue
for (int i = 0; i < 10; i++) {
_strip.setPixelColor(i, _strip.Color(0, 0, 255));
}
// 10 to 19 pixels to white
for (int i = 10; i < 20; i++) {
_strip.setPixelColor(i, _strip.Color(255, 255, 255));
}
// the last to red
for (int i = 20; i < 30; i++) {
_strip.setPixelColor(i, _strip.Color(255, 0, 0));
}
_strip.show();
delay(10);
}

This way I could add any pattern I wanted without difficulty and set a unique animation pattern for each.

However, the Arduino controllers are sequentials and do not support multithreading. With all animations and delays, my code resulted in a little mess. Some heavy animations did not release the processor, so the button state was not triggering and the current pattern was not changing.
I have to change my animations to smaller ones and use
Protothreads (see).

6. Results

I rode and “played” several months with it, without recharging anything. I changed the patterns a bit and rode in the streets. It was fun. Then, I offered it to a friend. Since, he still has not recharged it yet.

The strapping in-out was easy because the strip was on the middle fork:

On my friend’s bike, it was a bit tricky though, because the strip was passing into the fork just below the seat spot. But the result on his bike was flawless.

I have to say, the K2000 pattern (from “Knight Rider” TV show) was really beautiful.

You can find the code and the printed files in my repository:

Maker, Mobile developer, Dart enthusiast, IoT & DIY addict