How to modify schematic and or code for better performance .

I am working on the Arduino project that measures competences of capacitors .

It is slow measuring higher values(1000uF);

I would like some help modify the project to measure faster and more resolution(lower value nF, Higher uF) .

I have changed the value of the 10k resistor and it gets faster but looses the correct value.

Here is code.

Thanks for your help.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#define analogPin      1          // analog pin for measuring capacitor voltage
#define chargePin      3          // pin to charge the capacitor - connected to one end of the charging resistor
#define dischargePin   2          // 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;
LiquidCrystal_I2C lcd(0x27,16,2);
void setup(){
  lcd.init();                      // initialize the lcd 

  // Print a message to the LCD.
  lcd.begin(16, 2);
  pinMode(chargePin, OUTPUT);     // set chargePin to output
  digitalWrite(chargePin, LOW); 
  lcd.setCursor(0, 1);


void loop()
  digitalWrite(chargePin, HIGH);  // set chargePin HIGH and capacitor charging
  startTime = millis();
  while(analogRead(analogPin) < 647)
   // 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;   
  if (microFarads > 1)
    lcd.setCursor(0, 0);
    lcd.print(microFarads);       // print the value to serial port
    lcd.setCursor(6, 0);
    lcd.print(" uF");         // print units and carriage return
    // 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)

    lcd.setCursor(0, 0);
    lcd.print(nanoFarads);         // print the value to serial port
    lcd.setCursor(6, 0);
    lcd.print(" nF ");          // 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

I think the only way your going to get both speed and resolution is to make it dual range. I would use a second charge pin with a different charge value. Each setting would have to be calibrated individually. You could make it auto ranging by having it test for low capacitance first. If it takes too long have it discharge and start over at the higher setting. I would also have it test for 0V before starting the first test.

Keep in mind that you only have so much precision to work with when measuring time and voltage. Optimize for one end of the spectrum and the other suffers.

Two points:

  1. The discharge time would be much shorter if you connected R2 between D2 and the capacitor under test, instead of between D2 and D3.

  2. To speed up the test on large capacitors you need to reduce value of R1. However, pin D3 has an output resistance of a few tens of ohms, so this is effectively in series with R1. The lower the value of R1, the more significant this (unknown) output resistance becomes. Its effect will be to give you a capacitance reading that is higher than the true value.

What I would do is to implement (1) above and use a p-channel logic-level mosfet to switch the resistor. The mosfet should be wired with source to +5v, drain to capacitor under test through R1, and gate to D3 (through a 150 ohm resistor if it is a power mosfet, directly is OK for a small signal mosfet). Choose a mosfet with Rds(on) much less than R1 at Vgs=5v. Something like (unfortunately, small signal P-channel mosfets are only avaialble in SMD packaging). Then you can use a much lower value of R1. Pull pin D3 low to charge the capacitor, instead of high as you do now.

You could use 2 or more mosfets to switch in different values of R1, i.e. dual range.

Tell me more about this LCD that you indicate is responding to I2C signals on the LCD contrast and RS pins. Surely there is something that you have forgotten to tell us.

Your Arduino is interesting as well. It seems to have SCL and SDA pins in addition to A4 and A5 pins.


The LCD info is in the yellow note on bottom right. It has an I2C LCD Module board on it . It uses
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
It uses just 4 wires 2 power and 2 that go to A1 and A2 .
I used to do the work. I am not sure why it shows the SCL and SDA show up on it.

The LCD info is in the yellow note on bottom right. It has an I2C LCD Module board on it .

The LCD1602c is the LCD module. This module is mounted on some sort of unspecified I2C interface board. The I2C connections from the Arduino pins go to this mystery board they do not go to the LCD module pins as you have shown on both of your diagrams.


Yes I see your point. Since there were no I2C board in FRITZ I wanted to show the A4, and A5 did go over to the LCD>
Very sorry for any miss information.

I do not want to be rude, but now that you see why I showed the A4 and A5 going over the the lcd do you have any input as to help me speed up the Performance of this project.

Thanks for your input on the I2C, A4, A5 pins but I am looking for help with the circuit being slow to show the competence.