18 Bit Analog-Digital-Converter MCP3421

Neben dem 16 Bit Analog-Digital-Converter (ADC) ADS1115, den ich hier vorgestellt habe, verwende ich auch den MCP3421.

Mit einer Datenrate von 3,75 SPS (Samples Per Seconds) ist er zwar nur bei sich langsam ändernden Signalen einsetzbar und er besitzt auch nur einen Spannungs-Differenzeingang. Das Analogsignal wird dabei aber mit einer höheren Auflösung (17 Bit = 131072 Stufen) digitalisiert und als vorzeichenbehaftete 18 Bit Zahl im Zweierkomplement-Format ausgegeben. Die Datenrate könnte bis maximal 240 SPS erhöht werden, allerdings auf Kosten der Auflösung, die dann nur mehr 12 Bit beträgt. Die höheren Datenraten bei geringerer Auflösung nutze ich nicht (da verwende ich dann doch lieber den ADS1115) und auch meine Library für diesen Baustein unterstützt nur die Datenrate mit der hohen Auflösung von 18 Bit.

Angesprochen wird der ADC MCP3421 über die I2C-Schnittstelle.

                  

         Bild 1: MCP3421 auf Breakout Board


   Anschlussbelegung:

  • VCC, GND: Stromversorgung 2,7 - 5,5 V
  • SCL, SDA: Serial Clock und Serial Data Bus
  • VIn+, VIn-: Differential-Analogeingänge

Analogeingänge:

Der MCP3421 besitzt 2 Analogeingänge VIn+ und VIn-, die zur Erfassung von Differenz-Spannungen (VIn = VIn+ - VIn-) verwendet werden können.


Programmierbarer Verstärker PGA (Programmable Gain Amplifier):

Die Verstärkung (Gain) des PGA ist auf die Werte 1, 2, 4, 8 einstellbar. Der daraus resultierende Messbereich FS (Full-Scale Range) und die Spannungs-Auflösung (Resolution) bei 18 Bit ist in nachfolgender Tabelle 1 ersichtlich:


Tabelle 1: Messbereich (FS) und Spannungs-Auflösung (Resolution) bei 18 Bit in Abhängigkeit der vorgegebenen Verstärkung (Gain)

Achtung: Die zu messenden Spannungen müssen immer positiv sein, negative Messergebnisse können sich nur im Zuge der Differenz-Spannungsmessungen ergeben! Die an einem Analogeingang anliegende Spannung darf nicht kleiner als 0 V (minimal -0,3 V) und nicht größer als die Versorgungsspannung VDD (maximal VDD + 0,3 V) sein, sonst droht die Beschädigung des ADC. Die Versorgungsspannung VDD darf maximal 5,5 V betragen!


Datenrate:

Die Datenrate (Sample Rate) ist prinzipiell in folgenden 4 Stufen einstellbar:

  • 240 SPS (12 Bit Auflösung)
  • 60 SPS (14 Bit Auflösung)
  • 15 SPS (16 Bit Auflösung)
  • 3,75 SPS (18 Bit Auflösung)

(SPS = Samples Per Second)

Achtung: Meine Library unterstützt nur eine Datenrate von 3,75 SPS bei einer Auflösung von 18 Bit!


I2C-Adresse:

Der MCP3421-Chip besitzt keine Adresseingänge. Sofern vom Kunden bei der Bestellung keine andere Adresse vorgegeben wird (möglich wäre 0x69 - 0x6F), ist der ADC werksseitig fix auf die Adresse 0x68 eingestellt.


Betriebsmoden:

Prinzipiell kann sich der MCP3421 in 3 verschiedenen Betriebsmoden befinden, wobei aber nur die folgenden 2 Moden direkt ausgewählt werden können:

  • Einzelmessung (single-shot mode) oder
  • Kontinuierliche Messung (continuous conversion mode)

