externer Analog/Digital Wandler

Hallo Zusammen,

ich bin gerade dabei ein externen Analog/Digital-Wandler an den Arduino anzuschließen. Die Kommunikation soll über SPI laufen! Das analoge Signal erzeuge ich über ein Netzgerät.

Mein Frage wäre jetzt, wie gehe ich vor?

Ich hab mir das jetzt so vorgestellt.

Die SPI-Kommunikation arbeitet ja ein mit dem Master-Slave-Prinzip...! In diesem fall wäre mein Arduino mein Master und mein AD-Wandler mein Slave. Dann würde ich über MOSI dem Slave-Geräte (AD-Wandler) sagen, schick mir deine Daten und über MISO würde ich dem Master (Arduino) meine digitalen Daten senden.

Hab ich das soweit richtig verstanden? Gibt es einige Beispiele die ich mir vielleicht angucken könnte, wie man das programmiert?

Liebe Grüße Andreas

Welchen ADC hast du genau? Einen aus der MCP Reihe? Dafür sollte mit Google fertiger Code findbar sein. Einfach nach dem Typ + Arduino suchen.

Ansonsten musst du ins Datenblatt schauen. Das ist die Kommunikation genau beschrieben. Eventuell geht auch Code für einen ähnlichen Typ, oder man kann das anpassen.

Hallo,

ich hab diesen ADC hier: http://datasheets.maximintegrated.com/en/ds/MAX187-MAX189.pdf

Also den MAX187

Ok, Google spuckt da auf die schnelle nichts aus.

Aber auf Seite 10 und 11 ist es eigentlich alles erklärt. Die Wandlung startet mit CS auf Low. Dann geht DOUT auf Low und wird wieder High wenn die Wandlung fertig ist. Danach taktet man 12 Bits rein. Da du mit SPI.transfer() jeweils 8 Bit liest musst du das zweimal machen und die zwei Bytes entsprechend verwurschteln (Schieben und &). Danach CS wieder auf High.

Das komplizierte ist dabei das Ende der Wandlung abzuwarten. Wobei es dafür auch einfach Delay tut. Die Wandlung dauert maximal ca. 8.5µs. Wenn du einfach 9 oder 10µs wartest würde das wohl auch gehen. Das eigentliche Einlesen ist trivial.

Andreas_H: Die SPI-Kommunikation arbeitet ja ein mit dem Master-Slave-Prinzip...! In diesem fall wäre mein Arduino mein Master und mein AD-Wandler mein Slave. Dann würde ich über MOSI dem Slave-Geräte (AD-Wandler) sagen, schick mir deine Daten und über MISO würde ich dem Master (Arduino) meine digitalen Daten senden.

Hab ich das soweit richtig verstanden? Gibt es einige Beispiele die ich mir vielleicht angucken könnte, wie man das programmiert?

Das Übertragungsprotokoll ist von Wandler zu Wandler verschieden. Wenn ein A/D-Wandler mehrere Eingänge per Multiplexer auswählt ist dem Wandler zuerst zu sagen welchen Eingang Du messen willst. Wie bereits gesagt ist alles im jeweiligen Datenblatt beschrieben bzw jemand hat das für Dich bereits gemacht und eine Bibliothek geschrieben und veröffentlicht.

Grüße Uwe

Wo du beim Verdrahten aufpassen musst ist die Referenzspannung. Das Ding hat zwei Optionen:

1.) interne 4.096V Referenz. Dazu muss SHDN auf High. Dann ein 4,7µF Kondensator von REF auf Masse

2.) externe Referenz. Dazu SHDN offen lassen, die Spannung an REF und gleichzeitig mindestens 100nF von REF gegen Masse

Hallo Zusammen,

ich bekomme jetzt Werte vom ADC, aber leider nicht die richitgen. Wenn ich mein Spannung auf 0 V lege, dann zeigt mir der ADC einen Wert von 65535 was einer Spannung von 4,095 entspricht. Diesen ADC hier habe ich, http://datasheets.maximintegrated.com/en/ds/MAX1302.pdf.
Das Layout und die Platine für den ADC habe ich selber gemacht. Da ich jetzt keine große Erfahrung habe, weiss ich nicht, ob es jetzt an meinem Programm liegt oder am Layout.

Hier ist einmal mein Code:

#include <SPI.h>

int cs = 8;
unsigned long adcValueLSB;
unsigned long adcValueMSB;
unsigned long adcValue;

void setup(){
pinMode(cs, OUTPUT); // Pin cs (chip select) als Ausgang definiert
digitalWrite(cs, HIGH); // cs auf 1 setzen
SPI.begin(); // Startet die SPI-Bibliothek
SPI.setDataMode(SPI_MODE0); // Setzt den SPI-Modus
SPI.setClockDivider(SPI_CLOCK_DIV2); // Stellt die Geschwindigkeit ein
SPI.setBitOrder(MSBFIRST); // Setzt die Bit-Reihenfolge Most-Significant-Bit, scheint Standart zu sein!!!
Serial.begin(9600);
}

void loop()
{
digitalWrite(cs, LOW);
//delayMicroseconds(500);
SPI.transfer(0x90);
SPI.transfer(0x00);
delayMicroseconds(500);
adcValueLSB = SPI.transfer(0x00); // niederwertiges Byte zuerst, D15…D8
adcValueMSB = SPI.transfer(0x00); // höherwertiges Byte zum Schluss, D7…D0
digitalWrite(cs, HIGH);
adcValue = adcValueMSB << 8;
adcValue = adcValue | adcValueMSB;

Serial.print("analog value = ");
Serial.println(adcValue);
Serial.print(’\n’);
delay(1000);
}

Das Ding ist natürlich um einiges komplizierter. Hast du Pins 15-24 richtig anschlossen?

Wird aber nicht laut Datenblatt nur ein Konfigurations-Byte erwartet? Siehe Figure 2 auf Seite 15. Du müsstest glaube ich 0x80 senden für Channel 0. Also nur das Start-Bit 1. Der Rest 0. Das wird zwar ständig ein Clock signal angezeigt, aber auf DIN liegt nur ein Byte an. Das Clock Signal soll vielleicht nur verdeutlichen wie lange die Wandlung dauert.

Auskennen tue ich mich mit dem Ding aber auch nicht.

Aber wenn Du mal auf Seite 18 anguckst die Tabele 4, dann siehst Du für CH1 den Wert 001 also wäre Analog-Input Configuration Byte: 10010000 und das entspricht ja 0x90.

Ok. Wenn du Kanal 1 willst. Ich hatte erst mal mit 0 angefangen. Aber ok, das spielt keine so große Rolle

Das hier ist aber etwas problematischer glaube ich:

SPI.transfer(0x90);
SPI.transfer(0x00);

Mit der zweiten Zeile liest/sendest du noch ein Byte. So wie ich es sehe muss/darf man nur eines schicken

Mein ADC beträgt aber 16 Bit, somit muss ich doch zwei Byte schicken...oder!?

Gruß Andreas

Zwei Byte einlesen, aber das ist das Kommando-Byte mit dem du die Wandlung startest

Ich verstehe es so:
2.) CS Low
2) Kommando Byte schicken
3.) Etwa 8 oder 9 Takte warten
4.) Zwei Bytes einlesen
5.) CS High

Siehe Seite 15

Analog Input Configuration und Mode Control Bytes brauchst du denke ich nicht, da der ADC Standardmäßig in Mode 0 (external Clock) und Single Ended ist.

EDIT:
Oder braucht man die Taktung für die eigentliche Wandlung? Das ist sehr wahrscheinlich der Fall. Und dann wären zwei Bytes sinnvoll - nicht wegen der Daten, sondern dem Takt. Das würde auch erklären weshalb das Takt-Signal durchgehend eingezeichnet ist. An der Stelle könnte das Datenblatt ein wenig ausführlicher sein was die Text-Beschreibung angeht…

Dann würde es doch passen. Allerdings ist mir dann nicht klar wieso es nicht geht. Aber dieser ADC ist insgesamt sehr kompliziert.

Ich hab das Layout für den ADC selber gemacht, es kann sein das an der Hardware (ADC) was nicht stimmt! Also ich bin auch der Meinung, das mein Code richtig ist, aber hab leider nicht die Erfahrung, dass ich das 100 % sagen kann.