Shop OBEX P1 Docs P2 Docs Learn Events
propeller PING code math explanation — Parallax Forums

propeller PING code math explanation

AKruzelAKruzel Posts: 25
edited 2011-05-28 09:52 in Propeller 1
hello all,

this should be a very simple question however i've been pondering over it for way too long. I'm using the PING code with the propeller and all works well, however i really want to understand the math part where the number of ticks is converted to microseconds:

PUB ping(Pin):microseconds|cnt1, cnt2
dira[2..3]~~
outa[2] := 0
outa[3] := 1
outa[Pin]~
dira[Pin]~~
outa[Pin]~~
outa[Pin]~
dira[Pin]~
waitpne(0,|< Pin, 0)
cnt1 := cnt
waitpeq(0,|< Pin, 0)
cnt2 := cnt
microseconds := (||(cnt1-cnt2) / (clkfreq / 1_000_000)) >> 1

i understand everything except for why is the >> 1 added to the end? i tested the PING without it and saw that the measurement doubles so i can see the point of using it, but i want to make sure i have the correct reason. I'm thinking it's because the micro is working at 80MHz which is 80 million full cycles a second but the PING only outputs a high pulse which corresponds to the distance. do we use the >> 1 to divide by 2 since the ping ONLY outputs a high pulse? any simple explanation is greatly appreciated! thanks!

Adam

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-28 08:18
    The answer is really simple. The PING pulse is proportional to the amount of time it takes for the first echo to be received, but the sound has to travel to the object and back and you want the distance ("time of flight" of the sound) to the object, so you divide the time by two.

    As you've already figured out, dividing by (clkfreq / 1_000_000) converts the time to microseconds adjusting for the system clock frequency of the Propeller since the counts (cnt1 and cnt2) are in terms of system clock pulses.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-05-28 09:52
    That code is peculiar... it allows you to pass the Ping))) pin and yet manipulates others. Why? This could cause problems if you port the method to other projects. Here's another version for you to consider that you can copy-and-paste into any project.
    [b]pub[/b] ping(pin) : microseconds | tix
    
      outa[pin] := 1                                                ' pulse the Ping)))
      dira[pin] := 1
    
      dira[pin] := 0                                                ' set to input mode
    
      waitpeq(|< pin, |< pin, 0)                                    ' wait for pin to go high
      tix := -cnt                                                   ' start pulse timing
    
      waitpne(|< pin, |< pin, 0)                                    ' wait for pin to go low
      tix += cnt - 544                                              ' stop pulse timing
    
      microseconds := (tix / (clkfreq / 1_000_000)) >> 1            ' return 1-way duration
    

    Note that the -544 accounts for the time required by the Spin instruction to update the tix value. By doing this we remove ~7us error (@80MHz).
Sign In or Register to comment.