Ist allerdings der single-shot mode ausgewählt und findet gerade keine Wandlung statt, dann befindet sich der MCP3421 im dritten möglichen Modus, dem Stromsparmodus (power-down mode), solange bis wieder eine neue Einzelmessung gestartet wird.

Testaufbau: Temperaturmessung mit MCP3421 und LM35-Sensor

Verwendete Bauteile:

  • 1 Arduino Nano
  • 1 MCP3421 Breakout Board
  • 1 Kondensator 100 nF
  • 1 LM35


Library MyMCP3421 für Arduino und Attiny45/85:

Achtung: Meine Library unterstützt nur eine Datenrate von 3,75 SPS bei einer Auflösung von 18 Bit! Die vom MCP3421 möglichen höheren Datenraten bei geringerer Bit-Auflösung sind nicht in der Library ausgeführt.


  • Abfrage, ob der Baustein über I2C ansprechbar ist
  • Setzen und Abfragen des Betriebsmodus (Einzelmessung oder kontinuierliche Messung)
  • Setzen und Abfragen der Verstärkung des PGA
  • Start einer Einzelmessung
  • Lesen des Messwertes (18 Bit-Integer-Zahl des Conversion-Register)
  • Lesen des Messwertes als Spannungswert (= skalierter Wert des Conversion-Register)
  • Ausgabe des Configuration-Register am Seriellen Monitor (nur für Kontrollzwecke, nicht für Attiny), siehe Bedeutung der einzelnen Bits des Registers -> Register


Die Library kann hier heruntergeladen werden:

Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!

Version 1.0

MyMCP3421.cpp.txt

MCP3421h.txt

keywords.txt

Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library das Suffix ".txt" aus diesen Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyMCP34221" im Sketchbook-Ordner im Ordner "libraries" speichern.


Zur Auflistung der Funktionen der Library geht es hier: Funktionen

Programmbeispiel MyMCP3421:

Das nachfolgende Programmbeispiel verwendet, wie oben im Testaufbau dargestellt, einen Temperatursensor LM35 als Signalquelle. Dabei wird die vom Sensor ausgegebene temperaturabhängige Spannung mit dem ADC MCP3421 im Modus Einzelmessung einmal pro Sekunde digitalisiert und vom Arduino Nano eingelesen, der Temperaturwert berechnet und am Seriellen Monitor ausgegeben. Die Spannung, die vom Temperatursensor LM35 ausgegeben wird, beträgt im Bereich zwischen +0°C und +150°C linear 0 mV + 10 mV/°C. Eine Temperatur von 20°C entspricht also einer Spannung von 200 mV.


//Programmbeispiel fuer MCP3421 mit LM35-Sensor
//Code fuer Arduino
//Author Retian
//Version 1.0


#include <MyMCP3421.h>
MyMCP3421 Adc;


float voltage, temp;


void setup() {
  Serial.begin(115200);
  if (Adc.isReady()) Serial.println("ADC MCP3421 ok"); //Pruefe, ob der ADC ansprechbar ist ...
  else
  {
     Serial.println("ADC MCP3421 Fehler");
     while(1); //sonst geht's hier nicht weiter
  }
  Adc.init();
 
  //Parameter muessen nur eingegeben werden, wenn sie von
  //den nachfolgenden Default-Werten abweichen sollen:
  //Gain: MCP3421_PGA_2P048 ...... Verstaerkung 2,048 V (Full Scale)
  //Mode: MCP3421_MODE_SINGLESHOT ...... Einzelmessung

  Adc.setGain(MCP3421_PGA_1P024);
}


void loop() {
  Adc.startSingleMeas();
  while (!Adc.conversionReady());
  //Abfrage des Wandlungsergebnis in mV
  voltage = Adc.readVoltage();
  //Umrechnung der Spannung in mV in Temperatur (10 mV/°C)
  temp = voltage / 10.0;
  Serial.print("Temperatur: ");
  Serial.print(temp);
  Serial.println("°C");
  delay(1000);
}