Capacitor and Resistance Tester problem

You don't have to use the same values.
Any voltage divider that will give you 3.16V will work
2.4K and 1.4K or 3.6K and 2.1K or 6.2K and 3.6K
If you have a pot, you can use that

I used an 10k Potentiometer,


These are the readings for an 1 microFarad

And these are for 1 nanoFarad capacitor

Still better than before, maybe because of the potentiometer i get these values that fluctuate that much, but it's better, anyone any more ideas and advices please ?

Maybe.
Put a 1uf to 10uF cap between the wiper and ground but fixed resistors with a cap will be best

You may find this very interesting, especially the last one.

added no 1 nanoF between D7 and GnD, these are the values for and 100 nanoF, 10nanoF and 1 microF



So it;s much better now, not far from perfect

What does that mean? Are all three measurement tools giving inaccurate results? With or without the display? If so, show us the sketch and accurate schematic for the minimal circuit that demonstrates the problem.

Is your wiring soldered or breadboard etc? On rare occasions I've eventually isolated the cause of an obscure issue being a hidden break in a Dupont wire, or an enlarged breadboard socket.

you are right, it looks intresting, have you tried it or have any advice ?


For me it looks good, but i would need a reason to do a capacitor for that small range.

No I have not tried it and I have my doubts as to accuracy. It uses some "magic" numbers in the code that are unexplained.


this is for an 100 nanoF

this if for 1 microF

and this is for 100 microF

I think i will go with this one
Made some cable management, at the resistor part the 1k resistor it reads it preety good, but if a put a 220 Ohm or 10k it just give me bananas....
Will try to add the capacitance in the 'device' and update

I'm surprised it worked that good.

The ohmmeter should work fine with the 1K resistor

The Curent problem now is the ohm-meter, some weird values with the 220 ohm, the capacitance tester is ok-ish, there is an error or 2-3%, at an 100 nanoF i get 113 nanoF, i said 3% because on the datasheet the value of the capacitor is +-10%, i think that make sense, and the light meter is just fine, no calibration for that. Will try the next few days to make it more accurate.


Now is everything in order, i will research more and try to get rid as much as posible of those losses, but for now is ok

The jumpers and the solderless breadboard will have capacitance and maybe add 5-10pF to the measurement.

Which one of Nick's code do you use?
The last one does not use Microseconds and I get very constant values.
The exact voltage divider is not need.

At his suggestion we can do away with an exactly calculated voltage divider, and simply use two reasonable value resistors.

The second one, but i used an potentiometer and maybe thats why i don’t get that precision. At the end i chose this tutorial, i am more interested in the smaller values. 18pF - 470uF

The wires may also add significant induction...
...if you start measuring these low capacitance values...

Are you claiming that these wires could have so much inductance that it could somehow cause the capacitance values to be higher?

If you claim that any wire is a capacitor, then I claim any wire is also an inductor.
A small one, but longer wires have more induction and 10pF is a small capacitor. So, the inductance from the wires may influence the reading. A inductance in series will have the same effect as a capacitor in parrallel, so these effects might add up.
Might very well be that effect of inductance is less than the effect of capacitance...


Thank you guys for everything, it's working great, i can measure resistance between 100 ohms and 3.3 kOhms with an error of 1%-5%, witch is great for me and i am measuring capacitance between 17 pF and 470uF, at 1 nF i get 1.02 nF with is again GREAT !
Thank you again, i will close this topic.

You are not obligated to do so but it would be nice, when you have time, if you posted the final code and schematic so other can see what finally worked.

Here is the code, the only change the schematic is that i changed the capacitance, i am not using any resitance now, i am measuring with the A1 and A2 pins, i used this tutorial, with i recommend

How to Make an Arduino Capacitance Meter

// Programming a button to go back from a while menu thing
// https://forum.arduino.cc/t/programming-a-button-to-go-back-from-a-while-menu-thing/1325404
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>

#include <BH1750.h>
// #include <Wire.h>

 
 
BH1750 lightMeter;

#define TFT_CS   10   // Chip select (CS)
#define TFT_RST   8   // Reset pin
#define TFT_DC    9   // Data/Command pin

