Hi all,
I am following the tutorial on how to make a capacitance meter here. I have quite high value capacitors to test so I am using a 100R charge resistor and have 3 pins on a Nano all switching simultaneously to give distribute the current through the chip a bit better (rather than pulling >40mA though one pin).
The above works fine, getting accurate numbers.
I have a few 2V7 capacitors, which can't be tested with this 5V circuit. My plan was to put the pin output through a voltage divider (R1=100R, R2=200R) to reduce the charge voltage, and adjust the time constant reading to 63% of the new voltage. However I get a very different time constant (much lower, same order of magnitude). Tried the same with a R1=2k R2=2.2K network and same issue.
I get the feeling I am doing something fundamentally daft here, can anyone spot it?
Code below, thanks to Paul Bader for the original code on the tutorial.
/* 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 A0 // analog pin for measuring capacitor voltage
#define dischargePin 4 // pin to discharge the capacitor
//#define resistorValue 99.2 // change this to whatever resistor value you are using
#define resistorValue 2000.0 // change this to whatever resistor value you are using
#define num_pins 3
char charge_pin[num_pins] = {5, 6, 7};
float resistor[1] = {resistorValue};
char selector = 1;
unsigned long startTime;
unsigned long elapsedTime;
float microFarads; // floating point variable to preserve precision, make calculations
float nanoFarads;
float milliFarads;
float farads;
void discharge(char* pin);
long charge(char* pin);
int Vtau;
void setup() {
// Setup pin modes
for (int i = 0; i < num_pins; i++) {
pinMode(charge_pin[i], OUTPUT);
digitalWrite(charge_pin[i], LOW);
}
pinMode(dischargePin, OUTPUT);
pinMode(analogPin, INPUT);
// Set charge pins hig, read in the voltage and calculate 63%. Allows for changing potential without needing to reprogramme
pinMode(A1, OUTPUT); digitalWrite(A1, HIGH);
delay(1000);
analogReference(EXTERNAL);
for (int i = 0; i < num_pins; i++) {
pinMode(charge_pin[i], OUTPUT);
digitalWrite(charge_pin[i], HIGH);
}
delay(100);
Vtau = 0.63 * analogRead(analogPin);
for (int i = 0; i < num_pins; i++) {
pinMode(charge_pin[i], OUTPUT);
digitalWrite(charge_pin[i], LOW);
}
Serial.begin(115200); // initialize serial transmission for debugging
Serial.print("\n\nCapacitance Sensor at ");
Serial.print((float)Vtau * 0.00488 / 0.63, 2);
Serial.println("V\n\n");
}
void loop() {
/* dicharge the capacitor */
discharge(charge_pin);
elapsedTime = charge(charge_pin);
// convert microseconds to seconds ( 10^-6 )
farads = (float)elapsedTime * 1e-6 / resistor[0];
Serial.print(elapsedTime); // print the value to serial port
Serial.print("uS\t"); // print units and carriage return
if (elapsedTime <= 2) Serial.println("Not connected");
else if (farads >= 1.0) {
Serial.print(farads, 1); // print the value to serial port
Serial.println("F"); // print units and carriage return
selector = 0;
}
else if (farads > 10e-3) {
milliFarads = farads * 1e3;
Serial.print(milliFarads, 1); // print the value to serial port
Serial.println("mF"); // print units and carriage return
selector = 1;
}
else if (farads > 10e-6) {
microFarads = farads * 1e6;
Serial.print(microFarads, 1); // print the value to serial port
Serial.println("uF"); // print units and carriage return
selector = 2;
}
else
{
nanoFarads = farads * 1e9; // multiply by 1000 to convert to nanoFarads (10^-9 Farads)
Serial.print(nanoFarads, 1); // print the value to serial port
Serial.println("nF"); // print units and carriage return
selector = 3;
}
}
long charge(char* pin) {
for (int i = 0 ; i < num_pins ; i++) {
pinMode(pin[i], OUTPUT);
digitalWrite(pin[i], HIGH); // set chargePin HIGH and capacitor charging
}
startTime = micros();
Serial.print("Charging...");
while (analogRead(analogPin) < Vtau) { // 647 is 63.2% of 1023, which corresponds to full-scale voltage
}
return micros() - startTime;
}
void discharge(char* pin) {
Serial.print("Discharging...");
for (int i = 0; i < num_pins; i++) {
pinMode(pin[i], INPUT);
}
while (true) { // wait until capacitor is completely discharge
digitalWrite(dischargePin, HIGH);
delay(100);
if (analogRead(analogPin) <= 0) {
digitalWrite(dischargePin, LOW);
delay(100);
if (analogRead(analogPin) <= 0) break;
}
}
return;
}