ADS1115-Modul auf dem Breadboard

Analogwerte messen mit dem ADS1115

Mit dem ADS1115-Modul (oder breakout board) ist es möglich, Analogwerte deutlich genauer zu messen, als es ein ESP32 oder Arduino kann. Der ADC (Analog-Digital-Konverter) misst an vier Eingängen (Kanälen) Analogwerte mit einer Auflösung von 16 Bit und gibt die Daten per I2C-Schnittstelle an den Mikrocontroller aus. Außerdem verfügt der ADS1115 über eine bis zu 16-fache Verstärkung, differenzielle Messung und eine konfigurierbare I2C-Adresse.

Die Analog-Digital-Konverter (ADC) des ESP32

Der ESP32 besitzt zwei eingebaute ADCs mit einer Auflösung von bis zu 12 Bit (d.h. mit Messwerten zwischen 0 und 4095); die Eingangsspannung beträgt max. 3,3 Volt. In den Diagrammen der Pinbelegungen (auch pinout reference) werden sie meist mit ADC1_CHx und ADC2_CHx bezeichnet, wobei das „CH” für Kanal (Eingang; channel) steht. Nutzbar sind 6 Kanäle des ADC1 (CH0, CH3-CH7) und 10 Kanäle des ADC2 (CH0-CH9). ADC2 steht im WiFi-Betrieb nicht zur Verfügung – will man das WLAN nutzen, muss man sich auf ADC1 beschränken.

Die Messwerte der ADCs des ESP32 haben leider keinen linearen Verlauf. In den Randbereichen (bis etwa 0,1 V und größer als 3,1 V) sind die Messwerte sehr ungenau bzw. nicht zu gebrauchen, weil sie sich kaum ändern. Egal ob die Eingangsspannung 0 oder 0,1 Volt beträgt – der ESP32 liest einen Messwert von 0. Ebenso ist es an der oberen Grenze – ab etwas über 3,1 V wird der Messwert 4095 ermittelt. (Man kann das mit einer einfachen Schaltung selber testen. Mehr dazu weiter unten.)

Das ist keine Einschränkung, wenn man über den analogen Messwert bspw. die Helligkeit einer LED oder die Drehzahl eines Motors steuern will. Das exakte Messen analoger Daten eines Sensors ist mit dem ESP32 so aber nicht möglich.[1]Bspw. liefert der Temperatursensor LM35DZ Spannungswerte zwischen 0 und 1 Volt, um Temperaturen von 0-100°C anzuzeigen. 1 mV enstspricht dabei 0,1°C. Werte unterhalb von 10°C könnte der … Continue reading

Messen analoger Werte mit den Arduinos

Die Arduinos (und ihre Nachbauten) messen Analog-Werte wesentlich besser als der ESP32. Sie lösen zwar „nur” mit 10 Bit (0…1023) über einen Spannungsbereich von 0-5 Volt auf (also mit einer Auflösung von etwa 5 mV), das aber mit guter Genauigkeit und Linearität.

Wenn am Analogeingang nur niedrigere Spannungen anliegen (beim Arduino und Nano maximal 1,1 Volt), kann man die Auflösung der Messungen erhöhen, indem man die Referenzspannung reduziert. Beim Nano und Uno beträgt die Auflösung pro Schritt dann 1,075 mV statt der standardmäßigen 5 mV, ist also fast fünfmal feiner. Details und ein Beispiel liefert der Beitrag zum Temperatursensor LM35DZ.[2]Oder man geht direkt an die Quelle: Arduino Playground und Referenzspannungen der verschiedenen Arduino-Modelle.

Der verbreitete Arduino Uno besitzt 6, der Nano 8 analoge Eingänge; eine Übersicht über andere Modelle gibt die Arduino-Dokumentation der Funktion analogRead().

