Go Down

Topic: Issues in Measuring Capacitance (Read 3373 times) previous topic - next topic

Anant

Sep 10, 2011, 02:27 pm Last Edit: Sep 11, 2011, 01:41 pm by Anant Reason: 1
Code: [Select]
[code]I am learning arduino and i want to measure capacitance and i am trying this using this respective program in an Arduino Duemilanove.
The program is at the end of the mail.
 
i found this program in this link

http://arduino.cc/playground/Main/CapacitanceMeasurement

Now i have troubles understanding the program.
I'm using a 1uF capacitor and r = 10000 ohm, i.e. the program should give me an output of 10uF
q1) he is saying CAP_PIN = 14.
      Which is the pin 14 is it the AREF ?

q2) What is the circuit diagram ?
 This is what i did -
   -I connected AERF to resistance.
   - Resistance to capacitor
   - Capacitor to ground.
   - and again junction between resistance and capacitor to A(0), voltage divider.

q3) An arduino only gives values between 0 and 1023, so don't we need to scale the values using map function ?

I anyways ran the code using the mentioned circuit but it's giving me really arbit values. The code was made for capacitors having pF capacitance, since i'm measuring uF, do i need to make any changes ?




[code]#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#include <math.h>
#define CAP_PIN 14

/* fit e^(bx). Returns 1/b. Implementation of:
Weisstein, Eric W. "Least Squares Fitting--Exponential."
From MathWorld--A Wolfram Web Resource.
http://mathworld.wolfram.com/LeastSquaresFittingExponential.html
*/

double fit_exp(int *ys, int xstep, int n) {
 double sumy = 0;
 double sumxy = 0;
 double sumxxy = 0;
 double sumxylny;
 double sumylny;
 int i;
 for(i=0;i<n;i++) {
   int x = i*xstep;
   double xy = x*ys[i];
   double lny = log(ys[i]);
   sumy += ys[i];
   sumxy += xy;
   sumxxy += x*xy;
   sumxylny += xy*lny;
   sumylny += ys[i]*lny;
 }
 //b = (sumy*sumxylny-sumxy*sumylny) / (sumy*sumxxy-sumxy*sumxy);
 return (sumy*sumxxy-sumxy*sumxy) / (sumy*sumxylny-sumxy*sumylny);
}

void setup() {
 int n = 10;
 int values[n];
 // Make ADC faster by setting AD prescale to 16
 sbi(ADCSRA,ADPS2) ;
 cbi(ADCSRA,ADPS1) ;
 cbi(ADCSRA,ADPS0) ;
 
 Serial.begin(9600) ;
 
 //There's a capacitor between CAP_PIN and ground
   digitalWrite(CAP_PIN, HIGH);
   delay(2000);
   ;; //wait for the capacitor to charge
 
 //CAP_PIN should be connected to ground with a known resistance
 digitalWrite(CAP_PIN, LOW); //let the capacitor discharge
 for (int i=0; i<n; i++) {
   values[i] = analogRead(0); //one of these takes 16us
 }

 //After the capacitor discharges below adc resolution
 //all we get are zeros. Toss out the zeroes so they won't
 //skew the results.
 for(int i=0; i<n; i++) {
   if(values[i] == 0) {
     n = i;
     break;
   }
 }
 
 //fit_exp returns 1/b = -RC in us. With R=100k, C = -RC/10 pF.
 Serial.print("C (uF) = ");
 Serial.println( -fit_exp(values, 16, n)/10000.0 );
}

void loop() {
}
[/code][/code]

James C4S

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Grumpy_Mike

Quote
This is what i did -
    -I connected AERF to resistance.
    - Resistance to capacitor
    - Capacitor to ground.
    - and again junction between resistance and capacitor to A(0), voltage divider.

In place of the AREF use the +5V line

Quote
The code was made for capacitors having pF capacitance, since i'm measuring uF, do i need to make any changes ?

Yes you are using capacitors 1000000 times larger so you do need to change something.

When posting code, select it and then hit the # icon, it stops the forum software mangling you code like it has. Use the modify button and change your post. And it gives people a chance of seeing you code correctly.

Anant

i ran the code by using CAP_pin as A0, thanks for that, the code is still giving arbit values, i finally asked the code to print the values of sumy, sumxy, sumlny etc..  every time i run the code the values of all the variables change.

P.S. - this time i ran the code with 12pF capacitor and 120 Kilo ohm risistance

Grumpy_Mike

Add this bit of code:-

Code: [Select]

//After the capacitor discharges below adc resolution
  //all we get are zeros. Toss out the zeroes so they won't
  //skew the results.
  for(int i=0; i<n; i++) {
    if(values[i] == 0) {
      n = i;
      break;
    }
  }
// new code here - print out all the values you have taken
for(int j=0; j<n; j++) {
Serial.println(values[i]);
}


This will print out all your values that you measured. Are these a consistently falling value? Like in the graph in the web page?
If not then you have wired it up wrong.

Erni

#5
Oct 11, 2011, 04:00 pm Last Edit: Oct 11, 2011, 07:45 pm by Erni Reason: 1
If you can't get it to work like it should, there is a simpler sketch, and it even comes with a diagram:

http://arduino.cc/it/Tutorial/CapacitanceMeter

I have tried 3 different capacitors, all measured within 10% of the value printed on them

1mF, 0,33 mF and 0,1 mF




PaddyS011

Having a few issues with this circuit myself - the readings seem to vary quite a bit from those expected.

Could someone post a circuit diagram or photo of their working setup?  Would be a great help!

thanks

Go Up