Measuring audio phase shift through a circuit with a PIC


Closed Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 50
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default Measuring audio phase shift through a circuit with a PIC

    Need a sanity check here.

    I'd like to measure the phase shift through an audio circuit at different test frequencies, therefore to measure this with a PIC.

    In principle it's fairly simple - ie time a an audio signal for one complete cycle, store the result, immediately start timing how long until the output signal gets to the same point (ie use a comparator for both signals). Do some maths with the resulting times...this will yield the phase shift in degrees.

    I've setup something along these lines.

    (the input to my audio circuit is fed into the PIC comparator1, the output of my audio circuit feeds comparator2. Also timer1 is mapped to comparator 1, an timer2 is mapped to comparator 2 from a 'clock counting' perspective)

    ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++
    enable comparator1 interrupts

    when comparator1 interrupts, start timer1 running

    when comparator1 interrupts again, do the following....

    stop timer1 running & store the 'count' (this gives a clock pulse 'count' for the arriving frequency, but since I'm only after phase shift...which is a time based measurement, I don't calculate the frequency)

    clear timer2
    start timer2
    enable comparator2 interrupts

    Ok, now when comparator2 interrupts, stop timer2 & store the count



    My problem is that I can't seem to get the count of timer2 up in count value (no matter what I do with the prescalers) .

    For example I know the phase of the input vs output for my circuit 180 degrees out of phase (I can see this on my scope - it's a simple inverting opamp setup to test this all out), but I'm getting readings like this...

    comp1=2434 comp2=151
    comp1=2432 comp2=151
    comp1=2431 comp2=151
    comp1=2431 comp2=151
    comp1=2433 comp2=151
    comp1=2432 comp2=151
    comp1=2433 comp2=151
    comp1=2432 comp2=151


    Now for a signal that is 180 degrees out phase, I reckon comparator 2 should interrupt 'in or around' half the time that timer1 counted.

    Is my methodology wrong, is is my code wrong?

    (the prescalers prob aren't right below, but my issue is that no matter what I set the prescalers to, the second timer2 count (ie the inverted signal) never get's anythere near 50% of timer1)



    Code:
    @ __CONFIG _FCMEN_OFF & _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF
    '***********************************************************************************************
    
    '16F690 Pin Connections....
    ' PIN# NAME     USE & CONNECTION
    '  1   Vdd      +5VDC power supply   
    '  7   RC3      C12IN3- (external comparator1 input)
    '  14  RC2      C12IN3- (external comparator2 input)     
    '  20  Vss      Ground
    '*************************************************************************************
    DEFINE  OSC 8          ' set Oscillator at 8Mhz.
    DEFINE  NO_CLRWDT 1 
      
    DEFINE HSER_SPBRG 25   'HSEROUT Stuff.
    DEFINE HSER_TXSTA 24h  'HSEROUT Stuff.
    DEFINE HSER_CLROERR 1  'HSEROUT Stuff.
    
    txsta = %10100100       'setup the tx register
    RCSTA.7 = 1             ' Enable RB7 for TX USART
    INTCON.0 = 0            ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
    ANSEL      = 0    'disable AtoD.
    ANSELH     = 0    'disable AtoD.
    
    'Turn on & Set up Comparator 1
    CM1CON0 = %10100111    'Comparator1 On
    VRCON = %0000001       'turn on internal reference
    
    
    'Turn on & Set up Comparator 2
    CM2CON0 = %10100110   'turn on comparator 2.
    
    Comp1Time          var  word    ' used to amalgamate TMR1 High & Low Bytes.
    Frequency       var  word    'used to convert the count to frequency.
    Comp2Time  VAR WORD
    PHASE           var   word
    
              
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System  PO90OOO9
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   CMP1_INT,  _Comp1_Int,   PBP,  yes
            INT_Handler   CMP2_INT,  _Comp2_Int,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    T1CON = $10               ; 
    
    T1CON.0=0 'stop tmr1
    TMR1H = 0 'Set the high part of the timer1 value to 0
    TMR1L = 0 'Set the low part of the timer1 value to 0
    
    @ INT_ENABLE  CMP1_INT     ; enable Comparator 1 interrupts
    
    t2con = %00000000010 ' tmr2 prescaler 16
    TMR2 = 0 'Set the high part of the timer2 value to 0
    
    Comp1Time = 0 'clear down Comp1Time, prior to starting.
    comp2Time = 0  'clear down Comp2Time, prior to starting
    
    'Main body of Code*********************************************************************************************
    Main:
            HSEROUT ["comp1=", dec Comp1Time,9, "comp2=", dec comp2Time,13, 10]
            pause 10
            goto Main
            end
       
    'Comparator1 Interrupt Handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
    Comp1_Int:
    
            if T1CON.0= 0 then 'if timer1 is not running then...
            TMR1H = 0 'Set the high part of the timer value to 0
            TMR1L = 0 'Set the low part of the timer value to 0 
            T1CON.0= 1  'start timer
            else        'therefore if it is running, stop the timer & calculate the number of 'clock' counts between comparator interrupts....
            T1CON.0= 0  'stop tmr1
            TMR2 = 0    'clear tmr2
            T2CON.2= 1  'start tmr2
    @ INT_ENABLE  CMP2_INT  
            Comp1Time.Lowbyte = TMR1L 'puts the timer's low byte in Comp1Time's lower 8 bits 
            Comp1Time.Highbyte = TMR1H 'puts the timer's high byte in Comp1Time's upper 8 bits
    
            endif 
    @ INT_RETURN
    
    'Comparator2 Interrupt Handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
    Comp2_Int:
    @ INT_DISABLE  CMP2_INT 
            T2CON.2= 0 'stop timer2
            Comp2Time = tmr2
    @ INT_RETURN
    Last edited by HankMcSpank; - 5th September 2010 at 00:29.

  2. #2
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    I haven't checked your code, but, from the description, I think you need to look at it differently to get the correct results. Try it this way.

    enable comparator1 and 2 interrupts

    when comparator1 interrupts,
    clear timer1
    clear timer2
    start timer1 and timer 2 running

    when comparator1 interrupts again, do the following....

    stop timer1 running & store the 'count' (this gives a clock pulse 'count' for the arriving frequency, but since I'm only after phase shift...which is a time based measurement, I don't calculate the frequency)

    when comparator2 interrupts, stop timer2 & store the count

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    I haven't checked your code, but, from the description, I think you need to look at it differently to get the correct results. Try it this way.

    enable comparator1 and 2 interrupts

    when comparator1 interrupts,
    clear timer1
    clear timer2
    start timer1 and timer 2 running

    when comparator1 interrupts again, do the following....

    stop timer1 running & store the 'count' (this gives a clock pulse 'count' for the arriving frequency, but since I'm only after phase shift...which is a time based measurement, I don't calculate the frequency)

    when comparator2 interrupts, stop timer2 & store the count
    Thanks for you input....seems reasonable - I'll be revisiitng this tonight (last night I got waylaid trying to get PIC to control a digital pot via SPI .....failed - http://www.picbasic.co.uk/forum/show...3540#post93540 )

    Using your revised approach, I reckon to calculate the phase change it's this....

    time lag (ie phase difference) = timer2 - timer1

    then to work out the phase ....time lag x 360/timer1/


    So an example, lets say timer1 = 2000 & timer2 = 2,200

    this would give a difference (time lag) of 200 clock pulses

    Now bearing in mind timer1 = 360 degrees (one complete cycle)

    Therefore to establish out how many single degrees of phase...

    200 * 360 /2000 ....which means in this example the phase shift is a 36 degrees lag.


    Putting that into actual frequency ....

    clock = 2us
    one 'wave' period = 2000 x 2us = 4ms
    In Hertz = 1/0.004 = 250hz

    time lag of second waveform = 200 x 2us = 400us

    Now being lazy, to verify, using an online phase calculator & inputing 250Hz & a lag time of 400us...

    http://www.sengpielaudio.com/calcula...delayphase.htm

    = 36 degrees.
    Last edited by HankMcSpank; - 7th September 2010 at 10:28.

  4. #4
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    I haven't checked your code, but, from the description, I think you need to look at it differently to get the correct results. Try it this way.

    enable comparator1 and 2 interrupts

    when comparator1 interrupts,
    clear timer1
    clear timer2
    start timer1 and timer 2 running

    when comparator1 interrupts again, do the following....

    stop timer1 running & store the 'count' (this gives a clock pulse 'count' for the arriving frequency, but since I'm only after phase shift...which is a time based measurement, I don't calculate the frequency)

    when comparator2 interrupts, stop timer2 & store the count
    Actually, just re-reading your sequence - that sequence will give me the lag time direct (eg wrt a small phase lag, then comp2 will interrupt shortly after comp1)

    the upper frequency that I'm hoping to measure phase shift is about 1.4Kz - a 1 deg phase shift in time for 1.4Khz is just 2us (ie 1/1440 divided by 360). At 8Mhz Osc, I'm not sure there'll be sufficient time to do much at all before the Comp2 interrupt arrives!

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok. I've hit a wall - & I can't get passed it - I need a leg up!

    Te recap, I'm using a PIC to measure frequency (80Hz thru 1.4Khz) by counting the number of clock pulses between successive comparator interrupts. It works well.

    I now need to measure phase shift .....but how to actually use the PIC hardware options available, to detect the amount of clock pulse between the non phase shifted signal & phase shifted signal's leading edges?

    Here's a schematic of my test circuit...



    I detect frequency as follows...

    DT's Comp1 interrupt - start a timer
    DT's Comp1 interrupts again - stop a timer.

    so want to add in phase shift detect by bringing in another timer and measuring the clock counts until the second (lagging) signal's leading edge arrives, therefore the enlarged picture....

    Comp1 interrupt - start a timer
    Comp1 interrupts again - stop a timer.
    start another timer
    second (phase shifted) signal's leading edge arrives - stop the other timer.




    here's the bit I'm using for frequency detection (for clarity I've ommited the config/registers as this bit works)...

    Code:
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System  PO90OOO9
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   CMP2_INT,  _Comp2_Int,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE  CMP1_INT     ; enable Comparator 1 interrupts
    @ INT_ENABLE  CMP2_INT     ; enable Comparator 1 interrupts
    
    Comp1Time = 0 'clear down Comp1Time, prior to starting.
    comp2Time = 0  'clear down Comp2Time, prior to starting
    
    'Main body of Code*********************************************************************************************
    Main:
    
            HSEROUT ["comp2=", dec comp2Time,9,"comp1=", dec Comp1Time, 13, 10]
            goto Main
            end
       
    'Comparator1 Interrupt Handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
    Comp2_Int:
            if T1CON.0= 0 then 'if timer1 is not running then...
            TMR1H = 0 'Set the high part of the timer value to 0
            TMR1L = 0 'Set the low part of the timer value to 0 
            T1CON.0= 1  'start timer
            else        
            T1CON.0= 0  'stop timer1
            Comp2Time.Lowbyte = TMR1L            'puts the timer's low byte in Comp1Time's lower 8 bits 
            Comp2Time.Highbyte = TMR1H           'puts the timer's high byte in Comp1Time's upper 8 bits
            Comp2Time = Comp2Time
            endif
    @ INT_RETURN
    but when I add in a little bit extra (bolded below in red), the HSEROUT chokes....
    Code:
    @ INT_ENABLE  CMP1_INT     ; enable Comparator 1 interrupts
    @ INT_ENABLE  CMP2_INT     ; enable Comparator 1 interrupts
    
    Comp1Time = 0 'clear down Comp1Time, prior to starting.
    comp2Time = 0  'clear down Comp2Time, prior to starting
    
    'Main body of Code*********************************************************************************************
    Main:
    
            HSEROUT ["comp2=", dec comp2Time,9,"comp1=", dec Comp1Time, 13, 10]
            goto Main
            end
       
    'Comparator1 Interrupt Handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
    Comp2_Int:
            if T1CON.0= 0 then 'if timer1 is not running then...
            TMR1H = 0 'Set the high part of the timer value to 0
            TMR1L = 0 'Set the low part of the timer value to 0 
            T1CON.0= 1  'start timer1
            else        
            T1CON.0= 0  'stop timer1
            TMR2 = 0 'clear tmr2
            T2CON.2 = 1  'start tmr2
            Comp2Time.Lowbyte = TMR1L            'puts the timer's low byte in Comp1Time's lower 8 bits 
            Comp2Time.Highbyte = TMR1H           'puts the timer's high byte in Comp1Time's upper 8 bits
            Comp2Time = Comp2Time
            endif
    @ INT_RETURN
    
    Comp1_Int:  ' store the amount of clock pulses elapsed since routine above finished
            T2CON.2 = 0
            COMP1TIME = TMR2
            TMR2= 0
    @ INT_RETURN
    Last edited by HankMcSpank; - 11th September 2010 at 15:43.

  6. #6
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Hi Hank

    I'm sorry, I did not reply earlier. I thought you would find a way

    Ok, I will not get into the code you wrote nor will I write some, but, this is how I do a phase comparison on my projects. A 16 bit timer is free running all the time. No start/stop sequences. Comparator interrupts too are always enabled. No need to start/stop them. Remember Timer always counts up and rolls over, so CurrTimer nearly always is > PrevTimer. On rollover, the result of CurrTimer-PrevTimer is still valid since the bits are limited to a word size. So, 1000-500 is still same as 465-65500 (+ 1) when you do the 16 bit subtract.

    Define CurrTimer TMR1 ' alias CurrTimer as timer1
    PrevTimer var word
    FreqCount var word
    PhaseCount var word

    On comp1 interrupt
    FreqCount = CurrTimer - PrevTimer ' timer ticks between 2 edges of the same input give time proportional to the frequency
    PrevTimer = CurrTimer ' This is the new reference for phase measurement

    On comp2 interrupt
    PhaseCount = CurrTimer - PrevTimer ' gives the time between non shifted and shifted waves

    Convert phasecount to corresponding time as
    Phase(Degrees) = PhaseCount(uS)*180(degrees) / (180deg counts(us))

    Convert freqcount to corresponding freq similarly

    I hope this give you some hint. It's near bedtime and I can barely keep my eyes open. If you need some more hints, let me know, I'll try to help

    This code is definitely not PBP as I've just put the ideas forth.

    Regards

  7. #7
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Many thanks...I'll study your post in detail tonight (after I've got the kids off to bed!)

    I wasn't expecting anyone to analyse my code - I only offered it up in case someone wants to get an overall vibe for my approach. Equally, I wouldn't want anyone to write it for me (else I'll never learn) - I seek exactly what you've brought to the table....ideas wrt general approach from those that have trodden similar paths! (the detail, I'll try & work out myself!)

    thanks once again.

  8. #8
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi Jerson,

    Ok, had a bit of time to try & get my head around your method. I'd like to break each of you sentences down a little....

    A 16 bit timer is free running all the time. No start/stop sequences. Comparator interrupts too are always enabled. No need to start/stop them.
    I'm struggling with why you're letting them free run?

    The comparators first - they're gonna be generating a crazy amount of interrupts (to my simple brain, I actually wonder how the code will have time to do anythig else?! lol). Imagine a 1.4khz signal at the comparator pin - that's gonna be an interrupt every 700 us, but wait, there's the other signal presented at the other comparator pin (ie the one I want to measure the phase lag of) & it's generating interrupts too - so that's two interrupts arriving every 700us?!! (potentially the comparator might need to handle much higher frequencies...as high as 5Khz ....my mind boggles at the interrupt rate).The more I ponder this one (I'm into my 3rd night on this & nowhere near a result!), I do woder if there should be some other hardware I shopuld bring into play - to front end some of the work (I was looking at parrallax propellors - http://www.parallax.com/Portals/0/Im...lerBlock-L.jpg .....something like that architecture lends it self more to what I'm trying to do here?!)

    Now I'm inexperienced & that might not tax the PIC one iota, but bearing in mind my program already uses other interrupts (Interrupt on Change, INT_PIN etc), and it's to my mind my program is getting a bit interrupt busy!

    Ok, next (wrt allowing the timer to roll over) - I just can't get this clear in my head...

    Remember Timer always counts up and rolls over, so CurrTimer nearly always is > PrevTimer. On rollover, the result of CurrTimer-PrevTimer is still valid since the bits are limited to a word size. So, 1000-500 is still same as 465-65500 (+ 1) when you do the 16 bit subtract.
    I'm sure this is becuase I've not grasped the intracacies!

    If you reference my schematic above, once again - I'm measuring two signals for phase lag - what happens if if the first signal comes in before the timer rolls over, but by the time the lagged signal come in, the timer has rolled over?

    How does the maths work out for that scenario?

    Ok, to your code ideas for me to using...

    On comp1 interrupt
    FreqCount = CurrTimer - PrevTimer ' timer ticks between 2 edges of the same input give time proportional to the frequency
    Bearing in mind the source signal is a guitar - the frequency is forever moving (with periods where it's static), so I can't grasp how a moving target so to speak will work with that code approach?

    PrevTimer = CurrTimer ' This is the new reference for phase measurement
    This is about the one line I can grasp (!) - ie we need to put a stake in the ground to start timing until the second (phase lagged) signal arrives.

    On comp2 interrupt
    PhaseCount = CurrTimer - PrevTimer ' gives the time between non shifted and shifted waves
    Again, what if the phase has moved (becuase the incoming frequency changed) - couldn't you have a situation where the current Timer hasn't rolled over, but the previous timer (with the stored value) did?

    BTW - I really do appreciate you taking the time to explain to a dunderbrain like me!
    Last edited by HankMcSpank; - 12th September 2010 at 01:25.

  9. #9
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    Hi Jerson,
    I'm struggling with why you're letting them free run?
    Look at it a bit like you look at a stopwatch. I use the timer as a lap counter. I could choose to start / stop the timer, but it might increase the time spent in the interrupt a bit.

    The comparators first - they're gonna be generating a crazy amount of interrupts (to my simple brain, I actually wonder how the code will have time to do anythig else?! lol). Imagine a 1.4khz signal at the comparator pin - that's gonna be an interrupt every 700 us, but wait, there's the other signal presented at the other comparator pin (ie the one I want to measure the phase lag of) & it's generating interrupts too - so that's two interrupts arriving every 700us?!! (potentially the comparator might need to handle much higher frequencies...as high as 5Khz ....my mind boggles at the interrupt rate).
    Yes, you are right about the interrupts hogging all the time your processor has. But, you could always run the processor at say 20Mhz, makes it 5 times as fast than the default 4MHz. 5 times more that can be done. I've used this technique at 50Hz to check phase lag on mains signals.

    If you reference my schematic above, once again - I'm measuring two signals for phase lag - what happens if if the first signal comes in before the timer rolls over, but by the time the lagged signal come in, the timer has rolled over?

    How does the maths work out for that scenario?
    Ok, in the case of rollover, let us assume the first reading was 65500. Assume a phase shift of 500 counts. The new value is 66000. After rounding to 16 bits, you get 464 (66000-65536). So, current reading 464 - previous reading 65500 will give you your phase counts as 464-65500 = 01F4 in 16 bits (use the F5/F6 buttons on calc to see the Hex/Dec values). So, for an error of 1 count, you still get the same phase diff.

    Bearing in mind the source signal is a guitar - the frequency is forever moving (with periods where it's static), so I can't grasp how a moving target so to speak will work with that code approach?
    A phase diff measurement is just that. How you process it after you've found it out is up to you. I can suggest you put the phase count readings through a low pass filter to smooth out the variations.

    This is about the one line I can grasp (!) - ie we need to put a stake in the ground to start timing until the second (phase lagged) signal arrives.
    Precisely. That is what I am doing when I keep track of the last zero crossing of the first input. Comp1 interrupt. That is your pole in the ground.

    Again, what if the phase has moved (becuase the incoming frequency changed) - couldn't you have a situation where the current Timer hasn't rolled over, but the previous timer (with the stored value) did?
    It is possible in the real world scenario. For this, you can use an overflow mechanism to weed out this case. Any number bigger than expected range indicates the signal has died out.

    BTW - I really do appreciate you taking the time to explain to a dunderbrain like me!
    I am glad to help out as I was once in your shoes

  10. #10
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    Ok, in the case of rollover, let us assume the first reading was 65500. Assume a phase shift of 500 counts. The new value is 66000. After rounding to 16 bits, you get 464 (66000-65536). So, current reading 464 - previous reading 65500 will give you your phase counts as 464-65500 = 01F4 in 16 bits (use the F5/F6 buttons on calc to see the Hex/Dec values). So, for an error of 1 count, you still get the same phase diff.
    But how do you know the timer has rolled over or not? (ie using you analagy how are you counting laps & intra laps)

    For example, the frequency might change & therefore you get a a first reading count of 460 (vs 65500 in your example). So how do you know if a reading of 464 relates to the frequency changing massively, or is a result of the timer rolling over? (surely you have to track overflows too? I tried this, but the PIC baulked when I programmed it with my code! Too many interrupts arriving close together possibly?)

  11. #11
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Yes, you need to track overflows in your code - too low frequency. Of course, the same may not be true for the phase. Tracking the overflow needs to be done. I did not have to use such a thing since my frequency in was fixed at 50Hz. However, I can propose, you could use the timer start/stop method and track the timer overflow to indicate a very low frequency or too large values of time coming in.

    Possible implementation
    Comp1 int
    if T1 has overflowed, you have yourself an error condition here. Freq Too Low
    FreqCounts = T1
    T1 = 0

    Comp2 int
    PhaseCounts = T1

    Again, the 'stick in the mud' is T1 being set to 0. But, here, you get your freqcounts and phasecounts directly.!!!

    The time from one zero crossing (T1=0) to the next zero crossing on the same Comparator is the frequency counts. Read this, check for overflow and Set T1 = 0.

    The time from the zero crossing of Comp1 to the zero crossing of Comp2 is the phase counts.

    Oh, and you need to run your PIC at 20MHz just so you have more time in your ISRs. A helpful suggestion would be to write your ISR in ASM no matter how difficult it seems; PBP adds overhead to the code you write and its better to exit the ISR as quickly as you can to let other blocks of code to run.
    Last edited by Jerson; - 13th September 2010 at 01:58.

  12. #12
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Thanks Jerson....I'll study that later (it's 2.15am here in Lodnon!)

    Actually, this looks like it might have some signs of doing what I want...

    Code:
    'Comparator1 Interrupt handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++        
    Comp1_Int:
    @ INT_DISABLE  CMP1_INT
            Comp1Time.Lowbyte = TMR1L 'puts the timer's low byte in MyTime's lower 8 bits 
            Comp1Time.Highbyte = TMR1H 'puts the timer's high byte in MyTime's upper 8 bits
            TMR1H = 0 'Set the high part of the timer value to 0
            TMR1L = 0 'Set the low part of the timer value to 0
    @ INT_ENABLE  CMP2_INT
            'Comp1Time =Comp1Time +4 
            'dummy = b * c       '5,000,000 
            'frequency = div32 Comp1time
            'frequency =frequency/2
            'HSEROUT ["mytime = ", dec mytime,9, dec frequency/10,".",dec frequency//10,"Hz",13, 10]
              
    @ INT_RETURN
    
    'Comparator2 Interrupt handler+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Comp2_Int:
    @ INT_DISABLE  CMP2_INT
            Comp2Time.Lowbyte = TMR1L 'puts the timer's low byte in MyTime's lower 8 bits 
            Comp2Time.Highbyte = TMR1H 'puts the timer's high byte in MyTime's upper 8 bits
            TMR1H = 0 'Set the high part of the timer value to 0
            TMR1L = 0 'Set the low part of the timer value to 0  
    @ INT_ENABLE  CMP1_INT   
    @ INT_RETURN
    What's getting me bogged down is something as simple as setting my config correct for a 20Mhz external resonator. (the first time I've used an external clock)

    I'm putting a 1Khz test signal into comparator1 input pin- the handler it's registering 2500 timer1 'counts' between successive compartor1 interrupts - that doesn't seem correct for a 20Mhz external clock?

    at 1Khz, the actual physical time between interrupts should be 1ms - & I'm seeiing a count of 2500 for comparator 1 interrupts.....

    therefore 1ms divided by 2500 is 0.0000004 seconds ....or in frequency is 2500000Hz (2.5Mhz - that's not 20Mhz???).

    here's my settings...

    Code:
    @ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF
    
    DEFINE OSC 20        ' set Oscillator at 20Mhz.
    OSCCON.0 = 0
    what am I setting wrong? (I'm using MPASM assembler)

  13. #13
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Hi Hank

    Is it possible you got your T1 prescaler(T1CON) set to 1:8 ? That will explain the counts you see. 20e6 / 8 / 1000 = 2500 counts. You haven't mentioned which pic you use.

    I've never used a resonator on my circuits, but, you could try with HS / XT options. Most likely the XT might work.

    Regards

  14. #14
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    Hi Hank

    Is it possible you got your T1 prescaler(T1CON) set to 1:8 ? That will explain the counts you see. 20e6 / 8 / 1000 = 2500 counts. You haven't mentioned which pic you use.

    I've never used a resonator on my circuits, but, you could try with HS / XT options. Most likely the XT might work.

    Regards
    Thanks for bearing with me....and keep those ideas coming! (to my knowledge there are no prescalers set anyhere in my code)

    Ok, I think I know (in part) what the problem is....& I throw myself open to public ridicule.

    My signal path is this...

    Signal 1 -> Audio preamp->schmitt trigger-> comparator1 input pin

    Signal2 -> Audio preamp-> all pass filter-> schmitt trigger-> comparator2 input pin

    When dealing with phase shift - it's easier on the eye to work with sine waves on a scope (for me at least)....*but*, doh, I was aligning aformetnioned 'zer degrees phase shift' in sine wave form as viewed on the scope. Alas, it appears that becuase each of the signals is of different amplitude going into the schmitt tirrger, the schmitt triggers are erhm triggering at slightly different times wrt to one another - which translates itself into phase shift! (now I'm pretty sure I was checking at the input to the pic comparators the other night, so I'm bemused how this has only come to light)

    I therefore need to modify my circuit to ensure that the signals feeding into the shcmitt are of exactly the same amplitude (preferable amplified to nice sharp edged square wavea) ....this should ensure they trigger at the same point

    Ok, something else I've established tonight ....if I feed signal1 into both schmitt triggers & ultimately into both comparators (so, absolutely no phase shift in play whatsoever then!)....I get a constant count of 29....this stays at 29 no matter what the input frequency - would it therefore be safe to assume that that's how many clock cycles it takes for all of the interrupt routines, storing the counts etc to work?


    So therefore my new plan of attack is.....rejig my 'feed' circuitry to ensure an identical signal feeds amplitude into both schmitt triggers....and then also subtract 29 from the comp2 count. (at my upper frequency of 1.5Khz...I get a comp1 count of about 3000...therefore 1%, hich in phase terms is an error of about 3.6 degrees - not ideal. )

    Would using any other form of interrupts/hardware get this 'floor' count of 29 down? (faster processor, higher frequency oscillator - 40Mhz?)
    Last edited by HankMcSpank; - 16th September 2010 at 00:07.

  15. #15
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok, so I impemented my plan (square up the source signa, make them the same amplitude ....then subtract 29 from the final comp2 count).

    Works...

    (green trace is comp1 input, yellow trace is the phase lagged signal into comp2)








    Thanks for all your help........"I have exorcised the demons this code is clear!"
    Last edited by HankMcSpank; - 16th September 2010 at 22:17.

  16. #16
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240


    Did you find this post helpful? Yes | No

    Default

    Excellent Job. Congratulations!!!
    Thanks and Regards;
    Gadelhas

  17. #17
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by gadelhas View Post
    Excellent Job. Congratulations!!!
    Thanks...I've just hit a problem. While larger phase shifts are being measured well, using this method (feeding into 2 x PIC comparators & counting using DT's interrupts) it seems small phase shifts can't be measured accurately. I made a short video to illustrate the problem....

    (better to maximise the video to full screen & select 720p towards the right of the youtube video play bar)



    Here's the video's accompanying text with the video explaining what's going on....

    "Here you'll see two square waves feeding into the two comparators on a PIC...the green signal trace is feeding into comparator 1 (comp1 count is the count on the left & has a static count of about 9992) - the yellow trace is a 'phase lagged' signal feeding into the PIC's comparator 2. (the comparator 2 count is the green text on the right) What you see on screen is me reducing the phase lag of the yellow trace - as I reduce the phase lag, you can see the comp2 count decrement (as expected) BUT ...as the phase lagged signal gets into the small lag region, the comp2 count won't decrement below 336 - this suggests using PIC comparators & interrupts isn't workable for measuring small phase shifts?"

    The audio signal frequency in that video is about 500Hz...and due to the Comp2 count not decremeting below 336, it means any phase lag below 12.5 degrees can't be measured At just 1400Hz (Comp1 count = 3,600, comp2 = count 336 minimum) , it means phase lag under 33 degrees can't be measured


    Here are the two Comparator simple interrupt handlers...

    Code:
    'Comparator1 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp1_Int:
            Comp1Time.Lowbyte = TMR1L  'Store away the timer1 count - this  will be the non lagged signal 'period' count.
            Comp1Time.Highbyte = TMR1H    
            TMR1H = 0                     'Set timer1 value to 0
            TMR1L = 0                     
    @ INT_RETURN
    
    'Comparator2 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp2_Int:
            Comp2Time.Lowbyte = TMR1L    'Store away the timer1 count again (ie once the lagged signal leading edge arrives - this is the lag count)
            Comp2Time.Highbyte = TMR1H    
    @ INT_RETURN
    EDIT: Following on from the first blurry video I linked to, I re-made the video in HD & uploaded again (the new URL is edited in above)...be sure to view in 720p on youtube! (else the onscreen text will be blurred)
    Last edited by HankMcSpank; - 25th September 2010 at 14:26.

  18. #18
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default

    What PIC do you use and how fast do you run it?

  19. #19
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sinoteq View Post
    What PIC do you use and how fast do you run it?
    I use a 16f690 @20Mhz

    The 16F690's Comparator 1 receives the non lagged signal (set to internal VREF to trip at about 1/2 VCC)
    The 16F690's Comparator 2 receives the phase lagged signal (set to internal VREF to trip about 1/2 VCC too)

    Identical signals are fed into both comparators (bar the phase lag)

    DT's interrupts enabled for CMP1 & CMP2.

    On the scope the lag time measures about 20us - below which Comp2 will not decrement.

    I don't know enough about what's going on under the hood wrt interrupts (or timer1 zero-ing) to shine any more light on why the comp2 count won't go below 336...when clearly it should as the leading edge of the lagged signal gets close to zero lag. So being a bit wet nehind the ears, is there any other possible method I can use that circumvent this problem?
    Last edited by HankMcSpank; - 25th September 2010 at 15:02.

  20. #20
    Join Date
    Jul 2003
    Location
    USA - Arizona
    Posts
    156


    Did you find this post helpful? Yes | No

    Default

    So on the picture and data on post#15 things were looking honky-dory (you were measuring at least down to 161 counts on CMP2). Your new posts state that now CMP2 will not go below 336. Basic question; what changed?

  21. #21
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    I use a 16f690 @20Mhz

    The 16F690's Comparator 1 receives the non lagged signal (set to internal VREF to trip at about 1/2 VCC)
    The 16F690's Comparator 2 receives the phase lagged signal (set to internal VREF to trip about 1/2 VCC too)

    Identical signals are fed into both comparators (bar the phase lag)

    DT's interrupts enabled for CMP1 & CMP2.

    On the scope the lag time measures about 20us - below which Comp2 will not decrement.

    I don't know enough about what's going on under the hood wrt interrupts (or timer1 zero-ing) to shine any more light on why the comp2 count won't go below 336...when clearly it should as the leading edge of the lagged signal gets close to zero lag. So being a bit wet nehind the ears, is there any other possible method I can use that circumvent this problem?
    I'm coming into this sort of late, although I've been more-or-less following this thread. Very interesting stuff!

    Anyway, here's an idea that may help--just use a single interrupt. When the first comparator causes the interrupt, get your tmr1 count and zero it, then wait in a tight loop, checking PIR2.6. That should reduce latency to an absolute minimum.

    something like
    Code:
    'Make sure the Comparator 2 interrupt handler is disabled!
    'Comparator1 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp1_Int:
            Comp1Time.Lowbyte = TMR1L  'Store away the timer1 count - this  will be the non lagged signal 'period' count.
            Comp1Time.Highbyte = TMR1H    
            TMR1H = 0                     'Set timer1 value to 0
            TMR1L = 0
            PIR2.6 = 0                     'Clear the Comparator C2 Interrupt Flag bit
    Keep_Waiting:
            WHILE  PIR2.6 = 0         'Check to see if the Comparator 2 interrupt flag has flipped
                goto Keep_Wating
            WEND
            Comp2Time.Lowbyte = TMR1L    'Store away the timer1 count again (ie once the lagged signal leading edge arrives - this is the lag count)
            Comp2Time.Highbyte = TMR1H    
    @ INT_RETURN
    You could also add some sort of check so that it would exit the loop if an unreasonable amount of time has elapsed.

    Best Regards,
    Paul

  22. #22
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    H Paul,

    Thank you very much for your input - truthfully, I was was getting too wrapped up in this over the weekend, but after drawing a blank with every avenue explored, I'm taking a self enforced mini break from that particular problem (I often find coming back to a project after a rest sparks new ideas & approaches). re your specific idea...I'll freely admit that I'm sort of out my depth when it comes to the inner working of interrupts (ie Picbasic interrupts vs ASM interrupts vs DT interrupts), but at one stage I do recall getting intensely intimate with the datasheet & having a "what the hell" pop at something *very* similar to what you mention - I saw no difference (but I will revisit in the light of your input)

    I could really do with some interrupt big hitters to chime in & outline a little a bit about how to get such time sensitive interrupt timings down to the bare minimum (assuming your suggestion isn't the only attack) ....becuase as it stands right now, I have *NO* (zilch, nada, zero, scratch) idea why that comparator2 interrupt count will not register below 336 when I feed a very slightly phase lagged signal into comp2 ...and alas, the my future (parked) status as a multimillionaire who invented widget X depends on getting that count to reflect the time lag between comp1 & comp2 tripping


    I'm in part slightly reticent to even push this one too much in the (highly possible) case there's something inherently wrong in my PIC /PICBasic approach - what I am convinced about is that the inputs to the comparators are without question correct - I may be pants at programming, but I know how to drive a scope, sig gen etc! (I think my youtube video illustrates the issue seems to be a valid one)

    if anyone out their in the global 'PIC interest land' feels up to the challenge - they could see themselves what happens when they feed near identically phased signals (ie a clock?) into comparator1 & comparator2 (that said an identical signal might cause problems with a race scenario?...but I concede that most don't have the faciilities or interest to setup an all pass to phase shift the two signals!)...in principle, with identical (phase) signals into both comparators, the count for comparator 2 ought to be very close to zero (like single digits)

    But I will come back to this (& first on the list will be your suggestion..if for no other reason thatn your is the only suggestion I have, lol) - I'm presently now working on Project Y - it's not gonna be the blockbuster that Widget X will be ...but got to keep keep my kids in Nike trainers somehow or other

    Edit: While I'm publicily declaring my woeful lack of grasp of time sensitive h/w & corresponding code....I also wonder if changing my PIC might help to get that comp2 count down? (I'm using a 16F690 not becuase it's necessarily the most suitable - but it came bundled with my PIKIT2 starter kit & I've stuck with it from new and have started to get the hang of it a little - when your grappling in the dark as often as am, you need a torch that's familiar!), but I see a chart like this http://www.microchip.com/en_us/technology/xlp/ & then wonder, is there a more efficient PIC for doing this type of stuff out there...??? (eg pics optimised for single instructions - not even sure what that means but the bar chart looks like a shocker!)
    Last edited by HankMcSpank; - 28th September 2010 at 22:48.

  23. #23
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Hi Hank

    Since you're stuck, I wonder if you could post/PM your code of now so that I can take a whack at it. I'll see if I can find your problem with the min value of comp2 value.

    The barest minimum code which will compile and show the problem is sufficient. I should be able to run it.

    Regards

  24. #24
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Jerson View Post
    Hi Hank

    Since you're stuck, I wonder if you could post/PM your code of now so that I can take a whack at it. I'll see if I can find your problem with the min value of comp2 value.

    The barest minimum code which will compile and show the problem is sufficient. I should be able to run it.

    Regards
    Many thanks Jerson.

    The latest version of code was part of a hulking long program, but I found an earlier variant, which is purely deals with the comparator interrupt timer1 counting & therefore makes it a lot easier to look at...

    Code:
    @ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF
    
    DEFINE  OSC 20          ' set Oscillator at 20Mhz.
    DEFINE  NO_CLRWDT 1   ' PBP doesn't clear WDT automatically
    DEFINE HSER_TXSTA 24h ' Enable transmit
    DEFINE HSER_SPBRG 129 ' set USART to 9600 baud  @20Mhz
    
    '*********************************************************************************
    '16F690 Pin Connections....
    ' PIN# NAME     USE & CONNECTION
                    '  1   Vdd      +5VDC power supply
    TRISC.4 = 0     '  6   RC4      C2OUT
    TRISC.3 = 1     '  7   RC3      C12IN3- (comparator1 input)
    TRISC.2 = 1     '  14  RC2      C12IN2- (comparator2 input)
    TRISA.2 = 0     '  17  RA2      C1OUT
                    '  20  Vss      Ground
    '*********************************************************************************
    OSCCON.0 = %0001000 
    txsta = %10100100   'setup the tx register
    RCSTA.7 = 1         ' Enable RB7 for TX USART
    INTCON.0 = 0        ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
    ANSEL      = 0      'disable AtoD.
    ANSELH     = 0      'disable AtoD.
    
    'Turn on & Set up Comparator 1
    CM1CON0.7 = 1       'Comparator 1 on.
    CM1CON0.6 = 0       'C1OUT POLARITY BIT
    CM1CON0.5 = 1       '1 = C1OUT is present on the C1OUT pin (pin 17)
    CM1CON0.4 = 1       'C1OUT logic - 0 is not inverted  (1 for inverted)
    CM1CON0.3 = 0       'unimplemented
    CM1CON0.2 = 1       'Connect internally to the output of C1VREF   (or 0 for the the associated comp 'in' ext pin)
    CM1CON0.1 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)
    CM1CON0.0 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)
    
    'Turn on & Set up Comparator 2
    CM2CON0.7 = 1       'Comparator 2 on.
    CM2CON0.6 = 0       'C1OUT POLARITY BIT
    CM2CON0.5 = 1       '1 = C2OUT is present on the C2OUT pin (pin 6)
    CM2CON0.4 = 1       'C1OUT logic is not inverted  (1 for inverted)
    CM2CON0.3 = 0       'unimplemented
    CM2CON0.2 = 1       'Connect internally to the output of C1VREF (or 0 for the the associated comp 'in' ext pin)
    CM2CON0.1 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)
    CM2CON0.0 = 0       'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)
    
    ' Setup the internal VREF
    VRCON.7 = 1         'Comparator1 CV Ref enable bit
    VRCON.6 = 1         'Comparator2 CV Ref enable bit 
    VRCON.5 = 0         'high or low range  0 = High Range, 1 = low range
    VRCON.4 = 0         '0.6V Reference Enable bit   ....0 is disabled
    VRCON.3 = 0         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.2 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.1 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.0 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    
    
    Comp1Time       var  word    ' used to amalgamate TMR1 High & Low Bytes.
    Comp2Time       var  word
    
          
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System  PO90OOO9
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   CMP1_INT,  _Comp1_Int,   PBP,  yes
            INT_Handler   CMP2_INT,  _Comp2_Int,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON.0= 1  'start timer
    
    Comp1Time = 0 'clear down Comp1Time, prior to starting.
    comp2Time = 0  'clear down Comp2Time, prior to starting
    
    @ INT_ENABLE  CMP1_INT     ; enable Comparator 1 interrupts
    @ INT_ENABLE  CMP2_INT     ; enable Comparator 2 interrupts
    
    'Main body of Code****************************************************************
    Main:
            HSEROUT ["comp1=",dec Comp1Time,9,"comp2Time=", dec comp2time, 13, 10]
            PAUSE 80
            goto Main
            end       
    
    'Comparator1 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp1_Int:
            Comp1Time.Lowbyte = TMR1L       'Store timer1 Low into a variable  
            Comp1Time.Highbyte = TMR1H      'Store timer1 high into a variable.
            TMR1H = 0                                   'Set the high part of the timer value to 0
            TMR1L = 0                                    'Set the low part of the timer value to 0
    
    @ INT_RETURN
    
    
    'Comparator2 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp2_Int:
            Comp2Time.Lowbyte = TMR1L       'Store timer1 Low into a variable 
            Comp2Time.Highbyte = TMR1H      'Store timer1 high into a variable.
            TMR1H = 0                                  'Set the high part of the timer value to 0
            TMR1L = 0                                   'Set the low part of the timer value to 0
            
    @ INT_RETURN
    Last edited by HankMcSpank; - 29th September 2010 at 08:21.

  25. #25
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Hi Hank

    I may be wrong here, but, my suspicion is you are losing time in reentering PBP in your ISRs. See, a lot of PBP registers have to be saved even if they are not going to be used because you flagged your ISR to be coded using PBP functions.

    I suggest you slim it down by using ASM inside the ISR and avoiding ReEnterPbp. You should see better results.

    I might sound like a heretic here, but I prefer coding my ISR in ASM even though it may be painful to code.

    Regards

  26. #26
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Hi, Jerson

    + 1000 ...

    when I see the interrupts content (!) I do not understand why not to write them in . asm ...

    isn't worth saving and restoring all the PBP variables ... as saving and resetting TMR1 only need 4 more " _ " characters ...


    Now ... thinking to it ...

    if those measurements are " changed " while calculating frequency and Phase ...
    not so good ... eh !

    do not know about transmitting results nor ... ( didn't see any interrupt disabling around HSEROUT ...)

    Alain
    Last edited by Acetronics2; - 29th September 2010 at 12:07.
    ************************************************** ***********************
    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 " !!!
    *****************************************

  27. #27
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    As a relative PIC (& programming) n00b, even I realised that with every interrupt (& there'll be a whole heap of them generated here), some registers need to be stored away to be picked up again once the interrupt has finished. As the incoming audio frequency rises, the interrupt rate gets higher & higher eg at 2.5Khz, that's an interrupt every 400us...but it's worse than that, becuause there are two comparators, so it's actually an interrupt every 200us!

    So if having to store/restore registers every 200us, then it obviously makes sense to use the fastest interrupts - that's where I come unstuck ....I only presently know how to us DT's interrupts! (& I have no clue as to how fast they are vs ASM interrupts ...it's all a bit "Whoah...there goes scary stuff" at the moment!)

    Re your comment...

    I suggest you slim it down by using ASM inside the ISR and avoiding ReEnterPbp. You should see better results.

    bearing in mind the actualy routine is quite small....

    Comp1 Interrupt routine...
    store timer 1 count to a Variable "X"
    reset timer 1


    Comp2 Interrupt routine...
    store timer 1 count to a Variable "y"
    reset timer 1

    ..... would it be possible to at least get me started?

    Re the ISR - how would that be triggered?

    Re the ISR content - what ASM would that entail?

    I'm not expecting anyone to do this for me, but when you don't know where to even start....then any initial guidance is most welcome!

    Edit: Also, are there any suitable tools that can help me work out what's going on inside the PIC - I'm thinking along the lines of simulating in step time (vs real time) & seeing what's going on wrt registers.
    Last edited by HankMcSpank; - 29th September 2010 at 13:30.

  28. #28
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by prstein View Post
    Code:
    'Make sure the Comparator 2 interrupt handler is disabled!
    'Comparator1 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp1_Int:
            Comp1Time.Lowbyte = TMR1L  'Store away the timer1 count - this  will be the non lagged signal 'period' count.
            Comp1Time.Highbyte = TMR1H    
            TMR1H = 0                     'Set timer1 value to 0
            TMR1L = 0
            PIR2.6 = 0                     'Clear the Comparator C2 Interrupt Flag bit
    Keep_Waiting:
            WHILE  PIR2.6 = 0         'Check to see if the Comparator 2 interrupt flag has flipped
                goto Keep_Wating
            WEND
            Comp2Time.Lowbyte = TMR1L    'Store away the timer1 count again (ie once the lagged signal leading edge arrives - this is the lag count)
            Comp2Time.Highbyte = TMR1H    
    @ INT_RETURN
    You could also add some sort of check so that it would exit the loop if an unreasonable amount of time has elapsed.

    Best Regards,
    Paul
    I like Pauls approach, Seems to be the least amount of time between Comp1 and 2. one thing I would do, is program his while loop in ASM. This is because I have no idea how many instructions it takes using PBP. I think this will mask the issue of how long it takes to actually enter the handler. Which is what I think above folks are reffering to with the PBP include.

    heres the while loop in asm:
    Code:
         BCF PIR2,6       --> clears the comp 2 int flag
    HERE                    --> label to jump to
         BTFSS PIR2,6  --> test if comp 2 int flag is set
         GOTO HERE     --> not set, go back to test
    CONTINUE            --> Comp 2 int occured, do what ever needs to be done
    The above will take exactly 1 instruction to enter the loop, then 3 inscrutions to to run per loop. now for some math:

    you are running a 20mHz clock, so thats 5MIPS. so 1 instruction takes .0000002 sec to execute. At 1400 htz, each cycle takes .0071428 sec. that devided by 360 = .00000198sec per degree. so you should be able to measure to almost .5 degree. assuming comp2 fires between BCF and BTFSS, thats 3 instrution cycles, or .0000006 sec.(I think BTFSS may take 2 cycles when true)

    Someone please check my math, but these numbers show you have far too much overhead somewhere that can only be explained by the above posts.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  29. #29
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by cncmachineguy View Post
    I like Pauls approach, Seems to be the least amount of time between Comp1 and 2. one thing I would do, is program his while loop in ASM. This is because I have no idea how many instructions it takes using PBP. I think this will mask the issue of how long it takes to actually enter the handler. Which is what I think above folks are reffering to with the PBP include.

    heres the while loop in asm:
    Code:
         BCF PIR2,6       --> clears the comp 2 int flag
    HERE                    --> label to jump to
         BTFSS PIR2,6  --> test if comp 2 int flag is set
         GOTO HERE     --> not set, go back to test
    CONTINUE            --> Comp 2 int occured, do what ever needs to be done
    The above will take exactly 1 instruction to enter the loop, then 3 inscrutions to to run per loop. now for some math:

    you are running a 20mHz clock, so thats 5MIPS. so 1 instruction takes .0000002 sec to execute. At 1400 htz, each cycle takes .0071428 sec. that devided by 360 = .00000198sec per degree. so you should be able to measure to almost .5 degree. assuming comp2 fires between BCF and BTFSS, thats 3 instrution cycles, or .0000006 sec.(I think BTFSS may take 2 cycles when true)

    Someone please check my math, but these numbers show you have far too much overhead somewhere that can only be explained by the above posts.
    I agree with the maths...and I agree with the summary (something somewhere is taking way too long). Now that I have a few people interested & feeding in ideas , I will pull the breadboard out of cold storage tonight & try Paul's code.


    Bert, re this...

    Code:
         BCF PIR2,6       --> clears the comp 2 int flag
    HERE                    --> label to jump to
         BTFSS PIR2,6  --> test if comp 2 int flag is set
         GOTO HERE     --> not set, go back to test
    CONTINUE            --> Comp 2 int occured, do what ever needs to be done
    That looks like what will happen when comp2 interrupts....but within my program, how do I setup the 'trigger' condition ...ie to get the program to go and do that when a comp2 interrupt has arrived?

    I will feedback the results (it might be late - ie 21.30 GMT-ish .....got to do the 'kids off to bed' rigamrole first! Hey there's an idea...rather than read them Noddy goes to the Seaside, I could read them some of the ASM code put forward by Bert!! )
    Last edited by HankMcSpank; - 29th September 2010 at 13:56.

  30. #30
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    Comp1 Interrupt routine...
    store timer 1 count to a Variable "X"
    reset timer 1


    Comp2 Interrupt routine...
    store timer 1 count to a Variable "y"
    reset timer 1
    First I would combine these as Paul suggested. ASM provided in my above post.

    ..... would it be possible to at least get me started?
    Of course! we will!
    Re the ISR - how would that be triggered?
    triggering is easy, just have to turn on PIE's and GIE.

    Off the top of my head, there is some homework to be done. I am not sure how to share variables between ASM and PBP. I don't have my manual with me at work, but I do remember seeing it. Thats needs to be found. While you are reading it, see if says anything about needing to stack PBP stuff when entering ISR. Pic will take care of the important stuff, but what about bank select and such.

    Re the ISR content - what ASM would that entail?
    Thats the easy part

    Edit: Also, are there any suitable tools that can help me work out what's going on inside the PIC - I'm thinking along the lines of simulating in step time (vs real time) & seeing what's going on wrt registers.
    Do you use MPLAB? If so, I like the mplab sim in under debuggers. it's not real robust, but it will allow you to set things like the input pin, step through the program and watch reg's. I don't know if it works with PBP. Beyond that, hardware solutions start with something like ICD. and higher in the money scale.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  31. #31
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    Hey there's an idea...rather than read them Noddy goes to the Seaside, I could read them some of the ASM code put forward by Bert!! )
    LMAO, I always thought datasheets were better for this.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  32. #32
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    .got to do the 'kids off to bed' rigamrole first! Hey there's an idea...rather than read them Noddy goes to the Seaside, I could read them some of the ASM code put forward by Bert!! )
    My wife, back when she was studying to be an EMT, would recite her "protocols" (sort of flow charts for emergency medical actions) to get my daughter to go to sleep.

    Anyway, I've never used the DT interrupts. I've heard great things about them but never had cause to use them. I would do this by setting the registers for a single interrupt source, i.e. comparator 1. And I would use PBP interrupts (because I am a simple man...) at least at the offset. Once I had that working I would consider something more complicated (ASM interrupts) if the speed wasn't fast enough.

    Perhaps in the spirit of keeping it simple, don't use *any* interrupt routine. In the main loop, just keep checking the the state of the Comp1 interrupt flag, something like

    Code:
    PIR2.5 = 0    'Clear the Comp1 interrupt flag
    Main_Loop:
        WHILE PIR2.5 = 0
            GOTO Main_Loop
        WEND
            Comp1Time.Lowbyte = TMR1L  'Store away the timer1 count - this  will be the non lagged signal 'period' count.
            Comp1Time.Highbyte = TMR1H    
            TMR1H = 0                     'Set timer1 value to 0
            TMR1L = 0
            PIR2.6 = 0                     'Clear the Comparator C2 Interrupt Flag bit
    Keep_Waiting:
            WHILE  PIR2.6 = 0         'Check to see if the Comparator 2 interrupt flag has flipped
                goto Keep_Wating
            WEND
            Comp2Time.Lowbyte = TMR1L    'Store away the timer1 count again (ie once the lagged signal leading edge arrives - this is the lag count)
            Comp2Time.Highbyte = TMR1H    
            HSEROUT ["comp1=",dec Comp1Time,9,"comp2Time=", dec comp2time, 13, 10]
            PIR2.5 = 0    'Clear the Comp1 interrupt flag
            goto Main_Loop
    END
    Best Regards,
    Paul

  33. #33
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Ok, just to show you what is involved in ASM interrupts, this is an example for your particular case. This is the first time I am trying something like this using DT_ints , so, I may be off the mark. Most times I do it the hard way - pure asm code. Someone please correct me if I am wrong here. You should be able to realize significant improvement in the values you see. Darrell's wrapper code is cool and if you still need to save some more, look at the generated LST file and you should be able to sneak a trick or two from there. The ISR vector is at location 0004 in the PIC. So, you will find a goto INTHAND at that address.

    In your case since you are not doing any math functions or gosubs in the INTs, you could keep the PBP code as-is and do away with the ASM. Can save you some agony


    Code:
    @ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF
    
    DEFINE  OSC 20          ' set Oscillator at 20Mhz.
    DEFINE  NO_CLRWDT 1   ' PBP doesn't clear WDT automatically
    DEFINE HSER_TXSTA 24h ' Enable transmit
    DEFINE HSER_SPBRG 129 ' set USART to 9600 baud  @20Mhz
    
    '*********************************************************************************
    '16F690 Pin Connections....
    ' PIN# NAME     USE & CONNECTION
                    '  1   Vdd      +5VDC power supply
    TRISC.4 = 0     '  6   RC4      C2OUT
    TRISC.3 = 1     '  7   RC3      C12IN3- (comparator1 input)
    TRISC.2 = 1     '  14  RC2      C12IN2- (comparator2 input)
    TRISA.2 = 0     '  17  RA2      C1OUT
                    '  20  Vss      Ground
    '*********************************************************************************
    OSCCON.0 = %0001000 
    txsta = %10100100   'setup the tx register
    RCSTA.7 = 1         ' Enable RB7 for TX USART
    INTCON.0 = 0        ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
    ANSEL      = 0      'disable AtoD.
    ANSELH     = 0      'disable AtoD.
    
    'Turn on & Set up Comparator 1
    CM1CON0.7 = 1       'Comparator 1 on.
    CM1CON0.6 = 0       'C1OUT POLARITY BIT
    CM1CON0.5 = 1       '1 = C1OUT is present on the C1OUT pin (pin 17)
    CM1CON0.4 = 1       'C1OUT logic - 0 is not inverted  (1 for inverted)
    CM1CON0.3 = 0       'unimplemented
    CM1CON0.2 = 1       'Connect internally to the output of C1VREF   (or 0 for the the associated comp 'in' ext pin)
    CM1CON0.1 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)
    CM1CON0.0 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in3- (pin 7)
    
    'Turn on & Set up Comparator 2
    CM2CON0.7 = 1       'Comparator 2 on.
    CM2CON0.6 = 0       'C1OUT POLARITY BIT
    CM2CON0.5 = 1       '1 = C2OUT is present on the C2OUT pin (pin 6)
    CM2CON0.4 = 1       'C1OUT logic is not inverted  (1 for inverted)
    CM2CON0.3 = 0       'unimplemented
    CM2CON0.2 = 1       'Connect internally to the output of C1VREF (or 0 for the the associated comp 'in' ext pin)
    CM2CON0.1 = 1       'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)
    CM2CON0.0 = 0       'this bit with bit 1 set the external incoming pin - in this case c12in2- (pin 14)
    
    ' Setup the internal VREF
    VRCON.7 = 1         'Comparator1 CV Ref enable bit
    VRCON.6 = 1         'Comparator2 CV Ref enable bit 
    VRCON.5 = 0         'high or low range  0 = High Range, 1 = low range
    VRCON.4 = 0         '0.6V Reference Enable bit   ....0 is disabled
    VRCON.3 = 0         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.2 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.1 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    VRCON.0 = 1         'these 4 bits set the divider of the VREF ladder 16 values - 7 should yield 1/2 VCC
    
    
    Comp1Time       var  word    ' used to amalgamate TMR1 High & Low Bytes.
    Comp2Time       var  word
    
    ;-- Place a copy of these variables in your Main program -------------------
    ;--   The compiler will tell you which lines to un-comment                --
    ;--   Do Not un-comment these lines                                       --
    ;---------------------------------------------------------------------------
    wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
    ;wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
    
    ' --- IF any of these three lines cause an error ?? ------------------------
    '       Comment them out to fix the problem ----
    ' -- Which variables are needed, depends on the Chip you are using -- 
    wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
    wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
    ;wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
    ' --------------------------------------------------------------------------
    
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System  PO90OOO9
    'INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   CMP_INT,  _Comp1_Int,   ASM, yes
            INT_Handler   CMP2_INT,  _Comp2_Int,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON.0= 1  'start timer
    
    Comp1Time = 0 'clear down Comp1Time, prior to starting.
    comp2Time = 0  'clear down Comp2Time, prior to starting
    
    @ INT_ENABLE  CMP1_INT     ; enable Comparator 1 interrupts
    @ INT_ENABLE  CMP2_INT     ; enable Comparator 2 interrupts
    
    'Main body of Code****************************************************************
    Main:
            HSEROUT ["comp1=",dec Comp1Time,9,"comp2Time=", dec comp2time, 13, 10]
            PAUSE 80
            goto Main
            end       
    
    'Comparator1 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp1_Int:
    '        Comp1Time.Lowbyte = TMR1L       'Store timer1 Low into a variable  
    '        Comp1Time.Highbyte = TMR1H      'Store timer1 high into a variable.
    '        TMR1H = 0                                   'Set the high part of the timer value to 0
    '        TMR1L = 0                                    'Set the low part of the timer value to 0
    asm
        movf  TMR1L,w
        movwf _Comp1Time+0    ; the lsb
        movf  TMR1H,w
        movwf _Comp1Time+1    ; the msb
        clrw
        movwf TMR1L
        movwf TMR1H
    endasm
    
    @ INT_RETURN
    
    
    'Comparator2 Interrupt Handler++++++++++++++++++++++++++++++++++++++++++++++++++++ 
    Comp2_Int:
    '        Comp2Time.Lowbyte = TMR1L       'Store timer1 Low into a variable 
    '        Comp2Time.Highbyte = TMR1H      'Store timer1 high into a variable.
    asm
        movf  TMR1L,w
        movwf _Comp2Time+0    ; the lsb
        movf  TMR1H,w
        movwf _Comp2Time+1    ; the msb
    endasm
            
    @ INT_RETURN
    Last edited by Jerson; - 29th September 2010 at 14:38. Reason: :)

  34. #34
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi Jerson,

    So am I getting this right - you are using DT's interrupt as the 'trigger' to enter an actual routine that has ASM within?

    Kind of a like hybrid solution?

    Apologies for the naive line of questioning, but what's the pros cons of the (3?) type of interrupts available to user of Picbasic....

    PICbasic Interrupts
    DT's Interrupts,
    ASM Interrupts.

    hi Paul,

    i'm digging that idea about keeping it simple - once we've got to the bottom of the 'overhead', I can think about putting the solution back as an interrupt.

    Great stuff guys - I've got a new spring in my step with all this.
    Last edited by HankMcSpank; - 29th September 2010 at 14:41.

  35. #35
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Apologies for the naive line of questioning, but what's the pros cons of the (3?) type of interrupts available to user of Picbasic....

    PICbasic Interrupts
    DT's Interrupts,
    ASM Interrupts.
    No need for apologies. We all walked your way once upon a time.....

    PBP interrupts - the worst kind - you use them when you cannot think of anything else.
    It is as cruel as - execute one PBP statement, look for an interrupt, and repeat
    So, the real time nature of interrupts is lost.

    DT's interrupts - a superb wrapper to ease programmer pain
    Just use it and get your job done without having to bother with registers and internals connected with the particular interrupt you need.

    ASM interrupts - for those who like to drive Ferrari
    You know to drive it, don't look back. It is the fastest one there is!!! But you need to know how to ....

    Your best bet, DT_ints is your friend

    Cheers

  36. #36
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Thanks for the clarification...

    Quote Originally Posted by Jerson View Post
    No need for apologies. We all walked your way once upon a time.....

    Your best bet, DT_ints is your friend
    Except it seem most are now telling me to use ASM

    Does this mean I'm being unfaithful?!!

    Darrel - it's not you, i promise ...it's me.
    Last edited by HankMcSpank; - 29th September 2010 at 15:16.

  37. #37


    Did you find this post helpful? Yes | No

    Default

    These are some really good ideas comming forth. I can try Paul's idea, of one interupt
    and poll the the second in the ISR. I am already polling the CMCON.6 and 7. This should
    cut the processing time by a good bit.

    Something occured to me, since you are using schmitt triggers on the inputs, you also don't need to use the comparator interupts. You might find the CCP modules could do the same thing in a more effective way? Or change on portb. This also allows you to use other pics that don't have the comparators.

    I never put togeather my phase shifter. Need to get back on it.

    Interesting project!

  38. #38
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Hi Jerson,

    Your right, of course, in everything you said. However there is a place for PBP interrupts. First, for beginners (and even people who, like me, use the absolute minimum of assembly) it is simple, straightforward, and easy.

    Second, that high overhead isn't a big factor if used judiciously. For example, here's the entire code for the main loop of one of my products:
    Code:
    On Interrupt goto IntHandler
    INTCON.1 = 0 	'clear the INT0 flag
    PIR1.5 =  0		'clear the USART interrupt
    enable
    '#############
    ' Start of Main Loop
    '#############
    Start:
    	if USB_ON = 1 then
    	  	bConnected = true   
    	else  'USB_ON = 0
    	  	bConnected = FALSE
    	endif	
    
    	if bConnected = false and bStayInFastMode = false then
    		OSCCON =  %10000000		'32kHz, periperals should run in sleep mode
    	endif
    	@ nop
    	@ sleep                                           'snooze soundly until woken
    goto Start
    '############
    ' End of Main Loop
    '############
    disable
    The main loop checks to see if USB (through an FTDI serial converter) is connected, and if so it stays awake. Otherwise it goes to sleep until the interrupt wakes it (which in this case happens to be either a pulse from an external RTC or data in the serial buffer). The other ~1000+ lines of code are after the "disable" so the PBP interrupt overhead is not in them. I'm sure there are other ways to accomplish the same end, but the above works perfectly. I probably could have moved the ENABLE to just before the "@ nop" and saved another few bytes even.

    Incidentally, @ nop and @ sleep are the full extent of my assembly knowledge...8^)

    With all that said, I really end up not using interrupts very much at all (except to wake a sleeping PIC). What I do is look at the interrupt flags when convenient for the code. This keeps it nice and simple and controlled. Like I said before, I am a simple man.

    Again, I'm not disagreeing or disputing anything you said, just trying to carve out some justification for PBP ints for us simpler folk. It just has to work, it doesn't (always) have to be pretty. Ferraris are nice I suppose, but I hear they're high-maintenance and sort of temperamental. I have a real good time kicking around on my little scooter; it certainly gets me there. If someone told me I had to use ASM ints I would have given up before I started.

    I really need to look into these DT Ints that everybody keeps talking about...

    Best Regards,
    Paul

  39. #39
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    947


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by prstein View Post
    Hi Jerson,

    there is a place for PBP interrupts. First, for beginners (and even people who, like me, use the absolute minimum of assembly) it is simple, straightforward, and easy.

    [/CODE]

    The main loop checks to see if USB (through an FTDI serial converter) is connected,

    Incidentally, @ nop and @ sleep are the full extent of my assembly knowledge...8^)

    I really end up not using interrupts very much at all (except to wake a sleeping PIC). What I do is look at the interrupt flags when convenient for the code. This keeps it nice and simple and controlled. Like I said before, I am a simple man.

    I have a real good time kicking around on my little scooter; it certainly gets me there. If someone told me I had to use ASM ints I would have given up before I started.
    Hey Paul

    Sorry if I stepped on some toes here. In fact, I was seriously thinking of editiing my post, but, history has had me earlier too So, this is one boo-boo from me to stay here for posterity to see

    Ok, I understand the use of ON INTERRUPT as you use it. My point was about driving home the real-time performance hit and how high the latencies can be. Waking a PIC from sleep? LoL You must be doing much more than that for sure.

    I do not want my post to sound discouraging. Obviously, that will be the first thing a newbie will try when they want interrupts (because.... it is in the Manual)

    I do not have a ferrari either and hope I could buy something better than my old faithful scooter which I have just put up for sale )


    Just to make it clear, I learn new things out here almost everyday. Some of the folks who call themselves newbies and amateurs really astonish me with their coding style. If they only start giving back the little they know, I'm sure they will learn a lot more.

    But, seriously, if you want good realtime performance out of a PIC, DT_ints is the way to go. One more plug for DT_ints

    Cheers

  40. #40
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Hi Jerson,

    None of my toes were stepped upon; I appreciate that you presented the the opportunity to discuss my own take on interrupts and regret if I came off as defensive. Mr. McSpank appears to be quite sharp but I worry a little about making the learning curve too steep.

    I truly appreciate reading your posts--please don't hold back because of me!

    Your scooter looks nice but the shipping charges would be prohibitive...and my Kymco would be jealous.

    Best Regards,
    Paul

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