Prototyp eines Kapazitätsmessgerätes - AZ-Delivery

Der folgende Beitrag wurde uns von dem Leser Miguel Torres Gordo zugesandt. Viel Spaß beim Lesen und nachbasteln!

Dies ist der Prototyp zum Messen der Kapazität eines Kondensators mit ATMega328p. Wie die meisten wissen, haben die digitalen Pins des Mikrocontrollers eine Ausgangsspannung von 5 Volt. Wir werden diese Spannung und die ADC-Funktion der analogen Pins nutzen, um die notwendigen Berechnungen durchzuführen und auf diese Weise die Kapazität der Kondensatoren zu ermitteln.

Zunächst ein kurzes Detail über die Aufladung der Kondensatoren. Die einfachste Schaltung zum Laden eines Kondensators und seine Ladungskurve sind:

Schaltbild und Ladekurve

Wenn wir einen Kondensator an eine Spannung anschließen, können wir die Zeit bestimmen, die es braucht, um auf 63,2% der Versorgungsspannung aufzuladen, indem wir die Gleichung

T = R * C

verwenden, wobei T die Zeitkonstante in Sekunden ist, R der Widerstand in Ohm des Stromkreises und C der Wert des Kondensators in Farad.

Wie kann man dann die Zeit ermitteln, die benötigt wird, um auf 63,2 % aufzuladen? Die Antwort lautet: mit Hilfe des ADC in den Analog-Ports, denn 63,2 % von 5 Volt sind 3,16 Volt. Die vereinfachte Schaltung ist:

vereinfachte Schaltung

Das Projekt verfügt über einen Schalter zur Auswahl der Messung von Kondensatoren in den Bereichen µF-nF oder nF-pF, sowie einen OLED-Bildschirm zur Anzeige der Messungen.

Materialien

Projektschaltung

Schaltplan

Messschaltung für hohe Werte (F-nF), Auswahl von Pin D6 mit dem Schalter

Wir beginnen mit dem Aufladen des Kondensators mit Pin A2 durch den 10K-Widerstand, gleichzeitig starten wir einen Timer und messen die Spannung an Pin A0. Wir wissen, dass die von den Pins gelieferte Spannung 5 V beträgt. Mit dem ADC wissen wir also, dass 5 V dem digitalen Wert 1023 entspricht und 63,2 % von 5 V gleich 3,16 V sind, was dem Wert 648 entspricht. Wenn der Messwert von Pin A0 den Wert 648 erreicht, stellen wir die Spannungsversorgung ein und stoppen den Timer. Anschließend wird die Zeit dividiert, die durch den 10K-Widerstand verwendet wird, um den Wert des Kondensators zu ermitteln, dann wird der Kondensator entladen.

Messschaltung für kleine Werte (nF-pF), Auswahl von Pin D5 mit dem Schalter

Für niedrige Werte verwenden wir die gemessene Last an den Pins A3 bzw. A0. Wir legen die 5V-Spannung an Pin A3 über den 220-Ohm-Widerstand an und beginnen, den Kondensator zu laden. Wir verwenden den ADC von Pin A0. Wenn der Wert kleiner als 976 ist, bedeutet das, dass sich der Wert des Kondensators im pF-Bereich befindet. Wir führen die notwendigen Berechnungen mit der Messung und des Fehlerbereichs des Innenwiderstands des Nano V3.0 mit dem Außenwiderstand durch.

Wenn der Wert an A0 größer als 976 ist, dann stellen wir Pin A0 ein, um 5V am Ausgang zu liefern und Pin A3, um die Spannung zu lesen. Wir zählen die Zeit in Mikrosekunden und wenn in einer Zeit von 400 ms die Spannung nicht 5V erreicht, führen wir die Berechnungen der Kondensatorkapazität mit dem Wert des internen Pull-up-Widerstandes, der Zeitmessung und dem Umwandlungswert des ADC der Spannungsmessung in A3 durch. Wenn das Ergebnis des Wertes größer als 1000 ist, erfolgt die Messung in µF, wenn sie kleiner ist, erfolgt sie in pF.

Quellcode

Es folgt der Quellcode des Sketches für die Arduino-IDE (Download). Es müssen zwei Bibliotheken installiert werden. 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.

 /* Miguel Torres Gordo - Capacitence Meter */
 
 //OLED screen config
 #include <SPI.h>
 #include <Wire.h>
 #include <Adafruit_GFX.h>
 #include <Adafruit_SSD1306.h>
 
 #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

Projektaufbau

22pF

47µF

47µF discharging

100 µF

100µF discharging

 

Danke an Miguel Torres Gordo für diesen Beitrag.

Für arduinoGrundlagen elektronik

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. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery