Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 18 of 18

Thread: How to measure pulse width on Teensy 3.1 input pin.

  1. #1
    Junior Member
    Join Date
    Jan 2014
    Location
    Hazen, ND
    Posts
    8

    How to measure pulse width on Teensy 3.1 input pin.

    How can I measure the pulse width seen on a Teensy 3.1 input pin, say pin 4?
    If this requires use of Timer1 (and TimerOne.h), how do I do it?
    Thanks for any hints. . . .

  2. #2
    Senior Member
    Join Date
    Jun 2013
    Location
    Torrance CA
    Posts
    395
    How about attachInterrupt() on pin 4 with CHANGE as the mode, then in the interrupt routine use digitalReadFast() to see if the pin is high or low, and use the current clock with micros() or millis() (depending on the resolution) to see how long the width was? You could either use a global for the time if you only care about one pulse, or an array to record many samples for later analysis?

  3. #3
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    527
    You only need to know if it is high or low once. the next time will be the opposite

    ...unless your ISR is too slow or frequency input is too fast. ;-)

  4. #4
    Junior Member
    Join Date
    Oct 2014
    Posts
    5
    Quote Originally Posted by RLN37 View Post
    How can I measure the pulse width seen on a Teensy 3.1 input pin, say pin 4?
    If this requires use of Timer1 (and TimerOne.h), how do I do it?
    Thanks for any hints. . . .
    I am using the Teensy 3.1 to capture and measure the duration of a Loom Pick Pulse. Basically the Time of Flight for a Pick to move a thread across a Loom Fabric. This is just the critical pieces you would need to capture the pulse. I wasn't as successful get the CHANGE interrupt to work, but using the HIGH and LOW checks, I am able to capture down to the Millisecond with ease. I am still a novice coder, but the non-techies here are pretty impressed. I have about $80 in the install, compared to two bids of over $3500 each to do the same thing...!! The Teensy3.1 is amazing.

    Hope this helps....
    Steve


    Code:
    Setup() {
    Variables and other setup stuff goes HERE....
    attachInterrupt(Loom_Pulse, GoHigh, RISING); // encoder pin on interrupt 0 (pin 2);
    }
    
    Then when it detects a High Pulse....
    
    void GoHigh() {
      detachInterrupt(Loom_Pulse);
      microseconds = micros();
      attachInterrupt(Loom_Pulse, GoLow, FALLING); // encoder pin on interrupt 0 (pin 2);
    }  
    
    Then it waits for a Low Pulse....Does some Stuff then Resets the Interrupt to Looking for High.
    	
    void GoLow() {
      detachInterrupt(Loom_Pulse);  
      if(indexer < numberOfEntries ) {
        FlightTime = micros() - microseconds;
        if ((indexer > 0) && (FlightTime > 5000) && (FlightTime < 100000) && (Break_Out ==0)) {  //Eliminate readings below 5000 after Breakout and Restart   
          results[indexer] = FlightTime + MsecOffset;
          pressure[indexer] = analogRead(analogPin);
          indexer = indexer + 1; 
        }
        if (indexer == 0) {  //Throw away first measurement
          indexer = indexer + 1;
        }  
      }
     Break_Out = 0;
     attachInterrupt(Loom_Pulse, GoHigh, RISING); // encoder pin on interrupt 0 (pin 2);
    }

  5. #5
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I need to measure pulse width on two input pins. I want to use the same interrupt handler.
    is there a way to determine which pin caused the interrupt from the interrupt handler?
    In avr arduino, I use the pin mask to determine which pin changed. How do I do it in teensy 3.1?

    Thanks.

  6. #6
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I did some more reading, it looks like I can find out which pin caused the interrupt by reading the ISFR register.
    so if I configure pins 1 and 2 to use the same handler, I can check PORTB_ISFR bit 17 (for pin1) and PORTD_ISFR bit 0 (for pin 2) to find out which pin caused the interrupt? I assume the bits are not cleared until isr handler returns.

  7. #7
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    there is also a pulse width measuring library as I recall that uses a hardware timer in capture mode. This is simpler/better/more accurate than interrupts.

  8. #8
    Senior Member onehorse's Avatar
    Join Date
    Apr 2014
    Location
    Danville, California
    Posts
    921
    This is simpler/better/more accurate than interrupts.
    Not necessarily, see this

  9. #9
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I tried it and it works. It is quite simple. I just added this at the start of my handler

    Code:
      uint8_t i=0;
      
      if (PORTD_ISFR & CORE_PIN2_BITMASK)
        i = 1;
    I have pin change interrupt on pins 1 and 2. and my variables are in an array of size 2.
    if interrupt originated from pin2, it sets i=1 otherwise, assume it is pin 1 that caused the interrupt.

    this is good enough for me. it does not have to be accurate.
    I've used a similar feature you described with the library that use hardware timer on AVR, it is needed if you want exact timing, as even if other higher priority interrupt is executing, the timestamp of the actual time the interrupt occurred is captured.

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,169
    Hmmm... maybe I ought to make a PulseMeasure library, similar to FreqMeasure, but returning the time between rising and falling edges. FreqMeasure returns the time between successive rising edges.

  11. #11
    Senior Member onehorse's Avatar
    Join Date
    Apr 2014
    Location
    Danville, California
    Posts
    921
    Is it possible to allow the use of any digital pin with the proposed PulseMeasure library?

  12. #12
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I took a quick look at FreqMeasure, can only be used with hard coded pin 3, so I can't use it as I am measuring rpm on 2 pins.
    I agree a library should be usable with any pin, or better, multiple pins simultaneously (at least equal to number of FTM available) to be more useful.

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    4,870
    Looking at Pulseposition library I believe it shows: // rxPin can be 5,6,9,10,20,21,22,23

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,169
    Quote Originally Posted by doughboy View Post
    I agree a library should be usable with any pin, or better, multiple pins simultaneously (at least equal to number of FTM available) to be more useful.
    I'd love to do this with the FreqMeasure library someday.

    If anyone gets to it before I do, pull requests are welcome. This is open source, afterall.

    But eventually, I'll probably do this. It really is needed, and it seems unlikely anyone else will write such a library.

  15. #15
    Junior Member
    Join Date
    Nov 2013
    Posts
    17
    Hi Paul
    Any progress on the pwm measure library. I can do some testing if you want

  16. #16
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    595
    I thought I posted something a few months ago on this, but can't find it now. Anyway I remember making a fairly small modification to the "pulse position" library http://www.pjrc.com/teensy/td_libs_PulsePosition.html and getting good resolution (0.02 usec) on a pulse width.

  17. #17
    Senior Member joe_prince's Avatar
    Join Date
    Feb 2015
    Posts
    109
    Quote Originally Posted by JBeale View Post
    I thought I posted something a few months ago on this, but can't find it now. Anyway I remember making a fairly small modification to the "pulse position" library http://www.pjrc.com/teensy/td_libs_PulsePosition.html and getting good resolution (0.02 usec) on a pulse width.
    Can the Pulse Position library also be used as a replacement to the slow pulseIn() function to read microsecond PWM pulses from an RC Receiver, rather than PPM?

  18. #18
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    595
    Sorry, I misremembered- this was the post https://forum.pjrc.com/threads/28037...or-FreqMeasure but apparently I was doing frequency, not pulse width.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •