Menu

Programming A Comparator Module in GCB

Dave B
2016-04-21
2020-12-12
  • Dave B

    Dave B - 2016-04-21

    I've been looking through the GCB documentation, and I don't see anything related to programming a PIC's internal comparator module(s). Am I missing something? I'd like to try using the 12F683's comparator to replace the discrete op-amp comparator I'm now using as a pulse-shaper.

     

    Last edit: Dave B 2016-04-21
  • Dave B

    Dave B - 2016-04-21

    Never mind, found some info in previous posts after doing a search.

     
  • Dave B

    Dave B - 2016-04-21

    Ok, I've put together some test code, but while it compiles fine, I do not see any comparator output change at all when sweeping an input voltage or applying an AC signal. I see about .15-.2 volts on the output Here is the code, for a 12F683:

    #chip 12F683,4
    cmcon = b'01000011'             'set comparator mode to internal
                                                                         'reference with normal output
    VRCON = b'10101000'             'set reference voltage to half max
    

    Assuming the setup commands are correct, what else do I need for the comparator to show proper output? If I'm understanding the docs correctly, this should be all I need to see output change with input change.

     
  • kent_twt4

    kent_twt4 - 2016-04-21

    "CMCON0" will probably get you where you need to be. PICS aren't always consistant with the register naming across devices or device familes, especially with newer enhanced midrange devices. Double check the datasheet, or the chipfamily folder in GCBasic on specific registers/configuration is also a good resource.

     
  • Dave B

    Dave B - 2016-04-22

    Ooopsie, forgot to add the "0" at the end of the register name. That should do it. Now I have to wait until I'm back in the shop tomorrow to see if I can use that comparator output as the clock source for timer1 by running a jumper between the pins. Having been going over the data sheet for an hour or so just now, I'm guessing not.

     

    Last edit: Dave B 2016-04-22
  • Dave B

    Dave B - 2016-04-22

    Ok, finally got a chance to retry this, still do not see the comparator output as expected. New code is below. I am officially stuck. There HAS to be something I'm missing, but darned if i see it....

    #chip 12f683,4
    #define led GPIO.1  'set LED output pin
    dir led out                 'set LED pin for output
    dim dummy as word
    
    'pulse LED to indicate chip running
    
    for dummy = 1 to 5
        set led on
      wait 35 ms
      set led off
      wait 35 ms
    next dummy
    
    'set up comparator
    
    CMCON0 = 67     'b01000011 - set comparator mode to external
                                'reference with output
    VRCON0 = 167    'b10100111  'set reference voltage
    
     
  • William Roth

    William Roth - 2016-04-23

    You must configure the COUT Pin as an output

    DIR GPIO.2 OUT

    Disconnect any programmer connections to Pin 6 (CIN-)

    Depending upon the input source applied to CIN-, It may be a good idea to place a 10 K pullup resistor from Pin 6 to Vdd.

    Assuming you have a 5v Vdd, as you have it configured, a signal below about 3.1 volts applied to CIN-/Pin6 will cause COUT/PIN5 to go High.

     
  • Dave B

    Dave B - 2016-04-23

    I will give that a try and get back to you.

     
  • kent_twt4

    kent_twt4 - 2016-04-23

    What William said.

    Also the CIN- pin is an analog input so "Dir GPIO.1 In" and "VRCON" not "VRCON0". I chased my tail until the pullup resistor suggestion. Definetely don't want a floating comparator input here which was my problem.

    I decided to go with CINV = 1 and look for a positve going edge, so applied a 10k pulldown to CIN- pin. Here is the tested program:

    'This program tests comparator input CIN- (i.e. Vdd)
    'against CIN+ (i.e.VRCON 15/24*Vdd)
    
    #chip 12F683, 4 'mhz
    #define led GPIO.4
    dir GPIO.1 in
    CMCON0 = b'00010011'
    VRCON = b'10101111'
    
    Set led On
    wait 500 ms
    Set led Off
    wait 500 ms
    Main:
    'Use 10k pulldown on analog CIN-
    'so as not to have floating input
    If GPIO.2 = 1 Then
       Set led on
    Else
       Set led off
    End If
    wait 500 ms
    goto Main
    
     
  • kent_twt4

    kent_twt4 - 2016-04-23

    Also, further posting like the OP should be in the HELP forum, as Contributor forum should be reserved for program examples (e.g. like a new devices or sensors), library's and the like.

    The 12f683.dat file has an error concerning the CMCON0 and CMCON1 register BITS as they are expressed as CM0,COMCON0,0 etc. Brought this up in the .dat file forum. Copy and paste over, then save to correct the 12f683.dat file.

    COUT,CMCON0,6
    CINV,CMCON0,4
    CIS,CMCON0,3
    CM2,CMCON0,2
    CM1,CMCON0,1
    CM0,CMCON0,0
    T1GSS,CMCON1,1
    CMSYNC,CMCON1,0
    
     
  • Dave B

    Dave B - 2016-04-25

    I saw your post about a week and a half ago on the DAT file error. My stock DAT file is ok. I apparently downloaded a GCB package that was created after the 683 DAT file was fixed.

    After I made my second OP in this category, I realized my error in category selection.

     
  • rowdy

    rowdy - 2019-11-19

    Hello all, does anybody know of any other GCB code examples that uses a PIC's internal comparator module(s). ?, I have an idea for a small project that uses the comarater but I've been searching for same simple sample code but this is the only article I can find about useing a comparater, it seems this feature is not used much, and there are no codes used in the help files, any help appreciated

     

    Last edit: rowdy 2019-11-19
  • kent_twt4

    kent_twt4 - 2019-11-19

    It would help if you could tell us what PIC you going to use, or if you are open for suggestions. Also, be nice to know on how the comparator will be used.

    As far as having a comparator library for GCB, there hasn't been much call for it? The amount of permutations that one could encounter would be sizeable. Consider on the more advanced devices the number of internal references that could be employed, Timers, PWM, Voltage Reference and so on. By the time you set up the inputs, one could just set up it up manualy and save some code.

    People are here to help if you can give us the extra info.

     
  • rowdy

    rowdy - 2019-11-28

    Hello – Kent-twt4, Thanks for your reply, sorry for the delay in my reply as I have been very unwell the last few weeks.

    Yes its strange that there has been very little demand for the comparator function in Pics yet there are a few Avr projects about.

    Firstly, What I am interested in is experimenting with is just the basic comparator function in a 12f683.
    Using a simple external voltage reference made from a two resistor voltage divider, and the signal voltage on the other input pin and the out put of the comparator driving a LED.

    If that code could be made I would imagine that could be applied to other pics.
    An analogue comparator can be wired as inverting or non inverting, I don’t know if a Pic has that option but it would be handy to be able to have both configurations.

    Secondly , again using the external voltage reference and input voltage , I am wondering if the output of the comparator can be monitored internally and the output be used to trigger an simple one Frequency internally generated tone , I don’t know how to do all this, but any library code help would be appreciated and hopefully be able to be used by other people, thanks.

    Looking at the spec sheet for 12f683, pin GP0 has CIN+, pin GP1 has CIN-, Pin GP2 has C out.

     

    Last edit: rowdy 2019-11-28
    • sfyris

      sfyris - 2020-12-12

      well rowdy (if you are still there) there is a simple method to try. Assume for the 12F675, a trimmer on each pins AN0 and AN1 as voltage dividers and the code bellow gives you good comparator results about the difference of the two inputs. Just pick an_diff and treat it as you wish in your code. You can check this even with a simulator, put one oscilloscope channel on an output pin and give it pulses of an_diff milliseconds width (figure it on my attachment).

      P.S. Trying readad(AN0, AN1) does not working at last that simple.

      ;Chip Settings
      #chip 12F675,4
      #option explicit
      #config OSC=INTRC_OSC_NOCLKOUT
      
      ;Variables
      Dim an_diff As word
      Dim an0value, an1value As integer
      
      Do Forever
        an0value = readad(AN0)
        an1value = readad(AN1)
        an_diff = abs(an0value - an1value)
      Loop
      
       

      Last edit: sfyris 2020-12-12
  • Sleepwalker3

    Sleepwalker3 - 2019-11-30

    I know it's not exactly what you are after and isn't using GCB, but the code may assist you and the idea is quite interesting. It's a digitial LC meter much like various similar ones on the net, but this one is using the internal comparator of 16F628.
    https://sites.google.com/site/vk3bhr/home/index2-html

    (edit - Fixed link [I hope!])

     

    Last edit: Sleepwalker3 2019-11-30
  • rowdy

    rowdy - 2019-12-01

    Thanks Sleepwalker3

     
  • Thomas Henry

    Thomas Henry - 2019-12-01
     
    • Anobium

      Anobium - 2019-12-02

      Welcome back Thomas Henry. I have missed you. Truly.

       
  • Chris Roper

    Chris Roper - 2019-12-02

    Thank you Thomas,
    What an excellent article and with Example code in GCBASIC too.
    It is worth it waight in gold,
    Thanks for posting it.

    We need to keep it available without infringing on copyrights,
    Would a link to Nuts & Volts in the Help page be acceptable.

    Cheers
    Chris

     

    Last edit: Chris Roper 2019-12-02
  • rowdy

    rowdy - 2019-12-04

    Thanks all and Thomas Henry thats a great article, I will study and see what I can learn cheers.

     

    Last edit: rowdy 2019-12-04
  • Bert

    Bert - 2020-07-28

    I wrote a comparator program in GCB that precisely measures the charge time of a capacitor. It's for an in-circuit tester that must charge the capacitor through an input bridge rectifier, so it measures the charge time between 3 and 4 volts. Charging is controlled via a P-FET on an output pin. I had trouble at first until I realized the comparators have no hysteresis; the ISR was firing several times instead of just once for each test. This was solved by disabling each interrupt in the ISR, and enabling them only when ready for a test.
    The code was simplified for posting by using 16 bit timer1 and a prescaler of 2, giving a maximumm time of 65,535 uS. Adding a timer overflow interrupt can extend this time. My tested code uses timer0 with an overflow counter.

    ;Comparator Experiment #26: Mode 011 with interrupts
    ;
    ;The two comparators share a common
    ;external varying voltage but otherwise act as independent
    ;inverters with 2 different reference voltages.  
    ;The comparator outputs drive interrupts; one starts the timer and
    ;the other stops it.  
    ;The first entry into the ISR turns interrupts off, to prevent 
    ;oscillation near the set points.
    
    ;----- Configuration
    #chip 16F684, 8             ;PIC16F684 running at 8 MHz
    
    ' ----- Define ADC
    #Define ChgPin AN7
    
    ' ----- Define FET output
    #define FETGate     PortC.4
    set FETGate on      'PFET initially turned off
    dir FETGate out
    
    ' ----- Define Variables
    DIM VIN As Word
    DIM ChgTime as Word
    
    ' ----- Setup 16-bit Timer1
    InitTimer1 Osc, PS1_2  'For 8Mhz Chip, 1 uS ticks (1 MHz)
    stoptimer 1   'ensure it's not runnung
    
    ; ----- set up comparator mode
    CMCON0 =   0b00000011   'Two common ref. comparators, internal O/P
    
    ; ----- Program
    on interrupt Comp1Change call Comp1ISR
    on interrupt Comp2Change call Comp2ISR
    
    do
    VIN = READAD10(ChgPin)
    If VIN > 200 then    'Cap is not discharged, display message
      'Print "discharging"
      wait 2 s
    else                'Cap discharged enough, start test
      set C1IE on        'Enable comparator1 interrupt
      set C2IE on        'Enable comparator2 interrupt
      ChgTime = 0
      set FETGate off   'Turns on P-FET, charges capacitor
    
      wait 2 s          'Let Interrupts do the precise work
      set FETGate on    'Turns off P-FET, allows cap to discharge
     'Print (ChgTime)  'Do what you want with the value
    end if
    loop               'do forever
    
    Sub Comp1ISR
      set C1IE off      'stop further interrupts of C1
      starttimer 1
    End Sub
    
    Sub COMP2ISR
      set C2IE off     'Stop further interrupts on C2
      stoptimer 1
      ChgTime = timer1 'Charge time in uS
    End Sub
    
     
    • stan cartwright

      stan cartwright - 2020-07-29

      I have only recently seen this subject..and it looks interesting.
      only a beginer but need accurate variable pulses sometimes.
      all info is good

       
  • Anobium

    Anobium - 2020-07-28

    Good project. Nice.

     
  • stan cartwright

    stan cartwright - 2020-07-29

    Thomas Henry 's info link is interesting. tempting to try...er..mega328p, does it apply, or pic only?

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.