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 liquidware.com

Here are the filter
coefficients, they should work with any
IIR filter
implantation. The complete
BikeLight5 code can be found here.
// feed forward coefficientsdouble ff[] = { 1.93545410516e-06, 5.80636231547e-06, 5.80636231547e-06, 1.93545410516e-06};
// feed back
double fb[] = { 1.0, -2.94973583971, 2.90072698836, -0.950975665016};