calculate time between pulses


Closed Thread
Results 1 to 20 of 20
  1. #1
    Join Date
    Jun 2006
    Posts
    37

    Default calculate time between pulses

    Hi!
    I want to know how to calculate exact time between two pulses.Input is a pulse train with variable frequency.just want to calculate time between rising or falling edge of one pulse and the second one then second one and third one continously.
    thnx

  2. #2


    Did you find this post helpful? Yes | No

    Default Not enough information

    If the pulse train is slow, an all-Basic approach could be something like

    Loop:
    Counter = 0
    input sensepin
    if sensepin = 0 then Loop
    TimeHigh:
    counter = counter + 1
    pauseus 1000
    if sensepin = 1 then TimeHigh
    TimeLow:
    counter = counter + 1
    pauseus 1000
    if sensepin = 0 then TimeLow
    Done:
    Serout Tx232, 2, ["Pulsewidth = ", #counter, ", mSecs"]
    GOTO Loop

    This will need tweaking (by reducing the pauseus period) to get the timing exact. An oscilloscope needed.

    If your target pulse rate is too fast for the above you will need to setup Timer1 or Timer3 then invoke the CCP register which will give you the number of ticks of Timer1/3 between events on the defined CCPx pin. This will give you microsecond speeds and very high accuracy which can be defined by analysis rather than measurement in the Basic approach above.

    HTH
    Brian

  3. #3
    Join Date
    Jun 2006
    Posts
    37


    Did you find this post helpful? Yes | No

    Default ccp not working

    Ok here is a code for CCP but for some reason it is not working:
    Define LCD_DREG PORTD ' Define LCD connections
    Define LCD_DBIT 4
    Define LCD_RSREG PORTD
    Define LCD_RSBIT 2
    Define LCD_EREG PORTD
    Define LCD_EBIT 3



    Lcdout $fe, $80, " Pulse Reader"

    Pause 2000
    Lcdout $fe, $1





    Period var Word
    Capture var PIR1.2
    Overflow var PIR1.0 CCP1CON = %00000100
    T1CON = %00000001
    Loop:
    While Capture = 0 : Wend

    Period.lowbyte = CCPR1L Period.highbyte = CCPR1H
    If Overflow = 0 Then Lcdout $fe, $80, "Input Period: " , #Period , "uS"
    Endif
    Capture = 0 ' Clear the capture flag
    Rst:
    While Capture = 0 : Wend
    TMR1L = 0 TMR1H = 0
    Capture = 0
    Overflow = 0
    Goto loop

  4. #4
    Join Date
    Oct 2005
    Location
    Pinckney, Michigan
    Posts
    91


    Did you find this post helpful? Yes | No

    Default

    I've used the PULSEIN command as a tachometer for years.

    One trick is to employ a flip-flop in the signal chain that acts as a frequency divider. This has the effect of generating a single high pulse between two succesive edges, allowing the PULSEIN command to work, without having to switch context to time the high portion of the period and then the low portion of the period.

  5. #5
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,611


    Did you find this post helpful? Yes | No

    Smile some more infos ... please

    Hi, Hell_pk

    << I want to know how to calculate exact time between two pulses. >>

    The question 1 ) is : How exact must be your "exact time" ??? : +/- 1 ms ? +/- 1µS ... better accuracy ???

    The Question 2) is : Which is the period ( approximate ... ) of your signal.

    Could you also tell us what is your "signal" ???


    Then we will be able to show you ideas ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  6. #6
    Join Date
    Jun 2006
    Posts
    37


    Did you find this post helpful? Yes | No

    Default here are details

    signal is ttl from spindle of an old CNC machine.i want to measure rpm.max rpm are 2400 so max frequency is 50 Hz.the code i wrote above is now working correctly to calculate period.now iwant to calculate rpm.
    rmp=60/period
    should do the trick i think
    but how to perform this division?
    accuracy is not a problem now.

  7. #7
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,611


    Did you find this post helpful? Yes | No

    Wink

    Hi,

    You were near it in your question ...

    rmp=60/period * 1 000 000

    But ...

    care to the units of "period" , and overflow issues ...

    if you Xtal is 4 Mhz, then, period will be in µS ... the minimum "correct" display will be ~ 1100 rpm due to an overflow of your timer ... ( Period > 65535 ...)

    Then, the simplest way is to use a prescaler value of 8 ( 137 rpm ) or, if possible, 16 ( 68 rpm minimum )

    period will be in 8µS ( or 16 µS ) steps

    so,your result will then be :

    rpm = 60*1 000 000 /period*prescaler_value

    due to PBP limitations you'll have to use the DIV32 "function"

    So it will be Written :


    intermediate = 60 * 1000 / prescaler_value ' Compulsory !!!
    ' ( no "intermediate CON xxx" allowed )

    ' Disable interrupts ... if some used !!!

    Dummyvar = 1000 * intermediate

    rpm = DIV32 period

    ' re-enable interrupts allowed

    Alain



    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  8. #8
    Join Date
    Nov 2005
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    if your period counter has 1uS resolution

    asm
    move?cb 00h,r2 ; load dividend 60e6
    move?cb 87h,r2+1
    move?cb 93h,r0
    move?cb 03h,r0+1
    endasm
    TmpW = div32 Period
    lcdout dec Tmpw

    N.B. div32 is limited to 31bit / 15bit unsigned integer
    so Period must be < 32767

    Regards
    Gianni

  9. #9
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,611


    Did you find this post helpful? Yes | No

    Wink addendum ...

    Hi,

    Gioppy is bright right ...

    so let's add :



    IF period.7 then

    Period = period/2
    scale = 2

    ELSE

    scale = 1

    ENDIF



    intermediate = 60 * 1000 / prescaler_value ' Compulsory !!!
    ' ( no "intermediate CON xxx" allowed )

    ' Disable interrupts ... if some used !!!

    Dummyvar = 1000 * intermediate

    rpm = DIV32 period

    rpm = rpm / scale

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  10. #10
    Join Date
    Jun 2006
    Posts
    37


    Did you find this post helpful? Yes | No

    Default thanks guys

    thanks for ur help.
    I am also interested in what Mr. Wolf mentioned:using PULSEIN with flipflop.would u shed some light on it also.
    thanks

  11. #11
    Join Date
    Oct 2005
    Location
    Pinckney, Michigan
    Posts
    91


    Did you find this post helpful? Yes | No

    Default

    In short, what the flip-flop does for you, when measuring frequency, such as in a tachometer application, is it negates the need to measure the duration of the high portion of the period, then switch context and measure the duration of the low portion of the period. The time it takes to switch contexts (jump to another section of code) will be lost, and your measurement will be innacurate.

    The flip-flop makes one long pulse, spanning the entire period of the tach signal, so that a single PULSEIN command can accurately measure the duration of the period.

    For an explanation of the flip-flop idea go to the following Parallax URL:

    http://www.parallax.com/dl/appnt/stamps/bs1appnotes.pdf

    Scroll down to the "Practical Pulse Measurements" section.

    For the complete blow-by-blow as to how I implemented rotor tachometers on my helicopter go to the following URL:

    http://www.basicmicro.com/downloads/docs/RRPM.pdf

  12. #12
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    I have a PIC reliably reading 10 fan tachometers while it is doing other things. Something to keep in mind is that if your input signal is at all noisy, a simple period measurement may not result in a stable reading, since noise can easily affect a single reading. It is best to take a an average over a period.

    My method involves running a timer interrupt with a period shorter than the shortest expected "high" or "low" tachometer time. The interrupt service routine reads the port bits, and XORs them with the last reading of those bits. If the bit has changed, a counter is incremented. There is one counter for each fan to be monitored. The interrupt service routine keeps track of how many times it has run, so after a period of time (say a quarter or a half-second) it stores the individual counts. Simply multiplying the number of counts by a fixed value yields the RPM.

    The ISR is written in assembly, but this approach has several advantages:

    It doesn't require any external hardware
    It averages the counts over a short period, so the readings are stable even in the presence of noise.
    It works when the duty cycle is far from 50%.
    It runs in the background, so you can process other tasks at the same time.

    If you choose this approach, I can send you the code.
    Charles Linquist

  13. #13


    Did you find this post helpful? Yes | No

    Cool

    your saying it counts all 10 inputs while using just one timer? I'd like to see that code! sounds sweet.

  14. #14
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    OK, here you go.


    The interrupt period is 500uSec.

    All transitions in .5 seconds are added, since FanClock has a count value
    of 1000. 500E-9 X 1000 = .5 seconds.






    '------------------ Timer 0 interrupt handler-----------------------------------

    Asm
    ReadTachs

    movlw 0xEC ; Reload TMR0
    movwf TMR0H
    movlw 0x7E
    movwf TMR0L

    bcf INTCON,2 ; Clear the TIMER0 interrupt flag

    infsnz MasterClock
    incf MasterClock + 1 ; 16 bit Master system clock

    btfss TPE,0 ; Fan counter active gate
    bra CheckFans
    bra DoneForNow

    CheckFans
    infsnz FanClock
    incf FanClock + 1 ; 16 bit loop counter

    movlw 0x03 - 1 ; 1000 = 0x3E8, but must have one less
    cpfsgt FanClock + 1 ; to compare with greater than
    bra FanRoutine
    movlw 0xE8 - 1 ; Again, subtract one
    cpfsgt FanClock
    bra FanRoutine
    bsf TPE,0 ; Set the bit if completed 1000 loops
    clrf FanClock
    clrf FanClock + 1
    bra DoneForNow


    FanRoutine

    movf PORTB,0,0 ; Read the port bits all at once
    movwf Temp,0 ; Copy port into temp register
    xorwf OldPortB,0,0 ; XOR bits to see which ones have changed
    movwf changedB,0 ; Bits of changed ports will be set to "1"
    movff Temp,OldPortB ; Save the register for next pass

    movf PORTC,0,0
    movwf Temp,0
    xorwf OldPortC,0,0
    movwf changedC,0
    movff Temp,OldPortC

    movf PORTD,0,0
    movwf Temp,0
    xorwf OldPortD,0,0
    movwf changedD,0
    movff Temp,OldPortD


    Fan1
    btfss changedB,0
    bra Fan2
    infsnz Fan1Counter
    incf Fan1Counter+1

    Fan2
    btfss changedB,1
    bra Fan3
    infsnz Fan2Counter
    incf Fan2Counter+1

    Fan3
    btfss changedB,2
    bra Fan4
    infsnz Fan3Counter
    incf Fan3Counter+1
    Fan4
    btfss changedB,3
    bra Fan5
    infsnz Fan4Counter
    incf Fan4Counter+1

    Fan5
    btfss changedB,4
    bra Fan6
    infsnz Fan5Counter
    incf Fan5Counter+1

    Fan6
    btfss changedB,5
    bra Fan7
    infsnz Fan6Counter
    incf Fan6Counter+1

    Fan7
    btfss changedC,0
    bra Fan8
    infsnz Fan7Counter
    incf Fan7Counter+1

    Fan8
    btfss changedC,1
    bra Fan9
    infsnz Fan8Counter
    incf Fan8Counter+1

    Fan9
    btfss changedC,5
    bra Fan10
    infsnz Fan9Counter
    incf Fan9Counter+1

    Fan10
    btfss changedC,4
    bra DoneForNow
    infsnz Fan10Counter
    incf Fan10Counter+1

    DoneForNow
    INT_RETURN ; Return from the interrupt
    ENDASM

    ;---------------------- End of Timer 0 Int handler -----------------------------
    Charles Linquist

  15. #15


    Did you find this post helpful? Yes | No

    Smile ooh more to learn!

    Thanks for posting that!

  16. #16
    Join Date
    Jun 2006
    Posts
    37


    Did you find this post helpful? Yes | No

    Talking thanks

    thanks!
    can nay body covert this to pic basic pro.

  17. #17


    Did you find this post helpful? Yes | No

    Default am i understanding this?

    as far as i can tell this 1. can read a max of 1khz 2. reads or counts for half a second. and 3. was going to have more inputs on port D?

  18. #18
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    Yes, you are correct in assuming this version reads a max of 1KHz - and that is if the input is a square wave, less if the duty cycle is not 50%.

    I have used this routine successfully to read fan RPMs over 15,000.

    To increase the maximum frequency you can count, you have to increase the interrupt rate. Right now, the period is 500uSec, but could be easily decreased to less than 100uSec by changing the TMR preload (use Mr. E's calculator). I chose to run my routine for 1000 counts ( .5 seconds) so that I could get acceptable resolution, but there is no "magic". You do have to run it for a defined amount of time to come up with the answer you need.

    There is no limit to the number of pins you can read with this method. Theoretically, every pin on the pic could be an input.
    Charles Linquist

  19. #19


    Did you find this post helpful? Yes | No

    Talking Thanks!

    Thanks again for posting that. i actually learned a bit from it, and have a use for it! I mentioned the portd for expansion as it was read and compared while there doesn't appear to be a fan assigned to it. this is finally starting to make sense.

  20. #20
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    You are right about reading PortD and not using the result. I use this routine across several products. Some use PortD input, some do not. Because I support so many products, I sometimes have trouble with "cross pollination". This is one of those cases. I'll comment the port read out and save a few processor cycles. I have plenty of speed, since I always use 18F8722's at 40MHz.
    Charles Linquist

Similar Threads

  1. Count pulses between VARIABLE TIME
    By RodSTAR in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 15th October 2007, 13:44
  2. Timing input pulses and re-outputting them
    By jamie_s in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 28th February 2007, 02:50
  3. Replies: 1
    Last Post: - 18th April 2006, 20:11
  4. How to calculate machine time in basic code?
    By chai98a in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 24th February 2006, 00:44
  5. anyone knows how to calculate muslim prayer time?
    By luqman83salleh in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 6th September 2004, 10:54

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

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