Shop OBEX P1 Docs P2 Docs Learn Events
Bicycle Speedometer — Parallax Forums

Bicycle Speedometer

ArchiverArchiver Posts: 46,084
edited 2000-08-03 16:15 in General Discussion
--- In basicstamps@egroups.com, "Tyson Stephen" <tysonstephen@h...>
wrote:
>
> Hi, ok I need some help, I am just trying to make a bicycle
speedometer. I have it all worked out but the basic stamp program
can't handle the math...
>
> snip

You are trying to make this too complicated.
Ultimately it comes down to Speed = Constant/Time.

I just finished building a speedometer for my bicycle that logs speed
and altitude. I'm not using a real time display but download the
data for calculation and graphing.

I time for 4 revolutions and for my wheel(700mm) the formula comes
out to be Speed(mph) = 19677/time(ms)

For example for at 1303ms Speed = 19677/1303= 15.1mph

I use a timer chip from Peter Anderson to get the time and it works
very well.

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 10:13
    "Tyson Stephen" <tysonstephen@h...> wrote:
    > Hi, ok I need some help, I am just trying to make a bicycle speedometer.
    > I have it all worked out but the basic stamp program can't handle the
    math...

    > now I count when the magnet goes by on the wheel and I have worked out
    > approx 2 meters for every revolution of the wheel. now thats
    > microseconds/milliseconds if your going down a hill.

    > anyways alls I am trying to do is take my count and change it from
    > microseconds to seconds then multiply by 500 to get the total time
    > that it would take to go 1 kilometer at that speed
    > kilometer=1000meters.... and then devide take the total number
    > of seconds in 1 hour which is 3600 and divide how long it took
    > to go 1000meters and that willl give me KPH kilometer per hour....
    >...


    Hi Tyson,

    The core routine in your program is

    > wait1:
    > if in0 then wait1 ' await switch closed
    > time0:
    > x=x+1: branch in0,[noparse][[/noparse]time0] ' count & await switch open
    > time1:
    > x=x+1: if in0 then time1 ' count await switch closed

    This efficiently counts the time for one complete revolution of the wheel.
    However, the units of time are not exactly microseconds or milliseconds.
    They are in "loops". The time0 loop measures the interval the reed switch
    is closed, waiting for it to open, while the time1 loop measures the
    interval the switch is open, waiting for it to close. The sum is the time
    for one complete revolution. Most of the time is spent in the time1 loop.


    I have a good sense of the actual length of a time0 loop, which is
    characteristic of the BASIC Stamp. I have timed it at 1418 loops per
    second, or 7.05E-4 seconds per loop. That is close to one millisecond per
    loop. The timing for the other loop is probably close to that. It depends
    on the timing difference between the BRANCH and the IF syntax. I'm pretty
    sure that BRANCH is slightly faster than IF. Anyway, the exact value does
    not matter. It is going to take a "calibration" step in the end anyway,
    because there is uncertainty here and additional uncertainty in the exact
    diameter of your wheel. Let's just take those figures for example. The
    time for one revolution of your wheel is:
    (this is not yet "stamp math")
    revT = 7.05E-4 * x ' seconds, where x is the total count.
    To do this in Stamp math, it helps to know what values you will expect at
    reasonable velocities for your bicycle. Say you have a wheel 2 meters in
    diameter (as you state), and that you are traveling at 20km per hour, then
    one revolution will take 0.36 second. During that time interval, the value
    of x will reach about x= 0.36/7.05E-4 = 511. At 40kmph that value would
    trim down to 255. How fast will you go? It helps to have an estimate. At
    slow rates of travel, well, you will be stopped and the value of x could
    overflow the 65535 limit for counting x. Deal with that later.

    So the calculation to get kilometers per hour from the size of the wheel
    and the value of x, is:
    (still not stamp math--it is best to collect everything together first)

    kmph = 2 meters/(0.000705 * x) * 1/1000 * 3600 /1
    ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
    meters per second conversion to kmph

    = 10213/x

    Now it is stamp math.
    Plug in x=511 and you come up with kmph=19.
    The result should be 19.98, but the Stamp "/" drops the remainder.

    You can improve the accuracy in a couple of ways.

    Method #1: larger numerator, say 5* larger. 10212.76*5=51064
    kmph = 51064/x *2
    now plug in x=511 and you get kmph=198
    When you display it, you put in a decimal point, 19.8
    The display will have a resolution of 0.2 kmph, because of the *2 factor.
    That is an improvement.

    Method #2: use the remainder from division to apply a correction:
    kmph = (51064/x *10 + (51064//x*10/x)) * 2
    Plug in x=511, and out pops 1998. You get a second decimal place.
    Display it as 19.98 kmph, with resolution to 0.02 kmph. No bad.
    This last formula places limits on x.
    x>77 and x<6553
    That means you can't use this method #2 for
    rates of travel greater than about 122kmph (not a problem!?)
    or less than 1.6 kmph. (who cares?)
    Your software has to allow for that.

    The big issue is calibration. You get a reading, but is it right? It
    depends on the exact diameter of your tire and the exact calibration of
    your BASIC Stamp timing loops. Once you have the formula in the Stamp,
    you can time yourself running a course at a steady speed, and compare the
    result displayed on the stamp with your measured value. Or just compare
    your stamp circuit with a commercial bike speedometer (if you trust it).
    Then you fudge the numerator (10213 etc.) in the Stamp formula to make it
    come out right. A one-point calibration is all it takes. In your program,
    you used the time for ten revolutions of the wheel. That is fine, too.
    The idea for calculating speed is essentially the same. You might want an
    odometer as well as a speedometer, and the revolution counter gives you
    that. The odometer too would have to be calibrated.

    I hope that helps with the math--Ask if you have further questions.

    Tracy Allen
    Electronically Monitored Ecosystems
    http://www.emesystems.com
  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 10:42
    Hi, ok I need some help, I am just trying to make a bicycle speedometer. I have it all worked out but the basic stamp program can't handle the math...

    now I count when the magnet goes by on the wheel and I have worked out approx 2 meters for every revolution of the wheel.
    now thats microseconds/milliseconds if your going down a hill.

    anyways alls I am trying to do is take my count and change it from microseconds to seconds then multiply by 500 to get the total time that it would take to go 1 kilometer at that speed kilometer=1000meters....· and then devide take the total number of seconds in 1 hour which is 3600 and divide how long it took to go 1000meters and that willl give me KPH kilometer per hour....

    but to get from microseconds to seconds you have to divide by 1000000 and the stamp cuts off at 10000. now thats not the big problem you could always devide by 10000 and then divide again by 100 but NOOO that would be too easy... if you do that the stamp doesn't accept decimals.... and yes I know about the // but when I experimented with that lets say you have a number and divide it .... and the answers 0.000572 from what I see the stamp takes all the zeros out... .572..... argh...

    I have tried everything, can anybody help me.... thanks

    here's my code

    just ignore most of the variables I have been tinkering for a while.... thanks in advance


    ' Bike Program 3.2

    Meter con 1/2

    Kilo con 1000*meter

    LCD con 15

    N9600 con 84

    rct var word ' a word variable

    k var word 'km per hour

    k1 var word

    x var word

    d var word 'distance km

    m var word 'meters

    revolutions var word

    tmp var word

    tmp2 var word

    tmp3 var word

    n var byte ' variable for the bar graph



    pause 500

    Serout lcd, n9600,[noparse][[/noparse]$FE]

    'serout LCD, n9600,[noparse][[/noparse]%11111100]

    serout lcd, n9600,[noparse][[/noparse]$01]

    pause 50

    k=0

    d=0

    tmp=0

    tmp2=0

    low 0

    revolutions=0

    input 0

    'pulsin 0,0,rct 'time for the volts to rise to 1.3v

    'high 0 'discharge the capacitor to 0v

    top:

    revolutions=revolutions+1

    wait1:

    if in0 then wait1 ' await switch closed

    time0:

    x=x+1: branch in0,[noparse][[/noparse]time0] ' count & await switch open

    time1:

    x=x+1: if in0 then time1 ' count await switch closed

    other:

    if revolutions=10 then calc

    here:

    debug ? x

    branch in0,[noparse][[/noparse]top,here] ' await switch open

    Calc:

    debug ? x

    m=m+20

    tmp=(x/5)

    tmp2=10000/tmp*100+(10000//tmp*100/tmp)

    tmp2=100/tmp2*10+(100//tmp2*10/tmp2)

    tmp3=tmp2*250

    k=3600/tmp3

    k1=3600//tmp3

    debug cr,dec k,".",dec k1,cr, ? tmp2, ? tmp, ? tmp3

    gosub display

    revolutions=0

    x=0

    goto here

    Display :

    Serout lcd, n9600,[noparse][[/noparse]$FE]

    serout lcd, n9600,[noparse][[/noparse]$01]

    serout lcd, n9600,[noparse][[/noparse]"K=",dec k,".",dec2 k1,"/Hour"]

    pause 10

    serout lcd,n9600,[noparse][[/noparse]$FE]

    serout lcd,n9600,[noparse][[/noparse]$C0]

    serout lcd, n9600,[noparse][[/noparse]"D=",dec d,".",dec m,"KM"]

    pause 50

    return





    - Tyson Stephen

  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 15:48
    --- In basicstamps@egroups.com, "Tyson Stephen" <tysonstephen@h...>
    wrote:
    >
    > Hi, ok I need some help, I am just trying to make a bicycle
    speedometer. I have it all worked out but the basic stamp program
    can't handle the math...
    >snip

    Prior to using an event timer chip for my bicycle speedometer I did
    use the counted loop method and got reasonable results. I timed for 4
    revolutions and got about 500 loops at 35mph which is about my
    maximum (downhill) speed. What I did was to use the bicycle computer
    I bought to calibrate the one I made using the BS2. Ideally you
    would expect this relation speed=C1/loops. (C1 is a constant) This
    is close but I found that there is some fixed time overhead so a
    better function is speed=C1/(loops + C2). This second constant is
    simply the number of loops you add to deal with this fixed time
    overhead. As I recall this number was fairly small. What it does
    mean is that you can't use a one point calibration.


    As long as you're calibrating against a bike computer you really
    don't have to worry about calculations involving the wheel
    diameter.
    Just determine the number of loops at various speeds. (The maximum
    speed function is very helpful in doing this). First calculate C1 at
    various speeds using C1= speed* loops. You will see that it is not
    constant but changes somewhat with speed.
    Now try C1 = speed*(loops+C2). Play with C2 until you see little
    change in C1 with speed.
    Once C1 and C2 are determined you can put them into your BS2 program
    to calculate speed.
  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 16:51
    There is one more way of doing it

    using inches and MPH you can change it for your needs

    If you take the height of your tire x pi (3.141) = tire dia
    there are 63,360 inches per mile so 63,360 / tire dia = turns per mile
    if you take turns per mile and divide by 60 you will get the time in
    milliseconds for using the count command and no math needed in the
    bsII if you want 10th or 100th you multiply by 10 or 100 and use the
    dec and dig commands to an lcd.
  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 17:37
    jimsp@y... wrote:
    >Prior to using an event timer chip for my bicycle speedometer I did
    >use the counted loop method and got reasonable results. I timed for 4
    >revolutions and got about 500 loops at 35mph which is about my
    >maximum (downhill) speed. What I did was to use the bicycle computer
    >I bought to calibrate the one I made using the BS2. Ideally you
    >would expect this relation speed=C1/loops. (C1 is a constant) This
    >is close but I found that there is some fixed time overhead so a
    >better function is speed=C1/(loops + C2). This second constant is
    >simply the number of loops you add to deal with this fixed time
    >overhead. As I recall this number was fairly small. What it does
    >mean is that you can't use a one point calibration.

    >As long as you're calibrating against a bike computer you really
    >don't have to worry about calculations involving the wheel
    >diameter.
    >Just determine the number of loops at various speeds. (The maximum
    >speed function is very helpful in doing this). First calculate C1 at
    >various speeds using C1= speed* loops. You will see that it is not
    >constant but changes somewhat with speed.
    >Now try C1 = speed*(loops+C2). Play with C2 until you see little
    >change in C1 with speed.
    >Once C1 and C2 are determined you can put them into your BS2 program
    >to calculate speed.

    Good points. FWIW, the constants can drop out of a two point calibration.
    (A geeky alternative to "playing" witht the constants!)

    S= C1 / (X + C2)
    S: speed
    X: the number of loops from your program timer.
    C1 and C2: constants to be determined
    S1: a calibration low speed value
    X1: the corresponding loops
    S2: a calibration high speed value
    X2: the corresponding loops

    then (from solving two eqns for two unknown contants)

    C1 = S1*S2*(L1-L2)/(S2-S1)
    C2 = (S1*L1-S2*L2)/(S2-S1)

    If the loops are tightly written, C2 could be very small (like C2= 1 to 5).
    Jim?

    You can use still use the math I suggested in an earlier message, to
    improve the resolution of the display in kmph on the Stamp. Same if you
    use the timer chip and want to display the results in real time.

    -- Tracy Allen
    Electronically Monitored Ecosystems
    http://www.emesystems.com
  • ArchiverArchiver Posts: 46,084
    edited 2000-08-02 22:25
    > I have a good sense of the actual length of a time0 loop, which is
    > characteristic of the BASIC Stamp. I have timed it at 1418 loops per
    > second, or 7.05E-4 seconds per loop. That is close to one millisecond per
    > loop. The timing for the other loop is probably close to that. It depends
    > on the timing difference between the BRANCH and the IF syntax. I'm pretty
    > sure that BRANCH is slightly faster than IF. Anyway, the exact value does
    > not matter. It is going to take a "calibration" step in the end anyway,
    > because there is uncertainty here and additional uncertainty in the exact
    > diameter of your wheel. Let's just take those figures for example. The
    > time for one revolution of your wheel is:
    > (this is not yet "stamp math")
    > revT = 7.05E-4 * x ' seconds, where x is the total count.
    > To do this in Stamp math, it helps to know what values you will expect at
    > reasonable velocities for your bicycle. Say you have a wheel 2 meters in
    > diameter (as you state), and that you are traveling at 20km per hour, then
    > one revolution will take 0.36 second. During that time interval, the
    value
    > of x will reach about x= 0.36/7.05E-4 = 511. At 40kmph that value would
    > trim down to 255. How fast will you go? It helps to have an estimate.
    At
    > slow rates of travel, well, you will be stopped and the value of x could
    > overflow the 65535 limit for counting x. Deal with that later.
    >
    > So the calculation to get kilometers per hour from the size of the wheel
    > and the value of x, is:
    > (still not stamp math--it is best to collect everything together first)
    >
    > kmph = 2 meters/(0.000705 * x) * 1/1000 * 3600 /1
    > ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
    > meters per second conversion to kmph
    >
    > = 10213/x
    >
    > Now it is stamp math.
    > Plug in x=511 and you come up with kmph=19.
    > The result should be 19.98, but the Stamp "/" drops the remainder.
    >
    > You can improve the accuracy in a couple of ways.
    >
    > Method #1: larger numerator, say 5* larger. 10212.76*5=51064
    > kmph = 51064/x *2
    > now plug in x=511 and you get kmph=198
    > When you display it, you put in a decimal point, 19.8
    > The display will have a resolution of 0.2 kmph, because of the *2
    factor.
    > That is an improvement.
    >
    > Method #2: use the remainder from division to apply a correction:
    > kmph = (51064/x *10 + (51064//x*10/x)) * 2
    > Plug in x=511, and out pops 1998. You get a second decimal place.
    > Display it as 19.98 kmph, with resolution to 0.02 kmph. No bad.
    > This last formula places limits on x.
    > x>77 and x<6553
    > That means you can't use this method #2 for
    > rates of travel greater than about 122kmph (not a problem!?)
    > or less than 1.6 kmph. (who cares?)
    > Your software has to allow for that.
    >
    > The big issue is calibration. You get a reading, but is it right? It
    > depends on the exact diameter of your tire and the exact calibration of
    > your BASIC Stamp timing loops. Once you have the formula in the Stamp,
    > you can time yourself running a course at a steady speed, and compare the
    > result displayed on the stamp with your measured value. Or just compare
    > your stamp circuit with a commercial bike speedometer (if you trust it).
    > Then you fudge the numerator (10213 etc.) in the Stamp formula to make it
    > come out right. A one-point calibration is all it takes. In your
    program,
    > you used the time for ten revolutions of the wheel. That is fine, too.
    > The idea for calculating speed is essentially the same. You might want an
    > odometer as well as a speedometer, and the revolution counter gives you
    > that. The odometer too would have to be calibrated.
    >
    > I hope that helps with the math--Ask if you have further questions.


    Thanks, I found your info to be very helpful and explained well.

    this is my thought on how to get my calibration value, I have an lcd and
    what I am doing is outputing the value of x on it and every time it goes
    into the calc subroutine it adds to a tmp varaible and everytime the tmp
    variable reaches 65535 it adds 1 to tmp2 variable. I am going to ride around
    a school track which is a known distance of 400m so apporx 200 revolutions..
    then I will take how many "loops" the entire 400m took... from that I should
    be able to break it down into a per meter measurement... will that work?...
    I am not looking for perfect just yet.. I will work on perfecting the
    calibration after I have a good working model then I will tweek it.... but I
    think that will work...


    -Tyson Stephen
    tysonstephen@h...
  • ArchiverArchiver Posts: 46,084
    edited 2000-08-03 16:15
    --snip
    >
    > Good points. FWIW, the constants can drop out of a two point
    calibration.
    > (A geeky alternative to "playing" witht the constants!)
    >
    > S= C1 / (X + C2)
    > S: speed
    > X: the number of loops from your program timer.
    > C1 and C2: constants to be determined
    > S1: a calibration low speed value
    > X1: the corresponding loops
    > S2: a calibration high speed value
    > X2: the corresponding loops
    >
    > then (from solving two eqns for two unknown contants)
    >
    > C1 = S1*S2*(L1-L2)/(S2-S1)
    > C2 = (S1*L1-S2*L2)/(S2-S1)
    >
    > If the loops are tightly written, C2 could be very small (like C2=
    1 to 5).
    > Jim?

    I think it was around 8 but I didn't try to improve the coding as I
    abandoned this approach in favor of the event timer.
Sign In or Register to comment.