At the moment I’m building a massive controller for my car (BMW M3 E36). It’s eventually going to control and read lots of devices on my car and operate via Bluetooth with my mobile phone.
I’ve started with the basics – a race timer. This can read my speed and RPM and do some logging, timing and distance calcualtions.
I’ve got this working pretty well, I experimented with 2 different ways of measuring the speed, using pulses detected from my rear diff at a rate of 9 pulses per revolution.
I measured the timings, a pulse width of approx. 20ms was around 25mph. I then coded my idea and fine-tuned the readout with a GPS speedo. Just out of interest I also coded an alternate idea I had which measured the revolutions and time and calculated the speed based on the circumference of my tyre. I’ll quickly describe each method below.
Method 1 – Reading the pulse width
Set an interrupt for the speed sensor pin.
When this interrupt fires measure the pulse width by comparing the micros() from the last interrupt with the present micros()
If the pulse width is within sensible limits store this value in an array and move the pointer along 1
When the pointer reaches the end, jump back to the start
When you come to read the speed, I took the mode of the array which contained the last n samples. (I can increase the size of the array, n, to give me more error tolerance but less instant readings)
I then do the following to turn the pulse width into a speed in mph. speed = / pulseWidth;
Method 2 – Reading the revolutions per amount of time
Set an interrupt for the speed sensor pin.
When the interrupt fires add 1 to the revolutions variable.
When you read the speed you look at the time since the last reading and the number of revolutions counted, then reset the time and revolutions ready for the next reading.
Speed in mph = revolutions x circumference of tyre / time between readings
Now what I found was that using method 2, I only got very discrete speed readings. Let’s say you sample the speed every 100ms, this means that at a certain speed you will either get 10 or 11 pulses every 100ms. However the difference in mph between 10revs/100ms and 11revs/100ms is quite a lot. So my speedo would go up in 5mph steps for example.
So I guess I should stick with method 1, which I have only made accurate but comparing the output to a GPS speedo and making a number up that makes the calculation work. However I’m still worried that this method may be inaccurate. Because it comes down to measuring the pulse width in micro seconds, which at high speed is a very small % change in pulse width for a large change in speed. To make this worse I’m going to change from using my diff sensor, to using an ABS sensor, which will change from 9 pulses per revolution, to either 20 or 40 (I can’t remember which).
The end goal is, to as accurately as possible measure both speed and distance. I then want to be able to time how long it takes to travel exactly ¼ mile to the nearest 100th second. That’s about 200 revolutions of my wheel, so potentially 18,000 samples or even more when I switch to the ABS sensor.
So what do you guys reckon the best way to do this is?