Saturday, July 04, 2009

Improved brake light

So the brake light was acting a little flaky, turning on over bumps at random. Before, I was using a moving average filter, with ad-hoc checks. I decided to try out a IIR filter because they can produce good results with few taps. This is my first implementation of such a filter.

Infinite impulse response or IIR filters combine measured (feed forward) data and filtered (feed back) data. They get their name because a single non-zero input sample followed and preceded by all zeros can cause the filter to oscillate indefinitely as opposed to a finite impulse response or FIR filter which will return to zero after at most N measurements where N is the number of filter coefficients.

The problem with the brake light was that high frequency jitters were tripping the braking threshold. The only information I really car about is sustained braking, which is low frequency information. I needed a low pass filter, a filter that passes low frequency information and attenuates high frequency information. The Butterworth filter is a low pass IIR filter that is working great for this application.

The filter coefficients are determined by the sample interval, the cutoff frequency, and the number of filter coefficients to use. I chose 2 Hz to be the cutoff frequency. Any lower frequency would delay brake indication, any higher frequency could let in unwanted jitter. I wanted to keep the number of filter coefficients small so that the micro could keep up, It is having no trouble with that; I could probably get away with more filter coefficients, but that delays response time as well.

I was pleased to see how well this filter performed!
I captured this acceleration data riding up and down the street without braking and with. In each image, the raw data is pictured in blue, the filtered data is in yellow, and braking threshold (on the top plot) is indicated in red. As you can see, the raw data is very noisy. The noise is actually bumps on the side of the road, so don't blame the pololu 3-axis accelometer ($17.95!!) breakout I'm using. I purposely aimed for them to make sure the threshold was not set to high which could set of the brake lights every time you hit a bump. With the unfiltered data, it is impossible to set a consistent threshold for turning on the brake lights. The filtered data works though!

The above image just was captured with out braking. I just rode up and down the street without touching the brakes. The threshold was set near the minimum filtered acceleration in the X direction.

This data was collected getting up some speed and braking to various degrees. The X direction is in the velocity direction. Deceleration is indicated by lower X values. You can see the braking go below the threshold even for mild braking.

The Y and Z axis will be used for a future helmet mounted version.

Here is a snap of my data capture setup, thanks to the wave shield from ladyada, and battery and dual proto board from

Here are the filter coefficients, they should work with any IIR filter implantation. The complete BikeLight5 code can be found here.

// feed forward coefficients
double ff[] = {
// feed back
double fb[] = {


Possum said...

Nice idea to use a digital filter. I've been trying something similar on some accelerometer data, but don't seem to be cleaning it up anywhere near as well as you have been able to. What sampling frequency were you using to collect the raw data?

Also, how did you go about calculating your filter co-efficients. I seem to recall that, depending upon the order of the filter, the co-efficients for the unfiltered data points went (1,2,1) for 2nd order (1,3,3,1) for 3rd order (1,4,6,4,1) for 4th order, etc but your co-efficients don't follow a similar pattern.

See this site for more detail:

Justin said...

Thanks for reading this post. You have a great question. If I recall, I used a 4th order Butterworth filter from scipy.signal (

I should have linked the code.
The sample rate was about 1 KHz.

I hope this helps.

Justin said...

P.S. Thanks for the website. Looks very complete for filter designs.

As far as the feed forward coefficients, the are a scaled version of Pascals triangle (1, 3, 3, 1).