Will man dem ESP32 zu guten analogen Messwerten verhelfen oder benötigt beim Arduino eine höhere Auflösung, kann man dazu den ADS1115 nutzen (oder einen ähnlichen Chip wie den ADS1015, der sich vor allem durch seine kleinere Auflösung von 12 Bit vom ADS1115 unterscheidet). Auch am Rapberry Pi, der keine analogen Eingänge besitzt, kann so ein ADC-Modul sehr nützlich sein.

Datenblatt und technische Daten des ADS1115

Datenblatt beim Hersteller Texas Instruments: www.ti.com/lit/ds/symlink/ads1115.pdf

  • Versorgungsspannung: VDD 2 – 5,5 Volt
  • Auflösung: 16 Bit
  • 4 Kanäle: 4 single-ended oder 2 differenzielle Messungen
  • Eingangsspannung: -0,3 bis VDD + 0,3 V
  • programmierbare Sample-Rate von 8 – 860 Samples (Messungen) pro Sekunde
  • Verstärker (PGA; programmable gain amplifier) mit 6 Stufen: 2/3 (Standard),[3]Auch bei der Wahl des Verstäkrungsfaktors von 2/3 – also mit einer internen Abschwächung des Signals – darf das Signal nicht die maximale Eingangsspannung von VDD + 0,3 Volt … Continue reading 1-, 2-, 4-, 8- und 16-fach
  • 4 I2C-Adressen; Standard: 0x48 (0x49, 0x4A und 0x4B konfigurierbar)
  • Alarmfunktion

