Prototyp eines Kapazitätsmessgerätes

The following post was sent to us by the reader Miguel Torres Gordo. Have fun reading and building the project!

This is the prototype for measuring the capacity of a capacitor with atmega328p. Like most know, the microcontroller's digital pins have an output voltage of 5 volts. We will use this tension and the ADC function of the analog pins to perform the necessary calculations and thus determine the capacitance of the capacitors.

First, a brief detail about the charging of the capacitors. The simplest circuit for loading a capacitor and its charge curve are:

Switch panel and charging curve

If we connect a capacitor to a voltage, we can determine the time it takes to charge to 63.2% of the supply voltage by using the equation

T = R * C

use, where T the time constant is in seconds, R the resistance in ohms of the circuit and C The value of the capacitor in Farad.

How can you then determine the time needed to charge to 63.2%? The answer is: With the help of the ADC in the analog ports, because 63.2% of 5 volts are 3.16 volts. The simplified circuit is:

Simplified circuit

The project has a switch to select the measurement of capacitors in the areas μF-NF or NF-PF, as well as an OLED screen for displaying the measurements.

Materials

Project circuit

Circuit

Measuring circuit for high values ​​(F-NF), selection of PIN D6 with the switch

With the charging of the capacitor with pin A2 through the 10k resistor, at the same time we start a timer and measure the voltage to pin a0. We know that the voltage supplied by the pins is 5 V. With the ADC we know that 5 V corresponds to the digital value 1023 and 63.2% of 5 V are 3.16 V, which corresponds to the value 648. When the measured value of pin A0 reaches the value 648, we set the power supply and stop the timer. Subsequently, the time is divided, which is used by the 10K resistor to determine the value of the capacitor, then the capacitor is discharged.

Measuring circuit for small values ​​(NF-PF), selection of PIN D5 with the switch

For low values, we use the measured load to the pins A3 or A0. We attach the 5V voltage to pin A3 over the 220 ohm resistor and begin to load the capacitor. We use the ADC from PIN A0. If the value is less than 976, that means that the value of the capacitor in the pf-Area is located. We carry out the necessary calculations with the measurement and the error range of the internal resistance of Nano V3.0 with the external resistance.

If the value of A0 is greater than 976, then we introduce pin A0 to supply 5V at the output and pin A3 to read the voltage. We count the time in microseconds and when the voltage does not reach 5V in a period of 400 ms, we carry out the calculations of the capacitor capacity with the value of the internal pull-up resistor, the time measurement and the conversion value of the ADC's voltage measurement in A3. If the result of the value is greater than 1000, the measurement takes place in μFif it is smaller, it takes place in pf.

Source code

