Den 16-Bit AD-Wandler MCP 3426 mit dem Arduino verwenden

Der AD-Wandler MCP 3426A0-E/SN wurde auf eine Streifenrasterplatine gesetzt, wie im vorherigen Artikel beschrieben.

Nun soll er mit dem Arduino Uno verbunden und ausgelesen werden.

Der Arduino bietet „mehrere“ eingebaute AD-Wandler an den Ax Eingängen, die aber nur mit 8 Bit zwischen 0V und VCC (5V) wandeln, was eine Auflösung von ca. 9,8 mV pro Bit bedeutet. Der hier beschriebene AD-Wandler kann mit 12 bis 16 Bit wandeln und erreicht damit eine Auflösung von 62,5 uV bezogen auf ein Eingangssignal von +- 2,048 V. Ausserdem hat er eine genaue Referenzspannung eingebaut und ist mit nur 2 Drähten über den I²C Bus steuerbar. Der Preis liegt bei ca. 3 Euro.

Die Hardware

Am Eingang kann der AD-Wandler – 2,047 V bis + 2,047 V messen dazu wird ein Trimmpoti mit 1 kOhm in Reihe mit einem 1,2 kOhm Widerstand gelegt. Der Trimmpoti wird einseitig an Masse gelegt (schwarz), der Widerstand auf +5V (orange) und am Abgriff des Potis stehen jetzt 0 bis +2,27 V zur Verfügung, je nach Einstellung. Dies wird meine Messspannung.

Die Verbindung des AD-Wandlers zum Uno besteht aus 4 Leitungen.
Pin 3 > +5V (rot)
Pin 7 > GND (blau)
Pin 4 SDA > A4 (weiss)
Pin 5 SCL > A5 (gelb)

Der Messeingang am AD-Wandler ist Pin 1 (+) und Pin 2 (-).
An Pin 1 wird der Poti Abgriff gelegt (braun) und Pin 2 kommt an Masse (schwarz).

Der zweite AD-Wandler Eingang wird hier vorerst nicht verwendet.

Die Schaltung auf dem Steckbrett.

16-Bit AD Wandler am Uno

Die Software

Der Arduino Programmcode.

// MCP-3426 16-Bit AD Wandler mit dem Arduino Uno auslesen
// Messbereich: von -2,047 bis +2,047 V
// Auflösung (LSB) 16 Bit:62,5uV / 14 Bit: 250 uV / 12 Bit: 1mV
//
// Matthias Busse 6.5.2014 Version 1.0

// Anschlüsse MCP-3624  >  Arduino Uno
// 1 Eingang + Messspannung 1 +
// 2 Eingang - Messspannung 1 -
// 3 VCC > 5V
// 4 SDA > A4
// 5 SCL > A5
// 6 VSS > GND
// 7 Eingang + Messspannung 2 NC
// 8 Eingang - Messspannung 2 NC

#include < Wire.h> 

//MCP 3426 Einstellungen
byte i2cadress=B1101000;
byte resolution=12; // 12/14/16
byte gain=1; // 1/2/4/8

void setup() {
  Wire.begin();
  Serial.begin(38400);
  MCP3426Set(1,1);
} // setup()
 
void loop() {
  resolution=12;
  MCP3426Set(1,1);
  Serial.println(MCP3426Read()/gain,3);

  resolution=14;
  MCP3426Set(1,1);
  Serial.println(MCP3426Read()/gain,4);

  resolution=16;
  MCP3426Set(1,1);
  Serial.println(MCP3426Read()/gain,4);

  Serial.println();
  delay(1000);
} //loop()