#define  PRESSED  LOW // Using Pull-up, the button press connects to the GND
#define RELEASED HIGH

/////////////////////////////////////

const int OUT_PIN = A2;
const int IN_PIN = A1;
const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

/////////////////////////////////////
int   backButtonPin = 5;    // Buton Back (BB)
int     upButtonPin = 4;    // Buton Up (BU)
int   downButtonPin = 3;    // Buton Down (BD)
int selectButtonPin = 2;    // Buton Select (BS)
enum button_t : uint8_t {NONE, UP, DOWN, SELECT, BACK} button;

uint16_t menuLineNumber[] = {0, 30, 80, 130, 180};

// Ohm metru //
int analogPin = 0;
int raw = 0;
int Vin = 5;
float Vout = 0;
float R1 = 1000.0;
float R2 = 0;
float buffer = 0;
//Ohm metru //

void (*measurePtr)(void) = NULL;

int menuLine = 1;  // Meniul curent, începe de la 1

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

void afisaremeniu() {
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(30, 30);
  tft.print("Rezistenta");
  tft.setCursor(30, 80);
  tft.print("Capacitate");
  tft.setCursor(30, 130);
  tft.print("Intensitatea Luminoasa");
  tft.setCursor(30, 180);
  tft.print("Informatii");
}

void afisareLine() {
  static uint16_t oldMenuLine = 0;
  
  tft.setTextColor(ST77XX_BLACK); 
  tft.setCursor(10, menuLineNumber[oldMenuLine]);
  tft.print('>');
  tft.setTextColor(ST77XX_WHITE); 
  oldMenuLine = menuLine;
  tft.setCursor(10, menuLineNumber[menuLine]);
  tft.print('>');
}

void setup() {
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
 
  pinMode(    upButtonPin, INPUT_PULLUP);  // Setare buton Up ca INPUT_PULLUP
  pinMode(  downButtonPin, INPUT_PULLUP);  // Setare buton Down ca INPUT_PULLUP
  pinMode(selectButtonPin, INPUT_PULLUP);  // Setare buton Select ca INPUT_PULLUP
  pinMode(  backButtonPin, INPUT_PULLUP);
  Wire.begin();
  lightMeter.begin();
  tft.init(240, 320);  // Initializare ecran 240x320 pixeli
  tft.setRotation(1);  // Rotire ecran
 
  tft.setTextColor(ST77XX_WHITE);  // Text alb
  tft.setTextSize(2);  // Dimensiune text
  afisaremeniu();  // Afi?eaza meniul ini?ial
  afisareLine();
   Serial.begin(9600);
}

void loop() {
  static button_t oldButton = NONE;
  if     (digitalRead(    upButtonPin) == RELEASED) { button = UP;}
  else if(digitalRead(  downButtonPin) == RELEASED) { button = DOWN;}
  else if(digitalRead(selectButtonPin) == RELEASED) { button = SELECT;}
  else if(digitalRead(  backButtonPin) == RELEASED) { button = BACK;}
  else { button = NONE;}

  if (oldButton != button) {
    oldButton = button;
    switch (button) {
      case UP:  // Navigare în meniu folosind butonul Up (BU)
        if (menuLine == 1) {
          menuLine = 4;  // Revin la ultimul meniu daca scade sub 1
          
        }
        else {
          menuLine--;  // Mergem la meniul anterior
        }
        afisareLine();  // Actualizeaza meniul pe ecran
        break;
        
      case DOWN:  // Navigare în meniu folosind butonul Down (BD)
        if (menuLine == 4) {
          menuLine = 1;   // Revin la primul meniu daca depa?e?te 3
        }
        else {
          menuLine++;     // Trecem la urmatorul meniu
        }
        afisareLine();    // Actualizeaza meniul pe ecran
        break;
      case SELECT:  // Executa ac?iunea selectata cu butonul Select (BS)
        actiune();  // Executa ac?iunea pentru meniul curent
        // bs_apasat = true;
        break;
      case BACK:  // Back
        measurePtr = NULL;
        afisaremeniu();
        afisareLine();  // Actualizeaza meniul pe ecran
        break;
        
    }
  }
  if (measurePtr) (*measurePtr)();
  millis();
}

