Shop OBEX P1 Docs P2 Docs Learn Events
P2 with Ping - Ping echo'd pulse not seen @ P2 pin, though appears @ Ping signal out — Parallax Forums

P2 with Ping - Ping echo'd pulse not seen @ P2 pin, though appears @ Ping signal out

dgatelydgately Posts: 1,630
edited 2019-04-15 15:49 in Propeller 2
Howdy,

Using John Abshier's PingDemo.spin2 code (https://github.com/parallaxinc/propeller/tree/master/examples/EZLib), I'm not able to receive the echo pulse from a Parallax Ping, though a logic probe does see the echo pulse returned. I'm using the schematic from the P1 C demo tutorial @ learn.parallax.com/tutorials/language/propeller-c/propeller-c-simple-devices/sense-distance-ping. I assumed that the schematic should work for P2 as well...

Example%231.png
Set up this way, the logic analyzer displays:
Example%20%231%20Logic.png

If I connect the logic probe directly to the Ping signal pin:
Example%232.png
The analyzer displays the proper echo pulse:
Example%20%232%20Logic.png

So, John Absheir's code appears to work (the echo pulse is emitted from the Ping), but I'm not sure why the signal does not appear at the P2 pin. I've tried several resistor values (3.3k, 1.2k, etc) with no change. Since I'm physically not seeing the echo pulse after the resistor, is there something on the P2 pin side that needs to be present (pull-up or pull-down resistors don't make sense, correct?).

Any help appreciated,
dgately

Comments

  • Did you remember to tri-state the pin after sending the trigger pulse?

    -Phil
  • I think the code has a comment in pulsein about adding a f l t low or flthi. Not sure if I have the command spelled right. I had the same problem. I am at the pet groomer and cannot help now.
    John Abshier
  • Did you remember to tri-state the pin after sending the trigger pulse?
    So, you are saying that the pin may still be set as output and thus creating a high impedance that wont allow the pulse in, on the P2 pin side of the resistor? (excuse my ignorance :blush: )... I thought that the 'drvl _pin' in PulseOutUs was enough, no?

    The main code calls a Ping Inches function:
    ser.dec(Inches(pingPin))     '' <== 1st call is to get inches.
    
    Then, the call chain goes like this. I have 3 questions embedded as UPPERCASE comments within:
    PUB Inches(Pin) : Distance       | to_in
    ''Measure object distance in inches
     TO_IN := 73_746      ' Inches make a con when make Ping Object
     Distance := Ticks(Pin) * 1_000 / TO_IN     ' Calls Ticks and calculates Distance In Inches
    
    PUB Ticks(Pin) : microSeconds | timeOut
        timeOut := clkfreq / 1_000 * 20    ' max Ping time is 18.5 milliseconds
        pins.PulseoutUs(Pin,HIGH,5)    ' Calls PulseoutUS to initiate the 5 usec pulse
        microSeconds := pins.PulseinUs(Pin, HIGH, timeOut)
        microSeconds >>= 1       ' divide by 2 to only get return time not out and back
        ser.dec(microSeconds)
    
    PUB PulseoutUs(_pin, _polarity, _time)  | microSec
    '' Sends one pulse on a pin time in microseconds
    '' Input Parameters:  _pin a pin number 0-63.  Pins 58-36 for advanced users
    ''                    _polarity 0 for low pulse, 1 for high pulse.  If not valid method just returns
    ''                    _time length of pulse in microseconds
       microSec := clkfreq / 1_000_000
       if _polarity == HIGH_PULSE
           asm
              drvl  _pin             ' establish starting pin condition
           endasm
           _time := _time * microSec - 2
           asm
               drvh   _pin
               waitx  _time
    '' DOESN'T THIS 'drvl _pin' TRI-STATE THE PIN AT THE END OF THIS FUNCTION ???
               drvl   _pin
           endasm
       elseif _polarity == LOW_PULSE
           asm
              drvh  _pin             ' establish starting pin condition
           endasm
           microSec := clkfreq /1_000_000
           _time := _time * microSec - 2
           asm
               drvl   _pin
               waitx  _time
               drvh   _pin
           endasm
    
    '' SHOULD THIS CODE TRI_STATE THE PIN ON EACH INVOCATION ???
    PUB PulseinUs(_pin, _polarity,_timeout) : pulse  | microSec
    '' Measures a single pulse and rurn the length of the pulse in microseconds or an error flag
    '' Input parameters:  See PulseinClk
    '' Output:  Pulse length in microseconds or error flag as described in PulseinClk
    '                                              *** not tested after modifying to properly return error flag
        pulse := PulseinClk(_pin, _polarity,_timeout) / microSec
        if pulse > 0
            microSec := clkfreq / 1_000_000
            pulse /= microSec
    
    '' SHOULD THIS CODE TRI_STATE THE PIN ON EACH INVOCATION ???
    PUB PulseinClk(_pin,_polarity,_timeout) : pulse | timeOut, startTime, startEdge, endEdge
    '' Measures a single pulse and return the length of the pulse in clock ticks or an error flag
    '' Input parameters:  _pin  A pin number 0-63.  Pins 58-63 for advanced users
    ''                    _polarity  1 for a high pulse, 0 for a low pulse
    ''                    _timeout  Time in clock ticks to wait for an edge
    '' Output:  Pulse length in clock ticks
    '' Error outputs -1 for _polarity not in (0,1)  -2 timed out on start edge  -3 timed out on end edge                   
    
       if _polarity == HIGH_PULSE
          startEdge := %001 << 6 | _pin            'low to high
          endEdge :=   %010 << 6 | _pin            'high to low
       elseif _polarity == LOW_PULSE
          startEdge := %010 << 6 | _pin            'high to low
          endEdge :=   %001 << 6 | _pin            'low to high
       else                                        'bad argument for polarity
          pulse := -1
          return
    
       asm
               getct     timeOut
               add       timeOut,    _timeout
               setse1    startEdge
               setq      timeOut
               waitse1                  wc
        if_c   jmp       #timed_out
               getct     timeOut
               add       timeout,    _timeout
               setse1    endEdge
               getct     startTime
               setq      timeOut
               waitse1                  wc
               getct     pulse
        if_c   jmp       #timed_out2
               sub       pulse,  startTime
               jmp       #done
    timed_out  mov pulse,     #2
               neg pulse
               jmp       #done
    timed_out2 mov pulse,     #3
               neg pulse
    done
       endasm
    
    Sorry, my confusion is whether 'drvl _pin' sets the tri-state or if 'dirl _pin' is needed.


    Thanks for responding,
    dgately
  • PUB PulseinClk(_pin,_polarity,_timeout) : pulse | timeOut, startTime, startEdge, endEdge
    '' Measures a single pulse and return the length of the pulse in clock ticks or an error flag
    '' Input parameters:  _pin  A pin number 0-63.  Pins 58-63 for advanced users
    ''                    _polarity  1 for a high pulse, 0 for a low pulse
    ''                    _timeout  Time in clock ticks to wait for an edge
    '' Output:  Pulse length in clock ticks
    '' Error outputs -1 for _polarity not in (0,1)  -2 timed out on start edge  -3 timed out on end edge                      
       if _polarity == HIGH_PULSE
          startEdge := %001 << 6 | _pin            'low to high
          endEdge :=   %010 << 6 | _pin            'high to low  
          '****** do i need a fltl here ??  
       elseif _polarity == LOW_PULSE
          startEdge := %010 << 6 | _pin            'high to low  
          endEdge :=   %001 << 6 | _pin            'low to high
         '****** do i need a flth here ??   else                                        'bad argument for polarity
          pulse := -1
          return 
          
       asm
               getct     timeOut
               add       timeOut,    _timeout
               setse1    startEdge
               setq      timeOut
               waitse1                  wc 
        if_c   jmp       #timed_out 
               getct     timeOut
               add       timeout,    _timeout        
               setse1    endEdge
               getct     startTime
               setq      timeOut
               waitse1                  wc
               getct     pulse
        if_c   jmp       #timed_out2 
               sub       pulse,  startTime
               jmp       #done
    timed_out  mov pulse,     #2
               neg pulse
               jmp       #done
    timed_out2 mov pulse,     #3
               neg pulse
    done
       endasm  
    

    This is the routine in pins2.spin2 that may need to be changed. I will try to check this out later.

    John Abshier
  • dgately wrote: »
    Did you remember to tri-state the pin after sending the trigger pulse?
    Sorry, my confusion is whether 'drvl _pin' sets the tri-state or if 'dirl _pin' is needed.
    Adding the following 'dirl Pin' to the Ticks() function started giving results, though as John says, the code needs some work. At least I can see that the echo pulse is definitely showing up to the P2 pin, now (yay!)
    pins.PulseoutUs(Pin,HIGH,5)
    asm
        dirl    Pin
    endasm
      microSeconds := pins.PulseinUs(Pin, HIGH, timeOut)
    
    This change allows the pulse to show up on the pin, but the Ticks function returns a really low value of microseconds for the width of that pulse. Logic is giving a value like: .324 ms when an object is about 80 millimeters from the Ping. The Ticks code is returning the number 3.

    Thanks Phil and thanks John for taking a look,
    dgately
  • I think I have the Ping working now. Code is attached. Two changes made. I added a fltl or flth in Pins2.PulseinClk and I added a 200 microSecond delay in the Ping Ticks method. Give it a try. There are probably more improvements to be made. I was using a 1 killo ohm resistor between Ping and the Prop2.

    John Abshier
  • I think I have the Ping working now. Code is attached.
    Excellent!

    I'm getting realistic results now... I'll test the other functions of Pins2.spin2 as well!

    Thank you,
    dgately
Sign In or Register to comment.