I’m working on lights for my bicycle bag that will change colour based on my acceleration and the direction I’m moving in. The extra lights might help drivers see me at night, although the primary goal here is have fun while building and programming stuff for my bicycle, and to celebrate the 80’s in a silly way. The whole idea was initially inspired by Adafruit’s DIY Citi Bike Helmet, and I saw the other day that another guy made something similar.
A safety disclaimer: I use other red and white lights at night to be visible at night, and it might not be a good idea to ride a bicycle that has flashing blue lights. I’m curious as to whether drivers would pull over if they saw me coming, but I’m not sure I want to go down that road, pun intended.
What it Does
A short demonstration of the work in progress:
How it Works
I velcro’d a strip of 30 LEDs, whose colours are controlled by a sensor that measures acceleration and compass direction, about once per second, to a small bike bag that I rarely use. I already had the bag and tools and the pieces came to about $65. My list of materials:
- weather resistant NeoPixel strip (the colours of the LEDs are controllable!)
- an Adafruit Flora (the Adruino micro-controller)
- a compass (i.e. – magnometer) and accelerometer sensor
- bits of hook-up wire and solder to connect the components together
- an AAA battery holder
- velcro tape
- a Toba bike bag: the Terry model
I wrote some Arduino code that converts sensor data to set LED colors, so that when I’m riding
- north, the LED colours are based on the bike scene from Tron,
- west, the LED colours are based on the red Knight Rider light,
- south, the LED colours are based on the flashing blue and red Ghostbusters Ecto 1 car,
- east, the LED colours are based on the orange, green, and yellow Back to the Future time circuits.
When my acceleration exceeds 1.2 g’s (the constant g is 9.82 m/s2), the lights go to ludicrous speed: they use the plaid colours from a scene from Spaceballs (because light speed is too slow).
Normalizing the Sensors
The sensor simultaneously measures acceleration and magnetic field on three orthogonal axes. Interestingly, measurements are not normalized to anything meaningful. So I used this formula to normalize the ith component of the raw magnetization, Mi,raw,
Mi,normalized = (Mi,raw – Mi,mean) / (Mi,max – Mi,min).
The formula should map the magnetometer readings onto the unit sphere, the subscripts indicate what each variable refers to, and the min and max readings I found by moving the sensor around.
The accelerometer measures proper acceleration (i.e. – it includes gravitational acceleration) and I only needed its magnitude (i.e. – the square root of the sum the squares), so after normalizing each component I calculated the magnitude, which should be about 1.00 when the bag is stationary.
Although far from necessary, I incorporated a modified spherical coordinate system to determine compass direction and control the LED colours: the sensor measures along three orthogonal axes, x, y, z, with the y-axis pointing towards the sky. When the bag rotates about the y-axis, the normalized x and z components of the magnetization vector oscillate in a way that I think can be modeled with trigonometric functions and spherical coordinates, by calculating the heading with the function:
heading in degrees = arctan(Mz,normalized/Mx,normalized).
Placing my cell near the bag with its compass app running let me check the numbers the sensor was giving me.
What I Learned
Aside from learning how to program with Arduino and with a sensor, and refining my soldering skills:
- I would have guessed that the magnetization vector points in a direction a bit off from geographic north but parallel to the surface of the earth: my magnetometer was telling me that it points towards magnetic north, but with a 70 degree offset from horizontal. Is my magnetometer giving me an error?
- I was surprised by how easily the magnetometer gets really messed up whenever metallic objects get close to it, especially to the AAA battery pack that I use to power the whole contraption. I’ve since replaced the AAA pack a LiPo with better results.
The lights seems to get stuck in one or two modes because the sensor’s normalization constants drift to significantly different values from day to day, and I’m not entirely sure why. So I might re-code the Flora so that the lights stay in Knight Rider mode all the time, or start all over again with a color scheme that varies continuously with sensor measurements. And I think it might be fun to play with other lighting effects: its easy to re-program the Flora.