Platinen mit dem ADS1115 werden bspw. von Adafruit angeboten; es gibt auch günstigere Nachbauten.[4]Das Original-Breakout-Board von Adafruit kostet bei Reichelt Elektronik 17,60 €. Nachbauten gibt es im deutschen Versandhandel zu Preisen von gut 4 bis über 8 € (z.B. bei AZ-Delivery … Continue reading

Anschlüsse des ADS1115

Pinbelegung des ADS1115-Moduls
Pinbelegung des ADS1115-Moduls

Die Platine wird mit loser Pinleiste geliefert, d.h. man muss die Anschlusspins selbst anlöten.

  • VDD: Versorgungsspannung
  • GND: Masse
  • SCL und SDA: I2C-Anschlüsse
  • ADDR: Auswahl der I2C-Adresse
  • ALRT: Alarm (alert); geht auf LOW, wenn ein programmierbarer Vergleichswert überschritten wird
  • A0 – A3: Kanäle 0 – 3 für 4 single-ended oder zwei differenzielle Messungen

Änderung der I2C-Adresse

Als Standardadresse ist 0x48 voreingestellt. Will man mehrere (bis zu 4) Boards an einem I2C-Bus betreiben, müssen diese unterschiedliche Adressen haben. Beim ADS1115 ist das möglich, indem man den ADDR-Pins mit einem der Anschlüsse VDD, GND, SDA oder SCL verbindet (z.B. mit einer Steckbrücke auf dem Breadboard):[5]siehe Datenblatt Seite 23

  • GND: 0x48 (entspricht dem Standard; auch bei offener Verbindung)
  • VDD: 0x49
  • SDA: 0x4A
  • SCL: 0x4B[6]Die Nutzung dieser Adresse ist mir nicht gelungen. Bei Verbindung von ADDR- und SCL-Pin wird das Modul nicht von einem I2C-Scanner gefunden. Dafür dauert der Scan, der sonst den kompletten … Continue reading

Single-ended und differenzielle Messungen

Mit einer single-ended-Messung kann man an den Eingängen A0 – A3 parallel bis zu vier Werte messen. „Single-ended” bedeutet, dass nur ein Signal-Anschluss verwendet wird. Um die anliegende Spannung zu bestimmen, wird die Differenz zum Masse-Anschluss (GND) des Chips gemessen. Die Auflösung beträgt 15 Bit, da nur positive Spannungen gemessen werden.

Differenzielle Messungen messen die Spannungsdifferenz zwischen zwei Kanälen. Hierbei sind auch negative Differenzen möglich, sodass die Auflösung inkl. Vorzeichen 16 Bit beträgt. Es sind zwei parallele Messungen möglich: A0-A1 und A2-A3. Insbes. bei längeren Verbindungen oder starkem Rauschen sollte lt. Adafruit diese Methode gewählt werden, ebenso beim Verstärken schwacher Signale, da dabei auch das Rauschen verstärkt wird.

Achtung! (Bild von Clker-Free-Vector-Images auf Pixabay; freie kommerzielle Nutzung)Die zu messenden Spannungen an den Eingängen dürfen die Versorgungsspannung VDD des Moduls nicht wesentlich überschreiten – bei den ESPs also 3,3, bei den Arduinos 5 Volt. (Wenn man das Modul am ESP betreibt und eine Eingangsspannung bis 5 V nutzen will, kann man das Modul über den VIN-Pin des ESP mit 5 V versorgen.)
Das gilt auch, wenn man mit der (voreingestellten) 2/3-Verstärkung arbeitet!
Das Datenblatt nennt als absolute Grenzen -0,3 Volt bis VDD + 0,3 Volt.

Bibliothek Adafruit_ADS1x15

Ich nutze die Bibliothek Adafruit_ADS1x15. Sie ist in der Arduino-Bibliotheksverwaltung z.B. mit dem Suchbegriff „ads1” zu finden (wegen des „x” im Namen aber nicht mit „ads1115”). So findet man auch mehrere Bibliotheken anderer Entwickler.

Für eine manuelle Installation kann man sie von Github herunterladen: github.com/adafruit/Adafruit_ADS1X15/. (Eine Anleitung zur Installation der Bibliotheken liefert der Beitrag »Arduino-IDE: Bibliotheken verwalten«.)

Die Bibliothek unterstützt auch den Chip ADS1015; sie stellt u.a. folgende Funktionen zur Verfügung:

  • void begin(uint8_t i2c_addr = ADS1X15_ADDRESS, TwoWire *wire = &Wire);
    Bei der Initialisierung kann man eine andere als die Standard-I2C-Adresse setzen und ein eigenes I2C-Datenobjekt übergeben, wenn man will.[7]Das ist dann nötig, wenn man nicht die Standard-Anschlüsse des ESP32 für I2C verwendet; ausführliche Hinweise enthält der Beitrag »I2C-Schnittstellen am ESP32 und Arduino«.
  • void setGain(adsGain_t gain);
    Einstellen der Verstärkung; als Parameter wird einer der Werte GAIN_TWOTHIRDS (Default), GAIN_ONE, GAIN_TWO, GAIN_FOUR, GAIN_EIGHT oder GAIN_SIXTEEN übergeben.
    Die Verstärkung muss zum Signal passen – das verstärkte Signal darf nicht die Versorgungsspannung überschreiten. Erwartet man z.B. ein Signal zwischen 0 und 3,3 V, ist maximal einfache Verstärkung erlaubt.[8]In der Adafruit Header-Datei gibt es zur Benutzung der Methode setGain() folgenden Hinweis: »The ADC input range (or gain) can be changed via the following functions, but be careful never to … Continue reading
  • int16_t readADC_SingleEnded(uint8_t channel);
    single-ended Messung; Parameter: Nummer des Kanals (0-3)
  • int16_t readADC_Differential_0_1(); und int16_t readADC_Differential_2_3();
    differenzielle Messung an Kanal 0&1 oder 2&3 (kein Parameter)
  • void startComparator_SingleEnded(uint8_t channel, int16_t threshold);
    Messung eines Kanals mit einem Schwellenwert vergleichen
    Der Schwellenwert wird nicht in Millivolt angegeben, sondern muss als Zahlenwert mit dem zur Verstärkung passenden Multiplikator errechnet werden. Der Multiplikator gibt an, wie vielen Millivolt eine Messwertänderung von 1 entspricht. Er hängt ab von der Auflösung (beim ADS1115 16 Bit, beim ADS1015 12 Bit) und der Verstärkung (gain).
    Beispiel: Bei einfacher Verstärkung entspricht der Schwellenwert von 2 Volt dem Zahlenwert 2000 mV / 0,125 mV = 16000.
    Für den ADS1115 gelten folgende Multiplikatoren:[9]Siehe die mitinstallierten Beispielprogramme singleended.ino und differential.ino.
    • GAIN_TWOTHIRDS → 1 Bit entspricht 0,1875 mV (default)
    • GAIN_ONE → 0,125 mV
    • GAIN_TWO → 0,0625 mV
    • GAIN_FOUR → 0,03125 mV
    • GAIN_EIGHT → 0,015625 mV
    • GAIN_SIXTEEN → 0,0078125 mV
  • int16_t getLastConversionResults();
    letzten Messwert auslesen (wenn der ADS1115 kontinuierlich misst); deaktiviert den ALRT-Pin bei einer Vergleichsmessung
  • float computeVolts(int16_t counts);
    berechnet aus dem Messwert eine Angabe in Volt

Im Menü Datei → Beispiele / Beispiele aus eigenen Bibliotheken → Adafruit ADS1X15 findet man drei Beispiele, die die wesentlichen Funktionen zeigen. Da sie für den Chip ADS1015 mit 12 Bit Auflösung geschrieben sind, muss man sie für den ADS1115 anpassen; die jeweiligen Stellen sind durch Kommentare gekennzeichnet:

  • singleended.ino: Single-ended-Messung an einem der Kanäle A0 – A3
  • differential.ino: differenzielle Messung
  • comparator.ino: Beim Überschreiten eines Vergleichswerts an einem der Eingänge wird der ALRT-Ausgang aktiviert.

Schaltung und Beispielprogramme

Zum Testen des ADS1115 habe ich eine einfache Schaltung mit einem 10KΩ-Potentiometer aufgebaut. Der mittlere Pin des Potentiometers liefert das zu messende Signal und ist sowohl mit einem analogen Eingang des ESP32 (GPIO 4 bzw. ADC2_CH0; blaues Jumperkabel) als auch mit Kanal A0 des ADS1115 (weißes Jumperkabel) verbunden. Vor GPIO 4 habe ich einen 0,1 µF-Kondensator (100 nF; Beschriftung »104«) gesetzt, wie ihn espressif zur Verbesserung der Stabilität der Messungen empfiehlt.
Für die I2C-Verbindung werden die Standardpins des ESP32 (SCL an GPIO 22, gelbes Kabel; SDA an GPIO 21, grünes Kabel) verwendet.

Im ersten Beispiel wird eine differenzielle Messung durchgeführt, deshalb ist die Masse des Potentiometers mit Kanal A1 verbunden.

Schaltung mit ADS1115, ESP32 und Potentiometer
Schaltung mit ADS1115, ESP32 und Potentiometer

Für das zweite Beispiel (Vergleich mit einem Schwellenwert) habe ich zusätzlich den ALRT-Ausgang mit einem Digitalpin (GPIO 5) verbunden (oranges Jumperkabel).

Ein Beispiel für die Anwendung des ADS1115 enthält der Beitrag zum analogen Temperatursensor LM35DZ.

Beispiel 1: Vergleich der Messwerte ESP32 / ADS1115

Das Programm misst fünfmal pro Sekunde die am Eingabepin (GPIO 4) anliegende Spannung und fragt parallel die gleichen Messungen beim ADS1115 ab, während ich mit dem Potentiometer mehrfach langsam auf- und abwärts durch den Spannungsbereich von 0 bis 3,3 V gewechselt bin. Der ADS1115 hat dabei auch in den Randbereichen, in denen der ESP keine brauchbaren Werte liefert, plausible, lineare Werte gemessen.

  1. /* Abfrage von analogen Werten am ESP32
  2.  *  - per GPIO-Pin
  3.  *  - am ADS1115 mit Weitergabe per I2C
  4.  *
  5.  * 2021-05-28 Heiko (unsinnsbasis.de)
  6.  */
  7.  
  8. #define A_PIN 4  // GPIO-Pin für analoge Eingabe
  9.  
  10. #include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
  11. Adafruit_ADS1115 ads;
  12. #define ADS_I2C_ADDR 0x48
  13. const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung
  14.  
  15. void setup() {
  16.   Serial.begin(115200);
  17.   delay(500);
  18.   Serial.println("Analog-Test ESP32");
  19.  
  20.   ads.begin(ADS_I2C_ADDR, &Wire);
  21.   // Werte 1-fach verstärken (ESP32 liefert  max. 3,3V)
  22.   ads.setGain(GAIN_ONE);
  23. }
  24.  
  25. void loop() {
  26.   int A_Value;         // Messwert per GPIO
  27.   int adc0;            // Messwert an Kanal 0 des ADS1115
  28.   float A_mv, ads_mv;  // Messwert in Millivolt umgerechnet
  29.  
  30.   A_Value = analogRead(A_PIN);  // 0...4095
  31.   Serial.printf("Rohwert: %d", A_Value);
  32.  
  33.   // Wert in Millivolt umrechnen
  34.   A_mv = A_Value * 3300.0 / 4095.0;
  35.   Serial.printf("; %4.2f mV", A_mv);
  36.  
  37.   // Messung per ADS1115
  38.   // - Kanal 0 messen (single-ended)
  39.   // adc0 = ads.readADC_SingleEnded(0);
  40.   // ads_mv = ads.computeVolts(adc0) * 1000;
  41.   // oder
  42.   // - differenzielle Messung an Kanal 0/1
  43.   adc0 = ads.readADC_Differential_0_1();
  44.   ads_mv = adc0 * multiplier;
  45.   Serial.printf("; I2C: %4.2f mV\n", ads_mv);
  46.  
  47.   delay(200);
  48. }

Quellcode auf Github

Hinweise zum Programm:

  1. const float multiplier = 0.125F; // ADS1115-Multiplikator bei einf. Verstärkung

Zum Multiplikator siehe die Erläuterung der Bibliotheksfunktion startComparator_SingleEnded() weiter oben.

  1.   // Messung per ADS1115
  2.   // - Kanal 0 messen (single-ended)
  3.   // adc0 = ads.readADC_SingleEnded(0);
  4.   // ads_mv = ads.computeVolts(adc0) * 1000;
  5.   // oder
  6.   // - differenzielle Messung an Kanal 0/1
  7.   adc0 = ads.readADC_Differential_0_1();
  8.   ads_mv = adc0 * multiplier;

Je nachdem, ob man single-ended oder differenziell messen will, kommentiert man die nicht benötigten Anweisungen aus. Für die Single-ended-Messung sind die Zeilen 39 und 40 zuständig; hier soll aber differenziell gemessen werden, deshalb sind die Zeilen 43 und 44 aktiv.

Messwerte des ESP32-ADC und ADS1115
Messwerte des ESP32-ADC und ADS1115

Das Bild zeigt einen Teil der Ausgabe im seriellen Monitor – hier im Bereich zwischen 0 und gut 100 mV: zuerst den Messwert am ESP32, dann die mit einer einfachen Funktion daraus berechnete Spannung und zum Schluss die per I2C vom ADS1115 übertragenen Werte.
Die einfache Funktion geht von einem linearen Verlauf der Messwerte aus und funktioniert mit den Arduinos gut:
     Spannung = Messwert * max. Spannung / max. Messwert
Für den ESP32 mit 12 Bit Auflösung und 3,3 V Maximalspannung:
     Spannung in Volt = Messwert * 3,3 / 4095
Für die Arduinos mit 10 Bit Auflösung und 5 V Maximalspannung:
     Spannung in Volt = Messwert * 5 / 1023

Insgesamt habe ich knapp 2000 Messwerte gesammelt und daraus ein Diagramm erstellt, das sich so auch an vielen anderen Stellen im Web findet, die sich mit den Analog-Digital-Konvertern des ESP32 beschäftigen.

Diagramm der Messwerte des ESP32-ADCs
Diagramm der Messwerte des ESP32-ADCs

Auf der X-Achse sind die mit dem ADS1115 gemessenen Spannungswerte abgetragen – sie liegen zwischen 0 und 3,276 V (0,25 und 3276 mV), decken also nicht ganz den Bereich von 0 – 3,3 V ab. Die Y-Achse stellt die Rohwerte bei der Messung am ESP32 dar, also Werte von 0 – 4095.

Die Kurve zeigt, dass der ESP32 wie bekannt unterhalb von 0,1 und oberhalb von ca. 3,1 V konstant den Minmal- oder Maximalwert „misst”. Etwa zwischen 0,2 und 2,7 V verläuft die Kurve linear (ist also eine Gerade), danach steigt sie zunehmend steiler an, bis sie bei etwas über 3,1 V ihren Maximalwert erreicht.

Aus den Messwerten zwischen 0,2 und 2 V habe ich mir von Libre Office Calc eine Regressionsfunktion für eine (Ausgleichs-)Gerade berechnen lassen. Daraus ergibt sich die folgende Gleichung, um aus den Messwerten des ESP32 die anliegende Spannung in Millivolt zu berechnen:

     Spannung in Millivolt = (Messwert + 124,38) / 1,239 = Messwert / 1,239 + 100,38

Damit lassen sich für Messwerte zwischen ca. 200 und 3250 (entspricht ca. 0,25 – 2,7 V) Spannungswerte berechnen, die weniger als 1% von den Messwerten des ADS1115 abweichen.[10]Auch der ESP32-Core bietet in den SDK-Bibliotheken Funktionen zum Umgang mit der ADC-Kalibrierung. Man findet die Funktionen in der Datei esp_adc_cal.h im Ordner … Continue reading

Auch für den Bereich oberhalb von 2,7 V ließe sich vermutlich mit einer quadratischen Funktion noch eine gute Annäherung erreichen. Die Frage ist nur, ob sich all der Aufwand lohnt, denn das Grundproblem – die Randbereiche – bekommt man auch mit noch so schönen Korrekturfunktionen nicht in den Griff. Gerade das Messen kleiner Spannungen ist mit den ADCs des ESP32 einfach nicht möglich.

Beispiel 2: Abfrage des ALRT-Pins

Um die Funktionsweise einer Vergleichsmessung (Komparator-Funktion) und die Aktivierung des ALRT-Pins des ADS1115 bei Überschreiten eines Schwellenwerts zu zeigen, ist der ALRT-Pin mit einem Digital-Eingang des ESP32 verbunden (GPIO 5). Eine Reaktion soll bei einem Wert von 2 Volt erfolgen.

Die Methode startComparator_SingleEnded() bewirkt, dass der ADS1115 kontinuierlich am angegebenen Eingang (hier: A0) misst[11]sog. Continuous-Conversion Mode; siehe Datenblatt Seite 17 und bei Überschreiten der Schwelle den ALRT-Ausgang auf LOW zieht (standardmäßig hat er den Zustand HIGH). Er bleibt so lange auf LOW, bis durch Aufruf von getLastConversionResults() der letzte Messwert ausgelesen wird – auch wenn zwischendurch die Spannung am Eingang wieder unter die Schwelle sinkt.

Das Auslesen setzt den ALRT-Ausgang auf HIGH zurück. Die Vergleichsmessung läuft aber im Hintergrund weiter und aktiviert ihn ggf. gleich wieder (zieht in also wieder auf LOW), wenn der Schwellenwert immer noch überschritten ist.

  1. /* ADS1115
  2.  *  - Test der Funktionsweise des ALRT-Pins bei
  3.  *    Nutzung der Komparator-Funktion
  4.  *
  5.  * 2021-05-30 Heiko (unsinnsbasis.de)
  6.  */
  7.  
  8. #define ALERT_PIN 5  // GPIO-Pin für digitale Eingabe
  9.  
  10. #include <Adafruit_ADS1X15.h> // bindet Wire.h für I2C mit ein
  11. Adafruit_ADS1115 ads;
  12. #define ADS_I2C_ADDR 0x48
  13. const float multiplier = 0.1875F;  // ADS1115-Multiplikator bei 2/3 Verstärkung
  14.  
  15. void setup() {
  16.   Serial.begin(115200);
  17.   delay(500);
  18.   Serial.println("ADS1115 Alert-Test");
  19.  
  20.   ads.begin(ADS_I2C_ADDR, &Wire);
  21.   // Verstärkung 2/3 (GAIN_TWOTHIRDS ist Standard)
  22.   ads.setGain(GAIN_TWOTHIRDS);
  23.  
  24.   pinMode(ALERT_PIN, INPUT);
  25.   Serial.printf("Setup: ALERT ist %d\n", digitalRead(ALERT_PIN));
  26.   delay(100);
  27.   // Komparator starten an Kanal 0 bei 2 Volt;
  28.   // Schwellenwert = 2000 / 0,1875
  29.   ads.startComparator_SingleEnded(0, (int)(2000/multiplier));
  30.   Serial.printf("Setup nach Start: ALERT ist %d\n", digitalRead(ALERT_PIN));
  31. }
  32.  
  33. void loop() {
  34.   int adc0;      // Messwert an Kanal 0 des ADS1115
  35.   int alert;
  36.   float ads_mv;  // Messwert in Millivolt umgerechnet
  37.  
  38.   alert = digitalRead(ALERT_PIN);
  39.   // ALRT deaktivieren (zurücksetzen) durch Auslesen des letzten Wertes
  40.   adc0 = ads.getLastConversionResults();
  41.   ads_mv = ads.computeVolts(adc0) * 1000;  // in Millivolt umrechnen
  42.  
  43.   Serial.printf("Spannung: %4.2f mV; ALRT: %d\n", ads_mv, alert);
  44.  
  45.   delay(500);
  46. }

Quellcode auf Github

Der ADS1115 arbeitet diesmal mit der Standard-Verstärkung 2/3; insofern könnte man Zeile 22 auch weglassen. Für einen später noch nachvollziehbaren Programmablauf würde ich sie aber nicht löschen.

  1.   ads.startComparator_SingleEnded(0, (int)(2000/multiplier));

Die Vergleichsfunktion (Komparator) an Kanal 0 wird gestartet. Der Schwellenwert wird nicht in Millivolt angegeben, sondern muss als Zahlenwert mit dem zur Verstärkung passenden Multiplikator errechnet werden. (Der wird in Zeile 13 definiert; siehe auch die Erläuterung der Bibliotheksfunktion.)

ADS1115: Zustand des ALRT-Ausgangs bei Nutzung der Komparator-Funktion
ADS1115: Zustand des ALRT-Ausgangs bei Nutzung der Komparator-Funktion

Die Ausgabe im seriellen Monitor zeigt den Zustand des ALRT-Pins zu Programmbeginn, nach Start des Komparators im setup()-Teil und dann alle halbe Sekunde im Hauptprogramm loop() zusammmen mit der gemessenen Spannung.

Man sieht, dass er den Zustand HIGH (1) hat, bis die Schwelle überschritten wird. Dann geht er auf LOW (0) und wird erst wieder auf HIGH gesetzt, nachdem das erste Mal ein Messwert unter 2000 Millivolt gelesen wurde.

Da der ALRT-Pin vor dem Zurücksetzen ausgelesen wird, hat er im Beispiel auch bei einer gemessenen Spannung von 1917,19 mV noch den Wert LOW. Erst dann wird er zurückgesetzt und bleibt auf HIGH.

Links

Dokumentation des ADS1115 bei Adafruit: learn.adafruit.com/adafruit-4-channel-adc-breakouts

Dokumentation von espressif zu den ADC des ESP32: Analog to Digital Converter – im Abschnitt Minimizing Noise wird erläutert, dass man Rauschen mit einem 0,1 µF-Kondensator reduzieren kann.

DeepBlue Embedded: ausführliche Beschreibung der ADCs des ESP32 mit Hinweisen zum Umgang mit den Messungenauigkeiten

Analog-Pins und ADC der Arduinos: www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins

[Quellenangabe zum Bild „Achtung-Zeichen”: Clker-Free-Vector-Images auf Pixabay); Pixabay License: »Free for commercial use. No attribution required«]

