## Counting in decimal fractions....

18 posts / 0 new
Author
Message

So my bicycle wheel rotates 3150 times in 1 mile. I want to build a mileometer that shows distance to an accuracy of 0.01 miles.

I get one pulse from a sensor on my wheel every time it rotates one revolution.

So I need to increment my display every 31.5 pulses.

I want to offload the counting to an 8-bit AVR counter to minimise my CPU load - it's a clever mileometer that does loads of other things as well !

I can't set the counter to 224 or 225, let the pulses increment the counter, detect the overflow, increment my display by 0.01, reset the counter and start again, because either value won't show exactly 1.00 on the display after exactly one mile.

So what do I do?

Best Regards, Martin

counts = (n * counter) / q;

255 / 255 = 1.

find a value of n and q that will give a value of 1/10 mile on each roll-over of the counter.

So, I've already had many "Brain Farts" today! I could be full of S^*t, so go with caution. But do at least look into the concept.

Merry Christmas!

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

You could alternate the count between 31 and 32. Then only every other 0.01 of a mile would be slightly off, but not enough to matter.

Or, if your sensor is with a magnet on the rim as a trigger, then you could put another magnet at 180 degrees from the first, so you end up with 63 pulses per 0.01 mile. Then you wouldn't have that 1/2 rotation to worry about.

Regards,
Steve A.

The Board helps those that help themselves.

Quote:

my bicycle wheel rotates 3150 times in 1 mile.

Quote:

So what do I do?

Get a bicycle with a wheel diameter larger than 6.4"/16.26cm.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

The extra magnet is the easiest sollution, in fact more than one extra would increase resolution again and again. There's really no need to have that high a level of resolution accept to more easily simulate an acurate .01 mile counter, (or smaller) 4 or 8 sensors should be pretty easy to put on.

-Curiosity may have killed the cat
-But that's why they have nine lives

I don't know, I still lean toward getting a bigger bicycle. Would be a hell
of a lot easier to ride, too.

Tom Pappano
Tulsa, Oklahoma

Tom Pappano
Tulsa, Oklahoma

Circumference is (Pi)*diameter

6.4" * 3.14 = 20.1"
( 20.1" * 3150 )/12 = 5275 feet

Tom Pappano
Tulsa, Oklahoma

Not to make things more diffficult but the effective circumference actually changes with speed because centrifugal force pulls the tire away from center, also low/high tire pressure will change the effective circumference.

-Curiosity may have killed the cat
-But that's why they have nine lives

Nice replies!

Trouble is I don't have a bike at all 8) - my application solves a different problem but the bike analogy is perfect!

I realised after I'd posted that I'd made it too easy - what if it did 3173 revolutions per mile...that would stop the solution that alternates the count between two whole numbers :cry:

I have a perfect solution using interrupts - each pulse increments a variable by 100, when the variable exceeds 3173, I add one to the display and subtract 3173 from the variable. So the variable goes 0, 100, 200 ... 3100, 3200, (increment display), 27, 127, 227 etc. The last click over from 0.99 miles to 1.00 miles occurs exactly after 3173 pulses and each increment is as accurate as possible

...but it uses CPU time, more memory and an interrupt - is there a counter-oriented solution?

Best Regards, Martin

If you use a 16-bit timer as a counter (use external timer input pin) and throw it into compare match, you could do the input and compare completly in hardware. That way, when the counter reaches your requested value, it would throw a compare match interrupt and reset the counter automatically.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

MartinM57 wrote:
I want to offload the counting to an 8-bit AVR counter to minimise my CPU load - it's a clever mileometer that does loads of other things as well !

There ist absolutely no reason to fear calculations, in opposition, the µC like to do calculations for you.

E.g. to be ergonomic the display should no faster show a new value as every 200ms (because the human must be able to read it !).

Then assuming 1ms for the calculations, result in only 1ms/200ms = 0.5% CPU-load.

1ms = 16000 cycle = many time for the µC to do many things.

Peter

Dean...but the whole point is that I can't put 31.73 (the number of revolutions needed to increment the display by 0.01) into a counter :(

Quote:
want to offload the counting to an 8-bit AVR counter to minimise my CPU load - it's a clever mileometer that does loads of other things as well !

I agree entirely with danni, How much processing power to you think it will take? Or are you running the AVR at 1KHz to save power?

Four legs good, two legs bad, three legs stable.

I assume you mean readout resolution of 0.01 mi, not accuracy. Can't help you with the accuracy or precision of your sensing method.
Since your readout is in centimilies, let's calculate in that. Your wheel circumference is thus 0.031746 cmi.
If this was floating point, one would add 0.0317.. to an accumulator, and transfer 1 to the odometer whenever there's one. In integer math this becomes:

interrupt (wheelpulse)
{
int32 = int32 + 68174084; // 68174084 is from 2^31*0.031746
if (int32<0) { centimilecounter++; int32^=0x8000000; }
}

Depending on what additional accuracy error can be tolerated, int16 may be sufficient.

You are missing danni's point. What he is saying is to use a 16 bit counter to count the pulses. But the interrupt to display is not based on that counter, it's on a second counter triggered to interrupt at a certain time interval. At that time you calculate the distance based on the 16 bit timer value and display it. Also at that time, if the 16 bit timer is over 3173, you subtract 3173 and add one to your whole mile count.

Regards,
Steve A.

The Board helps those that help themselves.

I agree with that.
Basically, you dont even get a pulse at the 0.01 mile step.
So all you can do is to count the number of pulses up to 1 mile and use timervalue/3173 to display the digits after the decimal point. Of course the display wont switch by 0.01 at exactly that distance but this isnt possible anyway.

But your overall accuracy (in miles) is as good as you can get it.

Additionally, this wont need a lot of resources, when you use a compare interrupt.
Every solution that counts in fractions is a bad thing as the error grows with every revolution.

Hi.
If i understand right, Martin, you can't count 1/2 of wheel pulse.
And i think that you mast use one bit as FLAG, and flip this flag anytime when counter overflow, and set the counter to 224 or 225. And you can minimised error of count.

Best Regards.
Merry Christmas! And ...
ArTih.