It follows the source code of the sketch for the Arduino IDE (Download):

 / * Miguel Torres Gordo - Capacitence Meter * /
 
 // OLED SCREEN CONFIG
 #include
 #include
 #include
 #include
 
 #define SCREEN_WIDTH 128       // Width screen OLED
 #define SCREEN_HEIGHT 32       // Height screen OLED
 
 // Adafruit_SSD1306 class object
 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // -1 if sharing Arduino reset pin
 
 // Switch to select values to measure
 int ScalepF=5;
 int ScalenF=6;
 
 //High values//
 #define analogPin     A0
 #define chargePin     A2
 #define dischargePin   A1
 #define resistorValue 10000.0F // 10K resistor value to charge the capacitor
 
 unsigned long startTime;
 unsigned long elapsedTime;
 float microFarads;                
 float nanoFarads;
 
 //Low values//
 const int OUT_PIN = A3;
 const int IN_PIN = A0;  
 const float IN_STRAY_CAP_TO_GND = 50.28;     // Value with 220 resistors
                                               
 const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
 const float R_PULLUP = 30.0;  
 const int MAX_ADC_VALUE = 1023;
 
 void setup() {
   Serial.begin(9600);
   delay(100);
   Serial.println("Initializing OLED display");
 
   // Start OLED display at address 0x3C
   if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("OLED screen not found"));
  for(;;); // Don't proceed, loop forever
  }
 
   pinMode(ScalepF, INPUT);
   pinMode(ScalenF, INPUT);
 
   pinMode(OUT_PIN, OUTPUT);
   pinMode(IN_PIN, OUTPUT);
   pinMode(chargePin, OUTPUT);    
 }
 
 void loop() {
 
   /***************************   HIGH VALUES: SCALE 4F - 100nF   ****************************************/
 
   if (digitalRead(ScalenF)) {
   
     pinMode(OUT_PIN, OUTPUT);
     digitalWrite(OUT_PIN, LOW);         // A3 like GND
     pinMode(analogPin, INPUT);           // A0 read the voltage
   
     digitalWrite(chargePin, HIGH);  
     startTime = micros();
 
     while (analogRead(analogPin) < 648) {   }     // The capacitor is charging
 
     elapsedTime = micros() - startTime;
     microFarads = ((float)elapsedTime / resistorValue);
     
     if (microFarads > 1) {
 
    display.clearDisplay();                                 // Clean buffer
    display.setTextSize(1);                                 // Text size
    display.setTextColor(SSD1306_WHITE);                   // Color text
    display.setCursor(1, 2);                               // Text position
    display.println("Scale: 4F-100nF");
    display.setCursor(1, 12);
    display.println(microFarads);
    display.setCursor(50, 12);
    display.println("uF");
    display.display();                                     // Display text on screen
    delay(500);
 
    } else {
 
    nanoFarads = microFarads * 783;
    display.clearDisplay();                                 // Clean buffer
    display.setTextSize(1);                                 // Text size
    display.setTextColor(SSD1306_WHITE);                   // Color text
    display.setCursor(1, 2);                                      // Text position
    display.println("Scale: 4F-100nF");
    display.setCursor(1, 12);
    display.println(nanoFarads);
    display.setCursor(50, 12);
    display.println("nF");
    display.display();                                     // Display text on screen
    delay(500);
 
    }
   
     digitalWrite(chargePin, LOW);            
     pinMode(dischargePin, OUTPUT);            
     digitalWrite(dischargePin, LOW);         // Discharging the capacitor
   
     while (analogRead(analogPin) > 0) {   }     // Waits till the capaccitor is discharged
 
     pinMode(dischargePin, INPUT);             // This sets the pin to high impedance
   
     display.setTextSize(1);                                 // Text size
     display.setTextColor(SSD1306_WHITE);                   // Color text
     display.setCursor(1, 22);                               // Text position
     display.println("DISCHARGING.....");     // Message to display
     display.display();                                     // Display text on screen
     delay(1000);
 
   
  }
 
   /****************************   LOW VALUES SCALE 1nF - 1pF   ***************************/
 
   if (digitalRead(ScalepF)) {
     
     pinMode(chargePin, INPUT);
     pinMode(dischargePin, INPUT);       // Configure ports with high impedance because it is not used
 
     pinMode(IN_PIN, INPUT);
     digitalWrite(OUT_PIN, HIGH);
     int val = analogRead(IN_PIN);
     digitalWrite(OUT_PIN, LOW);
 
     if (val < 976) {
       
       pinMode(IN_PIN, OUTPUT);
 
       float capacitance = ((float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val))/2;                        
           
       display.clearDisplay();                                 // Clean buffer
       display.setTextSize(1);                                 // Text Size
       display.setTextColor(SSD1306_WHITE);                   // Color text
       display.setCursor(1, 2);                               // Text position
       display.println("Scale: 1nF-1pF"); // Message to display
       display.setCursor(1, 12); // Text position
       display.println(capacitance); // Value to display
       display.setCursor(50, 12);
       display.println("pF");
       display.display();                                     // Display text on screen
       delay(200);
 
    } 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) {
         display.clearDisplay();                                 // Clean buffer
         display.setTextSize(1);                                 // Text size
         display.setTextColor(SSD1306_WHITE);                   // Color text
         display.setCursor(1, 2);                               // Text position
         display.println("Scale: 1nF-1pF");
         display.setCursor(1, 12);
         display.println(capacitance/1000.0, 3);
         display.setCursor(50, 12);
         display.println("uF");
         display.display();                                     // Display text on screen
         
         delay(200);    
       
      } else {
         display.clearDisplay();                                
         display.setTextSize(1);                                
         display.setTextColor(SSD1306_WHITE);                  
         display.setCursor(1, 2);                              
         display.println("Scale: 1nF-1pF");
         display.setCursor(1, 12);
         display.println(capacitance, 3);
         display.setCursor(50, 12);
         display.println("pF");
         display.display();                                    
         
         delay(200);
      }
    }        
     while (micros() % 1000 != 0);
  }
 }

