Trying to measure time between two pulses on different pins.


Closed Thread
Results 1 to 27 of 27
  1. #1
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72

    Question Trying to measure time between two pulses on different pins.

    Hello all,

    I need to measure the time between two different pulses leading edges.

    The trigger pulse is a 60 Hz square wave with a 8.228mS width, 50% duty that is currently being generated by another PIC, but could actually be generated by the PIC I want to do the measuring from to simplify things. It needs to be constantly running.

    The second pulse varies in width by three different amounts, 555uS, 1.668mS and 3.33mS, but the width is unimportant to me, I’m just trying to measure the time between the trigger pulses leading edge and the leading edge of this pulse. The second pulses leading edge always stays within the envelope of the first pulse.

    I guess I’m trying to measure the phase between the two?

    I really need to do this on another, third, pulse as well, it’s the same as above, I just left it out of the explanation of my problem for clarity’s sake. It would be the green pulse in the included drawing

    I’ve searched around and found this post to be the most promising: http://www.picbasic.co.uk/forum/show...se+measurement
    But I’ve never used the CCP to measure anything or played with interrupts before.

    It looks like what I may need with a few tweaks, but it would also be nice to generate the 60 Hz square wave pulse, trigger off of its leading edge and measure the time until the leading edge of the second pulse and third pulses all on one PIC

    I need to spit the raw measurement out serially too. 2400 8N1 is fine.

    I figure I would grab three readings of the first timing, average, and then three readings of the second timing, average it too and then spit the raw averaged numbers (t1 and t2) out via SEROUT as the measurement doesn’t vary without me making it vary, so I know when to expect a change.

    My preferred hardware for this project is a 16F648A running off a 20MHz canned oscillator, but if I could pull it off on a DIP chip with less pins, I’m open to suggestions.

    Any and all help is much appreciated!

    Name:  Variable Phase Pulse.jpg
Views: 1574
Size:  53.3 KB

  2. #2
    Join Date
    Jan 2012
    Location
    Grid EN19MV
    Posts
    157


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    What if you were to use DT's Instant Interrupts? Have an interrupt that times out at some frequency - every time that interrupt happens, increment a counter. When the leading edge of the first pulse happens (could also be an interrupt), zero the counter. When the leading edge of the second pulse hits, read the counter and multiply by the frequency of the interrupt to determine the time.

    That was my first thought. Never actually done it - but I think it would work.
    Last edited by andywpg; - 21st August 2014 at 17:17. Reason: Spelling
    "I have noticed that even those who assert that everything is predestined and that
    we can change nothing about it still look both ways before they cross the street"


    -Stephen Hawking

  3. #3
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Wow, I am shocked speechless.

    I have used Darrel's gifts to the PBP world for years now. Most of what I have done with PBP has had some kind of help or influence from Darrel, if not robbing his code line per line. I had his instant interrupts in mind when I started fleshing out this latest pic based project and was hoping he might help me yet again, even though he didn't know who I was.

    I was just searching around to see if he was still active and came across the word that he has passed.

    Now I don't even know what to say.

    He was just an awesome person for helping so many people with the gift of knowledge. I could tell by his enthusiastic posts that it really made him happy to help out and gift his ideas to all of us.

    Even when I was at my wits end with a project, just reading his posts would help me push thru my problem. It also made me want to say thank you a million times over and be as nice as I could for all of you that have helped me. Real appreciation. This stuff isn't always easy, and to have someone so willing to guide the way was amazing.

    Darrel Taylor will be missed by a whole lot of people, and I think that says a lot for the guy.

    R.I.P DT!

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    a pic with timer1 gate control would be a perfect fit for this , eg 16f1825

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi,
    Questions:

    1) Pulse 2 and 3 both falls within the envelope of pulse 1 but is pulse 3 always trailing pulse 2 or can it equally well be leading pulse 2?

    2) Once you've got your PIC doing these measurements, what else (if anything) do you need it to do?
    (I ask because quite often around here you come up with a possible implementation only to then get something like: Oh, that's great! Now I need to add this and that and..... - Which may render the initial idea and work useless.

    3) Will there always be two pulses or is it possible that one (or both) will be missing?

    Here's a bare bones aproach, it expects the pulses to be "in order" and there's no timeout or anything. Both can be easily accommodated for though.
    Code:
    Time1 VAR WORD
    Time2 VAR WORD
    Pulse1 VAR PortB.0
    Pulse2 VAR PortB.1
    Pulse3 VAR PortB.2
    
    Main:
    	GOSUB Measure
    	' Do whatever with the measurements
    Goto Main
    
    
    Measure:
    	T1CON.0 = 0		' Stop Timer
    	TMR1H = 0 : TMR1L = 0	' Clear timer
    
            While Pulse1 : WEND	' Wait until the 60Hz Square wave signal is low before "arming"
    
    	While Not Pulse1 : WEND ' Now wait for rising edge
    	T1CON.0 = 1          	' Start timer
    
    	WHILE Not Pulse2 : WEND	' Wait for leading edge of second pulse
    	Time1.HighWord = TMR1H
    	Time1.LowWord = TMR1L
    
    	While Not Pulse3 : WEND	' Wait for leading edge of third pulse
    	Time2.HighWord = TMR1H
    	Time2.LowWord = TMR1L
    RETURN
    /Henrik.

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,383


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    henrik
    is there a possibility of tmr1l rolling over after tmr1h read causing an error here ?

    and as you say will pulse 3 always lag pulse 2 . I also wonder what sort of resolution is required

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi Richard,
    Yes there is. On some chips (not the 16F648 though, I believe) the timer is dubble buffered so you don't need to worry about it. On chips where it isn't you do need to cater for it by reading TMR1H "on both sides" of reading TMR1L and comparing the result to verify that it didn't roll over.

    As I said, the example is a bare bones approach. I didn't want to put too much into it before getting more details.

    /Henrik.

  8. #8
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Ok,

    Sorry I didn’t get back to my issue at hand. I was pretty bummed and just wasn’t feeling it yesterday.

    Anyway…

    I have two circuits that are identical. They are both clocked with a 60Hz, 50% duty, ~8.2mS pulse width +5 volt going square pulse. Low is 0V, high is 5V. They both need this signal all the time. So for now I’m just using a 12F675 to provide that signal.

    With that clock signal running, the two individual circuits each output a +5V square wave of their own, which by itself on a scope, doesn’t look like much but a square wave.

    But when you trigger a scope using the leading edge of the 60Hz, 50% duty pulse that the 12F675 is currently generating (and being provided to the clock inputs on the two circuits) and you have one of the other pulses on a second scope channel, you’ll see what is in my drawing, which shows just one circuits output for clarity.

    You have the 60Hz pulse with the other square wave nested inside of it. And if you adjust that circuit’s control, the pulse can be moved in relation to the steady 60Hz pulse. The other circuit is identical and does the exact same thing. And yes, it can lead the other circuits pulse (not the 60Hz pulse, both other pusles are always inside of the 60Hz pulse!) or fall behind it, or be right on top of it.

    My perfect solution for this would be:

    1. Generate the 60Hz 50% duty signal on one pin. Always running. HPWM10 maybe?

    2. Trigger a timer off of the leading edge of the 60Hz 50% duty signal (no clue, still haven’t messed with timers!!!)

    3. Count until the leading edge of the pulse from the first circuit comes in on a pin, hold that number in a variable.

    4. Repeat 2 and 3 a few times to build an average – hold that average in a variable.

    5. Trigger a timer off of the leading edge of the 60Hz 50% duty signal

    6. Count until the leading edge of the pulse from the second circuit comes in on another pin, hold that number in a variable.

    7. Repeat 5 and 6 a few times to build an average – hold that average in a variable

    8. Send the measurement from both average variables out via SEROUT.

    The future plan is to find out exactly what numbers to expect by spitting them out via SEROUT, once I know the ranges and such, I would build a lookup table using SELECT CASE or something and if the shift in a signal falls within a certain value, send a command out serially. This would be done for both circuits

    So: SEROUT serialPin, 4, [circuit1Data, circuit2Data…]

    The only timing in this that is critical is the 60Hz pulse must always be there, steady, constant. And of course the measurement itself need to be fairly accurate, with my lookup table I’m planning on building in hysteresis(?) like of

    circuit one's variable equals 225, my lookup would handle it as “if x = <230 AND <220 then” – or something like that just to cancel out minor errors.

    The signals I am measuring only vary by user input (i.e. turning a knob) and are independent of each other and will be handled by separate lookup tables, so measuring one before the other doesn’t matter, or if they both get measured at the same time. And seeing them change in any fine detail doesn’t matter either, So waiting on a routine to finish or something isn’t a big deal. Mainly its just getting an accurate measurement of the shift between the clock pulses leading edge and each circuits outputs leading edge.

    I’d like to do this all on one chip if possible. I was trying to think in terms of the 16F648A because I have them on hand and have used them quite a bit. I’m trying to stay away from having more pins than I need, so I really don’t want to have to use an 18F4550 or something. So if there is something around the same pin count as the 16F648A that can do all this in one chip, great. If not, I can live with the 12F675 and two 16F648A I guess.

    As always, thanks to all of you for helping me out!

    Respectfully,

    Ryan

    Name:  Variable Phase Pulse 2.jpg
Views: 1400
Size:  71.3 KB

  9. #9
    Join Date
    Apr 2011
    Location
    Welches, Oregon
    Posts
    198


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    I admit to not following the thread carefully; I find it difficult to follow prewritten cade (even my own) and maybe this has already been suggested, but wouldn't it work to:

    Monitor two pins for input signal. First indication set TIMER to 0 and FLAG = 1.
    Continue to monitor both pins
    If "Other" pin indicates, capture TIMER as "elapsed count" variable, reset FLAG, and calculate for average (as the timer starts from 0 on each initial indication, there is no need to worry for rollover or complicated math).
    If "Same" pin indicates, reset TIMER and FLAG = 1 (missed second signal indication - count errors if you like).

    ?

  10. #10
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Ryan,
    Don't know if you looked at my previous idea or not. It was an initial idea but had some issues (and syntax errors).
    Unfortunately you won't be able to use HPWM to generate the 60Hz output signal - it won't go that low in frequency. There are other ways of doing it of course but for now I've been focusing on the measurments. Here's a second attempt based on the same idea as the previous code, this time with a bit more features and it does compile - I haven't tested it though.
    Code:
    Time1 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse2
    Time2 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse3
    Temp  VAR BYTE                      ' Temporary variable, use at will
    
    Trig   VAR PortB.0
    Pulse1 VAR PortB.1
    Pulse2 VAR PortB.2
    
    TMR1IF VAR PIR1.0
    
    Main:
    	GOSUB Measure
    	' Do whatever with the measurements
    Goto Main
    
    
    Measure:
    	T1CON.0 = 0 : TMR1IF = 0       ' Stop Timer, Clear Interrupt flag
    	TMR1H = 0 : TMR1L = 0	       ' Clear timer
    	Time1 = 0 : Time2 = 0          ' Clear measurments
    
        While Trig : WEND	           ' Wait until the 60Hz Square wave signal is low before "arming"
    	While Not Trig : WEND          ' Now wait for the rising edge of the 60Hz signal
    	T1CON.0 = 1          	       ' Start timer
    
        DO
    '-------------------------------------------------------------------------------
    	    ' Do we have a rising edge on Pulse1 input?
    	    ' Capture value ONLY if we haven't already done so.
            IF Pulse1 AND (Time1 = 0) THEN
              Time1.HighBYTE = TMR1H
              Time1.LowBYTE = TMR1L
              
              ' Make sure TMR1L didn't overflow inbetween reading the high and low byte
              Temp = TMR1H
              If Temp <> Time1.HIGHBYTE THEN
                Time1.HighBYTE = TMR1H
                Time1.LowBYTE = TMR1L
              ENDIF          
            ENDIF
    '------------------------------------------------------------------------------- 
    	    ' Do we have a rising edge on Pulse2 input?
    	    ' Capture value ONLY if we haven't already done so.
            IF Pulse2 AND (Time2 = 0) THEN
              Time2.HIGHBYTE = TMR1H
              Time2.LOWBYTE = TMR1H
    
              ' Make sure TMR1L didn't overflow inbetween reading the high and low byte
              Temp = TMR1H
              If Temp <> Time2.HIGHBYTE THEN
                Time2.HighBYTE = TMR1H
                Time2.LowBYTE = TMR1L
              ENDIF
            ENDIF
    '-------------------------------------------------------------------------------    
        LOOP UNTIL ((Time1 <> 0) AND (Time2 <> 0)) OR TMR1IF
    
    RETURN
    /Henrik.

  11. #11
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi,
    OK, this version generates the 60Hz, 50% dutycycle in the background using TMR0 and DT-Ints.
    Since we are generating the output I don't see the need to feed the signal back into the PIC to trig on.
    Anyway, this compiles and runs on a 16F628 here on my breadboard. It generates the 60Hz output but I haven't actually fed any pulses back into it to see if the actual measurment code works. You'll have to do that yourself. Please note that since we're using interrupts in the background you can not use SEROUT to send the data since the interrupts will mess with the timing. Fortunately the 628/648 have an USART - use it with HSEROUT as in the code.

    Let us know how it works out.

    Code:
    DEFINE NO_CLRWDT 1                  ' We need the prescaler for TMR0, can't use the WDT
    DEFINE OSC 20                       ' Running with a 20MHz x-tal
    
    #CONFIG
       __config _HS_OSC & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
    #ENDCONFIG
    
    ' Variables needed by DT-INTS (we miss you Darrel!)
    wsave VAR BYTE $70 SYSTEM
    wsave1 VAR BYTE $A0 SYSTEM
    wsave2 VAR BYTE $120 SYSTEM
    
    Time1 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse2
    Time2 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse3
    Temp  VAR BYTE                      ' Temporary variable, use at will
    Measure VAR BIT                     ' Semaphore to indicate when we want to start a measurment.
    
    TrigOut VAR PortB.3                 ' Pin for 60Hz output
    Pulse1  VAR PortB.4                 ' Input pin for first pulse
    Pulse2  VAR PortB.5                 ' Input pin for second pulse
    
    TMR1IF VAR PIR1.0                   ' Alias to TMR1 interrupt request flag which we use for timeout feature.
    
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR0_INT,  _ISR,   PBP,  yes
        endm
        INT_CREATE                      ; Creates the interrupt processor
    ENDASM
    
    OPTION_REG = %11000111              ' Prescaler assigned to TMR0, 1:256 ratio
    TRISB = %11110111                   ' Set PortB direction.
    
    @ INT_ENABLE TMR0_INT               ; Enable the 120Hz interrupt for the square wave generator.
    
    Main:
        Pause 1000
        Gosub Capture
        
        IF TMR1IF THEN
            HSEROUT["Timeout before capturing both pulses.",13]
        ELSE
            HSEROUT["Time 1: ", DEC5 Time1, " ticks.",13]
            HSEROUT["Time 2: ", DEC5 Time2, " ticks.",13]
        ENDIF
    Goto Main
    
    '-------------------------------------------------------------------------------
    Capture:
        Measure = 1
        While Measure = 1 : WEND        ' Wait untill ISR have created the rising edge and started the timer
    '-------------------------------------------------------------------------------
        ' Now look for the rising edge of the two pulses we're expecting to recieve.
        ' Once we see the pulse we grab the TMR1 value and store it.
        ' If we don't get both pulses before the TMR1 overflows (as indicated by
        ' the TMR1 Interrupt Flag) we abort the operation. This happens after
        ' 200ns * 2^16 = ~13ms.
        DO
    
    	    ' Do we have a rising edge on Pulse1 input?
    	    ' Capture value ONLY if we haven't already done so.
            IF Pulse1 AND (Time1 = 0) THEN
              Time1.HighBYTE = TMR1H
              Time1.LowBYTE = TMR1L
              
              ' Make sure TMR1L didn't overflow inbetween reading the high and low byte
              Temp = TMR1H
              If Temp <> Time1.HIGHBYTE THEN
                Time1.HighBYTE = TMR1H
                Time1.LowBYTE = TMR1L
              ENDIF          
            ENDIF
    '------------------------------------------------------------------------------- 
    	    ' Do we have a rising edge on Pulse2 input?
    	    ' Capture value ONLY if we haven't already done so.
            IF Pulse2 AND (Time2 = 0) THEN
              Time2.HIGHBYTE = TMR1H
              Time2.LOWBYTE = TMR1H
    
              ' Make sure TMR1L didn't overflow inbetween reading the high and low byte
              Temp = TMR1H
              If Temp <> Time2.HIGHBYTE THEN
                Time2.HighBYTE = TMR1H
                Time2.LowBYTE = TMR1L
              ENDIF
            ENDIF
        
        LOOP UNTIL ((Time1 <> 0) AND (Time2 <> 0)) OR TMR1IF
    '-------------------------------------------------------------------------------
    RETURN
    
    '-------------------------------------------------------------------------------
    ISR:
    If TrigOut = 0 THEN                 ' If trig output is low....
        If Measure = 1 THEN             ' ...and we want to start a measurment
            T1CON.0 = 0 : TMR1IF = 0    ' Stop timer and clear interrupt flag
            TMR1H = 0 : TMR1L = 0       ' Clear the time
            Time1 = 0 : Time2 = 0       ' Clear measurements
            T1CON.0 = 1                 ' And start the timer
            Measure = 0                 ' Let main program know we've set the ball in motion.
        ENDIF
        TrigOut = 1                     ' Set trig output high
    ELSE
        TrigOut = 0                     ' Trig output was high, set it low.
    ENDIF
       
    TMR0 = TMR0 + 94                    ' Reload TMR0 for 120Hz interrupt rate
    @ INT_RETURN
    '-------------------------------------------------------------------------------
    /Henrik.

  12. #12
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    OK, last post, I promise.
    I felt I had to test see if it worked the way it's intended and it looks like it actually does, whoohoo!

    I set up my Rigol DG4162 to output a a single pulse on each of its two channels and then set it up for external trigger. I fed the 60Hz output signal from the PIC to the trigger inputs on the waveform generator. The output of the generator was fed back into the two inputs on the PIC. On the waveform generator I can set the delay between trigger event and output pulse, I set that to 1.5ms for channel 1 and 4.5ms for channel 2:
    Name:  AWG Setup.jpg
Views: 1329
Size:  49.9 KB

    The scope confirms these settings:
    Name:  Scope snapshot.png
Views: 1451
Size:  25.9 KB
    You can see the rising edge of the 60Hz signal on channel 1 (yellow) and then the two pulses at 1.5ms (blue) and 4.5ms (purple) respectively.

    I changed the HSEROUT code in the previous post to
    Code:
        IF TMR1IF THEN
            HSEROUT["Timeout before capturing both pulses.",13]
        ELSE
            HSEROUT["Time 1: ", DEC4 Time1/5, " us.",13]
            HSEROUT["Time 2: ", DEC4 Time2/5, " us.",13,13,13]
        ENDIF
    And it says
    Time 1: 1525 us.
    Time 2: 4523 us.
    It's not perfect but pretty close. If it's critical it might be possible to tweak some of the error out but I'll leave it at this for the time being.

    Ryan, let us know if you try it!

    /Henrik.

  13. #13
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Henrik,

    That looks awesome! I will try it this weekend when I get some time.

    I did get it to work on an 18F2320 by taking the first bit of code that Bruce posted in the link in my initial post and modifying it a bit. Basically I could only measure one circuits pulse in relation to the 60HZ signal though. Not both circuits.

    I did that by taking out his failing edge capture and replacing it with a rising edge capture of the second pulse via CCP2

    So CCP1 looks for the rising edge on the 60Hz signal, and then it switches to look for the rising edge of the second pulse on CCP2. The rest is the same as his code for the most part.

    I think its pretty close to your original thinking, except using CCP to capture instead of raw pins.

    I got some really nice, workable results right off the bat, so I was pretty happy I figured something out at least

    I can wait to try your code out, as it gets me even closer.

    Thanks so much to all of you for helping and lending your thoughts. I'll let you know how it goes!

    -Ryan

  14. #14
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi Ryan,
    Yes, using a chip with two CCP modules will allow you to get the absolute best results.
    Basically, what we're doing here is the same thing as the CCP module is doing when operating in capture mode except that we are polling the input pins in software in order to determine when to "capture" the timers value while that's being done all in hardware when using the CCP module.

    Polling the inputs like in my example will always introduce some latency, jitter etc. You said your preferred hardware for this was the good old 628/648 (which only got one CCP module) so that's what I tried to do :-)

    /Henrik.

  15. #15
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Ok,

    Super big thanks Henrik for helping me get this working on a 16F648A!

    It seems to do ok, but of course I can’t leave well enough alone.

    The 16F648A code does what I need, but has some “quarks” I assume are due to the polling. Like if I run the same signal into both capture pins, the times are different by a bit, which I would think comes from the fact one pin is getting polled later than the other, which is fine, I can live with it.

    But wanting to learn more about interrupts and timers, I tried taking the code for 18F chips using Darrel’s instant interrupts that Bruce did in the post here: http://www.picbasic.co.uk/forum/show...se+measurement and combining it with the code that Henrik provided.

    This is what I have so far for an 18F2320, 20MHz HS, 2.60C, All configs set properly (off , input pin, etc.):

    Code:
    DEFINE NO_CLRWDT 1
    DEFINE OSC 20
    DEFINE HSER_BAUD 9600
    DEFINE HSER_TXSTA 20h
    
    TrigOut VAR PortB.3
    
    Time1 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse2
    Time2 VAR WORD                      ' Time between leading edge of Pulse1 and leading edge of Pulse3
    Measure VAR BIT                     ' Semaphore to indicate when we want to start a measurment.
    OverFlows  VAR BYTE                 ' Timer1 overflow total
    
    
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    
    ;----[High Priority Interrupts]----------------------------------------
    ASM
    INT_LIST  macro    ; IntSource,   Label,   Type, ResetFlag?
            INT_Handler   TMR0_INT,  _SixtyHz,   PBP,  yes
            INT_Handler   CCP1_INT,  _Capture1,  PBP,  yes
            INT_Handler   CCP2_INT,  _Capture2,  PBP,  yes
    	    INT_Handler   TMR1_INT,  _Timer1,    PBP,  yes
        
    	endm
        INT_CREATE               ; Creates the High Priority interrupt processor
    ENDASM
    
    CCP1CON = %00000101  ' Capture1 mode, capture on rising edge
    CCP2CON = %00000101  ' Capture2 mode, capture on rising edge
    T0CON = %11000111    ' Prescaler assigned to TMR0, 1:256 ratio
    T1CON = 0            ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
    
    @    INT_ENABLE TMR0_INT ; Enable the 120Hz interrupt for the square wave generator.
    
    Main:    
        Gosub Capture
        IF T1CON.0 = 0 THEN ' If done, show result
          hserout ["Timer Overflows = ",DEC OverFlows]
          hserout [" Remaining ticks = ",dec time1]
          hserout [" Remaining ticks = ",dec time2,13,10]
        ENDIF
        PAUSE 2000
        GOTO Main
    
    '-------------------------------------------------------------------------------
    Capture:
        Measure = 1
        While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
        @    INT_ENABLE  CCP1_INT       ; Start new capture
        Measure = 1
        While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
        @    INT_ENABLE  CCP2_INT       ; Start new capture
        RETURN
    '-------------------------------------------------------------------------------
    
    
    '---[CCP1 - interrupt handler]------------------------------------------
    Capture1:
         
         Time1.LowByte = TMR1L     ; Get remaining Timer1 counts 
         Time1.HighByte = TMR1H
    
    '---[CCP2 - interrupt handler]------------------------------------------
    Capture2:   
    
         Time2.LowByte = TMR1L     ; Get remaining Timer1 counts 
         Time2.HighByte = TMR1H
    @ INT_RETURN
    
    '---[TMR1 - interrupt handler]---------------------------------------------
    Timer1:
        OverFlows = OverFlows + 1
    @ INT_RETURN
    
    '-------------------------------------------------------------------------------
    SixtyHz:
    If TrigOut = 0 THEN                 ' If trig output is low....
        If Measure = 1 THEN             ' ...and we want to start a measurment
            T1CON.0 = 0 : PIR1.0 = 0    ' Stop timer and clear interrupt flag
            TMR1H = 0 : TMR1L = 0       ' Clear the time
            Time1 = 0 : Time2 = 0       ' Clear measurements
            T1CON.0 = 1                 ' And start the timer
            Measure = 0                 ' Let main program know we've set the ball in motion.
        ENDIF
        TrigOut = 1                     ' Set trig output high
    ELSE
        TrigOut = 0                     ' Trig output was high, set it low.
    ENDIF
       
    TMR0 = TMR0 + 94                    ' Reload TMR0 for 120Hz interrupt rate
    @ INT_RETURN
    '-------------------------------------------------------------------------------
    
    
         END
    It compiled the first time with an error about TMR0 not being defined, so I edited the .INC file and got around that, but of course it still doesn’t work. No 60Hz square wave out and no serial output.

    Anyone care to have a gander at my code and tell me what I’m doing wrong? Point and laugh?? Poke at me with a stick???

    Huge thanks as always!

    -Ryan

  16. #16
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi Ryan,
    Like if I run the same signal into both capture pins, the times are different by a bit, which I would think comes from the fact one pin is getting polled later than the other, which is fine, I can live with it
    Yes, that's correct.

    I think you're trying to bite off a bit too much at a time with this new version.
    I'd start by getting the serial output going without any interrupts or anything, a simple Hello World kind of thing.
    Then I'd get a LED blinking on what will eventually be the 60Hz output, just so you know you have control over that pin.
    Then I'd get the TMR0 interrupt going.
    Then.... ah you get the picture ;-)

    For example, PortB.3 (your 60Hz output) is an ADC input and it "comes up" in analog mode, I don't see you setting it to digital (see ADCON1 register).
    You say "All configs set properly" but I don't see you setting any TRIS register in the code. All pins comes up as inputs, TRIS bit needs to be cleared for them to become outputs.

    /Henrik.

  17. #17
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Alright, you caught me!

    I wrote that, or rather pieced it together when I should have been going to bed for the evening. It does have the typical “noob” mistakes of not turning the analog inputs off and setting TRIS for my output pins and probably a few more mistakes!

    I have a bad habit of tackling this stuff right before bed, figuring I can get things off my mind before trying to sleep with ideas bouncing around in there. Then I start racing the clock and trip myself up. I’m an electronics technician by profession, but it’s actually mostly high voltage and tubes for me. I don’t get to do as much programming unless it’s my own stuff, after work.

    Another problem is that, as you can see by my forum join date, I’ve been using PicBasic Pro a few years now. But I only work on PIC based projects once every few months, sometimes longer. And as they say: if you don’t use it…

    But that said I’ve done all sorts of complex projects with PicBasic Pro, from thermostats with one-wire sensors and LCD readouts to all kinds of PWM motor and lighting controllers, robots, etc. I’ve just always found ways around using scary interrupts and timers. But I guess that’s what separates the men from the boys.

    I tend to use SEROUT over HSEROUT because it doesn’t require outside help to communicate directly with the serial port on my PC. And I did remember that when trying to run your code the first time and gibberish was appearing in hyperterminal . I just inverted it with a 4049 and all was well. So a “hello world” I can handle.... I hope!

    I’ll start again and try to work on a bit at a time (smaller bytes ) and maybe get it working. But I think I’m having trouble wrapping my little brain around Interrupts. I mean I understand the basics of it. Like: when pin 1 sees signal X, jump to Y routine without regard to what the program was doing, and then return to that point in the program when the ISR is satisfied. But in the context of actual code, I’m clueless.
    Like:
    Code:
    Capture:
    	    Measure = 1
    	    While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
    	    @    INT_ENABLE  CCP1_INT       ; Start new capture
    	    Measure = 1
    	    While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
    	    @    INT_ENABLE  CCP2_INT       ; Start new capture
    	    RETURN
    Isn’t this the same as polling kind of sort of? Why would I want to do that? Am I even supposed to be doing that?! Does it really matter if CCP2 gets a read of the counter before CCP1? On and on…

    Anyway, I’ll play around with it until I either figure it out or get tired and go back to hiding from the hard stuff!

    Thanks Again!
    Ryan

  18. #18
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi Ryan,
    I wrote that, or rather pieced it together when I should have been going to bed for the evening. It does have the typical “noob” mistakes of not turning the analog inputs off and setting TRIS for my output pins and probably a few more mistakes!

    I have a bad habit of tackling this stuff right before bed, figuring I can get things off my mind before trying to sleep with ideas bouncing around in there. Then I start racing the clock and trip myself up. <snip>
    Yes, I think we're all guilty of the above now and then ;-)

    Another problem is that, as you can see by my forum join date, I’ve been using PicBasic Pro a few years now. But I only work on PIC based projects once every few months, sometimes longer. And as they say: if you don’t use it…
    That's the situation in my case as well. It can go months without me working on a particular project. However, what I do is visit this forum (and the MELABS forum (though it's pretty silent most of the time)) and trying to help other members with their issues, discuss implementation ideas etc. Doing that helps me remember what I've learned and learn a lot of new stuff.

    But that said I’ve done all sorts of complex projects with PicBasic Pro, from thermostats with one-wire sensors and LCD readouts to all kinds of PWM motor and lighting controllers, robots, etc. I’ve just always found ways around using scary interrupts and timers. But I guess that’s what separates the men from the boys.
    Not at all. Everything is hard (more or less) until you know how to do it. Interrupts are no different but Darrel has really made a BIG difference with the DT-INTS routines. It makes it really quite easy without the drawbacks of ON INTERRUPTS, though it does have it drawbacks which you'll also get familiar with over time.

    I tend to use SEROUT over HSEROUT because it doesn’t require outside help to communicate directly with the serial port on my PC. And I did remember that when trying to run your code the first time and gibberish was appearing in hyperterminal .
    Nothing wrong with SEROUT but you really "should" get up to speed with using HSEROUT, especially so now when you start introducing interrupts because once you do your SEROUT will basically stop working (if you don't see to it that an interrupt will NOT fire while the PIC is executing the SEROUT). I've got a couple of different development boards and they all got level translators (MAX232 etc) and/or a FTDI USB<->RS232 chip on them so I usually don't need to do anything special. When breadboarding (as I did with this code) I've got this thing which makes it really easy.

    Code:
    Capture:
    	    Measure = 1
    	    While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
    	    @    INT_ENABLE  CCP1_INT       ; Start new capture
    	    Measure = 1
    	    While Measure = 1 : WEND        ' Wait until ISR has created the rising edge and started the timer
    	    @    INT_ENABLE  CCP2_INT       ; Start new capture
    	    RETURN
    Isn’t this the same as polling kind of sort of? Why would I want to do that? Am I even supposed to be doing that?! Does it really matter if CCP2 gets a read of the counter before CCP1? On and on…
    I'm not sure I understand. You're polling the Measure flag but you're not polling the actual input(s). However, the way you have it written above it will first measure the time between the trig pulse and the first pulse. Then it will sit there and wait for the next trig pulse and THEN measure the time between THAT trig pulse and the second pulse. What you probably want to do is enable the CCP interrupts from the SixtyHz interrupt routine and (again probably) get rid of the Capture subroutine alltogether.

    /Henrik.

  19. #19
    Join Date
    Jun 2009
    Location
    Sc*nthorpe, UK
    Posts
    333


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    TrigOut VAR PortB.3
    TrigOut is your output but you have not set TRIS register as output for this pin?
    Last edited by EarlyBird2; - 29th August 2014 at 09:33.

  20. #20
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Ok,

    Just focusing on getting 60Hz out of the thing. kind of left the other code in there knowing it probably won't work completely until I rewrite it, but....

    I fixed ADCON1 (= 7) and TRISB to output on B.3 and now I have a pulse! The only problem is that it seems to be 38.1Hz

    Not knowing what "TMR0 = TMR0 + 94" for me is doing exactly (maybe preloading timer 0 so it overflows earlier or something?) and it has a nice integer there to play with, I changed it to various things, but no difference in the 38.1Hz.

    Should I be playing with the prescaler value or something? I figure as long as the oscillator is still 20MHz, it should be the same I know pretty much nothing when it comes to our timer friends.

    My next plan is to maybe get the working code for the 16F648A ported over and seeing if that will work on an 18F with the 18F DTII stuff and go from there.

    Thanks for taking the time to help me out!

  21. #21
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Hi Ryan,
    I fixed ADCON1 (= 7) and TRISB to output on B.3 and now I have a pulse! The only problem is that it seems to be 38.1Hz
    That 38.1Hz tells me that your interrupt rate is 76.2(939)Hz, which is exactly what you get when you have 16bit timer free-running at 5MHz. (20Mhz / 4 / 2^16).

    On the 16F648 TMR0 is 8 bits wide with an 8bit prescaler shared with the WDT....
    On the 18F2320 TMR0 is configurable to be either 8 bit OR 16 bit wide with its own dedicated 8 bit prescaler.

    Going by your description alone and not seeing the actual code my guess is you've got the timer configured in 16 bit mode. That'll work too but the code needs to be changed to use the full 16 bit timer instead of the 8bit timer AND 8bit prescaler of the 16F648.

    Not knowing what "TMR0 = TMR0 + 94" for me is doing exactly (maybe preloading timer 0 so it overflows earlier or something?) and it has a nice integer there to play with, I changed it to various things, but no difference in the 38.1Hz.
    Yes exactly. In the original code where we had a 8 bit timer, "restarting" the timer at value of 94 each interrupt (which isn't REALLY what happens but it's easier to understand) will cause it to overflow in 162 ticks (256-94) instead 256 ticks. With a a 16bit timer running at 5MHz, "restarting" the timer at 94 to in the ISR will only change the interrupt rate by approximately 0.11Hz which is probably why you think you don't see it change.

    /Henrik.
    Last edited by HenrikOlsson; - 3rd September 2014 at 22:09.

  22. #22
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    I have TMR0 set to 8 bit mode actually T0CON = %11000111.

    Changing the prescaler to either 128 or 64 seemed to speed it up. I can't seem to get to 60Hz no matter what I do.

    I tried porting over your working code from the 16F648A and using DT_INTS-18 instead of 14, but get a whole bunch of compiler errors.

    I notice that the code Bruce wrote using DT_INTS-18 didn't include the wsave varibles that the DT_INTS-14 looks to require?

    I know I have workable code and should just leave it alone, but I want to learn how to make this work with CPP on the 18F2320.

    As always, thank you!

    Haven't tried this yet, but maybe it will work?:

    Code:
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    
    DEFINE OSC 20                       ' Running with a 20MHz x-tal
    
    ' #CONFIG - doing this manually at the moment via programmer
    
    ADCON1 = 7
    
    TRISB = %11110111                   ' Set PortB direction.
    
    T0CON = %11000111                 ' Prescaler assigned to TMR0, 1:256 ratio
    
    TrigOut VAR PortB.3                   ' Pin for 60Hz output
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR0_INT,  _ISR,   PBP,  yes
        endm
        INT_CREATE                      ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR0_INT         ; Enable the 120Hz interrupt for the square wave generator.
    
    Main:
        Pause 2000
                 HSEROUT["Is This Working???",10,13]
    Goto Main
    
    ISR:
    If TrigOut = 0 THEN                 ' If trig output is low....
       TrigOut = 1                         ' Set trig output high
    ELSE
        TrigOut = 0                        ' Trig output was high, set it low.
    ENDIF
    TMR0 = TMR0 + 94                    ' Reload TMR0 for 120Hz interrupt rate
    @ INT_RETURN
    '-------------------------------------------------------------------------------

  23. #23
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    For 60Hz.
    Set Timer0 to 16 Bit with a 1:8 prescale
    Add this to your variable section
    Code:
    PreLoad     VAR WORD
    PreLoad = 23868
    and in the ISR routine
    Code:
    TMR0L = PreLoad.LowByte  
    TMR0H = PreLoad.HighByte
    I think...
    Dave
    Always wear safety glasses while programming.

  24. #24
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Thanks Dave!

    This is what is actually working for me thus far! At least some success:

    Code:
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
    
    DEFINE OSC 20                           ' Running with a 20MHz x-tal
    DEFINE HSER_BAUD 9600
    DEFINE HSER_TXSTA 20h
    
    @ __CONFIG    _CONFIG1H, _HS_OSC_1H & _FSCM_OFF_1H & _IESO_OFF_1H
    @ __CONFIG    _CONFIG2L, _PWRT_OFF_2L & _BOR_OFF_2L
    @ __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
    @ __CONFIG    _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
    @ __CONFIG    _CONFIG3H, _CCP2MX_OFF_3H & _PBAD_DIG_3H & _MCLRE_OFF_3H 
    
    ADCON1 = 7
    
    TRISB = %11110111                   ' Set PortB direction.
    
    T0CON = %10000001                  ' 16 bit Prescaler assigned to TMR0, 1:4 ratio
    
    TrigOut VAR PortB.3                    ' Pin for 60Hz output
    PreLoad     VAR WORD
    PreLoad = 52000
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR0_INT,  _ISR,   PBP,  yes
        endm
        INT_CREATE                          ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR0_INT          ; Enable the 120Hz interrupt for the square wave generator.
    
    Main:
        Pause 2000
                 HSEROUT["Is This Working???",10,13] ' The lights are on... is anyone home?
    GOTO Main
    
    ISR:
    IF TrigOut = 0 THEN                 ' If trig output is low....
       TrigOut = 1                          ' Set trig output high
    ELSE
        TrigOut = 0                         ' Trig output was high, set it low.
    ENDIF
    TMR0L = PreLoad.LowByte       ' TMR0 High and low bytes preloaded
    TMR0H = PreLoad.HighByte
    @ INT_RETURN
    GOTO main:
    Now to add to it

  25. #25
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Sorry to keep beating on this post! I just really want to figure this out and having support is nice. Also, this is what I do on my lunch break ha-ha... So I write everthing in notepad, post it here and then I can cut and paste to my IDE when I get home

    Anyone care to look and maybe do a little bug hunting? I'm probably doing something wrong here. Something feels funny about having interrupts enable other interrupts. Maybe something will go wrong when those interrupts return? I'm not used to "Main" sitting there twirling away and then having my TMR0 doing it's own thing, which also happens to the be the starting point for all the real work.

    But what i think should happen is: each time the PulseGen ISR fires off a rising edge, it will start by intializing everything and then it will start TMR1 ticking and look to see which CCP interrupt was last enabled, and if the first one wasn't, it will enable it and mask it so it doesn't get selected the next go around. When CCP1 gets a rising edge, it will stop TMR1, disable itself and TMR1 interrupts, get the count from TMR1 into a variable and return (uh-oh...)

    If all goes to plan, it will start over and do the same with CCP2 and unmask CCP1 for the next round.

    My worries are since all this is happening from the TMR0 PulseGen interrupt, its timing will be at the mercy of those CCP and TMR1 interrupts... Also where those interrupts are getting returned to. Is that a safe place? Will it continue to skip out of the IF THEN ELSE traps and allow PulseGen to continue on? Maybe a GOTO PulseGen: added to the return points???

    Interrupts are hard on the brain!

    Thanks again!!! I promise once I get this going as desired I will give a full disclosure as to what it's for - some of you might find a good use for it. Oh, and I'll shut up and go away for a while

    Code:
    INCLUDE "DT_INTS-18.bas"       		' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"     	' Include if using PBP interrupts
    
    DEFINE OSC 20                           ' Running with a 20MHz x-tal
    DEFINE HSER_BAUD 9600
    DEFINE HSER_TXSTA 20h
    
    @ __CONFIG    _CONFIG1H, _HS_OSC_1H & _FSCM_OFF_1H & _IESO_OFF_1H
    @ __CONFIG    _CONFIG2L, _PWRT_OFF_2L & _BOR_OFF_2L
    @ __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
    @ __CONFIG    _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
    @ __CONFIG    _CONFIG3H, _CCP2MX_OFF_3H & _PBAD_DIG_3H & _MCLRE_OFF_3H 
    
    ADCON1 = 7				' Turn off analog inputs
    TRISB = %11110111                   	' Set PortB direction.
    T0CON = %10000001                  	' TMR0 16 bit Prescaler 1:4 ratio
    T1CON = %00000000			' TMR1 prescale 1:1 clock=Fosc/4, TMR1=off (200nS per count @20MHz)
    CCP1CON = %00000101  			' CCP1 Capture mode, capture on rising edge
    CCP2CON = %00000101  			' CCP2 Capture mode, capture on rising edge
    
    TrigOut    VAR PortB.3                  ' Pin for 60Hz output
    OverFlows  VAR BYTE 			' Timer1 overflow total
    Remainder1  VAR WORD 			' Remaining Timer1 ticks after first pulse capture
    Remainder2  VAR WORD 			' Remaining Timer1 ticks after second pulse capture
    FirstCapt  VAR BIT : FirstCapt = 0
    PreLoad    VAR WORD : PreLoad = 52000   ' Preload TMR0 for 120Hz interrupt rate
    
    
    ;----[High Priority Interrupts]-------------------------------------------------------------------
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR0_INT,  _PulseGen, PBP,  yes
            INT_Handler    TMR1_INT,  _Timer1,   PBP,  yes
            INT_Handler    CCP1_INT,  _Capture1, PBP,  yes
            INT_Handler    CCP2_INT,  _Capture2, PBP,  yes
        endm
        INT_CREATE                          ' Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR0_INT          		' Enable the 120Hz interrupt for the square wave generator.
    
    '-------------------------------------------------------------------------------------------------
    
    '---[Main Routine]--------------------------------------------------------------------------------
    
    Main:
         IF T1CON.0 = 0 THEN 		' If TMR1 done, show result
    	HSEROUT["Timer Overflows = ",DEC OverFlows,"Ticks 1 = ",DEC Remainder1,"Ticks 2 = ",DEC Remainder2,10,13] 
         ENDIF
    GOTO Main:
    
    '-------------------------------------------------------------------------------------------------
    
    '---[TMR0 - Interrupt handler / 60Hz Squarewave Trigger Pulse Generator]--------------------------
    
    PulseGen:
       IF TrigOut = 0 THEN			' If trig output is low....
         TrigOut = 1                        ' Set trig output high
         TMR1L = 0                     	' Clear Timer1 Low Byte count
         TMR1H = 0     			' Clear Timer1 High Byte counts
         T1CON.0 = 1                   	' Turn Timer1 on at rising edge capture
         OverFlows = 0                 	' Clear over flow counts
         Remainder = 0                 	' Clear remainder
         PIR1.0 = 0                    	' Clear Timer1 overflow flag before enable
    @    INT_ENABLE  TMR1_INT         	' Enable Timer 1 Interrupts 
         IF FirstCapt = 0 THEN              ' If first pulse hasn't been looked for yet...
            FirstCapt = 1                   ' Mark it as such and...
    @    INT_ENABLE  CCP1_INT               ' Start looking for 1st pulse
         ELSE
         FirstCapt = 0                      ' Reset first pulse search mask and... 
    @    INT_ENABLE  CCP2_INT               ' Start looking for 2st pulse
         ENDIF
    ELSE
         TrigOut = 0                        ' Trig output was high, set it low.
    ENDIF
    
    TMR0L = PreLoad.LowByte       		' TMR0 High and low bytes preloaded
    TMR0H = PreLoad.HighByte
    @ INT_RETURN
    
    '-------------------------------------------------------------------------------------------------
    
    '---[CCP1 - interrupt handler]--------------------------------------------------------------------
    
    Capture1:
         T1CON.0 = 0                   	' Stop Timer1
    @    INT_DISABLE  TMR1_INT    		' Disable Timer 1 Interrupts
    @    INT_DISABLE  CCP1_INT    		' Disable CCP1 Interrupts
         Remainder1.LowByte = TMR1L    	' Get remaining Timer1 counts
         Remainder1.HighByte = TMR1H
    @ INT_RETURN
    
    '-------------------------------------------------------------------------------------------------
    
    '---[CCP2 - interrupt handler]--------------------------------------------------------------------
    
    Capture2:
         T1CON.0 = 0                   	' Stop Timer1
    @    INT_DISABLE  TMR1_INT    	   	' Disable Timer 1 Interrupts
    @    INT_DISABLE  CCP2_INT         	' Disable CCP2 Interrupts
         Remainder2.LowByte = TMR1L    	' Get remaining Timer1 
         Remainder2.HighByte = TMR1H
    @ INT_RETURN
    
    '-------------------------------------------------------------------------------------------------
    
    '---[TMR1 - interrupt handler]--------------------------------------------------------------------
    Timer1:	
        OverFlows = OverFlows + 1      	' Count the number of times TMR1 overflows
    @ INT_RETURN
    
    '-------------------------------------------------------------------------------------------------
    
    GOTO Main:
    
    END

  26. #26
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    A quick read through your code and I do not see a problem. So the big question...
    Does it work as expected?
    If so Then NoProblem...
    Dave
    Always wear safety glasses while programming.

  27. #27
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Re: Trying to measure time between two pulses on different pins.

    Nope,

    It didn't work. I did catch a few mistakes as soon as I posted that. Like needing to comment my assembly stuff with ";" for example. And never flipping "FirstCapt" back after looking for the second pulse. And I had to play with the TMR0prescaler some more. The code I posted before this was running at 120Hz instead of 60Hz.

    I think I would have to find a way to keep proper order and timing of when my interrupts fire. When I corrected the above mistakes and ran that code, my output varibles would lock onto a certain value and stay that way. Almost as if the CCPs were firing as soon as their interrupts were enabled. I tried all sorts of stuff and never had any luck with getting it to all work together.

    I ended up using what Henrik had come up with for the 16F648A, I just got it to work on the 18F2320 and rolled in capturing with the CCP modules instead of the port B pins. It samples both CCPs 5 times, averages the results and breaks one of them out into 16 discrete "levels" before outputing via HSER.

    I need to tweak some things yet. But I'll post what I came up with soon and explain what it's for.

Similar Threads

  1. Measure time in mS between two pulses
    By Fredrick in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 7th March 2011, 08:20
  2. time measurement between 2 pulses
    By xvladx in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 27th April 2010, 18:33
  3. calculate time between pulses
    By hell_pk in forum mel PIC BASIC Pro
    Replies: 19
    Last Post: - 20th October 2007, 17:49
  4. Count pulses between VARIABLE TIME
    By RodSTAR in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 15th October 2007, 13:44
  5. Timed pulses on 2 pins
    By Danie Joubert in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 15th March 2004, 08:38

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