Shop OBEX P1 Docs P2 Docs Learn Events
Detecting two pulses using a single cog. — Parallax Forums

Detecting two pulses using a single cog.

HughHugh Posts: 362
edited 2014-06-10 17:39 in Propeller 1
Hi,

I currently have two cogs that detect different pulses using waitpe and waitpne and put the measured frequencies into hub ram. These work well but I have run out of cogs and, if possible, would like to combine the two.

One signal is approx 120 Hz; the other circa 1 Hz but of relatively short (TBC) pulse width.

My working assumptions are:
  • It is not possible to 'OR' pins using waitpe
  • Waitpe reacts very quickly
  • Using Spin to compare the current state of the pin with the previous state is going to take a while.
Have I set myself on a wild goose-chase or could this be feasible?

(The pulse width is TBC awaiting inf from the vendors)

Thanks
Hugh

Comments

  • ReinhardReinhard Posts: 489
    edited 2014-06-10 02:36
    hi, if you use propgcc as programming language, maybe in the simpletool library you find useful functions, like pulse_in()
  • T ChapT Chap Posts: 4,223
    edited 2014-06-10 04:14
    How about ctra and ctrb using a positive edge mode counter. After some time, read both phsa and phsb with a single cog to see how many pulses were detected. Or do a staggered read, for example take a count1 := cnt then after whatever duration you want to use for the sample of pulse 1, do if count1 - cnt > 80_000_000 then getpulse1 := count1. The staggered method means you launch ctra and ctrb at different times, and read them separately different times.
    count1 := cnt
    waitcnt(20_000_000 + cnt)   'stagger
    count2 := cnt   'stagger the count2 init count read
    
    if count1 - cnt > 80_000_000
       getpulse1 := count1
       'calculate the frequency
       phsa~
    
    if count2 - cnt > 80_000_000
       getpulse2 := count2
       'calculate the frequency 
       waitcnt(20_000_000 + cnt)   'stagger
       phsb~
    

    Launch ctra and ctrb from any cog, including main, or a single cog. This is a crude example, it will need tweaking to stagger the reads better.
  • HughHugh Posts: 362
    edited 2014-06-10 04:59
    T Chap wrote: »
    How about ctra and ctrb using a positive edge mode counter. After some time, read both phsa and phsb with a single cog to see how many pulses were detected. Or do a staggered read, for example take a count1 := cnt then after whatever duration you want to use for the sample of pulse 1, do if count1 - cnt > 80_000_000 then getpulse1 := count1. The staggered method means you launch ctra and ctrb at different times, and read them separately different times.
    count1 := cnt
    waitcnt(20_000_000 + cnt)   'stagger
    count2 := cnt   'stagger the count2 init count read
    
    if count1 - cnt > 80_000_000
       getpulse1 := count1
       'calculate the frequency
       phsa~
    
    if count2 - cnt > 80_000_000
       getpulse2 := count2
       'calculate the frequency 
       waitcnt(20_000_000 + cnt)   'stagger
       phsb~
    

    Launch ctra and ctrb from any cog, including main, or a single cog. This is a crude example, it will need tweaking to stagger the reads better.

    Thanks T Chap. I haven't used CTRA / CTRB before so I'll go off and read the manual..

    Cheers
    Hugh
  • MJBMJB Posts: 1,235
    edited 2014-06-10 06:33
    Hugh wrote: »
    Hi,

    I currently have two cogs that detect different pulses using waitpe and waitpne and put the measured frequencies into hub ram. These work well but I have run out of cogs and, if possible, would like to combine the two.

    One signal is approx 120 Hz; the other circa 1 Hz but of relatively short (TBC) pulse width
    • It is not possible to 'OR' pins using waitpe
    • Waitpe reacts very quickly
    • Using Spin to compare the current state of the pin with the previous state is going to take a while.
    how short is
    relatively short (TBC) pulse width
    ?

    but looks like there is lots of time ..

    waitpe and waitpne: take a MASK
    so you can write a mini state machine
    and waitne with the current state of A and B.
    on each state change you can log cnt and restart waitne with new current state.

    And of course on each state change you do what needs to be done ... write to HUB etc...
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-10 07:34
    As MJB mentioned, the waitpxx statements takes a mask which can monitor two (or more) pins at once.
  • HughHugh Posts: 362
    edited 2014-06-10 08:53
    I've roughed out MJB's state-machine and understand what I'd need to do.

    If I follow T Chap's suggestion would this be how I set up ctrA for pin 17?
    ctra[30..26]:= %01010   ' Set the five most significant bits to POSEDGE mode
    ctra[5..0]:= 17      ' Set the least significant bits to 17 (the pin I wish to monitor)
    

    Thanks for bearing with me!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-06-10 09:34
    That works, Hugh. Be sure to set frqa to 1 as well, so the counter counts up. You will be checking phsa at constant intervals to discern the frequency.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2014-06-10 09:35
    Yes. If this method has some advantages for you, then practice looking at the result of phsa to see the accumulation of input pulses. The longer the sample, the more accurate the result of measuring.

      ctra[30..26]:= %01010   ' Set the five most significant bits to POSEDGE mode
      ctra[5..0]:= 17      ' Set the least significant bits to 17 (the pin I wish to monitor)
      frqa := 1    accumulate by 1
    
      Repeat
         phsa~    'clear phsa to 0
         waitcnt(80_000_000 + cnt)   ' wait 1 sec before checking again
         pst.dec(phsa)  '  view the current value in phsa with your terminal or other output method.  
        ' pst.linefeed
    
  • HughHugh Posts: 362
    edited 2014-06-10 10:43
    Bl**dy brilliant!

    Thank you all. It's easy when you know how. :lol:
  • David CarrierDavid Carrier Posts: 294
    edited 2014-06-10 17:39
    Hugh,
    For a really low-latency low-power way to read the high and low pulse times on all of the I/O pins (or any subset thereof) check out the ReadPulseWidths.Spin file in the Eddie Firmware.

    — David Carrier
    Parallax Inc.
Sign In or Register to comment.