Forum: Mikrocontroller und Digitale Elektronik Kommunikation mit AD-Wandler ADS1255


von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Guten Abend,

ich versuche jetzt schon seit heute früh mit dem AD Wandler (ADS1255 
)auf meiner Platine zu kommunizieren. Ich dachte ich beginne erstmal 
damit das Status Register des Chips erfolgreich auszulesen. Leider 
bekomme ich das bereits nicht hin. Ich habe diverse SPI-Modi ausprobiert 
aber ohne Erfolg.
Habe jetzt bereits an mehreren Stellen im Internet gelesen, dass die 
t6-Zeitspanne im SPI-Timing auf jedenfall eingehalten werden muss, 
deshalb habe ich erstmal 50 µs beim Übertragen eingefügt. Das sollte ja 
genügen. Das ist das erste mal, dass ich einen externen AD ansteuern 
möchte deshalb verzeiht mir bitte falls ich sehr grobe Fehler begehe :) 
Ich habe meinen Code im Anhang weitesgehend kommentiert. Viel ist es ja 
noch nicht, aber eventuell endeckt ja jemand bereits einen Fehler. Hier 
auch das Datenblatt des Chips.

Die Beschaltung ist grundlegend wie im Datenblatt auf Seite 28. Auf 
Seite 6 ist das besagte SPI-Timing Diagramm, das ich probiert habe 
einzuhalten. Als Antwort, die ich per UART ausgebe, bekomme ich immer 
nur "0xFFFFFFFF". Das kann ja nicht stimmen. Denn auch wenn ich 
beispielsweise das DRATE-Register für die Abtastrate anstatt des 
Statusregisters auslese bekomme ich denselben Wert.

Die Beschreibung des Registersatzes beginnt auf Seite 30 und die des 
Befehlssatzes auf Seite 34.

Vielleicht mag ja jemand mal über den Code schauen und entdeckt einen 
Fehler. Eventuell kennt ja auch jemand den Chip und kann mir ein paar 
Tips geben. Ich bin für alles offen.

Schönen Abend allen.

von Tobi (Gast)


Lesenswert?

Noch als weiteren Hinweis. Die Kommunikation per SPI wird von einem 
Atmega168 gesteuert. Der rennt mit einem externen 7,3728 MHz Quarz. Mit 
Prescaler 16 läuft die SPI also mit ca. 460 kHz.

von Dirk F (Gast)


Angehängte Dateien:

Lesenswert?

Hi, evtl hilft Dir mein C-Code von ADS1256 am PIC32

Gruß

von Tobi (Gast)


Lesenswert?

Hallo Dirk.

Vielen Dank für deine Antwort. Ich hatte deinen Code, den du netterweise 
zur Verfügung stellst, bereits in einem anderen Thread entdeckt.

Beitrag "ADS1255 / ADS1256 Beispielcode"

Ich habe noch nie mit PICs gearbeitet aber ich hatte trotzdem probiert 
einige Informationen herauszuziehen und in meinen Code einzubauen. 
Leider ohne Erfolg. Ich bekomme wie ich bereits geschrieben habe immer 
nur "0xFFFFFFFF" als Rückgabewert.

Grundsätzlich passiert in meinem Code ja auch noch nicht so viel. Ich 
initialisiere den SPI als Master und setze die Pins von SCK, MOSI und 
!CS auf Ausgang. Momentan sind CPOL UND CPHA auf "0". Ich habe aber auch 
anderen Modi bereits ausprobiert.

Der UART wird initialsiert und der funktioniert auch einwandfrei.

Der Rest sind denk ich ganz normale SPI-Funktionen wie man sie sowohl im 
Datenblatt als auch überall im Netz findet. Mit der Ausnahme, dass ich 
in der Transceive-Funktion nach dem Warten auf eine erfolgreiche 
Übertragung 50 µs warte um die Distanz von t6 einzuhalten.

Nachdem !CS auf Low gezogen wurde wird 0x10 kombiniert mit dem Wert 0x00 
übertragen. Das entspricht dem Befehl für Registerauslesen. Und in dem 
Fall das Statusregister. Der nächste Wert, der übertragen wird sagt dem 
Chip, dass nur ein Register gelesen werden soll. Dann ein Dummybyte 
wodurch der Chip eigentlich den Registerwert zurückgeben sollte. Leider 
tut er das noch nicht.... Abschließend wird !CS wieder auf High gezogen. 
Das wars eigentlich. Klingt simple funktioniert nur noch nicht.

von Jim M. (turboj)


Lesenswert?

Tobi schrieb:
> Ich dachte ich beginne erstmal
> damit das Status Register des Chips erfolgreich auszulesen. Leider
> bekomme ich das bereits nicht hin. Ich habe diverse SPI-Modi ausprobiert
> aber ohne Erfolg.

Bei dem großen Bruder (ADS1298) hatte ich genau das Problem wenn die 
analoge Spannung nicht OK war. Miss die mal mit 'nem Multimeter nach.

Ansonsten: Digitales Oszi an die SPI Pins und Kurven anschauen.

von Adam P. (adamap)


Lesenswert?

Hey,

beim ADS1299 gehe ich im Init() wie folgt vor:

- Reset vom ADS1299
- Disable Read Continous (sonst nimmt er keine Befehle an)
- Stop Befehl
- Config Reg. schreiben
- Config Reg. lesen und ID prüfen

Ich würde mir sonst anschauen ob die Kommunikation ansich überhaupt 
stimmt.

von Adam P. (adamap)


Lesenswert?

Tobi schrieb:
> Momentan sind CPOL UND CPHA auf "0"

Beim ADS1255 hab ich jetzt auf anhieb nichts gefunden, beim ADS1299 ist 
es so:

NOTE: SPI settings are CPOL = 0 and CPHA = 1.

von Christoph db1uq K. (christoph_kessler)


Angehängte Dateien:

Lesenswert?

Ich habe auch eine ganze Weile gebraucht um den ADS1256 anzusteuern, am 
Raspberry mit Python. Hier ein Teil des Programms. Die Reihenfolgen und 
Verzögerungszeiten sind vermutlich wichtig. Wieweit der 1255 kompatibel 
ist weiß ich nicht. Man findet jedenfalls noch weitere Leidensgenossen 
im Web.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

"pi.spi_open(0, 200000, 0x00000061)"
http://abyz.me.uk/rpi/pigpio/python.html#spi_open
Mode POL PHA
 0    0   0
 1    0   1
 2    1   0
 3    1   1
die beiden letzten Bits von 0x..61 bestimmen den SPI-Modus, nämlich 
"01", also so wie es mein Vorredner schon schrieb.
Die drei ADS1255-1257 unterscheiden sich anscheinend nur in der Anzahl 
der Analogeingänge.

von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Jim M. schrieb:
> Bei dem großen Bruder (ADS1298) hatte ich genau das Problem wenn die
> analoge Spannung nicht OK war. Miss die mal mit 'nem Multimeter nach.

Spannungen an den Pins sind alle okay. AVDD = 5,01 V stabil und DVDD = 
3,30 V stabil.

Adam P. schrieb:
> beim ADS1299 gehe ich im Init() wie folgt vor:
>
> - Reset vom ADS1299
> - Disable Read Continous (sonst nimmt er keine Befehle an)
> - Stop Befehl
> - Config Reg. schreiben
> - Config Reg. lesen und ID prüfen

Bei TI im Forum wurde mir auch geraten den SDATAC befehl einzufügen. Was 
ich jetzt auch getan habe. Reset kann ich vorher noch ausprobieren. Stop 
Befehl gibts bei dem Chip nicht. Ansonsten will ich erstmal das Lesen 
hinbekommen um die grundsätzliche Verbindung herzustellen.

Christoph K. schrieb:
> Ich habe auch eine ganze Weile gebraucht um den ADS1256 anzusteuern, am
> Raspberry mit Python. Hier ein Teil des Programms. Die Reihenfolgen und
> Verzögerungszeiten sind vermutlich wichtig. Wieweit der 1255 kompatibel
> ist weiß ich nicht. Man findet jedenfalls noch weitere Leidensgenossen
> im Web.

Danke für den Code. Ich kenn leider weder den Umgang mit Raspberry PI 
noch Python. Aber ich denke den groben Ablauf konnte ich trotzdem 
erkennen.
  - Soft-Reset
  - Status-Register schreiben
  - Config-Register schreiben
  - Data-Rate Register schreiben
  - ADC kalibrieren
  - ...

Ich habe die SPI Pins mal durchgemessen. So weit ich das beurteilen kann 
sehen die Signale okay aus. Siehe Anhang. Channel 1 (gelb) ist jeweils 
das !CS Signal. Wie man sieht tut sich an der DOUT leitung gar nix außer 
ein bisschen "Geraschel". Der ADC antwortet also gar nicht...

  - Bild 1: Channel 2 zeigt DIN am ADC
  - Bild 2: Channel 2 zeigt SCLK am ADC
  - Bild 3: Channel 2 zeigt DOUT am ADC

Die Bilder zeigen jeweils eine Befehl Sequenz. Zwischen den Befehlen 
wird !CS jeweils wieder auf High gezogen. Nachdem !CS auf LOW gezogen 
wurden und bevor es wieder auf High gezogen wird sind jeweils 20 µs 
Verzögerung.

  - 1. Befehl : Stop Read Data Continuously (0xF)
  - 2. Befehl : Wakeup (0x00)
  - 3. Befehl : Read Register (0x10)

Das einzige, das mir auffällt ist, dass SCLK nicht auf Masse liegt, 
sondern einen Offset hat. Weiß nicht ob dsa normal ist bzw. woran das 
liegt und ob das das Problem sein könnte?! Laut Datenblatt erkennt der 
ADC maximal 0.2*DVDD als "LOW" an den digitalen Inputs an. Ich denke 
aber da liegt das Signal noch knapp drunter. Irgendwer eine Idee wie ich 
den ADC dazu bringen kann mit mir zu sprechen? :)

Code ist auch im Anhang. Danke für eure Hilfe.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Das ist auch praktisch mein erstes Python-Programm und mein erstes auf 
dem Raspberry.
Vor dem ADS1256 kam schon der DDS, der im Programm auch erwähnt ist. Der 
hat auch erst mal keine Reaktion gezeigt, ich stand praktisch an allen 
Fronten am Anfang - waren es Hardwarefehler, Softwarefehler oder hatte 
ich das Datenblatt nicht verstanden. Durch Vergleich mit Hard- und 
Software anderer im Web konnte ich schließlich eine erste Reaktion an 
einem Pin des DDS feststellen, damit war der Durchbruch geschafft. Mit 
dem ADS1256 ging dasselbe nochmal los.

Wenigstens kann ich jetzt etwas Python, kommt mir vor wie ein würdiger 
Nachfolger von BASIC, speziell für schnelle Erfolge für Einsteiger wie 
einst in den Achtzigern. Das ganze objektorientierte Geschwurbel muss 
man nur einfach ignorieren, man kann damit genausogut funktionierende 
Software alten Stils schreiben.

Zum ADS noch: den ersten Messwert lasse ich unter den Tisch fallen, da 
erst die erste Abfrage eine AD-Wandlung auslöst - wenn ich noch recht 
weiß, ist schon über ein Jahr her.

: Bearbeitet durch User
von Tobi (Gast)


Lesenswert?

Ich bin mir mittlerweile eigentlich relativ sicher, dass ich so 
zumindest irgendeine Reaktion von dem Chip bekommen sollte...Leider 
kommt immer noch "0x00" zurück. An der DOUT-Leitung tut sich also immer 
noch nichts. Zum verzweifeln.

von Dirk F (Gast)


Lesenswert?

Was ist den mit dem _DRDY Pin ?
Messe den mal mit dem Oszi.
Er sollte nach dem Anlegen der Spannung zyklisch auf Low gehen, immer 
dann wenn eine Wandlung fertig ist.
Wenn er das nich macht, ist der Chip wohl im Eimer...

LG Dirk

von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Dirk F schrieb:
> Was ist den mit dem _DRDY Pin ?
> Messe den mal mit dem Oszi.
> Er sollte nach dem Anlegen der Spannung zyklisch auf Low gehen, immer
> dann wenn eine Wandlung fertig ist.
> Wenn er das nich macht, ist der Chip wohl im Eimer...

Du meinst zyklisch auf High oder? (Datenblatt S. 27). Das macht er auch. 
Siehe Anhang. Frequenz passt auch. Habe einen 7.3728 MHz Quarz.

(7.3728 / 7.68)* 30 kHz = 28.8 kHz

von void (Gast)


Lesenswert?

Tobi schrieb:
> Bild 3: Channel 2 zeigt DOUT am ADC
> (...)
> Irgendwer eine Idee wie ich
> den ADC dazu bringen kann mit mir zu sprechen? :)

Ja. Wie wäre es, wenn du aufhörst ihm das Maul zuzuhalten?

Wenn du dir Bild3 nochmal genau anschaust, siehst du dass das Signal 
DOUT vom ADC um mehrere hundert Millivolt im Takt hoch und 
runter-springt. Das deutet darauf hin, dass das DOUT Signal vom ADC 
gegen ein anderes Ausgangs-Signal welches bei low hängt getrieben wird.

- DOUT vom ADC korrekt mit MISO am uC verbunden?
- Niederohmige Verbindung von DOUT nach GND? / zu einem anderen Signal?
- Ist das MISO signal am uC wirklich auf Input eingestellt?
- Treibt jemand andes auch noch MISO? (z.b. der Debugger)


P.S.: Die delay_us(10) gehören übrigens genau überall NICHT hin wo du 
die geschrieben hast. Die Zeit t6 (50us) ist genau nur vor dem Lesen 
(also in der Zeile vor "//send Dummy-Byte and save return value" in 
deinem Code) notwendig. Und da fehlt sie.

von void (Gast)


Lesenswert?

Ah, und noch ein Grund warum das DOUT des ADC garnicht am MISO deines uC 
anliegen wird:

  > ADS1255_transceive(0b10|0x00); (..)
  > Bild 1: Channel 2 zeigt DIN am ADC

Das Bild 1 zeigt schön beim ersten gesendeten Byte 0x10,
dass DIN am ADC low-low-low-high low-low-low-low geht.
Das passt zum Byte 0x10.

(Man beachte 0 = low, 1 = high Level.)


  > - Bild 3: Channel 2 zeigt DOUT am ADC (...)
  > Als Antwort, bekomme ich immer nur "0xFFFFFFFF"

Bild 3 zeigt DOUT am ADC ist immer low.
Dein uC liest aber 0xFF, also immer high.
Das passt doch nicht zusammen!

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.