void actiune() {
  switch (menuLine) {
    case 1:
      tft.fillScreen(ST77XX_BLACK);
      tft.setCursor(10, 30);
      tft.print("Masurare rezistenta:");
      measurePtr = masurareRezistenta;
      break;

    case 2:
      tft.fillScreen(ST77XX_BLACK);
      tft.setCursor(10, 30);
      tft.print("Masurare Capacitate:");
      measurePtr = masurareCapacitate;
      break;
    case 3:
      tft.fillScreen(ST77XX_BLACK);
      tft.setCursor(10, 30);
      tft.print("Masurare Iluminarii");
      measurePtr = masurareLumina;
      break;
    case 4:
      tft.fillScreen(ST77XX_BLACK);
      tft.setCursor(10, 30);
      tft.print("Dispozitiv electronic ");
      tft.setCursor(0, 50);
      tft.print(" portabil pentru masurarea");
      tft.setCursor(0, 70);
      tft.print("componentelor si marimilor");
      tft.setCursor(0, 90);
      tft.print("electrice ");
      break;
  }
}
void masurareRezistenta() {
    raw = analogRead(analogPin);
    if(raw){
    buffer = raw * Vin;
    Vout = (buffer)/1024.0;
    buffer = (Vin/Vout) - 1;
    R2= (R1 * buffer);

  tft.fillRect(10, 50, 220, 30, ST77XX_BLACK);  // Cura?a zona de afi?are
  tft.setCursor(10, 50);

  if (R2 > 3000000.0) {  // Rezisten?a infinita sau foarte mare
    tft.print("R: Inf");
  }
  else if (R2 > 999.0) {  // Conversie la kOhm
    tft.print("R: ");
    tft.print(R2 / 1000.0, 2);  // 2 zecimale pentru precizie
    // tft.print(" kΩ");
    tft.print(" kOhm");
  }
  else {  // Rezisten?a în Ohmi
    tft.print("R: ");
    tft.print(R2, 2);  // 2 zecimale pentru precizie
    // tft.print(" Ω");
    tft.print(" Ohm");
  }
    }
  delay(100);
}
void masurareCapacitate() {
    tft.fillRect(10, 50, 220, 30, ST77XX_BLACK);  // Cura?a zona de afi?are
    tft.setCursor(10, 50);
    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_PIN);
    digitalWrite(OUT_PIN, LOW);

    if (val < 1000){
      pinMode(IN_PIN, OUTPUT);

      float capacitance =  (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val) ;

      //tft.print(F("Capacitance Value = "));
      tft.print(capacitance, 3);
      tft.print(F(" pF "));

    }

    else{
      pinMode(IN_PIN, OUTPUT);
      delay(1);
      pinMode(OUT_PIN, INPUT_PULLUP);
      unsigned long u1 = micros();
      unsigned long t;
      int digVal;

      do{
        digVal = digitalRead(OUT_PIN);
        unsigned long u2 = micros();
        t = u2 > u1 ? u2 - u1 : u1 - u2;
      } while ((digVal < 1) && (t < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_PIN);
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t / 1000L) * 5;
      delay(dischargeTime);   
      pinMode(OUT_PIN, OUTPUT);  
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);

      float capacitance = -(float)t / R_PULLUP / log(1.0 - (float)val / (float)MAX_ADC_VALUE ) ;

      if (capacitance  > 1000.0){
        tft.print(capacitance / 1000.0, 2);
        tft.print(F(" uF"));
      }
      else{
        tft.print(capacitance, 2);
        tft.print(F(" nF"));
      }
    }
    while (millis() % 1000 != 0); 

    if (digitalRead(backButtonPin) == RELEASED) {
    measurePtr = NULL;
    afisaremeniu();
    afisareLine();
    return;
  }
    // Do nothing until capacitor is discharged      
}
 void masurareLumina() {
  float lux = lightMeter.readLightLevel();
   tft.fillRect(10, 50, 220, 30, ST77XX_BLACK);  // Cura?a zona de afi?are
   tft.setCursor(10, 50);
   tft.print(lux);
   tft.print(" lx");
   delay(200);
   
   }