Fußnoten

Fußnoten
1 Bspw. liefert der Temperatursensor LM35DZ Spannungswerte zwischen 0 und 1 Volt, um Temperaturen von 0-100°C anzuzeigen. 1 mV enstspricht dabei 0,1°C. Werte unterhalb von 10°C könnte der ESP32 gar nicht erkennen, erst ab etwa 15°C wären die Daten halbwegs verlässlich (müssten aber immer noch umgerechnet bzw. korrigiert werden).
2 Oder man geht direkt an die Quelle: Arduino Playground und Referenzspannungen der verschiedenen Arduino-Modelle.
3 Auch bei der Wahl des Verstäkrungsfaktors von 2/3 – also mit einer internen Abschwächung des Signals – darf das Signal nicht die maximale Eingangsspannung von VDD + 0,3 Volt überschreiten; siehe Datenblatt S. 17. Die 2/3-Verstärkung ist nicht dafür gedacht, eigentlich zu hohe Spannungen auf für den ADS1115 geeignete Werte zu reduzieren.
4 Das Original-Breakout-Board von Adafruit kostet bei Reichelt Elektronik 17,60 €. Nachbauten gibt es im deutschen Versandhandel zu Preisen von gut 4 bis über 8 € (z.B. bei AZ-Delivery oder Makershop.de); bestellt man direkt in China, zahlt man etwa 3 € (jeweils zzgl. Versandkosten; Stand: Mai 2021).
5 siehe Datenblatt Seite 23
6 Die Nutzung dieser Adresse ist mir nicht gelungen. Bei Verbindung von ADDR- und SCL-Pin wird das Modul nicht von einem I2C-Scanner gefunden. Dafür dauert der Scan, der sonst den kompletten Adressbereich von 0x00 – 0x7F in Sekundenbruchteilen absucht, deutlich länger (für jede einzelne Adresse ein paar Zehntelsekunden, d.h. man kann zugucken, wie eine Adresse nach der anderen abgefragt wird). Da scheinen also irgendwelche Signale auf dem Bus durcheinanderzukommen.
Weil ich nur dieses eine Modul besitze, kann ich nicht sagen, ob das immer so ist. Vielleicht liegt es daran, dass es sich um einen chinesischen Nachbau des Adafruit-Originals handelt? Für mein einzelnes Modul sind drei konfigurierbare Adressen aber mehr als genug. 😉
7 Das ist dann nötig, wenn man nicht die Standard-Anschlüsse des ESP32 für I2C verwendet; ausführliche Hinweise enthält der Beitrag »I2C-Schnittstellen am ESP32 und Arduino«.
8 In der Adafruit Header-Datei gibt es zur Benutzung der Methode setGain() folgenden Hinweis:
»The ADC input range (or gain) can be changed via the following functions, but be careful never to exceed VDD +0.3V max, or to exceed the upper and lower limits if you adjust the input range! Setting these values incorrectly may destroy your ADC!«
9 Siehe die mitinstallierten Beispielprogramme singleended.ino und differential.ino.
10 Auch der ESP32-Core bietet in den SDK-Bibliotheken Funktionen zum Umgang mit der ADC-Kalibrierung. Man findet die Funktionen in der Datei esp_adc_cal.h im Ordner C:\Users\<benutzername>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\tools\sdk\include\esp_adc_cal\ (oder bei Github). Die ESP32-Dokumentation enthält hierzu den Abschnitt »ADC Calibration«. Ob und wie man mit diesen Funktionen aus den Messungen der ESP32-ADCs bessere Werte herausholen kann, habe ich bisher nicht überprüft.
11 sog. Continuous-Conversion Mode; siehe Datenblatt Seite 17

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht.