Capacitance Meter

Arduino Capacitance Meter and RC time constants
Sparkfun kit
Sparkfun kit, schematic
http://elm-chan.org/works/cmc/report.html
More capacitance info



 

I really need to get some thinner wire for these kinds of things.  Dragging around a solid 20 gauge wire around my breadboard to carry fractions of an amp is silly.








 

/* 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 charge_pin and common point  
*  220 ohm resistor between discharge_pin and common point  
*  Wire between common point and analog_pin (A/D input)  
*/ 

#define analog_pin            0   // analog pin for measuring capacitor voltage 
#define discharge_pin         8   // pin to discharge the capacitor 
#define analog_voltage_pin    0   // pin 14 to read the discharge value 
#define comparitor_state_pin  4   // pin 
int fast_charge_pin         = 5;  // pin to charge the capacitor - connected to one end of the charging resistor 
int slow_charge_pin         = 3;  // pin to charge the capacitor - connected to one end of the charging resistor 
int current_charge_pin      = 0;
int calibrate_pin           = 2;
float resistorValue;              // change this to whatever resistor value you are using
                                  // F formatter tells compliler it's a floating point value
volatile byte  event;
#define  total_chars        4 
#define  clock_pin          19       // set clock pin 
int   data_enable_pins[] = {17, 16}; // set slave select pins 
int   data_pins[]        = {18, 18}; // set master out, slave in pins 
int   font[64];
int   c;
char  buf[16]           = "";
unsigned long calibrate_time = 184; // Initial calibration value unsigned long start_time;
unsigned long elapsed_time;
volatile unsigned int count = 0;
volatile unsigned long interrupt_time;
float micro_farads;                // floating point variable to preserve precision, make calculations 
float nano_farads;
float pico_farads;

