Help needed on Capacitance Meter

This is my code:
Please tell me if anything is wrong,Here i have connected an RC circuit between pin 12 and Ground and i have tapped off the analog voltage from the junction.

const int controlpin = 12;
const int cappin = 0;
float capvalue;
unsigned long timeconstant = 0;
unsigned int initialtime = 0;
int voltvalue;

void setup()
{
pinMode(controlpin,OUTPUT);
digitalWrite(controlpin,LOW);
Serial.begin(9600);
delay(10000);
Serial.println(“Capacitance Meter By Nitin”);
}

void loop()
{
digitalWrite(controlpin,HIGH);
initialtime = micros();
voltvalue = analogRead(cappin);
if(voltvalue == 647) //(timevalue > 644)&&(timevalue < 649)
{
timeconstant = micros() - initialtime;
capvalue = (((float)timeconstant)/90.00F);
Serial.println(timeconstant);
Serial.print(capvalue);
Serial.println(" Micro Farad");
digitalWrite(controlpin,LOW);
}
}

if(voltvalue == 647)

The change that you can catch this equality is low, 1 in 20 or worse.

Check the code below (not compiled or tried)

void loop()
{
  digitalWrite(controlpin,HIGH);
  initialtime = micros();

  while (analogRead(cappin) < 647) ; // wait until certain level is reached.

  timeconstant = micros() - initialtime;
  capvalue = timeconstant/90.0;

  Serial.print("TIME: ");
  Serial.println(timeconstant);
  Serial.print("CAP: ");
  Serial.print(capvalue, 4);  // 4 digits
  Serial.println("   micro Farad");
  digitalWrite(controlpin,LOW);
  // optionally delay(10000);
}

Thanks for the help...i'll try...however the equality condition worked for me and returned a value everytime i tried to the serial monitor... :)

The problem is that your code is going to an infinite loop…
trying to fix it using a for loop

The problem is that your code is going to an infinite loop

No where?

Do you mean:-
while (analogRead(cappin) < 647) ; // wait until certain level is reached.

or do you mean that it is in loop() and will repeat? If so that is what it is supposed to do as it is what your code did.

Its printing the value continuously, however these values are not consistent and keep printing increasing values no where near to the actual value…

Think the RC circuit is not discharged in my code after the measurement, . so the controlpin must be LOW at least for the timeconstant seconds ?? or until a certain value is reached.

Where does the value 647 comes from? Assuming AREF is 5.0Volt 647 stands for 3.1622 volt ??? 3.1622 is approx sqrt(10) ...

647 is 63.2% of 1023 .i.e,it is the % of max volt across the capacitor at t=time constant… 8)

So you have the following, right?


[color=blue]Arduino (Digital) pin 12 ----->Resistor---+--->Capacitor---+
                                          |                |
                                          |                |
Arduino (Analog)  Pin A0 <----------------+                |
                                                           |
                                                           |
Arduino           Ground ----------------------------------+[/color]

Then, here’s the drill:

1. Apply '0' to pin 12.  Wait for lots of time constants
   (Or make a loop that reads analog pin 0 and wait until
    it is zero.)

2. Apply '1' to pin 12 and save the start time in microseconds.

3. Make a loop that repeatedly reads analog pin 0.
   Exit the loop when the reading reaches or exceeds 647.

4. Read analog pin 0 again to make sure the ADC count is not (a lot)
   more than 647.  If it is, then you can increase the value of 
   the resistor and start again.  (But---See Footnote.)

5. Save the end time in microseconds.

6. Now, if the reading is still 647, then you know that
   R * C is approximately equal to the elapsed time
   (end time - start time).

7. Calculate C in microfarads by dividing elapsed
   time in microseconds by resistance in Ohms.
   (Ya gotta get the value of R in there somewhere, right?)

Regards,

Dave

Footnote:
If the reading after the loop is more than 647, but not really, really close to 1023, you can try calculating the capacitance by solving the following equation for C

adcReading / 1024 = 1 - exp(-elapsedTime/RC)

With the standard library natural log function, log(), I think the expression for calculating C could look something like

    float C = elapsedTime*1.0 / (R * (-log(1.0-adcCount / 1024.0)));

I think a better way is to have a selection of resistors available to give a reasonable time constant for whatever capacitance you are expecting. Maybe make the value of R something that the user enters so that the program doesn’t have to be recompiled as you substitute different values of R. Something like that might actually make it practical.

It might be even more interesting if you had several resistors (multiples of 10 of each other, maybe) connected to different Arduino digital pins and do auto-ranging based on counts that you get from the ADC. If the number of microseconds is very large, then use a smaller value resistor. If the reading after the loop is more than 647, use a larger value resistor. Stuff like that.

Thanks a lot...i will definitely try

Based on a couple of experiments with a few capacitors on my workbench and a couple of resistors that I just happen to have lying around:

For capacitance in the neighborhood of 1 nF (.001 uF), a resistance value of 220K (220000 Ohms) gave reasonable results with the setup that I showed and with the formula that I showed.

For capacitance in the neighborhood of 100 nF (0.1 uF), I used an 82K resistor (82000 Ohms)

For capacitance in the neighborhood of 22 uF, I used a 2K7 resistor (2700 Ohms)

If you try to measure lower values (in the tens of picofarads or a few hundred picofarads), the circuit capacitance may affect results (capacitance of Arduino input pins; stray circuit capacitance, including pin-to-ground capacitance of a solderless breadboard if you are using one, etc., etc.) Higher values of resistance needed for low capacitance measurements may very well make reduced noise immunity a problem.

If you try to measure higher values (many tens of uF or even hundreds of uF), lower resistance values may cause charging current to exceed Arduino output pin limit specification.

Regards,

Dave