ADC Wandler (Bsp. ADS1115)
Beim IC ADS115 handelt es sich um einen Analog zu Digital Converter (ADC) mit 16 Bit Auflösung. Die Auflösung des Messbereiches kann zu der erwarteten Spannungshöhe eingestellt werden. Die maximal messbare Spannung ist ±6,144V. Es gibt 4 Analoge Messeingänge die mit Bezug auf GND oder als Differenz zweier Eingänge zueinander ausgegeben werden können. Die Messrate kann eingestellt werden. Von einer Messung erst auf Anforderung zu einer Dauermessung von bis zu 860 SPS (Samples Per Second). Im IC ist auch ein Komparator integriert. Bei erreichen einer einstellbaren Spannungsschwelle wird am Ausgang ALERT ein Signal ausgegeben.
| Pinbelegung | |
|---|---|
| VDD | Spannungsversorgung + |
| GND | Masse - |
| ADDR | Pin um die I2C Adresse einzustellen. Mit offenem Eingang ist die Adresse in 0x48 |
| AIN0-AIN3 | Analoge Messeingänge |
| ALERT/RDY | |
| SDA | I2C Datenleitung |
| SCL | I2C Clockleitung |
Funktionsweise ADS1115
Multiplexer (MUX)
Über den Multiplexer wird der Eingang ausgewählt, welcher gemessen wird und dessen Messwert im Messwertspeicher abgelegt wird. Es kann nur ein Eingang oder eine Differenzspannung von zwei Eingängen gleichzeitig gemessen werden.
Verstärker (PGA)
Noch vor dem eigentlichen ADC können die analogen Signale mit einem 'Programmable Gain Amplifier' durch die
Erhöhung der Gain-Spannung verstärkt werden. Da das ausgehende und in den ADC eingehende Signal eine Auflösung von
215=32768 hat ändert sich dadurch auch die Auflösung der Spannungsmessung. Wenn ±0,256V maximal
gemessen werden werden ist die Auflösung 7,8125μV (0.256V/3278). Müssen die 32768 Stufen auf ±6,144V aufgeteilt
werden ist die Auflösung mit 187.5 μV deutlich gröber.
Hinweis: Da eine Stelle des 16bit ADC für die Polarität (+/-) reserviert ist, beträgt die eigentliche
Auflösung nur 15 Bit übrig.
ADC
Der hier verwendete Analog Digital Converter arbeitet nach dem Delta-Sigma (ΔΣ) Prinzip. Ein interner Komparator
ist dabei so verschaltet, dass bis zur Schaltschwelle zuerst ein Kondensator geladen sein muss. Wie schnell der
Kondensator geladen wird ist spannungsabhängig.
Der Ausgang des Komparators wird, gesteuert durch einem Oszillator, regelmäßig abgefragt und die Clock-Pulse dabei
bis zum Schalten des Komparators gezählt. Wenig Pulse bis zum Schalten entsprechen dann einer hohen Spannung.
Vergehen viele Pulse bis zum Erreichen der Schaltschwelle liegt eine geringere Spannung an.
Komparator
Der ALERT Ausgang wird durch einen oder zwei Komparatoren angesteuert. Bei der 'konventionellen' Einstellung ist ein Komparator aktiv welcher beim Überschreiten der High-Schwelle ein Signal auf den Ausgang gibt. Bei der 'window' Einstellung sind zwei Komparatoren aktiv und der Messwert muss innerhalb eines Fensters bleiben. Beim Überschreiten der High-Schwelle oder beim Unterschreiten der Low-Schwelle wird der ALERT Ausgang angesteuert.
I2C Kommunikation
Der ADS1115 hat 5 Register die über I2C von außen zugänglich sind. Standardmäßig greift I2C mit dem ersten übertragenen byte auf das Address Pointer Register zu. In diesem Register wird dann ein Pointer zu einem der 4 anderen Register gesetzt. Das dann folgende Übertragungsbyte wird dann in das verwiesene egister geschrieben oder Daten von dort angefordert.
Die 4 Register auf die das 'Address Pointer Register' verweist sind: Das Config Register in dem sämtliche Einstellungen vorgenommen werden, das Conversion Register in dem die Messwerte zur Abholung gespeichert sind, und noch 2 Register um eine obere (Hi_thresh Register) und eine untere (Lo_thresh Register) Alarmschwelle für den ALERT Ausgang anzugeben.
Registereinträge ändern
Zum ändern von Registereinträgen wird mit Wire.beginTransmission(Adresse) der ADC Slave über
seine I2C Adresse angesprochen und zum Lesen aufgefordert. Das erste byte landet im 'Address Pointer Register'.
Dort kann man dann den Pointer für die folgenden Daten beispielsweise auf das 'Config Register' setzten. Das
'Config Register' ist 16 Stellen lang. Es müssen also zwei weitere Bytes übertragen werden. Mit
Wire.endTransmission() wird die I2C Übertragung durch den Mikrocontroller (Master) beendet.
Wire.beginTransmission(0x48);
Wire.write(B00000001); // Pointer im Addressregister auf 'Config Register' setzen
Wire.write(B01000010); // MSB (Bits 15-8) des 'Config Registers' setzen
Wire.write(B00000010); // LSB (Bits 7-0) des 'Config Registers' setzen
Wire.endTransmission();
Registereinträge anfordern
Auch hier müssen wir zunächst das Pointer Register mit dem Verweis auf das Messwerteregister beschreiben.
Wire.beginTransmission(0x48);
Wire.write(0b00000000); // Pointer im Addressregister auf 'Config Register' setzen
Wire.endTransmission();
Wenn der Pointer für die folgenden Übertragung gesetzt ist können die Messwerte mit
Wire.requestFrom(Adresse, Anzahl erwarteter Bytes) angefordert werden. Bei der I2C
Übertragung werden die Daten immer Byteweise übertragen. Um das 16 bit Register des Messwerts zu übertragen werden
also zwei Bytes gesendet. Zuerst das HighByte, dann das LowByte.
Wire.requestFrom(0x48, 2);
unsigned int messWert = Wire.read() << 8 ; // High Byte 8 Stellen nach links schieben
messWert = messWert | Wire.read(); // Low Byte hinzufügen
Register des ADS1115
Address Pointer Register
Das Register hat die Größe von einem byte. Nur die zwei LSB werden für die Adressierung benötigt. Das Register
kann nur beschrieben werden.
B00000000 : Conversion register (default)
B00000001 : Config register
B00000010 : Lo_thresh register
B00000011 : Hi_thresh register
Conversion Register
In diesem 16 Bit Register wird der Messwert der letzten Messung gespeichert. Es ist nur der Messwert gespeichert welcher im Config Register ausgewählt wurde. Das MSB kennzeichnet ob es sich um einen Minus oder Pluswert handelt. Der eigentliche Messwert hat damit ein Auflösung von 215 = 32768. Das Register kann nur gelesen werden.
Config Register
Dieses Register hat eine Größe von 16 Bit. Das Config Register kann neu beschrieben oder die Einstellwerte ausgelesen werden.
| MSB | Einzelmessung auslösen 0 : keine Auslösung 1 : Auslösung wenn mt bit 8 Einzelmessung eingestellt ist |
| 14-12 | Hier werden die Messeingänge ausgewählt (Multiplexer) 000 : Differenz zwischen AIN0 und AIN1 (Standard) 001 : Differenz zwischen AIN0 und AIN3 (default) 010 : Differenz zwischen AIN1 und AIN3 011 : Differenz zwischen AIN2 und AIN3 100 : Differenz zwischen AIN0 und GND 101 : Differenz zwischen AIN1 und GND 110 : Differenz zwischen AIN2 und GND 111 : Differenz zwischen AIN3 und GND |
| 11-9 | Verstärkungsfaktor auswählen (PGA) Der Messbereich kann angepasst werden, so dass kleine Messwerte verstärkt werden um die 16 bit Auflösung auszunutzen. 000 : ±6.144 V 001 : ±4.096 V 010 : ±2.048 V (default) 011 : ±1.024 V 100 : ±0.512 V 101 : ±0.256 V |
| 8 | Messmodus auswählen 0 : kontinuierliche Messung 1 : Einzelmessung auf Anforderung über MSB (default) |
| 7-5 | Messfrequenz (Abtastrate) einstellen 000 : 8 SPS (Samples per Second) 001 : 16 SPS 010 : 32 SPS 011 : 64 SPS 100 : 128 SPS (default) 101 : 250 SPS 110 : 475 SPS 111 : 860 SPS |
| 4 | Komparator-Modus einstellen 0 : nur oberer Grenze aktiv (default) 1 : Window Komparator mit aktiver oberen und unteren Grenze |
| 3 | Polarität des ALERT Ausgangs einstellen 0 : Active low (default) 1 : Active high |
| 2 | ALERT Ausgang auf 'latch' stellen 0 : latch nicht aktiviert (ALERT ist nur aktiv solange die Messwerte außerhalb der Grenzen ist) 1 : latch aktiviert (ALERT bleibt bis zum Lesen der Messwerte angesteuert) |
| 1-LSB | Einstellen wie oft die der Komparator eine Grenzverletzung erkennen muss, bevor ALERT angesteuert
wird 00 : nach einer einer Überschreitung 01 : nach zwei Überschreitungen 10 : nach vier Überschreitungen 11 : Komparator ausgescchlatet (default) |
Lo_thresh Register
Hier wird in 16 bit die untere Toleranzgrenze für die Ansteuerung des ALERT Ausgangs angegebenHi_thresh Register
Hier wird in 16 bit die obere Toleranzgrenze für die Ansteuerung des ALERT Ausgangs angegeben.Programmcode
#include "Wire.h"
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
// Konfigurationsregister einstellen
Wire.beginTransmission(0x48);
Wire.write(B00000001); // Pointer im 'Address Register' auf 'Config Register' setzen
Wire.write(B11000001); // MSB (Bits 15-8) des 'Config Registers' setzen
Wire.write(B00000000); // LSB (Bits 7-0) des 'Config Registers' setzen
Wire.endTransmission();
// Pointer auf das Ergebnisregister stellen
Wire.beginTransmission(0x48);
Wire.write(0b00000000); // Pointer im 'Address Register' auf 'Config Register' setzen
Wire.endTransmission();
// Messwert auslesen (2 Byte)
Wire.requestFrom(0x48, 2);
unsigned int messWert = Wire.read() << 8 ; // High Byte 8 Stellen nach links schieben
messWert = messWert | Wire.read(); // Low Byte hinzufügen
// Messwert ausgeben
Serial.print(messWert); Serial.print("\t");
Serial.print(map(messWert, 0, 32767, 0, 6144)); Serial.println(" mV");
delay(250);
}