Shop OBEX P1 Docs P2 Docs Learn Events
Counter question: how to set-up a counter to detect going from low to high? — Parallax Forums

Counter question: how to set-up a counter to detect going from low to high?

vanmunchvanmunch Posts: 568
edited 2011-08-17 21:01 in Propeller 1
I'm trying to figure out how to measure the time between the moment the code initiates an action (starts to move a servo) until a button is pushed and I was thinking that this would be a great job to use a counter for. I'm thinking that it would be very similar to the code used for seeing when a pin goes from high to low (documented in the PEK), only here I would need to know when the pin goes from low to high. I've looked through the manual, but I can't seem to get anything to work. Please let me know if you have any ideas or if you think there's a better way to do this, but I'm guessing/hoping there's a simple answer. Thanks!

Dave

Comments

  • kwinnkwinn Posts: 8,697
    edited 2011-07-28 14:06
    Use a pullup resistor to the pin with the push button grounding it, then the pin will go from high to low and you can use the existing code.
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-28 16:44
    I don't know this particular PEK solution (reference?) but can't you just reverse the condition?
  • vanmunchvanmunch Posts: 568
    edited 2011-08-03 19:41
    Hey Guys,

    I apologize for not responding sooner. Lots going on.

    kwin,
    Thanks for your suggestion. I would have liked to have gone that route, but the way the button (which is a tactile sensor with the center energized and the outer spring being the ground) requires the pin to go from low to high. Physically, this makes more sense and works great... except now I want to try and use the counter funtion. :)

    kuroneko,
    The example is found on pg 121-130 in v 1.1 that you can download here:
    http://www.parallax.com/Portals/0/Downloads/docs/prod/prop/PELabsFunBook-v1.1.pdf
    and I'd like to reverse the condition, but it requires more knowledge than I have about how to set-up counters than what I have. :) I'm guessing that it's something really simple.

    Anyhow, I'd love to hear any more thought's. Thanks!

    Dave
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-03 20:05
    vanmunch wrote: »
    The example is found on pg 121-130 in v 1.1 that you can download here:
    http://www.parallax.com/Portals/0/Downloads/docs/prod/prop/PELabsFunBook-v1.1.pdf
    and I'd like to reverse the condition, but it requires more knowledge than I have about how to set-up counters than what I have. :)
    There seem to be examples all over the place. So I just use your OP as a guide and guess that you want something like a NEG detector.
    CON
      pin = 16
    
    PUB null | n
    
      ctra := constant(%0_01100_000 << 23 | pin)            ' monitor pin for low
      frqa := 1                                             ' system clock resolution
    
    ' If pin reads low then the counter is already busy counting.
    ' This doesn't matter as we have a specific starting point.
    
      phsa := 0                                             ' measurement starts now
      waitpne(0, |< pin, 0)                                 ' wait for pin to leave low state
    
      n := phsa                                             ' grab timer value (may need overhead
                                                            ' adjustment)
    
    Would this work for you?
  • vanmunchvanmunch Posts: 568
    edited 2011-08-03 20:18
    Hey Kuroneko,

    Thanks for the suggestion/idea. I won't be able to try it out until later next week, but I'll let you know how it goes. Thanks again.

    Dave
  • vanmunchvanmunch Posts: 568
    edited 2011-08-17 20:11
    Hey Kuroneko,

    I tried to get your code idea to work, but I think that I'm missing something. It wouldn't return a value. (I'm guessing that I'm missing something obvious.)
    The code is:

    CON

    _clkmode = xtal1 + pll16x ' System clock → 80 MHz
    _xinfreq = 5_000_000

    CR = 13
    pin = 0
    OBJ

    Debug: "FullDuplexSerialPlus" ' Use with Parallax Serial Terminal to
    ' display values


    PUB null | n

    Debug.Start(31, 30, 0, 57600)
    waitcnt(clkfreq * 2 + cnt)
    Debug.Str(String(13, "going "))

    ctra := constant(%0_01100_000 << 23 | pin) ' monitor pin for low
    frqa := 1 ' system clock resolution

    waitcnt(clkfreq*3 + cnt)
    ' If pin reads low then the counter is already busy counting.
    ' This doesn't matter as we have a specific starting point.
    Repeat
    Debug.Str(String(13, "in program loop "))

    phsa := 0 ' measurement starts now
    waitpne(0, |< pin, 0) ' wait for pin to leave low state

    n := phsa

    Debug.Str(String(13, "n = "))
    Debug.Dec(n)
    waitcnt(clkfreq/2 + cnt)




    I also tried to modify the RC decay example by switching it from POS to NEG detector, and I get a value, but it's always "770" so I have something wrong.
    The code is:

    CON

    _clkmode = xtal1 + pll16x ' System clock → 80 MHz
    _xinfreq = 5_000_000

    CR = 13

    OBJ

    Debug: "FullDuplexSerialPlus" ' Use with Parallax Serial Terminal to
    ' display values

    PUB Init

    'Start serial communication, and wait 2 s for connection to Parallax Serial Terminal.

    Debug.Start(31, 30, 0, 57600)
    waitcnt(clkfreq * 2 + cnt)

    ' Configure counter module.

    ctra[30..26] := %01100 ' Set mode to "Neg detector"
    ctra[5..0] := 0 ' Set APIN to 0 (P0)
    frqa := 1 ' Increment phsa by 1 for each clock tick

    Debug.Str(String(13, "going "))
    main ' Call the Main method

    PUB Main | time

    repeat


    phsa~ ' Clear the phsa register
    dira[0]~ ' Pin to input stops charging circuit
    Debug.Str(String(13, "in program loop (presse button to stop counter)"))

    time := phsa

    ' Display Result

    Debug.Str(String(13, "time = "))
    Debug.Dec(time)
    waitcnt(clkfreq/2 + cnt)

    Just to repeat my goal. I'd like to be able to start a counter and have it monitor a pin for me, watching for it to go from low to high. I'd like it to then give me a "time" value. It would be like having the program say "go" and then pushing a button to close the circuit. The program would then tell you how long it took you to read the message and push the button. This isn't my finial objective (stated in an earlier post), but the same idea. :)

    Any help would be great. I appreciate everyone's time and suggestions. :)

    Dave
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-17 20:56
    vanmunch wrote: »
    I tried to get your code idea to work, but I think that I'm missing something. It wouldn't return a value. (I'm guessing that I'm missing something obvious.)
    Can you elaborate on wouldn't return a value? Do you mean it never prints out n? This would mean the waitpne never sees a high level on pin. I just grabbed the code you posted and added a fake trigger (second cog which sets pin high after a second). And I get repeated output of about 80M + overhead (80009737).
  • AribaAriba Posts: 2,690
    edited 2011-08-17 21:01
    I think something like that would do what you want:
    PUB Main | time
    
     ctra := %01010<<26 + pin   'setup POSEDGE counter mode
     frqa := 1
    
     repeat
    
       'initate action here
       time := cnt              'remember start time
    
       phsa := 0                'wait for pos edge
       repeat until phsa > 0
    
       time := cnt - time       'calc delta time
    
       debug.str(string(13, "time = "))  'disp time
       debug.dec(time)
    

    As long as you dont fill in code to initate your action, it will just measure the time between low to high changes on pin.
    This is untested and you need to add the CON and OBJ section as in your examples above.

    Andy
Sign In or Register to comment.