/////////////////////////////////////////////////////////////////////////////////////////////////////// 
void setup(){
	pinMode(analog_voltage_pin, INPUT);
	Serial.begin(19200);            // initialize serial transmission for debugging
	setup_led();

	// Set comparitor AIN1 (positive pin) to 3.160v, 63.212% * 5v, time constant 1   
	// Time constant  1:  63.212%   
	// Time constant  2:  86.466%   
	// Time constant 10:  99.995%   
	// More info at:  http://www.allaboutcircuits.com/vol_1/chpt_16/4.html

	pinMode(comparitor_state_pin, OUTPUT);
	digitalWrite(comparitor_state_pin, HIGH);
	pinMode(calibrate_pin, INPUT);
	digitalWrite(calibrate_pin, HIGH); //Turn on pull up resistors   
	ACSR =   (0< 1) {}   
	delay(100);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////// 
char *ftoa(char *a, double f, int precision) {
	long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
	char *ret = a;
	long heiltal = (long)f;
	itoa(heiltal, a, 10);
	while (*a != '\\0') a++;
	*a++ = '.';
	long desimal = abs((long)((f - heiltal) * p[precision]));
	itoa(desimal, a, 10);
	return ret;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////// 
void output_results(){
	unsigned long time;
	char stmp[20];
	//char ascii[16];
	Serial.print("Elapsed: ");
	Serial.print(elapsed_time);
	Serial.print("     Calibrate: ");
	Serial.print(calibrate_time);
	Serial.print("     Resistance: ");
	Serial.print(resistorValue);
	if(elapsed_time > calibrate_time) {
		time = elapsed_time - calibrate_time;
	} else {
		time = 0;
	}
	Serial.print("     Time: ");
	Serial.print(time);
	// convert microseconds to seconds ( 10^-6 ) and Farads to micro_farads ( 10^6 ),  net 1    
	micro_farads = ((float)time / resistorValue);
	if (micro_farads >= 1){
		//Serial.print((long)micro_farads);
		//Serial.println(" micro_farads");
		Serial.print("    ");
		Serial.print(micro_farads);
		Serial.print(" micro_farads");
		format_for_led (micro_farads, 'u');
	} else if (micro_farads >= 0.001){
		// if value is smaller than one microFarad, convert to nano_farads (10^-9 Farad).
		// This is  a workaround because Serial.print will not print floats
		nano_farads = micro_farads * 1000.0;		// multiply by 1000 to convert to nano_farads (10^-9 Farads)
		Serial.print("    ");
		Serial.print(nano_farads);
		Serial.print(" nano_farads");
		format_for_led (nano_farads, 'n');
	} else {
		// if value is smaller than one microFarad, convert to nano_farads (10^-9 Farad).
		// This is  a workaround because Serial.print will not print floats
		pico_farads = micro_farads * 1000000.0;		// multiply by 1000000 to convert to pico_farads
		Serial.print("    ");
		Serial.print(pico_farads);
		Serial.print(" pico_farads");
		format_for_led (pico_farads, 'p');
	}
	Serial.println();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////// 
void format_for_led (float farads, char scale) {   char ascii[8];
	float temp = farads;
	//temp = 314.159265;
	if (temp >= 999.0) {
		sprintf(ascii, "OVER ", 1);
	} else {
		int temp1 = (temp - (int)temp) * 100;
		//Serial.print("    temp: ");
		//Serial.print(temp);
		//Serial.print("    temp1: ");
		//Serial.print(temp1);
		sprintf(ascii, "%0d.%02d", (int)temp, abs(temp1));
		//Serial.print("    ascii-1: ");
		//Serial.print(ascii);
		sprintf(ascii, "%-4.4s%c ", ascii, scale);
		//Serial.print("    ascii-2: ");
		//Serial.print(ascii);
	}
	print_led(ascii);
	Serial.print("    Display: ");
	Serial.print(ascii);
	Serial.print("    ");
} 

/////////////////////////////////////////////////////////////////////////////////////////////////////// 
// LITE-ON, LTP-8647AP, 2 digit, 14-Segment Red LED 
// Jameco.com, part no. 1955933, $2.95 
// http://www.jameco.com/webapp/wcs/stores/servlet/Product_10001_10001_1955933_-1 
// 
// Code by Scott Cooper 
// The code is setup to multiplex the data_pins and the data_enable_pins. 
// This allows for a single ATMEGA168 to run up to 100 chips or 200 characters at a time (10x10) 
// In this example the first chips is connected to pins 3 and 5. 
// The second chip is connected to pins 4 and 6. 
// All chips will use the same clock. 
// The only pins needed to run the LTP-8647 chip: 
//       4  data enable 
//       5  clock 
//       6  data 
//       7  +5vdc 
//       8  +3.3vdc 
//       9  12k resistor going to Gnd, brightness 
//      14  Gnd 
/////////////////////////////////////////////////////////////////////////////////////////////////////// 
void setup_led() {   
	// Add 32 to the font index to get the corresponding ASCII value   

	font[0]  = 0;     // space
	font[1]  = 6144;  // !
	font[2]  = 272;   // "
	font[3]  = 16383; // #
	font[4]  = 11730; // $
	font[5]  = 2541;  // %
	font[6]  = 11309; // &
	font[7]  = 8;     // '
	font[8]  = 12;    // (
	font[9]  = 33;    // )
	font[10] = 255;   // *
	font[11] = 210;   // +
	font[12] = 1;     // ,
	font[13] = 192;   // -
	font[14] = 1666;  // .
	font[15] = 9;     // /
	font[16] = 16137; // 0
	font[17] = 6144;  // 1
	font[18] = 14016; // 2
	font[19] = 15424; // 3
	font[20] = 6592;  // 4
	font[21] = 9604;  // 5
	font[22] = 12224; // 6
	font[23] = 14336; // 7
	font[24] = 16320; // 8
	font[25] = 15808; // 9
	font[26] = 18;    // :
	font[27] = 17;    // ;
	font[28] = 12;    // <
	font[29] = 1216;  // =
	font[30] = 33;    // >
	font[31] = 12354; //
	font[32] = 14160; // @
	font[33] = 15296; // A
	font[34] = 15442; // B
	font[35] = 9984;  // C
	font[36] = 15378; // D
	font[37] = 10176; // E
	font[38] = 9088;  // F
	font[39] = 12096; // G
	font[40] = 7104;  // H
	font[41] = 18;    // I
	font[42] = 7680;  // J
	font[43] = 908;   // K
	font[44] = 1792;  // L
	font[45] = 6952;  // M
	font[46] = 6948;  // N
	font[47] = 16128; // O
	font[48] = 13248; // P
	font[49] = 16132; // Q
	font[50] = 13252; // R
	font[51] = 11712; // S
	font[52] = 8210;  // T
	font[53] = 7936;  // U
	font[54] = 777;   // V
	font[55] = 6917;  // W
	font[56] = 45;    // X
	font[57] = 42;    // Y
	font[58] = 9225;  // Z
	font[59] = 9984;  // [
	font[60] = 36;    // backslash
	font[61] = 15360; // ]
	font[62] = 12297; // ^
	font[63] = 1024;  // _

  pinMode(clock_pin, OUTPUT);                // set SCK pin to output
 
  for (int i=0; i     pinMode(data_enable_pins[i], OUTPUT);    // set CS pin to output
    digitalWrite(data_enable_pins[i], HIGH); // hold slave select 1 pin high, so that chip is not selected to begin with
  }
 
  for (int i=0; i     pinMode(data_pins[i], OUTPUT);           // set MOSI pin to output
  }

  print_led("    ");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
void print_led (char mystr[]) {
  for (int i=0; i     spi_out(data_pins[(i+1)/2], data_enable_pins[(i+1)/2], mystr[i],  mystr[i+1]);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
void spi_out(int data_pin, int data_enable_pin, char c1, char c2) {
  unsigned long working;

  if (c1 >= 97 && c1 <= 122) { c1-=32; }  // check for lower case
  if (c2 >= 97 && c2 <= 122) { c2-=32; }  // check for lower case
  if (c1 < 32) { c1=' '; }                // check for too small
  if (c2 < 32) { c2=' '; }                // check for too small
  if (c1 > 95) { c1=' '; }                // check for too big
  if (c2 > 95) { c2=' '; }                // check for too big

  c1-=32;
  c2-=32;
 
  working = 1;
  working = working << 14;
  working += font[c2];
  working = working << 14;
  working += font[c1];
  working = working << 3;
  // Bits 32, 33 & 34 are not accessible because the long is only 32 bits.
 
  digitalWrite(data_enable_pin, LOW); // set low to enable this led.

  for(int i = 0; i <= 35; i++) {
    digitalWrite(clock_pin, LOW);

    //if(i == 2) { Serial.print(" "); }
    //if(i == 16) { Serial.print(" "); }
    //if(i == 30) { Serial.print(" "); }
    //if(i == 33) { Serial.print(" "); }
   
    if (working > 2147483647) { // test the most significant bit
      //Serial.print("1");
      digitalWrite (data_pin, HIGH); // if it is a 1 (ie. B1XXXXXXX), set the master out pin high
    } else {
      //Serial.print("0");
      digitalWrite (data_pin, LOW); // if it is not 1 (ie. B0XXXXXXX), set the master out pin low
    }
    digitalWrite (clock_pin,HIGH); // set clock high, the pot IC will read the bit into its register
    working = working << 1;
  }

  //Serial.print("  ");
  //Serial.print(c2, BYTE);
  //Serial.print("  ");
  //Serial.print(c1, BYTE);
  //Serial.println();
  digitalWrite(data_enable_pin, HIGH); // set high to disable this led.
}

 

 

 

 




created: Dec. 1, 2013, 1:01 a.m.
modified: April 14, 2019, 12:44 a.m.

Dullbits.com