How to measure capacitance with a microcontroller?
Microcontrollers are widely used in measuring various physical variables. The techniques involved in the measurements could be different for individual variable type and are mostly based on the characteristics of the variables to be measured. This tutorial describes some methods for measuring the capacitance of a capacitor using microcontrollers. The techniques use the characteristics of the capacitor itself and are therefore universal and can be easily implemented with any microcontrollers.
Based on R-C time constant
We know that the voltage across a capacitor doesn't build instantaneously. The charging and discharging of a capacitor take place exponentially, and depends upon the resistance it is connected to. When a capacitor (C) is charged from a source voltage (Vin) through a series resistor (R), the instantaneous voltage across the capacitor is given by,
Here, τ = RxC, is known as the time constant. If you put t = τ in the above equation, you get
vo(t = RC) = 0.63 Vin.
Thus at t = RC, the voltage across the capacitor reaches at about 63 % of the supply voltage.
Now, if you could somehow measure the time elapsed before the voltage across the capacitor reaches 63 % of the supply voltage, you can easily find the capacitance value, assuming the resistance R is known. The measurement of time interval can be done by using the built-in Timer module of a microcontroller. You need to tell the microcontroller when to start and when to stop the Timer. The timer should be started right after the switch S is closed and must be stopped when the capacitor voltage reaches 0.63 Vin. Modern microcontrollers are equipped with one or more analog comparator modules. You can set the reference pin of the comparator to 0.63 Vin using a potentiometer, and feed the another input of the comparator with the voltage across the capacitor. When the capacitor voltage crosses 0.63 Vin, the comparator output is flipped, which can interrupt the microcontroller to stop the timer. Noppharat Tawanron has demonstrated this technique with PIC microcontroller in his website.
Based on an oscillation circuit
A capacitance is a primary component in determining the frequency of many oscillation circuits such as an astable multivibrator using a 555 timer IC. The frequency of oscillation for the 555 timer circuit shown below is given by,
Assume R1 = R2 = 10K, you get C = 48000/f, where f is in Hz and C is in nF. In this way, the capacitance can be estimated indirectly by measuring the frequency of the 555 output. You can create a 10 ms window in the software and count the number of output pulses within that window using the Timer module (operated as a counter). Suppose, if N pulses are arrived in the 10 ms window, then C = 480/N, nF. If you get N= 48, the measured capacitance would be 10 nF.
Remember that both of these methods rely on the accuracy of the resistance values used.
How it work?
Begin with the voltage equation for RC charging circuit is: The time that the capacitor is charge to 1/2 of Vs is : let R = 10k and set up the timer to overflow every 69.3 us so where N is a number of periods that elapsed. |
---|
Schematic
When TEST botton is pressed, RA3 pin is set to "1". R2 and R3 are divide the voltage to 1/2 Vra3 which is connected to RA2 pin to be a Vref for comparator. The C undertest is charging and the timer is start. When the voltage of C undertest is more than 1/2 or above Vref, the timer is stop. and a number of periods that elapsed multiply by 10 is the C value in nF. Convert C number to string and display to 1x16 LCD.
The code
/*
* Project name:
Capacitance Meter
* Description:
* Test configuration:
MCU: PIC16F88
Dev.Board: -
Oscillator: HS, 8.0000 MHz internal
Ext. Modules: -
SW: mikroC v8.1.0.0
* NOTES:
*/
#define Vappied PORTA.F3
#define TEST PORTA.F0
unsigned int gCap = 0;
char gOverTest = 0;
char gMessage[8];
char gCapstr[8];
void interrupt(){
if(PIR1.TMR2IF){
TMR2 = 0x87; // best value to create 69.3us
gCap++;
if(gCap > 65500) gOverTest = 1;
PIR1.TMR2IF =0; // Clear int bit
}
}
void main(){
char i,j;
char cap_size;
ANSEL = 0;
TRISB = 0;
PORTB = 0;
OSCCON = 0x7E; // 8Mhz, RC internal clock
OPTION_REG.T0CS = 0;
INTCON.GIE = 1; //Enable global interrupt
INTCON.PEIE = 1; //Enable peripheral interrupt
//------------ Set up Timer2 ------------
PIE1.TMR2IE = 1;
T2CON = 0; // timer2 off, prescaler 1:1
TMR2 = 0x87;
PIR1.TMR2IF =0; // Clear int bit
//----------------------------------------
CMCON = 5; // one independent comparator
// RA1 = Vin- , RA2 = Vin+ = Vref
CMCON.C2INV = 1; // C2 output inverted
//------------------------------------------
ANSEL |= 6;
TRISA |= 6; // RA1 and RA2 are analog input
//---------------------------------------------
TRISA |= 1; // RA0 is digital input
TRISA &= ~8; // RA3 is digital outupt
//------------------------------------------
//while(1){}
Lcd_Init(&PORTB);
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Capacita");
Lcd_Out(2, 1, "nceMeter");
delay_ms(2000);
Lcd_Cmd(Lcd_Clear);
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1, 1, "Ready...");
Vappied = 0;
while(1){
if(!TEST) {
gCap = 0;
gOverTest =0;
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Testing.");
Lcd_Out(2, 1, "...");
TMR2 = 0x87;
Vappied = 1; //apply voltage
T2CON.TMR2ON = 1; // start timer
//T1CON.TMR1ON = 1; // start timer1
while(!CMCON.C2OUT) {
if(gOverTest) break;
}
T2CON.TMR2ON = 0; // stop timer
Vappied = 0;
//---------------------------------
if(!gOverTest){
WordToStr(gCap, gMessage); // convert int to string
//---------- remove space ' ' ----------
j=0;
for(i=0; i<6; i++){
if(gMessage[i]!= ' ') {
gCapstr[j] = gMessage[i];
j++;
gCapstr[j] = 0;
}
}
//--------------------------------------
cap_size = strlen(gCapstr); // find capacitor size in x10 nanofarad
switch (cap_size) {
case 1: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[0];
gCapstr[2] = '0';
gCapstr[1] = '.';
gCapstr[0] = '0';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 2: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[1];
gCapstr[2] = gCapstr[0];
gCapstr[1] = '.';
gCapstr[0] = '0';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 3: {
gCapstr[4] = 0;
gCapstr[3] = gCapstr[2];
gCapstr[2] = gCapstr[1];
gCapstr[1] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 5, gCapstr);
break;
}
case 4: {
gCapstr[5] = 0;
gCapstr[4] = gCapstr[3];
gCapstr[3] = gCapstr[2];
gCapstr[2] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 4, gCapstr);
break;
}
case 5: {
gCapstr[6] = 0;
gCapstr[5] = gCapstr[4];
gCapstr[4] = gCapstr[3];
gCapstr[3] = '.';
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 3, gCapstr);
break;
}
}
Lcd_Out(2, 1, "uF");
} else {
gOverTest = 0;
Lcd_Cmd(Lcd_Clear);
Lcd_Out(1, 1, "Can not ");
Lcd_Out(2, 1, "test.");
}
delay_ms(1000);
}
}
}
With Regards,
s.m.sethupathy,
sms communication,
Tanjore -1.
mobile :9944 186 173
www.questionpaperlink.co.cc
www.sethu-panguvarthagam.blogspot.com
Currently have 0 comments: