CTMU Clarifications

Discussion in 'Embedded Systems and Microcontrollers' started by Techbee, Sep 8, 2015.

  1. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    hey!!
    I am currently working i CTMU for PIC24FJ64GA306. I reffered the data sheet and example codes given by microchip,
    still ctmu is not working. i am getting weired result form adc, like varying a lot.

    Hardware connection.

    for current caliberation, i connected 4.2M ohm accros tha analog pin and ground,
    for which i got,

    Current=11.863800
    Current=12.270011
    Current=12.915173
    Current=11.302270
    Current=13.512544
    Current=10.681003
    Current=14.372759
    Current=10.131422
    Current=13.954599
    Current=11.385901
    Current=12.819593
    Current=12.485065
    Current=11.792114
    Current=13.428912
    Current=11.194742
    Current=14.038231
    Current=10.274791
    Current=14.575865
    Current=10.860215
    Current=13.369175
    Current=11.983274
    Current=12.198328
    Current=13.034647
    Current=11.302270
    Current=13.572281
    Current=10.597371
    Current=14.372759
    Current=10.286738
    Current=13.703702
    Current=11.565114
    Current=12.676225
    Current=12.640382
    Current=11.589008
    Current=13.452806
    Current=11.015531



    for capacitance caliberation i connect a capacitor say value 22pf across the analog pin anf ground,where i shoild get 22 pf at result but am getting,

    1.696517
    1.710702
    1.728041
    1.725127
    1.736842
    1.754717
    1.776042
    1.788461
    1.797891
    1.801057
    1.807421
    1.807421
    1.810619
    1.836625
    1.866788
    1.866788
    1.853261
    1.839928
    1.817052
    1.797891
    1.782230
    1.776042


    So i am confuces where i am stucked in, wheather in hardware or software,I had attached my code along with this thread,please have a look and help me...

    Capcitance measurement code:
    Code (Text):
    1.  
    2. #include "main.h"
    3.  
    4. // CONFIG4
    5. #pragma config DSWDTPS = DSWDTPS3       // Deep Sleep Watchdog Timer Postscale Select bits (1: 256 (8.3 mS))
    6. #pragma config DSWDTOSC = LPRC          // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock)
    7. #pragma config DSBOREN = OFF            // Deep Sleep BOR Enable bit (DSBOR Disabled)
    8. #pragma config DSWDTEN = OFF            // Deep Sleep Watchdog Timer Enable (DSWDT Disabled)
    9. #pragma config DSSWEN = ON              // DSEN Bit Enable (Deep Sleep is controlled by the register bit DSEN)
    10.  
    11. // CONFIG3
    12. #pragma config WPFP = WPFP63            // Write Protection Flash Page Segment Boundary (Page 52 (0xFC00))
    13. #pragma config VBTBOR = ON              // VBAT BOR enable bit (VBAT BOR enabled)
    14. #pragma config SOSCSEL = ON             // SOSC Selection bits (SOSC circuit selected)
    15. #pragma config WDTWIN = PS25_0          // Watch Dog Timer Window Width (Watch Dog Timer Window Width is 25 percent)
    16. #pragma config BOREN = ON               // Brown-out Reset Enable (Brown-out Reset Enable)
    17. #pragma config WPDIS = WPDIS            // Segment Write Protection Disable (Disabled)
    18. #pragma config WPCFG = WPCFGDIS         // Write Protect Configuration Page Select (Disabled)
    19. #pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory)
    20.  
    21. // CONFIG2
    22. #pragma config POSCMD = XT              // Primary Oscillator Select (XT Oscillator Enabled)
    23. #pragma config BOREN1 = EN              // BOR Override bit (BOR Enabled [When BOREN=1])
    24. #pragma config IOL1WAY = OFF            // IOLOCK One-Way Set Enable bit (The IOLOCK bit can be set and cleared using the unlock sequence)
    25. #pragma config OSCIOFCN = OFF           // OSCO Pin Configuration (OSCO/CLKO/RC15 functions as CLKO (FOSC/2))
    26. #pragma config FCKSM = CSDCMD           // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching and Fail-Safe Clock Monitor are disabled)
    27. #pragma config FNOSC = PRI              // Initial Oscillator Select (Primary Oscillator (XT, HS, EC))
    28. #pragma config ALTVREF = DLT_AV_DLT_CV  // Alternate VREF/CVREF Pins Selection bit (Voltage reference input, ADC =RA9/RA10 Comparator =RA9,RA10)
    29. #pragma config IESO = OFF               // Internal External Switchover (Disabled)
    30.  
    31. // CONFIG1
    32. #pragma config WDTPS = PS8192           // Watchdog Timer Postscaler Select (1:8,192)
    33. #pragma config FWPSA = PR32             // WDT Prescaler Ratio Select (1:32)
    34. #pragma config FWDTEN = WDT_DIS         // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled)
    35. #pragma config WINDIS = OFF             // Windowed WDT Disable (Standard Watchdog Timer)
    36. #pragma config ICS = PGx1               // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1)
    37. #pragma config LPCFG = OFF              // Low power regulator control (Disabled)
    38. #pragma config GWRP = OFF               // General Segment Write Protect (Disabled)
    39. #pragma config GCP = OFF                // General Segment Code Protect (Code protection is disabled)
    40. #pragma config JTAGEN = OFF             // JTAG Port Enable (Disabled)
    41. void ADCInit();
    42. void pps();
    43. void init_io();
    44. void setup();
    45.  
    46. void main()
    47. {
    48.     int j = 0;
    49.     unsigned int Vread = 0;
    50.     float CTMUISrc, CTMUCap, Vavg, VTot, Vcal;
    51.     setup();
    52.     printf("CTMU MEASUREMENT ");
    53.  
    54.     while(1)
    55.     {
    56.         CTMUCON1bits.CTMUEN = 1; //Enable the CTMU
    57.          
    58.         for(j=0;j<10;j++)
    59.         {
    60.             AD1CON1bits.SAMP = 1; //Manual sampling start
    61.             CTMUCON1bits.IDISSEN= 1;  //drain any charge on the circuit
    62.             __delay_us(60);  //wait 62.5 us
    63.             CTMUCON1bits.IDISSEN = 0;  //end drain of circuit
    64.             CTMUCON2bits.EDG1STAT = 1; //Begin charging the circuit
    65.  
    66.             //using the CTMU current source
    67.             __delay_us(60); //wait for 62.5 us for circuit
    68.             //to charge
    69.             CTMUCON2bits.EDG1STAT = 0; //Stop charging circuit and begin
    70.            
    71.             //Analog-to-Digital conversion
    72.             AD1CON1bits.SAMP = 0;
    73.             while(!IFS0bits.AD1IF);  //Wait for conversion to complete
    74.             Vread = ADC1BUF0;  //Get the value from the ADC
    75. //            printf("%d\t",Vread);
    76.             IFS0bits.AD1IF = 0;  //Clear AD1IF
    77.             VTot += Vread;  //Add the reading to the total
    78.         }
    79. //           printf("VTot=%f\t",VTot);
    80.             Vavg = (VTot/10); //Average of 10 readings
    81. //            printf("Vavg=%f\t",Vavg);
    82.             Vcal = (Vavg/ADSCALE*ADREF);
    83. //            printf("Vcal=%f\t",Vcal);
    84.             CTMUISrc = 5.5; //CTMUISrc is in 1/100ths of uA
    85.             //use the nominal value or the value
    86.             CTMUCap = (CTMUISrc*ETIME/Vcal)/100;  //time is in us
    87.             printf("%f\n\r",CTMUCap);
    88.             //CTMUCap is in pF
    89.             VTot=0,Vavg=0,Vcal=0,CTMUCap=0;
    90.     }
    91. }
    92.  
    93. void init_io()
    94. {
    95.     TRISB = 0X00;
    96.     TRISD = 0XFF;
    97. }
    98.  
    99. void pps()
    100. {
    101.     PPSUnLock;
    102.     iPPSInput(IN_FN_PPS_U1RX, IN_PIN_PPS_RP12);
    103.     iPPSOutput(OUT_PIN_PPS_RP11, OUT_FN_PPS_U1TX);
    104.     //    iPPSInput(IN_FN_PPS_ADCH2, IN_PIN_PPS_RP12);
    105.     PPSLock;
    106. }
    107.  
    108. void setup()
    109. {
    110.     ADCInit();
    111.     uart1_init();
    112.     pps();
    113. }
    114.  
    115. void ADCInit()
    116. {
    117.     ANSBbits.ANSB10=1;
    118.     AD1CHS0 = 10; //Select the analog channel(10)
    119.     AD1CSSL = 0x0000; //
    120.     AD1CON1 = 0x8000; //Turn On ADC, continue in Idle mode,
    121.     AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan,
    122.     AD1CON3 = 0x0000; //ADC uses system clock,
    123.     CTMUCON1 = 0x0090; //make sure CTMU is disabled
    124.     CTMUCON2 = 0xC0C0;
    125.     CTMUICON = 0x0100; // 0.55uA, Nominal - No Adjustment
    126. }
    127.  

    Thanks in Advance!!!
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,180
    1,800
    A couple of questions.
    1. What is the parallel impedance of 4.2MΩ in parallel with the input impedance of the A/D converter?
    2. Where do you think the measured current is flowing?
    3. How are you measuring capacitance with a capacitor across the A/D input?
    4. What does CTMU stand for? Top google hit is http://www.ctmu.org/
    A schematic diagram of your setup would be helpful since it is not at all obvious what you are doing.
     
  3. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    Is this the example sheet you're using?
    CTMU
     
  4. jayanthd

    Member

    Jul 4, 2015
    275
    29
    How does the PIC know that you have connected 22pf Capacitor to ADC input ?

    If ADC is 10 bit and 0 represent 1 pf and 5V adc input represent 1000pf (1023 raw adc value) then calculate what adc input gives 22 pf.
    Without you convert the adc input voltage to capacitance how did you expect PIC24 to convert the voltage to capacitance for you ?
     
  5. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    hey all!!
    Thanks for the reply.
    1. what i have understood from ctmu datasheet is for measuring capacitance we need to calibrate current and capacitance.
    For current calibration we need a RCAL, what should be the value for RCAL???

    2. For capacitance calibration, we need to connect a capacitance across the analog pin and ground. I don't know whether it is right or not.
    Please clarify.

    3 Finally for capacitance measurement, we are using the calibrated current and voltage for the capacitance measurement.

    If this is not the way,please guide the right way!! It will be a great help if someone share the code!!
    @nsaspook YES!!

    For capacitance measurement how should we connect the capacitor??

    Thankyou
     
    Last edited: Sep 9, 2015
  6. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Code (Text):
    1.  
    2. int main(void)
    3. {
    4.     __delay_ms(3000);
    5.     setup();
    6.    
    7.     while(1)
    8.     {
    9.         printf("\n\r");
    10.         printf("\n\r");
    11.         CalibrateCTMU(4200000,ADC_CH0_POS_SAMPLEA_AN10);
    12.         CAPACITOR = CapacitanceMst();        // calculate capacitance
    13.         printf("CAPACITOR = [%g]\n\r",CAPACITOR);
    14.     }
    15. }
    16.  
    17. float CapacitanceMst(void)
    18. {
    19.     float voltage,time;
    20.     double capacitance;
    21.  
    22.     //current = 0.000055 ; // 55uA - 100_BASE_CURR
    23.     //current = 0.0000055 ; // 5.5uA - 10_BASE_CURR
    24.     //current = 0.00000055 ; // 0.55uA - BASE_CURR
    25.  
    26.  
    27.     /*Configure ADC to read channel 1*/
    28.     /******************** ADC configured for:***************************************************
    29.         * FOSC-RC as source of conversion clock
    30.         * Auto sampling enabled
    31.         * scanning of channels disabled
    32.         * Result is right justified
    33.         * Sampling time 17 TAD
    34.         * conversion time 254 Tcy
    35.         * AN1 for sampling
    36.         * ADC interrupt on 16 conversions
    37.         * ADC reference voltage from VDD & VSS
    38.     *******************************************************************************************/
    39.  
    40. //    ANSBbits.ANSB10   = 1;
    41. //    AD1CON1bits.ADON  = 0;
    42. //    AD1CSSL = 0x0000;
    43. //    AD1CHS0 = 10;
    44. //    AD1CON1 = ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON ;
    45. //    AD1CON2 = ADC_SCAN_OFF | ADC_INTR_16_CONV ;
    46. //    AD1CON3 = ADC_SAMPLE_TIME_17 | ADC_CONV_CLK_254Tcy;
    47. //    AD1CON1bits.ADON = 1;
    48.     /*Configure the CTMU*/
    49.     /********************** CTMU configured for:*************************************************
    50.         * Edge 1 programmed for a positive edge response
    51.         * Edge 2 programmed for a positive edge response
    52.         * CTED1 is a source select for Edge
    53.         * trigger output disabled
    54.         * Edge sequence of CTMU disabled
    55.         * no edge delay generation
    56.         * CTMU edges blocked
    57.     *******************************************************************************************/
    58.  
    59.     CTMUCON1 = CTMU_TIME_GEN_DISABLE|CTMU_EDGE_DISABLE|CTMU_EDGE_SEQUENCE_OFF|CTMU_IDLE_CONTINUE
    60.             |CTMU_TRIG_OUTPUT_DISABLE;
    61.     CTMUCON2 = CTMU_EDGE1_POLARITY_POS|CTMU_EDGE2_POLARITY_POS|CTMU_EDGE1_SOURCE_OC1
    62.             |CTMU_EDGE2_SOURCE_OC1;
    63.  
    64.     CTMUICON = CTMU_NOMINAL_CURRENT | CTMU_CURR_RANGE_BASE_CURR;
    65.  
    66.     Enbl_CTMUEdge1;    //Enable current source  to charge the capacitor connected to AN1
    67.  
    68.     /*************** Wait for 10 msec ******************************************************/
    69.     __delay_ms(10);
    70.  
    71.     time = 0.01;
    72.  
    73.     Disbl_CTMUEdge1;                        //Disable current source. stop charging the capacitor
    74.  
    75.     /* Read ADC*/
    76.  
    77.     int j;
    78.     unsigned int Vread = 0;
    79.     double VTot = 0;
    80.     printf("\n\r");
    81.     for(j=0;j<10;j++)
    82.     {
    83.             AD1CON1bits.SAMP = 1;           //Manual sampling start
    84.             __delay_ms(100);
    85.             ADC1_Clear_Intr_Status_Bit;     //make sure A/D Int not set
    86.             AD1CON1bits.SAMP = 0;           //and begin A/D conv.
    87.             while(!IFS0bits.AD1IF);         //Wait for A/D convert complete
    88.             AD1CON1bits.DONE = 0;
    89.             Vread = ADC1BUF0;               //Get the value from the A/D
    90.             printf("Vread: %d\t",Vread);
    91.             ADC1_Clear_Intr_Status_Bit;     //Clear A/D Interrupt Flag
    92.             VTot += Vread;                  //Add the reading to the total
    93.     }
    94.     printf("VTot: %f\n\r",VTot);
    95.     Vavg = (float)(VTot/10.000);            //Average of 10 readings
    96.     printf("Vavg:[%f]\n\r",Vavg);
    97.  
    98.     voltage = (Vavg*3.3)/1024;            // convert ADC count into voltage
    99.     printf("CTMUISrc: %g\n\r",CTMUISrc);
    100.  
    101.     capacitance = (CTMUISrc * time)/voltage; // calculate the Capacitance value using the current value obtained from calibration
    102.     printf("capacitance: %g\n\r",capacitance);
    103.  
    104.     CloseADC10();                             //disable ADC
    105.     CloseCTMU();                            //disable CTMU
    106.  
    107.     return capacitance;
    108. }
    109.  
    110.  
    111. void CalibrateCTMU(unsigned long resistance, unsigned int adcch)
    112. {
    113.     int i;
    114.     int j = 0;                             //index for loop
    115.     unsigned int Vread = 0;
    116.     double VTot = 0;
    117.  
    118.      CTMUCON1 = CTMU_TIME_GEN_DISABLE|CTMU_EDGE_DISABLE|CTMU_EDGE_SEQUENCE_OFF|CTMU_IDLE_CONTINUE
    119.                 |CTMU_TRIG_OUTPUT_DISABLE;
    120.      CTMUCON2 = CTMU_EDGE1_POLARITY_POS|CTMU_EDGE2_POLARITY_POS;
    121.  
    122.      CTMUICON = CTMU_NOMINAL_CURRENT | CTMU_CURR_RANGE_BASE_CURR;
    123.  
    124.     /**************************************************************************/
    125.     //setupAD converter;
    126.     /**************************************************************************/
    127.  
    128.     ANSBbits.ANSB10 =   1;
    129.     AD1CHS0 = 10; //Select the analog channel(10)
    130.     AD1CSSL = 0x0000; //
    131.     AD1CON1 = 0x0000; //Turn On ADC, continue in Idle mode,
    132.     AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan,
    133.     AD1CON3 = 0x0001; //ADC uses system clock,
    134.     AD1CON1bits.ADON = 1;
    135.  
    136.     CTMUCON1bits.CTMUEN = 1;         //Enable the CTMU
    137.  
    138.     for(j=0;j<10;j++)
    139.     {
    140.             AD1CON1bits.SAMP = 1;           //Manual sampling start
    141.             CTMUCON1bits.IDISSEN = 1;       //drain charge on the circuit
    142.             for(i=0;i<500;i++);             //wait 125us
    143.             CTMUCON1bits.IDISSEN = 0;       //end drain of circuit
    144.             Enbl_CTMUEdge1;                 //Begin charging the circuit
    145.                                             //using CTMU current source
    146.             for(i=0;i<500;i++)              //wait for 125us
    147.             Disbl_CTMUEdge1;                //Stop charging circuit
    148.             ADC1_Clear_Intr_Status_Bit;     //make sure A/D Int not set
    149.             AD1CON1bits.SAMP = 0;           //and begin A/D conv.
    150.             while(!IFS0bits.AD1IF);         //Wait for A/D convert complete
    151.             AD1CON1bits.DONE = 0;
    152.             Vread = ADC1BUF0;               //Get the value from the A/D
    153.             printf("Vread: %d\t",Vread);
    154.             ADC1_Clear_Intr_Status_Bit;     //Clear A/D Interrupt Flag
    155.             VTot += Vread;                  //Add the reading to the total
    156.     }
    157.     printf("VTot: %f\n\r",VTot);
    158.     Vavg = (float)(VTot/10.000);            //Average of 10 readings
    159.     printf("Vavg: %f\n\r",Vavg);
    160.     Vcal = (float)((Vavg*3.3)/1024);        //  for unsigned conversion 10 sig bits * Vdd connected to A/D Vr+
    161.     printf("Vcal: %f\n\r",Vcal);
    162.     CTMUISrc = Vcal/resistance;             //CTMUISrc
    163.     printf("CTMUISrc: %g\n\r",CTMUISrc);
    164. }
    165.  
    166. void init_io()
    167. {
    168.     TRISB = 0X00;
    169.     TRISD = 0XFF;
    170. }
    171.  
    172. void pps()
    173. {
    174.     PPSUnLock;
    175.     iPPSInput(IN_FN_PPS_U1RX, IN_PIN_PPS_RP12);
    176.     iPPSOutput(OUT_PIN_PPS_RP11, OUT_FN_PPS_U1TX);
    177.     PPSLock;
    178. }
    179.  
    180. void setup()
    181. {
    182. //    ADCInit();
    183.     uart1_init();
    184.     pps();
    185. }
    186.  
    187. void ADCInit()
    188. {
    189.     ANSBbits.ANSB10 =   1;
    190.     AD1CHS0 = 10; //Select the analog channel(10)
    191.     AD1CSSL = 0x0000; //
    192.     AD1CON1 = 0x8000; //Turn On ADC, continue in Idle mode,
    193.     AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan,
    194.     AD1CON3 = 0x0000; //ADC uses system clock,
    195. }
    196.  
     
  7. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    The CTMU uses a known current source , set time and known capacitance for the calibration to find a unknown capacitance.

    If you assume the ADC is correct first you calibrate the current source with a known resistance to generate a calibration voltage.

    Program the current source register for a set value with a known resistance (as in the example to give 70% of full ADC value), this results in voltage drop across the resistor to ground that's measured. If the ADC result matches the calculated voltage the current source is correct. If the results don't match you can trim the current source value with the adjustment register until it does or save a software offset to what the current value actually is.

    Now you know the current source value.
    ctmu_cap.png
    Next measure with no capacitance to be measured in the circuit to get the stray capacitance voltage level for a set time period and save this value.


    Then measure with the known capacitance to get a value (with the added stray capacitance) for the slope of voltage for different capacitance values. It's all in the example code.

    The theory is a current source charging a capacitor gives a linear voltage value over time. If you fix time and you know the voltage values for two known values of capacitance you can define a scale of voltages that directly relates to any value capacitor within the limits of the measurement device.
    Here you can see the voltage ramp and how it varies with the addition of body capacitance (increased value and lower voltage on the measurement circuit in the same time frame) in a touch application.
    https://flic.kr/p/aXvemz
    https://flic.kr/p/aXvfcx
    [​IMG]

    The CTMU used to measure relative capacitance in a hand or body detector to project capacitance (by altering the field configuration of the plates) up using an active ground guard configuration with several plates in a small box with a simple unity gain voltage buffer 3553AM to drive the fields up.
    ctmu_cap_guard.png
    https://flic.kr/p/bkLcga
    [​IMG]
    [​IMG]
    [​IMG]
    Upper left ground plate, lower left sensor guard plate, lower right the sensor plate.
    [​IMG]
    Buffer amp to the PIC18 CTMU sensor detector with the needed software to reduce noise and generate a bar graph of the received capacitative signal.
     
    Last edited: Sep 9, 2015
    Techbee likes this.
  8. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Thank you for your reply.
    As far current calibration works fine but we are stucked in capacitance calibration.
    As you mentioned in the previous reply when we measured with no capacitance, voltage we are getting is zero.
    When we measured with a known capacitance (33pf) we are getting 0.319677v.
    We have some doubts :
    1> Rcal =100kohm and is there any limitation for setting Rcal?
    2> CTMUISrc = 5.5ua, time = 6us (how to set time?), Vcal = 0.319677v.
    3> Capvalue = ((5.5x6)/Vcal) = 103pf
    Hardware connection:
    33pf cap connected across analog pin and ground.
    Is our calculation right? Please give a suggestion.
    Thank you.
    -TechBee
     
    Last edited: Sep 9, 2015
  9. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    [​IMG]
    Get an oscilloscope and connect it to the ADC pin that's used to measure capacitance. You should see a ramp of voltage if your code and timing is correct.
    [​IMG]
    You need to adjust the time with no capacitance to read ~70% of the ADC max reference voltage when you start the ADC conversion at (2).
    http://www.embedded.com/print/4218309

    I would also run a rough calibration check on the ADC readings to be sure that's working correctly. You won't need offset and gain correction factors for the measurement circuit to work if they are within the specified limits of the chip. If not you can adjust with something like this.
    Code (C):
    1.  
    2. #define   ADOFFSET   0.0015   // correct for zero shift
    3. #define ADGAIN     0.983   // correct for voltage offset from calibration value 2.000 volts
    4.  
    5. Vcal0 = ((Vval / ADSCALE * ADREF) + ADOFFSET)*ADGAIN;
    6.  
    http://www.atmel.com/images/doc2559.pdf
     
    Last edited: Sep 9, 2015
    Techbee likes this.
  10. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Thanks for the reply...

    When we connect the oscilloscope, we are getting a graph with adc, a spike occurs.

    plz check our code, is it right??
    Code (Text):
    1.  
    2. CTMUCON1bits.CTMUEN = 1; //Enable the CTMU
    3.         for (j = 0; j < 10; j++)
    4.         {
    5.             AD1CON1bits.SAMP = 1;           //Manual sampling start
    6.             CTMUCON1bits.IDISSEN = 1;       //drain charge on the circuit
    7.             __delay_us(125);                //wait 125us
    8.             CTMUCON1bits.IDISSEN = 0;       //end drain of circuit
    9.             CTMUCON2bits.EDG1STAT = 1;      //Begin charging the circuit
    10.             __delay_us(150);                //wait for 125 us
    11.             CTMUCON2bits.EDG1STAT = 0;      //Stop charging circuit
    12.             IFS0bits.AD1IF = 0;             //make sure ADC Interrupt is not set
    13.             AD1CON1bits.SAMP = 0;           //begin Analog-to-Digital conversion
    14.             while (!IFS0bits.AD1IF);        //Wait for conversion to complete
    15.             AD1CON1bits.DONE = 0;
    16.  
    17.  
    18.             Vread = ADC1BUF0;               //Get the value from the ADC
    19.             IFS0bits.AD1IF = 0;             //Clear ADC Interrupt Flag
    20.             VTot += Vread;                  //Add the reading to the total
    21.         }
    22.         Vavg = (float) (VTot / 10.000);     //Average of 10 readings
    23.         printf("Vavg    =   %f\t",Vavg);
    24.         Voltage = (double) (Vavg / ADSCALE * ADREF);
    25.         printf("Voltage        =   %g\t",Voltage);
    26.         printf("Resistance  =   %g\t",(Voltage/.55)*1000000);
    27.  
    28.  
    29.         CTMUISrc = .55;                     //CTMUISrc is in 1/100ths of uA
    30.                                             //use the nominal value or the value
    31.  
    32.         CTMUCap = (CTMUISrc * 7 / Voltage);  //time is in us
    33.                                                                  //CTMUCap is in pF
    34.         printf("Capacitor Value =   %f\n\r",CTMUCap);
    35.  
    36.  
    37.     //    CTMUISrc = Vcal / RCAL; //CTMUISrc is in 1/100ths of uA
    38.     //    printf("Current=%f\n\r",CTMUISrc);
    39.         VTot=0,Vavg=0,Voltage=0,CTMUISrc=0;
    40. }
    41.  
    Any suggestion plzz!!!!
     
  11. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    The waveform is OK but looks exponential like its loaded down with resistance. You have removed the current cal resistor from the circuit while measuring capacitance?
     
  12. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    hi Nsaspook,
    Now i can measure the capacitance ranging from 1nf tp 100nf correctly.
    But how can we extend the range????
    By calulation adc can give resistor value of 6Mohm ie.,(resistor=3.3/0.55ua).
    But here i can ony messure upto 100K correctly.
    I tried in all currrent sources,still for higher resistance values problem occurs....
    Since human finger have capcitance range upto 5 to 15pf, not

    Please give me suggetions!!!


    Thanks
    Techbee.
     
  13. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    yes

    now i am connected capacitor across the analog pin and ground without resistor.
    I am confused with the range, how can we measure pf range capacitor, and what value r cal should be calibrated?
     
  14. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    To measure smaller range capacitors you need to reduce the charge time period to less than the time constant for the selected current source and smallest capacitance in the needed range so the ADC reading will be about 70% of the full ADC range.
    Code (C):
    1.  
    2.             CTMUCON2bits.EDG1STAT = 1;      //Begin charging the circuit
    3.             __delay_us(150);                //wait for 125 us <--- [B]reduce this time[/B]
    4.             CTMUCON2bits.EDG1STAT = 0;      //Stop charging circuit
    5.  
     
  15. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Hi Nsaspook,
    I changed my code as u referred, can u plz check my code below,is my calculation right?

    voltage=(Vavg/1023*3.3);
    capacitance=((ctmrsc*150u)/voltage);
     
  16. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,913
    2,187
    The best way to check your code is to see if it works. I'm glad to help you with the concept but I'm not going to fix your possible coding problems when the doc's on this are very clear.
     
  17. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Thanks Nsaspook!!!!!
    Let me go through the documents clearly, Once again thanks for the help!!!!!
     
  18. Techbee

    Thread Starter New Member

    Sep 8, 2015
    14
    0
    Hi Nsaspook,
    I have doubt in range calculation. As we know we can measure the 70%of adc value.
    What is the maximum resistor range we can measure with ctmu.
    As I know upto 2.3v will get the accurate resistor value, ie., 2.3/0.55u=4.2Mohm
    But when i set 0.55uA, i can only measure up to 330Kohm, ie., 0.18
    I use the trimming process, but by setting maximum positive voltage from nominal current
    I am getting only 0.1815 Voltage????


    Is there anything i should consider apart from trimming process???
     
    Last edited: Sep 16, 2015
Loading...