Projektfotos

Project structure

Powder

47μF

47μF Discharging

100 μF

100μF Discharging


Danke an Miguel Torres Gordo für diesen Beitrag.

For arduinoBasics electronics

8 comments

Robert Baptist

Robert Baptist

Andreas, Vielen Dank fur die Antwort. und Grusse an Miguel.
RB

Andreas Wolter

Andreas Wolter

@Robert Baptist: ich habe das an den Autoren weitergegeben und folgendes von ihm zurück erhalten:

Der Wert 783 in der Skizze des Schaltungsaufbaus ist die Anpassung, die ich mit verschiedenen Werten vornehmen musste, um den richtigen Wert der Kondensatoren zu erhalten, da die Messwerte für Kondensatoren mit sehr niedrigen Werten in nF sind und die Toleranzen der elektronischen Komponenten es unmöglich machen, dass man Werte mit der idealen Umrechnung von 1 µF = 1000 nF erhält.

Der Wert der internen Pull-up-Widerstände des Arduino sind 10K, aber ich denke, worauf Sie sich beziehen, sind die Werte der Konstanten R_PULLUP = 30.0 und IN_STRAY_CAP_TO_GND = 50.28. Diese Werte werden verwendet, um die Berechnungen der Kondensatorwerte (mit dem Selektor für niedrige Kondensatorwerte) am ADC auzulesen mit der Spannungen an Pin A3 mit einem Serienwiderstand von 220 Ohm und A0.

Robert Baptist

Robert Baptist

Guten Tag.
Woher (und warum) kommt der Wert 783 in der Linie 92 nanoFarads = microFarads * 783 in diesem “Prototyp eines Kapazitätsmessgerätes” Projekt ? Warum nicht 1000?
Welche sind die Einheiten für den Pull-Widerstand und die parasitäre Kapazität ?Kohm und pF?
Danke fuer die Erklarung.

Andreas Wolter

Andreas Wolter

Danke für den Hinweis zum Schaltplan. Der wurde von uns aktualisiert.

Grüße,
Andreas Wolter

Andreas Wolter

Andreas Wolter

@Wolfgang Rind: ich vermute, dass die Bibliothek für das Display nicht installiert wurde. Dazu müssen Sie den Bibliothekenverwalter öffnen (Werkzeuge → Bibliotheken verwalten… oder STRG+UMSCHALT+i). In das Suchfeld SSD1306 eingeben und die Bibliothek Adafruit_SSD1306 installieren. Falls es nicht gleich automatisch mit installiert wird, muss auch Adafruit_GFX installiert werden. Dann sollte es funktionieren. Ich ergänze das im Beitrag.

Grüße,
Andreas Wolter

Wolfgang Rind

Wolfgang Rind

Hallo, Ursache gefunden, SSD1306 2.4.7 installiert und im Schaltplan ist die Verdrahtung vom Bereichs Schalter verkehrt, blau und braun sind vertauscht.

Wolfgang Rind

Wolfgang Rind

Hallo, habe den Sketch geladen, bei der Überprüfung kommt die Fehlermeldung:
exit status 1
‘SSD1306_WHITE’ was not declared in this scope
was muss ich Ändern?

DIYLAB

DIYLAB

Hallo zusammen,
hier wäre dann z.B. noch der größere Bruder dieses Projekts, ein LCR-Meter mit dem Nano:
https://github.com/gavinlyonsrepo/LCR_meter
Falls ihr eh beim Basteln seid ;)

Viele Grüße
DIYLAB
www.diylab.de

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN