Forum: Mikrocontroller und Digitale Elektronik ADC AD7794 steigt nach einiger Zeit aus - woran kann es liegen?


von HansWurscht (Gast)


Lesenswert?

N'Abend Leute!

Vielleicht habe ich ja Glück und es hat schonmal jemand mit diesem ADC 
gearbeitet...also wie gesagt, es handelt sich um den AD7794 von Analog 
Devices. Dies ist ein 24Bit Sigma-Delta-Wandler. An dieser Stelle bitte 
keine Diskussion über die Sinnhaftigkeit vom Einsatz eines 
24Bit-Wandlers - ich verwende diesen, da er von den Features her perfekt 
passt und weil er auch noch zwischen -40°C und +125°C super Ergebnisse 
liefert. Die 24Bit sind dabei nicht nötig, da es sich bei dem Aufbau 
aber um ein Einzelstück handelt, ist der horrende Preis nicht 
ausschlaggebend.

Also: Ich habe den ADC bereits erfolgreich im Betrieb - er läuft in 
einer Temperaturkammer und misst zyklisch verschiedene Probanden, welche 
durch einen Multiplexer auf seine Eingänge gelegt werden. Soweit erstmal 
alles problemlos.

Was aber leider passiert: Irgendwann steigt er aus...völlig sporadisch 
liefert er nurnoch Müll zurück. Wohl gemerkt auch bei Raumtemperatur, 
also daran liegt es nicht. Starte ich alles neu (egal ob Strom weg und 
wieder dran, oder nur durch einen Reset des Programms während des 
Debuggens), dann ist wieder alles in Ordnung...bis er dann irgendwann 
wieder aussteigt.

Angesteuert wird er durch eine State-Machine, welche im Hintergrund 
ihren Dienst verrichtet - und dies auch perfekt, bis eben dann 
irgendwann...

Was hilft ist, wenn ich zwischendurch einen Software-Reset an den ADC 
sende (4 Bytes mit 0xFF), dann geht es wieder, aber dann muss ich auch 
immer alle Register wieder neu beschreiben. Dies ist natürlich möglich, 
aber im Prinzip darf das ja nicht sein - ich habe so etwas jedenfalls 
noch nie erlebt bei anderen Bausteinen.

Vor dem Holen des Ergebnisses frage ich immer schön den Status ab und 
hole das Ergebnis nur dann, wenn es auch als fertig angezeigt wird.

An dieser Stelle würde ich erstmal gerne wissen, ob evtl. auch schonmal 
jemand mit dem ADC gearbeitet hat und ggf. auch ein Problem damit hatte 
- vielleicht kann man sich ja austauschen. Ansonsten gebe ich natürlich 
gerne weitere Infos.

Danke erstmal.

von HansWurscht (Gast)


Lesenswert?

Eine wichtige Sache noch hinterher:

Der uC und der ADC sind nicht auf der selben Platine, sondern mit einem 
Kabel verbunden. Also SPI geht über das Kabel. Habe erst gedacht, dass 
es halt an der Leitung liegt, aber auch mit 20cm und einem Takt von ca. 
900kHz geht es irgendwann nicht mehr. Das muss doch wohl machbar sein, 
oder?

von Arc N. (arc)


Lesenswert?

Das ist machbar, habe den AD7794 in diversen Schaltungen ohne Probleme 
im Einsatz.
Ein "netter" Effekt trat mal beim Testen auf: Hatte denselben Wert 
sowohl in Mode-High, als auch Mode-Low geschrieben mit dem Effekt, dass 
der ADC mit einem nicht vorhandenen externen Takt laufen sollte...

von HansWurscht (Gast)


Lesenswert?

Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und 
holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob 
dieser sich ändert?

von hilfe ein wahnsinniger (Gast)


Lesenswert?

Die GND der beiden Schaltungen sind verbunden ? Dieser chip ja ja genau 
deswegen Differentielle eingaenge, dass man die analogen signale fuehren 
kann. Platzier den mal neben den Prozessor. Sonst wuerde ich auf EMV 
tippen. Genau so schaut's aus.

von jibi (Gast)


Lesenswert?

>Die GND der beiden Schaltungen sind verbunden ?

Wie sollte sonst die SPI-Übertragung funktionieren`?

von GB (Gast)


Lesenswert?

Dann hast Du Störungen auf dem SPI-Clock, das schmeisst ihn 
durcheinander (hatten wir mit einem AD7719, auch SPI über Kabel).

von HansWurscht (Gast)


Lesenswert?

Also letzteres scheint wohl so zu sein.

Massen sind verbunden, klar.

Ich habe jetzt mal probehalber in die Datenleitungen einen 100R 
eingeschleift, brachte aber nichts. Weiterhin habe ich einen 74HC565 als 
Buffer sowohl an die ADC-Karte, wie auch an die uC-Karte gepackt. Aber 
dennoch Fehler nach einer gewissen Zeit.

Womit es jetzt erstmal zu 99,99% stabil läuft, ist die Verringerung des 
SPI-Taktes auf 100kHz. Wie lange wird sich jetzt zeigen. Die Sample-Rate 
ist zum Glück nicht relevant, da ich lediglich Abweichungen der 
DC-Spannung unter Temperatureinfluss messen muss und da eh nichts 
schnelles passiert.

Wie sieht es generell aus mit Serienwiderständen in den Leitungen? Gut 
oder eher noch hinderlicher? Wenn gut, dann wie groß? 100R zuviel?

Gruß, die Wurscht

von HansWurscht (Gast)


Lesenswert?

GB schrieb:
> Dann hast Du Störungen auf dem SPI-Clock, das schmeisst ihn
> durcheinander (hatten wir mit einem AD7719, auch SPI über Kabel).

Und wie habt ihr das gelöst?

von HansWurscht (Gast)


Lesenswert?


von Arc N. (arc)


Lesenswert?

HansWurscht schrieb:
> Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und
> holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob
> dieser sich ändert?

Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem 
Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung 
ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.
Edit: 27R jeweils auf Seiten der ADCs und des Controllers
Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier 
nach dem Muster:
ADC CS -> low
Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben
ADC CS -> high
10 us warten
und dasselbe für das/die nächste/n Register

: Bearbeitet durch User
von HansWurscht (Gast)


Lesenswert?

OK, danke!

Bei mir läuft es so ab: Ich setze aus der main per Funktion ein Flag, 
welches durch die State-Machine des ADCs abgearbeitet wird. Die 
State-Machine wird jedesmal in der main aufgerufen. Hier wird dann 
geguckt, ob ein Flag z.b. zum Schreiben eines Registers gesetzt ist und 
falls ja, dieses abgearbeitet. Während dieser Zeit wird ein anderes Flag 
gesetzt, durch welches ich aus der main sehen kann, ob ein ADC-Ergebnis 
abzuholen ist oder ob der ADC gerade mit anderen Dingen beschäftigt ist. 
Alle Operationen haben Vorrang vor dem samplen eines Wertes. Erst wenn 
alle Flags abgearbeitet sind, nimmt der ADC automatisch wieder Messungen 
und meldet eine fertige Wandlung durch ein....ratet...Flag ;-)

Nun gut, also 100R sind übertrieben meinste.

von Spratzel-Bernd (Gast)


Lesenswert?

Hallo OP.

Schau' dir mal die FAQs zu dem Wandler an, insbesondere den Teil zur 
Robustheit des Interfaces.
http://www.analog.com/static/imported-files/faqs/AD779x_FAQ_Instru_Conv.pdf

>Das hilft ist, wenn ich zwischendurch einen Software-Reset an den ADC
>sende (4 Bytes mit 0xFF), dann geht es wieder, aber dann muss ich auch
>immer alle Register wieder neu beschreiben.
>Dies ist natürlich möglich, aber im Prinzip darf das ja nicht sein

Ein Reset ist keine Schande.
Ich hantiere mit ähnlichen Wandlern herum, allerdings in einer sehr 
EMV-versauten Umgebung. Natürlich kann/muss man seine Hardware durch 
geeignete Maßnahmen gegenüber externen Störungen robuster machen.
Aber ein periodischer Reset, der den Wandler alle 5000ms neu 
initialisiert, war bei meinen Anwendungen noch nie verkehrt.

von HansWurscht (Gast)


Lesenswert?

Hey!

Danke für den Link! Das werde ich mir mal gründlich durchlesen.

Ein Reset ist keine Schande, klar - war halt nur der Meinung, dass das 
ja wohl nicht Sinn der Sache sein kann...also dass das zwingend 
notwendig ist.

Ich sehe es ja ein, dass der Controller evtl. Mist liefert bei einer 
Übertragung, bei der der CLK mies ist. Dachte darüber hinaus aber auch, 
dass der Wandler ja eigentlich nach !CS bei der nächsten Übertragung 
wieder klarkommen sollte und nicht ab da nurnoch konstant Müll rausgibt.

Aber wer weiß, welches Register ich durch die fehlerhafte Übertragung 
beim eigentlichen Auslesen ggf. nun neu BESCHRIEBEN habe.

von HansWurscht (Gast)


Lesenswert?

Sehr interessantes Dokument! Das beantwortet es ja eigentlich nur zu 
gut!

Danke nochmal

von martin (Gast)


Lesenswert?

Hallo,
ich versuch einen AD7794 anzusteuern, jedoch ohne Erfolg.
Kann mir jemand von euch ein Beispiel bzw. eine Bibliothek zu dem Chip 
geben?

schon mal viele Dank

von Purzel H. (hacky)


Lesenswert?

Diese ADC bedingen genauestes Lesen des Datenblattes. Teilweise ist 
jedes Wort wichtig. Zum Debuggen erst mal das Timing auf jede Flanke 
nachpruefen.

: Bearbeitet durch User
von Felix (Gast)


Lesenswert?

Arc Net schrieb:
> HansWurscht schrieb:
>> Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und
>> holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob
>> dieser sich ändert?
>
> Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem
> Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung
> ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.
> Edit: 27R jeweils auf Seiten der ADCs und des Controllers
> Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier
> nach dem Muster:
> ADC CS -> low
> Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben
> ADC CS -> high
> 10 us warten
> und dasselbe für das/die nächste/n Register

Bin ich bescheuert, oder sieht das im AD7794-Datenblatt auf Seite 9 so 
aus, als ob der ADC eigentlich gerne SPI-Mode 3 hätte?

Ich bin auch gerade dabei, das Ding an einem Atmega32M1 in Betrieb zu 
nehmen. Habe einen Logic-Analyzer, die Software zur Ansteuerung der SPI 
auf dem Atmega und die dafür verwendete state-machine kann ich also 
schonmal ausschließen. Ich bekomme bei Abfrage des Status-registers für 
Bit SR3 häufig eine 0 zurück - was laut Datenblatt des AD7794 (Seite 18) 
nicht sein kann.

Momentan betreibe ich den AD7794 im SPI-Mode 3 (SPCR |= 
(1<<CPOL)|(1<<CPHA)), Mode 0 brachte leider auch keine Abhilfe. (Das 
Verhalten wird anders, aber ich vbekomme immer noch 0x00 als Inhalt des 
Status-Registers)

Ich kann leider nicht direkt die MISO-Leitung als Interruptquelle 
nutzen, da noch andere Komponenten die SPI-Schnittstelle verwenden 
sollen (momentan aber noch nichts dergleichen realisiert). 
Dementsprechend polle ich das Status-Register, und genau da Fällt auf, 
das irgendwas nicht stimmt.

Vielleicht ist auch meine Initialisierung zu kompliziert. Ich schicke 
momentan folgende Befehle (pro zeile ein Datenframe, nach jeder Zeile 
wird _CS wieder auf high gesetzt):

0xFF FF FF FF   //spi-reset
2ms warten
0x10 10 00      //write config register, unipolar mode, channel 1
0x08 80 03      //write mode register, internal zero scale calibration, 
123Hz Update rate
2ms warten
0x40 00         //read status register

der letzte dieser Schritte wird solange wiederholt, bis das _RDY-Bit auf 
0 steht. Das passiert auch irgendwann (nach einigen ms, während denen 
der AD7794 nur mit 0xFF FF antwortet). Zu dem Zeitpunkt, an dem das Bit 
auf 0 springt, kommt aber leider 0x80 00 zurück. Also 0x80 während dem 
Schreibzugriff auf das Communications-Register, und dann 0x00 als 
Antwort. Das passt jedenfalls nicht mit dem Angaben aus dem Datenblatt 
zusammen.

Im weiteren Verlauf würde ich wieder auf das mode-register schreiben, um 
die internal full scale calibration zu starten, dann warten, bis diese 
fertig ist, das Ganze für alle genutzen Kanäle wiederholen, und dann 
Anfangen zu messen. Habe ich da einen Denkfehler? Kann bitte jemand, der 
das Ding bereits am Laufen hat, mal seine Initialisierung posten?

von Arc N. (arc)


Lesenswert?

Felix schrieb:
> Arc Net schrieb:
>> Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem
>> Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung
>> ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.
>> Edit: 27R jeweils auf Seiten der ADCs und des Controllers
>> Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier
>> nach dem Muster:
>> ADC CS -> low
>> Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben
>> ADC CS -> high
>> 10 us warten
>> und dasselbe für das/die nächste/n Register
>
> Bin ich bescheuert, oder sieht das im AD7794-Datenblatt auf Seite 9 so
> aus, als ob der ADC eigentlich gerne SPI-Mode 3 hätte?

Ja, zumindest sagt mir auch mein Quelltext das es SPI-Mode 3 ist...

> Momentan betreibe ich den AD7794 im SPI-Mode 3 (SPCR |=
> (1<<CPOL)|(1<<CPHA)), Mode 0 brachte leider auch keine Abhilfe. (Das
> Verhalten wird anders, aber ich vbekomme immer noch 0x00 als Inhalt des
> Status-Registers)
...
> Vielleicht ist auch meine Initialisierung zu kompliziert. Ich schicke
> momentan folgende Befehle (pro zeile ein Datenframe, nach jeder Zeile
> wird _CS wieder auf high gesetzt):
>
> 0xFF FF FF FF   //spi-reset
> 2ms warten
> 0x10 10 00      //write config register, unipolar mode, channel 1
> 0x08 80 03      //write mode register, internal zero scale calibration,
> 123Hz Update rate
> 2ms warten
> 0x40 00         //read status register


Externe Referenz oder interne Referenz? Bzw. im Config Reg REF_DET 
einschalten und beim Auslesen des Statusregisters NOXREF überprüfen.

> Im weiteren Verlauf würde ich wieder auf das mode-register schreiben, um
> die internal full scale calibration zu starten, dann warten, bis diese
> fertig ist, das Ganze für alle genutzen Kanäle wiederholen, und dann
> Anfangen zu messen. Habe ich da einen Denkfehler?

Sieht so weit in Ordnung aus.

> Kann bitte jemand, der
> das Ding bereits am Laufen hat, mal seine Initialisierung posten?

Kann nach dem Aufstehen mal die Quelltexte passend zusammenstellen...

von Felix (Gast)


Lesenswert?

Das wäre mir glaube ich eine große Hilfe! Vielen Dank schon mal für die 
bisherige Antwort!


Im Moment verwende ich externe Referenz an Refin1 (5V mittels Tiefpass 
geglättet, soll dann auch das Messobjekt (Kraftmessdose) versorgen).

Ref_detect habe ich nicht aktiviert, NOXREF auch nicht überprüft. Sollte 
ich das? Ändert das irgendwas am Verhalten?

Ich versteh auch nicht so ganz, ob es Sinn macht, nach dem Start einer 
Kalibrierung direkt ununterbrochen das Statusregister zu pollen, bzw ob 
ich das Ergebnis der Kalibrierung im Statusregister sehe (_RDY low? 
stimmen dann auch die drei untersten Bits für den aktuell gewählten 
Kanal? da kommt nämlich alles mögliche raus bei mir..)

Ich werde nachher mal die Strippen kontrollieren, momentan sind es ca 
10cm Kabel für die SPI, der uC hat 220 Ohm Schutzwiderstände in allen 
Datenleitungen, Signale sahen am Oszi aber 1A aus. Vielleicht hat sich 
irgendwo ein Wackler eingeschlichen. Was wiederum dagegen sprechen 
würde, ist die Tatsache, dass das Verhalten im Logikanalyzer absolut 
reproduzierbar zu beobachten ist.. SPI-Frequenz hab ich auch schon rauf- 
und runtergeschraubt, anfangs 1MHz, jetzt 125kHz, macht keinen 
Unterschied...

von Arc N. (arc)


Angehängte Dateien:

Lesenswert?

Hier mal die angepassten und zusammenkopierten Routinen für den AD7794

Edit: wo noch += 2 steht müsste ++ stehen (ursprünglich waren die 
Routinen für zwei Bänke von AD7794, die an unterschiedlichen SPI-Modulen 
hingen und deren /CS an div. Ports hingen und z.T. gleichzeitig 
gestartet wurden)

: Bearbeitet durch User
von Felix (Gast)


Lesenswert?

vielen Dank für die Hilfe!

Ich habe die billigen China-Strippen mal durch angelötete Kabel ersetzt, 
und das Ganze läuft schon besser. Habe außerdem in meinem Code die 
Pausen zwischen den _CS verlängert auf über 10us. Leider steigt die 
Kommunikation immer wieder aus, auch Baudratenunabhängig. Kann es sein, 
dass 220 Ohm in der Datenleitung schon zu viel ist?

Momentan überprüfe ich das Statusregister auf die festen Bits 
0bXXX01XXX. Wenn andere Daten vom AD7794 kommen, initialisiere ich ihn 
neu. Genauso auch, wenn ich bereits mehrfach einen bestimmten Kanal 
angefordert habe, dieser aber nicht im Statusregister als aktiver Kanal 
erscheint.
Ausserdem habe ich einen Timeout eingebaut, für den Fall, dass der 
AD7794 die Kommunikation eingestellt hat und mal wieder nur noch 0xFF 
von sich gibt.
Mit diesen drei Maßnahmen läuft die ganze Sache recht robust.

Jetzt kanns ans Feintuning gehen..

Eventuell wird es notwendig sein, den AD7794 ein Stück (40cm) entfernt 
vom Atmega zu betreiben. Wie sollte ich meine SPI-Schnittstelle denn 
optimalerweise beschalten (Serien- und Abschlusswiderstände), um 
möglichst Robust gegen EMV zu sein? Die Kabel wären selbstverständlich 
geschirmt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.