Go Down

Topic: Issues in Measuring Capacitance (Read 3638 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy