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:
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:
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
- 1 x Nano V3.0 mit ATmega328
- Widerstände: 2 x 1 KOhm, 1 x 10 KOhm, 1 x 220 Ohm
- 1 x 0,91 Zoll OLED I2C Display 128x32 Pixel
- 1 x Schalter
- Kondensatoren
- Verbindungskabel mit Breadboard im Set (oder pin header sockets mit PCB platine)
Projektschaltung
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
// Width screen OLED
// 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//
// 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
Danke an Miguel Torres Gordo für diesen Beitrag.
8 Kommentare
Robert Baptist
Andreas, Vielen Dank fur die Antwort. und Grusse an Miguel.
RB
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
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
Danke für den Hinweis zum Schaltplan. Der wurde von uns aktualisiert.
Grüße,
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
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
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
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