Comparator - tracking the high low condition more robustly.


Closed Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default Comparator - tracking the high low condition more robustly.

    I've set a PIC Internal comparator up to interrupt when a signal goes below a preset VRef level.

    Here's what happens in the interrupt routine...

    (in the code below, 'above_threshold' is a variable to monitor whether comparator is above or below the preset Vref threshold)

    Code:
    Comp1_Int:
    @ INT_DISABLE CMP1_INT
    If above_threshold = 1 then ; 
    above_threshold = 0             
    else 
    above_threshold = 1
    endif
    
    @ INT_ENABLE CMP1_INT
    @ INT_RETURN
    Essentially it's toggling between a 1 or a 0 each time the comparator interrupts. (btw: please excuse the n00b type coding - is there a more elegant way to toggle a variable?)

    Have I got the jist of how this should be approached? I'm actually now thinking as I've typed this out, that maybe the comparator only trips/interrupts in one direction?

    It seems to be working, but occasionally it gets 180 degrees out of sync ...ie if the signal is above threshold it's variable is a 0 (wrong!) & if below it's a 1 (also wrong!)

    How can I make this routine more robust?
    Last edited by HankMcSpank; - 4th February 2011 at 10:16.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default

    Hi,
    I've never actually used the comparators but I'm looking at its section in the 18F25K22 datasheet and it says that the interrupt flag is set each time the output changes state - in other words you'll get an interrupt on rising and falling edge of comparator output.

    However, as far as I can see, you need to read (or write) the CMxCON0 register in the ISR in order to clear the mismatch condition, much like you commonly need to do with the interrupt on change feature. It looks like you're not doing that.

    You might want to actually read the output of the comparator in order to know - for sure - if you're over or under you threshold. The comparator output is available as bit6 in the CM1CON0 register (for comparator 1).

    One way to "toggle" a bit is Above_Threshold = !Above_Threshold where the exclamation mark means "not".

    /Henrik.

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi Henrik,

    Many thanks for the tips.

    I've had a look at the 16f690 datasheet, & you're completely right - it seems that bit 6 of the CM1CON0 register reflects the logic level output of comparator 1.

    Therefore I'm thinking something like this will work...

    Code:
    Comp1_Int:
    If CM1CON0.6 = 0 then above_threshold = 0             
    If CM1CON0.6 = 1 then above_threshold = 1  
    
    @ INT_RETURN
    ...that should keep my variable in total sync with the comparator1 output logic level?

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default

    Or simply Above_Threshold = CM1CON0.6 or you may not even need a "mirror" of the output, instead of using Above_Threshold in your main application simply use CM1CON0.6 directly.

    On the other hand, if all the interrupt is really doing is to "copy" the state of the comparator output then there's really no need to use the interrupt at all - simply read the comparator output directly in your code.

    If you want you can even create an alias, like:
    Above_Threshold VAR CM1CON0.6

    Now, when you use Above_Threshold in your program you are actually reading the comparator output.

    /Henrik.

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Thanks Henrik.

    the reason I'm using an interrupt, is that I eventually want things to kick in as soon as the comparator changes state....so I will now begin expanding the interrupt routine to include other stuff.

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


    Did you find this post helpful? Yes | No

    Default

    [QUOTE=HankMcSpank;98799]
    Code:
    If above_threshold = 1 then; 
    above_threshold = 0             
    else 
    above_threshold = 1
    endif
    (btw: please excuse the n00b type coding - is there a more elegant way to toggle a variable?)
    QUOTE]

    Above code could be this:
    Code:
     above_threshold = above_threshold ^1
    -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!

Members who have read this thread : 0

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