This shouldn’t be too hard, what the future program will need to do: measure the time between two input signals, and convert it to speed. Maybe add a part to the program, where the user will be able to set up the tire size…
Ok, everyone and his brother knows the formula for calculating the circumference of a wheel, right? C=2r*PI
r is the radius, PI is the mathematical constant 3.141. But how do we calculate speed from the time it takes to turn this wheel one time? (Well, we do it easy, but our microcontroller will have to do at least one floating point calculation – darn, that’s ~1K of RAM right there!) Plus, when you take a wheel (rim+tire) it is not that obvious what the radius is, especially if you live in Europe, where you get the tire width in millimeters, the sidewall height in percentage of the width, and the rim diameter is in inches. So, the radius, or rather the diameter is made up of 3 things:
1. (Rim diameter x 2.54)
3. actually, it’s 2 again, because we need the diameter.
So diameter = (2*(width*(height/100))/10)+(rim_dia*2,54)
The division with ten in the center of the formula is there because the first bracket gives you a number in millimeters and the second in centimeteres, but this way, both are in centimeter. One kilometer is 1000m, or 100000cm. So the wheel rotates 100000/diameter times as it rolls along the road every km. The time it takes to make 1 revolution is one hour (3600secs) divided by the number of rotations. Thru some wizardry, to get the speed in km/h from this, (36/time)*circumference=spd, where time is in milliseconds.
Setting up the Timer/Counter to give 1000 ticks every second
Using the ATmega88’s 8-bit Timer/Counter0, and using the default 8MHz system clock, first set the Timer Control registers so, that the T/C will operate in output compare mode (CTC)
TCCR0A = ((0<<WGM00)|(1<<WGM01));
Then calculate the prescaler value, so we won’t overflow the compare register OCR0A. (because it’s 8-bit, you have a maximum value of 254 here). With the prescaler unset, you’d get 8×10^6 counter increment per second, and 8x10E divided by 1000 is more, than 254. But if the clock prescaler is at /64, you get 125000 cycles per second, and that divided with 1000 is 125, much better!
TCCR0B = ((1<<CS01)|(1<<CS00)|(0<<WGM02));
OCR0A = 125; // 1000 interrupt/sec
Now that the basic math is down, let’s do some mechanical work! Create the PCB!