void MCP3426Set(byte channel, byte continious) {
// Das Configuration Register schreiben > Datenblatt Seite 18
//
// Parameter:
// channel 1 | 2
// continious 1 | single shot 0
//
// Matthias Busse 6.5.2014 Version 1.0 

byte ga, oc, ch, sa, datarate;
  
  switch (channel) {
    case 1:ch=0; break;    // Kanal 1
    case 2:ch=1; break;    // Kanal 2
    default: ch=0;         // Kanal 1
  }
  switch (continious) {
    case 0:oc=0; break;    // one-shot
    case 1:oc=1; break;    // continious
    default: oc=1;         // continious
  }
  switch (resolution) { // Samples per second min. > Datenblatt Seite 5
    case 16:sa=2; datarate=11; break;   // 11 SPS > 16 Bit
    case 14:sa=1; datarate=44; break;   // 44 SPS > 14 Bit
    case 12:sa=0; datarate=176; break;  // 176 SPS > 12 Bit
    default: sa=2; datarate=11;         // 11 SPS > 16 Bit
  }
  switch (gain) {
    case 1:ga=0; break;    // gain = 1
    case 2:ga=1; break;    // gain = 2
    case 4:ga=2; break;    // gain = 4
    case 8:ga=3; break;    // gain = 8
    default:ga=0;          // gain = 1
  }
  byte config_register = 1 << 7 | ch << 5 | oc << 4 | sa << 2 | ga; // OK
  Wire.beginTransmission(i2cadress);
  Wire.write(config_register);
  Wire.endTransmission();
  delay(1000/datarate); // Eine AD-Wandlung abwarten nach der Umstellung
} // MCP3426Set()


double MCP3426Read() {
// AD Wandler Wert auslesen  
// Ausgabe:
// Gain * Volt
//
// Matthias Busse 6.5.2014 Version 1.0 

int hdata,ldata,conf;
long data;
double gainvolt;

   Wire.requestFrom(i2cadress, (byte) 3);
   hdata=Wire.read();
   ldata=Wire.read();
   conf=Wire.read();
   data = hdata << 8 | ldata;
   if(resolution==16) {
     data &= 0xFFFF;
     if(data >= 32768) data -= 65536l;
     gainvolt= (double) 2.048 / 32768.0 * data;
   }
   else if(resolution==14) {
     data &= 0x3FFF;
     if(data >= 8192) data -= 16384l;
     gainvolt= (double) 2.048 / 8192.0 * data;
   }
   else if(resolution==12) {
     data &= 0x0FFF;
     if(data >= 2048) data -= 4096l;
     gainvolt= (double) 2.048 / 2048.0 * data;
   }
   return gainvolt;
} // MCP3426Read()

Der Programmablauf

Es werden alle 3 Auflösungen 12 , 14 und 16 Bit, eingestellt und die Spannung wird immer wieder ausgelesen und auf COM ausgegeben.

Die zwei Funktionen

void MCP3426Set(byte channel, byte continious)
Stellt die Werte im Configuration Register des AD Wandlers ein. Siehe Datenblatt Seite 18.
Dazu kann der Kanal 1 oder 2 gewählt werden. Und es wird übergeben ob continuierlich gemessen werden soll (der Wandler läuft durch und der aktuelle Wert kann jederzeit ausgelesen werden) oder single shot (eine einmalige Messung, die bei jedem späteren Auslesen wieder zur Verfügung steht).

double MCP3426Read()
Liest den aktuellen Wert aus und gibt Volt * Gain zurück. Um die richtige Spannung zu erhalten muss im Hauptprogramm durch den Gain geteilt werden.

Anmerkung

In Zeile 68 und folgende wurde nicht die typische Samplingrate angegeben, sondern die minimale Samplingrate laut Datenblatt Seite 5. Damit ist unter allen Umständen eine korrekte Wandlung gewährleistet.

In Zeile 85 wird eine AD Wandlung abgewartet, so kann im Hauptprogramm nach der neuen Einstellung mit MCP3426Set(..) gleich mit MCP3426Read() der Wert ausgelesen werden. Hier muss keine Wartezeit berücksichtigt werden.

Fazit

Mit dem MCP 3426A0-E/SN IC ist eine viel genauere Spannungsmessung möglich als mit den beim Arduino eingebauten 8-Bit AD Wandler. Bei 16 Bit Auflösung und einem Gain von 1 beträgt die Auflösung (LSB) 62,5 uV bei einem + – 2,047 V Messbereich.

Mit einem Gain von 8 kann die Auflösung (LSB) im Bereich von + – 0,255 V bis auf ca. 8 uV im Idealfall gesteigert werden. Dafür ist aber ein guter Aufbau und eine stabile Messspannung ohne Restwelligkeit notwendig, also z.B. aus einer Batterie.

Mit den beiden neuen Funktionen kann der AD Wandler einfach angesprochen und ausgelesen werden.

von Matthias Busse

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.