Go Down

Topic: Qn about understanding capacitance meter code (Read 2872 times) previous topic - next topic

Myrmidon

Jan 20, 2011, 08:15 pm Last Edit: Jan 20, 2011, 08:16 pm by Myrmidon Reason: 1
Hello everyone, I have a question about the code found in the tutorial section of the site regarding a capacitance meter.  The code is:
Code: [Select]
/*  RCTiming_capacitance_meter
*   Paul Badger 2008
*  Demonstrates use of RC time constants to measure the value of a capacitor
*
* Theory   A capcitor will charge, through a resistor, in one time constant, defined as T seconds where
*    TC = R * C
*
*    TC = time constant period in seconds
*    R = resistance in ohms
*    C = capacitance in farads (1 microfarad (ufd) = .0000001 farad = 10^-6 farads )
*
*    The capacitor's voltage at one time constant is defined as 63.2% of the charging voltage.
*
*  Hardware setup:
*  Test Capacitor between common point and ground (positive side of an electrolytic capacitor  to common)
*  Test Resistor between chargePin and common point
*  220 ohm resistor between dischargePin and common point
*  Wire between common point and analogPin (A/D input)
*/

#define analogPin      0          // analog pin for measuring capacitor voltage
#define chargePin      13         // pin to charge the capacitor - connected to one end of the charging resistor
#define dischargePin   11         // pin to discharge the capacitor
#define resistorValue  10000.0F   // change this to whatever resistor value you are using
                                 // F formatter tells compliler it's a floating point value

unsigned long startTime;
unsigned long elapsedTime;
float microFarads;                // floating point variable to preserve precision, make calculations
float nanoFarads;

void setup(){
 pinMode(chargePin, OUTPUT);     // set chargePin to output
 digitalWrite(chargePin, LOW);  

 Serial.begin(9600);             // initialize serial transmission for debugging
}

void loop(){
 digitalWrite(chargePin, HIGH);  // set chargePin HIGH and capacitor charging
 startTime = millis();

 while(analogRead(analogPin) < 648){       // 647 is 63.2% of 1023, which corresponds to full-scale voltage
 }

 elapsedTime= millis() - startTime;
// convert milliseconds to seconds ( 10^-3 ) and Farads to microFarads ( 10^6 ),  net 10^3 (1000)  
 microFarads = ((float)elapsedTime / resistorValue) * 1000;  
 Serial.print(elapsedTime);       // print the value to serial port
 Serial.print(" mS    ");         // print units and carriage return


 if (microFarads > 1){
   Serial.print((long)microFarads);       // print the value to serial port
   Serial.println(" microFarads");         // print units and carriage return
 }
 else
 {
   // if value is smaller than one microFarad, convert to nanoFarads (10^-9 Farad).
   // This is  a workaround because Serial.print will not print floats

   nanoFarads = microFarads * 1000.0;      // multiply by 1000 to convert to nanoFarads (10^-9 Farads)
   Serial.print((long)nanoFarads);         // print the value to serial port
   Serial.println(" nanoFarads");          // print units and carriage return
 }

 /* dicharge the capacitor  */
 digitalWrite(chargePin, LOW);             // set charge pin to  LOW
 pinMode(dischargePin, OUTPUT);            // set discharge pin to output
 digitalWrite(dischargePin, LOW);          // set discharge pin LOW
 while(analogRead(analogPin) > 0){         // wait until capacitor is completely discharged
 }

 pinMode(dischargePin, INPUT);            // set discharge pin back to input
}


Particularly this bit
Code: [Select]
void loop(){
 digitalWrite(chargePin, HIGH);  // set chargePin HIGH and capacitor charging
 startTime = millis();

 while(analogRead(analogPin) < 648){       // 647 is 63.2% of 1023, which corresponds to full-scale voltage
 }

 elapsedTime= millis() - startTime;
// convert milliseconds to seconds ( 10^-3 ) and Farads to microFarads ( 10^6 ),  net 10^3 (1000)  
 microFarads = ((float)elapsedTime / resistorValue) * 1000;  
 Serial.print(elapsedTime);       // print the value to serial port
 Serial.print(" mS    ");         // print units and carriage return


Can someone explain why the elapsed time bit is outside the {} for the while loop?  Am I right in thinking that this means that analogRead is constantly reading until it's >= 648?

Could this also be done similar to:
Code: [Select]

while(analogRead(analogPin) < 648){
       do something
}

if (analogRead(analogPin)>=648){
     do something else
}

I'm not great at programming and i'm trying to understand this as i'm doing something similar but i'm not getting what I expect.  I haven't posted it because it's for a uni project and would rather understand the issue so I can implement it.

westfw

Quote
Am I right in thinking that this means that analogRead is constantly reading until it's >= 648?

Yes, exactly.  "While analogRead is < 648, do nothing.  Then see how much time elapsed waiting for that to happen."

pocketscience

That while loop in the original code simply spins until the condition to break the loop is met - ie analogRead returning >= 649. They record the start time just before the loop, and then the time again right after the loop breaks - and a simple subtraction shows you how long the loop was spinning waiting for the condition to be met.

You pseudo-code is similar, however you need to consider the case where the while loop breaks and then the thing you're reading immediately goes back to < 648. Your if test will fail. The window for this to happen is small, but it could happen and bugs like that are tricky to find!
Is life really that serious...??!

pocketscience

No replies in hours - then 2 within 11 seconds!! :-)
Is life really that serious...??!

Myrmidon

#4
Jan 21, 2011, 11:37 am Last Edit: Jan 21, 2011, 11:38 am by Myrmidon Reason: 1
pocketscience, that could be what is happening in my code for mine.  I'm a hardware guy and fairly new to software so i'm still learning the nuances. :P

I'll mess around a bit more and change my while bit to more like the original code and see what happens.  I might be back. :P

Thanks for the help guys.

:)

Go Up