
ESP32 ADC und DAC
Elektronik-Labor Projekte AVR

Alle arbeiten mit ESP-Controllern, und ich bin damit bisher nicht warm
geworden. Jetzt möchte ich diese Bildungslücke schließen und habe mir
ein ESP32 WROOM-32 Development Board besorgt. Zuerst interessieren mich
nur die Eigenschaften des Controllers und seine Peripherie, also Ports,
ADC und DAC. Alles wird mit der Arduino-IDE getestet.
Die Anordnung der Portanschlüsse ist einigermaßen verwirrend, weil sie
nicht in einer Reihe liegen, sonders sehr gewürfelt aussehen. Und ich
musste erst herausbekommen, dass man alle Ports und auch die
ADC-Anschlüsse einfach nach der GPI-Nummer benennt.
analogRead(39) meint ADC1_CH3 am Pin GPI39
dacWrite (25, 255) meint DAC_1 am Pin GPI25
// These constants won't change. They're used to give names to the pins used:
const int analogInPin = 39; // Analog input pin
const int analogOutPin = 25; // Analog output pin
Zuerst habe ich das Beispielprogramm AnalogInOutSerial.ino geladen und
die Anschlüsse angepasst. Der erste Test lief erst, nachdem ich
verstanden hatte, da ich bei der Meldung Download auf den Boot-Knopf
drücken muss. Und bei weiteren Versuchen musste ich erst lernen, dass
ein Upload nicht funktioniert, wenn der Serielle Plotter oder der
Serielle Monitor noch aktiv ist, ganz anders als beim Arduino, wo er
dann automatisch geschlossen wird, um die COM freizumachen.
Also gut, da kommen Messwerte. Dann kann ich ja mal testen, wie
hochohmig der analoge Eingang ist. Dazu schließe ich einen
Folienkondensator mit 10 nF an und lade ihn kurz auf. Je langsamer er
sich entlädt, desto hochohmiger ist der Eingang. Mein Eindeuck ist,
langsam genug, ausreichend hochohmig.
Gegen Ende der Messung zeigte sich eine starke Abweichung von der
normalen Entladekurve. Vergleichsmessungen haben zu dem Ergebnis
geführt, dass der ADC seinen Nullpunkt bei ca. 0,2 V sieht.
Nächster Versuch, diesmal mit den DAC. Ich lasse ihn gleichmäßig hochzählen und messe die Ausgangsspannung mit dem ADC.
void loop() {
for (int n = 0; n<256; n++){
dacWrite(25,n);
delay(100);
Serial.print("DAC = ");
Serial.print(n);
int d = analogRead(39) / 16;
Serial.print(" ADC = ");
Serial.println(d);
}
}
Hier sieht man den Offset von ca. 0,2 V und außerdem eine erhebliche
Nichtlinearität. Nicht gut! Und außerdem war ich verwirrt, weil ich
gelesen hatte, dass die ADC-Referenz 1,1 V ist, aber ich konnte bis ca.
3,3 V messen. Eigentlich waren es nur ca. 2,8 V, weil auch die 5 V vom
USB deutlich kleiner waren. Ich verwende nämlich einen Hub, und der hat
in der Versorgungsleitung eine Diode und noch eine zusätzliche
PTC-Sicherungen. Das schützt den PC im Fehlerfall und hat sonst meist
keine großen Auswirkungen. Aber der ESP32 ist wesentlich durstiger,
weshalb die Spannung so stark einbricht, dass der Spannungsregler nicht
mehr auf 3,3 V stabilisieren kann.
Der entscheidende Tipp kam von https://forum.arduino.cc/t/fixing-the-non-linear-adc-of-an-esp32/699190
Der AD-Wandler verwendet tatsächlich eine Referenz von 1,1 V.
Zusätzlich gibt es aber einen Abschwächer, der standardmäßig 11 dB
abschwächt und damit den Bereich auf 3,3 V erweitert. Die beobachteten
Schwächen kommen tatsächlich nicht vom AD-Wandler, sondern vom
Abschwächer. Ich vermute, das ist kein Spannungsteiler, sondern eine
Zauberschaltung mit geschalteten Kondensatoren, die aber gewisse
Nebenwirkungen hat. Mit analogSetAttenuation(ADC_0db); kann man den
Abschwächer ausschalten und hat dann den AD-Wandler in seiner Reinform
mit einem Bereich bis 1,1 V. Weil der Testaufbau höhere Spannungen
liefert, wurde ein Widerstand von 10 k zwischen DA und AD geschaltet.
void setup() {
Serial.begin(9600);
analogSetAttenuation(ADC_0db);
}
Der AD-Wandler zeigt nun eine gute Linearität. Damit kann man arbeiten.
Gegen das Rauschen dürfte eine Mittelung über viele Messwerte helfen.
Elektronik-Labor Projekte AVR