Shop OBEX P1 Docs P2 Docs Learn Events
Using a smart pin to get frequency of a pin — Parallax Forums

Using a smart pin to get frequency of a pin

I'm trying to use a smart pin to get the number of pulses in a given amount of time.

  _pinstart(pin, P_EVENTS_TICKS, 2000, 0)
  while (_pinr(pin) == 0);
  t = _rdpin(pin);

The docs say that it will run for 2000 clicks and tell me how many ticks it saw in that time frame.
It never gives an answer.

Mike

Comments

  • The Y parameter is determines whether you want to count the number of rises, edges, or the amount of time the pulse is high.

      count := 2000
    
      pinstart(pin, P_EVENTS_TICKS, count, %001)
      repeat
        repeat until pinr(pin)
        result := rdpin(pin)                                         ' returns the number of ticks required to count n pulses
        result := float(clkfreq) /. float(result) *. float(count)    ' convert to frequency
        debug(fdec(result)
    
  • JonnyMacJonnyMac Posts: 9,249

    Chris beat me to it, by my test is similar (w/o the float stuff). I used a PWM pin to generate a frequency and connected to it with p_minus1_a.

      pwm.startx(PWM_OUT, 25, 100, 3333, pwm.M_SAW)
    
      pinstart(FRQ_IN, p_minus1_a | p_events_ticks, 1, %01) 
      repeat until pinread(FRQ_IN)
    
      ticks := rdpin(FRQ_IN)
    
      term.dec(ticks) 
    

    I tested with several frequencies and the results are very close to the ideal.

  • RaymanRayman Posts: 15,038

    Guess it's this in silicon docs:

    %10010 AND !Y.[2] = Time X A-input highs/rises/edges
    
    Time is measured until X A-input highs/rises/edges are accumulated.
    
    X.[31..0] establishes how many A-input highs/rises/edges are to be accumulated.
    
    Y.[1..0] establishes A-input high/rise/edge sensitivity:
    
    %00 = A-input high
    %01 = A-input rise
    %1x = A-input edge
    

    Would be nice if the silicon docs also mentioned the Spin2 names for the modes...

    Also, with Y=0, seems it should have reported time that input was high for 2000 clocks, right?
    The documentation is still rather sparse, but seems like that should be...

  • evanhevanh Posts: 16,352

    There's also the high precision example that Chip posted - https://forums.parallax.com/discussion/170882/reciprocal-counter-demo/p1

  • evanhevanh Posts: 16,352
    edited 2025-03-26 21:33

    @Rayman said:
    ..., with Y=0, seems it should have reported time that input was high for 2000 clocks, right?

    Yes, it would provide the average high time during that count of input pulses, which is like measuring PWM. EDIT: Err, maybe, I'm not sure now. It's written like it counts the sysclock ticks.

    The next modes down the smartpin mode list all do similar function. Here's my quick reference list:

        %10010_0, P_EVENTS_TICKS    Y=%0nn  ' Time: of X number of highs/pulses/steps
                                    Y=%1nn  ' Time: since latest high/rise/edge, with X timeout
        %10011_0, P_PERIODS_TICKS           ' Time: of X number of A-B cycles
        %10100_0, P_PERIODS_HIGHS           ' Accum: A up, during X number of A-B cycles
    
        %10101_0, P_COUNTER_TICKS           ' Time: of complete A-B cycles, for at least X duration
        %10110_0, P_COUNTER_HIGHS           ' Accum: A up, during complete A-B cycles, for at least X duration
        %10111_0, P_COUNTER_PERIODS         ' Count: of complete A-B cycles, for at least X duration
    
  • iseriesiseries Posts: 1,508

    Yes, it would.

    Is there a reverse of this. I would like to have it do 2000 clock ticks and tell me how many pulses there were. That way if the pin stalls it would report zero instead of freezing things up.

    Mike

  • evanhevanh Posts: 16,352
    edited 2025-03-26 21:27

    @iseries said:
    Is there a reverse of this. I would like to have it do 2000 clock ticks and tell me how many pulses there were. That way if the pin stalls it would report zero instead of freezing things up.

    Yep, that's the latter three modes: P_COUNTER_TICKS, P_COUNTER_HIGHS, P_COUNTER_PERIODS. Chip's example code uses them.

  • JonnyMacJonnyMac Posts: 9,249
    edited 2025-03-27 00:17

    Is there a reverse of this.

    This works:

      pinstart(FRQ_IN, p_minus1_a | p_count_rises, CLK_FREQ/10, 0)
      repeat until pinread(FRQ_IN)
    

    The answer in the terminal was 1000 (was using a 10kHz signal into the pin).

    To be fair, this is a bit of a cheat -- I'm only counting the rising edge of each cycle, but that gives you what you want, right?

  • evanhevanh Posts: 16,352

    Oh, good point. Jon's choice is the right one. It doesn't need any pulses to have occurred to give a reading of zero.

    Chip's example still needs at least one pulse to give a reading.

  • RaymanRayman Posts: 15,038
    edited 2025-03-27 02:15

    Seems we have great hardware but not a whole lot of examples of how to use it…

    Maybe Ai can step in and fix this ?

  • evanhevanh Posts: 16,352

    AI mostly relies on examples already existing. It'll go splat with any code that needs crafted to hit new metal, me thinks.

    I'll be impressed if it can correctly glue together a low-level program by just reading multiple datasheets for both a new instruction set and new custom eccentric devices. The objective doesn't have to be complex but it needs to be able to work from just the technical manuals without having already trained on examples for that same equipment.

Sign In or Register to comment.