Forum: Mikrocontroller und Digitale Elektronik ADS131M06 ADC SPI Python


von Chris N. (chris_n854)


Angehängte Dateien:

Lesenswert?

Hallo sehr geehrte Mit-Technikenthusiasten,

ich versuche aktuell einen sehr speziellen Rail-to-Rail ADC über eine 
SPI Schnittstelle mit Hilfe eines Raspberry Pi 3B+ (Raspberry-OS) zu 
verwenden.
Hierbei habe ich (Aufgrund von SMD Bauteil) nach dem Datenblatt eine 
Adapterplatine entworfen (Siehe Anhang) mit welcher ich über ein 
Breadboard verbindungen zum Raspi hergestellt habe. Lötfehler sollten 
ausgeschlossen sein, da ich es unter einem Mikroskop begutachte konnte 
und nichts aufgefallen ist, dass irgendwie die Funktion beeinträchtigt. 
Das clk Signal bekommt der ADC über einen PWM-Pin des Raspi.

Meine Verwendete Library für die SPI-Schnittstelle ist "spidev"

Der verwendete Code sieht wie folgt aus:
1
 
2
#imports
3
import binascii
4
import time
5
import spidev
6
import RPi.GPIO as GPIO
7
from ADS131_Command import *
8
from ADS131_Reg import*
9
10
#settings
11
GPIO.setmode(GPIO.BCM)
12
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
13
GPIO.add_event_detect(17,GPIO.FALLING)
14
15
adcC = ADS131_Command()
16
adsReg = ADS131_Reg()
17
18
19
spi = spidev.SpiDev()
20
spi.open(0,0) 
21
spi.mode = 0b01
22
spi.max_speed_hz = 1024000
23
spi.lsbfirst = False
24
25
def send(msg):
26
    while True:
27
        if GPIO.event_detected(17):
28
            
29
            #print("send some Data")
30
            #print(msg)
31
            spi.writebytes(msg)
32
            
33
            break
34
    
35
def receive(n):
36
    while True:
37
        if GPIO.event_detected(17):
38
            
39
            #print("receive some Data")
40
            respbin= 0
41
            resp = spi.readbytes(n)
42
            
43
            for i in resp:
44
                respbin = respbin<<8
45
                respbin = respbin+i
46
                    
47
            print(bin(respbin))
48
            break
49
        
50
if __name__ == '__main__':
51
    
52
    for i in range(5):
53
        send(adcC.rreg(0x01,0x00))
54
        receive(2)
55
        time.sleep(0.2)
56
    spi.close()

Output:
1
0b10100111111
2
0b10100111111
3
0b10100111111
4
0b10100111111
5
0b10100111111
Die "Klasse" ADC_Commands beinhaltet lediglich die im Datenblatt 
abgelegten Befehle in HEX als Konstanten.

Nun zu meinem eigentlichen Problem:
Beim auslesen des ADC erhalte ich immer die gleiche Nachricht, 
unabhängig davon was ich vorher gesendet habe. Auf den Reset-Befehl, 
genauso wie auf Unlock, Standby, Wakeup usw. reagiert er nicht. Die 
Verbindung vom MOSI bis zum ADC besteht.

Gibt es hier vielleicht jemanden der mir einen Vorschlag unterbreiten 
kann was ich noch ausprobieren kann? Ich sitz schon eine ganze Woche an 
dem Problem.

von Paul (Gast)


Lesenswert?

Chris N. schrieb:
> Lötfehler sollten
> ausgeschlossen sein

Layoutfehler scheinbar nicht, oder was machen die 4 Luftlinien da unten 
links im Bild? Wireless Leiterbahnen?

VG Paul

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris N. schrieb:
> Beim auslesen des ADC erhalte ich immer die gleiche Nachricht
Welche denn?

> Gibt es hier vielleicht jemanden der mir einen Vorschlag unterbreiten
Du musst messen:
1. mit dem Oszi: wie sehen die Signale SCLK und DIN direkt am ADC aus? 
Passen Spannungspegel und Flankensteilheit zu den Anforderungen aus dem 
Datenblatt? Sieht man Klingeln oder Stufen in den Flanken?
2. mit dem LA oder 4-Kanal-Oszi: passt das Timing und die Polarität der 
Signale CS#, SCLK und DIN zu den Anforderungen aus dem Datenblatt?
3. werden die Datenbits auf DIN in der richtigen Reihenfolge übertragen?

: Bearbeitet durch Moderator
von Chris N. (chris_n854)


Lesenswert?

Paul schrieb:
> Layoutfehler scheinbar nicht, oder was machen die 4 Luftlinien da unten
> links im Bild? Wireless Leiterbahnen?

Die Vier nicht belegten Pins am ADC sind NC-Kontakte (Bei der 8-Channel 
variante Belegt, bei der 6-Channel variante nicht -> Hier irrelevant). 
Trotzdem danke für den Hinweis.

Lothar M. schrieb:
> Chris N. schrieb:
>> Beim auslesen des ADC erhalte ich immer die gleiche Nachricht
> Welche denn?
>
>> Gibt es hier vielleicht jemanden der mir einen Vorschlag unterbreiten
> Du musst messen:
> 1. mit dem Oszi: wie sehen die Signale SCLK und DIN direkt am ADC aus?
> Passen Spannungspegel und Flankensteilheit zu den Anforderungen aus dem
> Datenblatt? Sieht man Klingeln oder Stufen in den Flanken?
> 2. mit dem LA oder 4-Kanal-Oszi: passt das Timing und die Polarität der
> Signale CS#, SCLK und DIN zu den Anforderungen aus dem Datenblatt?
> 3. werden die Datenbits auf SCLK in der richtigen Reihenfolge
> übertragen?

Dann Schnapp ich mir mal ein Oszi und versuch das Auszumessen. Die 
Timings müssen ja dann zu denen aus dem Datenblatt passen nehme ich an. 
Ich berichte dann.
Die Nachrichten sind im Post unter "output", sehen genau SO aus, egal 
welchen Befehl ich sende.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Du solltest dir auch das Kapitel "8.5.1.7 SPI Communication Frames" mal 
ganz genau anschauen, denn vermutlich stellst du dir die Kommunikation 
mit dem Baustein etwas anders vor, als der sich das vorstellt: bei SPI 
wird mit jedem Takt ein Bit sowohl auf MOSI(=DIN) wie auch auf 
MISO(=DOUT) übertragen. Mit dem Senden des Kommandos und der CRC (und 
nachfolgenden Nullbytes) vom µC zum ADC wird gleichzeitig die 
"Antwort" auf das vorher gesendete Kommando vom ADC zum µC übertragen.

Du wirst mit dem Oszi/LA ja sofort sehen, ob das was auf deinem Bus 
passiert, zu den Anforderungen im Datenblatt passt.

von Chris N. (chris_n854)


Lesenswert?

Lothar M. schrieb:
> Du solltest dir auch das Kapitel "8.5.1.7 SPI Communication Frames" mal
> ganz genau anschauen, denn vermutlich stellst du dir die Kommunikation
> mit dem Baustein etwas anders vor, als der sich das vorstellt: bei SPI
> wird mit jedem Takt ein Bit sowohl auf MOSI(=DIN) wie auch auf
> MISO(=DOUT) übertragen. Mit dem Senden des Kommandos und der CRC (und
> nachfolgenden Nullbytes) vom µC zum ADC wird gleichzeitig die
> "Antwort" auf das vorher gesendete Kommando vom ADC zum µC übertragen.
>
> Du wirst mit dem Oszi/LA ja sofort sehen, ob das was auf deinem Bus
> passiert, zu den Anforderungen im Datenblatt passt.

Ich wusste schon, dass die Datenübertragungen auf MISO und MOSI quasi 
zeitgleich erfolgen. Aber ergibt sich nicht aus eben genau diesem 
Schaubild, dass ein warten auf !DRDY ausreicht um die Daten auszulesen?

PS: Oszi ist in Besorgung

PPS: Die Wortlänge die ich erwarte sollte ja im Bereich von 16 Bit bis 
Vielfaches betragen (Je nach dem wie viele Register auf einmal ich über 
den RREG Befehl auslesen möchte)?

Edit: Natürlich schau ich mir trotzdem noch an ob das Timing von !DRDY, 
!CS, SCLK, MOSI und MISO passt.

: Bearbeitet durch User
von Chris N. (chris_n854)


Angehängte Dateien:

Lesenswert?

Guten Morgen zusammen,

ich hab über das Wochenende mal ein Oszi an die SPI Schnittstelle 
angeschlossen und mir die Signale ausgeben lassen. Mir ist dann 
aufgefallen dass ich zwar immer die Gleiche Nachricht bekomme, jedoch 
diese nur der Anfang einer längeren Nachricht ist.

Das vorherige Nicht-reagieren des ADC kam wohl davon, dass ich nur einen 
kleinen Anteil der Nachricht ausgelesen habe.

Nun komme ich aber zu einem weiteren Problem:
Im Datenblatt sind die länge der Register sowie ein schematischer 
Signalablauf aufgezeigt. Woher bekomme ich denn jetzt die Information 
welche Bits der Nachricht zu welchem Register gehören?
Aufgezeigt ist ja nur, dass die Nachricht unterschiedlich lang sein 
kann, je nach dem wie viele Register man versucht aus zu lesen. Aber wie 
lang genau sie bei welchen Registern ist wird mir nicht ersichtlich. 
Kann es vielleicht sein, dass die Register in unterschiedlichen 
Nachrichten mit gleicher Länge ausgegeben werden? Wenn ja woher weiß ich 
dann ab welchem Bit in den einzelnen Nachrichten der Wert der z.B. 
analog Register beginnt?

PS: Ein Oszi Bild habe ich zur Vollständigkeit mal angehängt.

von Paul (Gast)


Lesenswert?

Das steht alles im Datenblatt des ADC, glaub mir.
Das wäre dann auch die richtige Reihenfolge in der Vorgehensweise.
Datenblatt lese und verstehe, Aufbau ( besser nicht Breadboard) , 
programmieren……
Wahrscheinlich wird dann der OSZi obsolet.

von Chris N. (chris_n854)


Lesenswert?

Paul schrieb:
> Das steht alles im Datenblatt des ADC, glaub mir.
> Das wäre dann auch die richtige Reihenfolge in der Vorgehensweise.
> Datenblatt lese und verstehe, Aufbau ( besser nicht Breadboard) ,
> programmieren……
> Wahrscheinlich wird dann der OSZi obsolet.

Ich versuche wirklich zu Verstehen wie das alles Funktioniert und wälze 
seit fast 2 Wochen das Datenblatt hoch und runter.
Die Vorgehensweise ist mir im Ablauf so schon bekannt, leider fehlen mir 
trotzdem Informationen die ich nicht im Datenblatt finde weil sie 
entweder nicht drin stehen (unwahrscheinlich) oder weil ich die Begriffe 
dafür einfach nicht kenne.
Um ein bisschen Hilfestellung der Begriffe wegen wäre ich sehr dankbar.

von Klaus S. (kseege)


Lesenswert?

Chris N. schrieb:
> Um ein bisschen Hilfestellung der Begriffe wegen wäre ich sehr dankbar.

Da wir nicht wissen, welche Begriffe Du nicht verstehst, wird eine 
Erklärung schwierig.

Ich würde daher zusätzlich noch vorschlagen, ein stinkeinfaches Programm 
ohne zusätzliche Schleifen oder Unterprogrammaufrufe zum Testen zu 
schreiben.
Also:
Aktiviere ChipSelect f.den Slave
Sende die Kommandosequenz für einen einfachen Befehl
Sende die Anzahl der erwarteten Antwortbytes als Dummy
Deaktiviere ChipSelect für den Slave

Dann die Vorschläge von Lothar und Paul aktivieren!

Just my 2 cents

von Chris N. (chris_n854)


Lesenswert?

Klaus S. schrieb:
> Chris N. schrieb:
>> Um ein bisschen Hilfestellung der Begriffe wegen wäre ich sehr dankbar.
>
> Da wir nicht wissen, welche Begriffe Du nicht verstehst, wird eine
> Erklärung schwierig.
>
> Ich würde daher zusätzlich noch vorschlagen, ein stinkeinfaches Programm
> ohne zusätzliche Schleifen oder Unterprogrammaufrufe zum Testen zu
> schreiben.
> Also:
> Aktiviere ChipSelect f.den Slave
> Sende die Kommandosequenz für einen einfachen Befehl
> Sende die Anzahl der erwarteten Antwortbytes als Dummy
> Deaktiviere ChipSelect für den Slave
>
> Dann die Vorschläge von Lothar und Paul aktivieren!
>
> Just my 2 cents

Hallo Klaus, danke für die Antwort.

ich habe bereits ein stinkeinfaches Programm, auch ohne Schleife, 
ausprobiert um die Funktion zu Überprüfen. Ich bekomme mittlerweile auch 
Daten die, zumindest zum Beginn, gleich sind. Jedoch stehe ich noch 
immer vor der Problematik, dass ich nicht genau weiß wie groß die 
Empfangenen Daten sein müssen und an welcher Stelle genau die einzelnen 
Bits für den jeweiligen Antwortblock stehen. Auch beim heutigen genau 
gezielten durchlesen aller Seiten auf dem Datenblatt sind mir die Längen 
und Positionen nicht klar geworden und ich steh im Dunkeln.

Trotzdem Danke für den Hilfeversuch an alle Beteiligten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris N. schrieb:
> Mir ist dann aufgefallen
- Hast du vorneweg mal das Bittiming kontrolliert? Zeig dafür mal nur 
das erste Byte auf der gesamten Bildschirmbreite an. Und versuch mal, 
die Zeitskala auf etwas Menschenlesbares wie z.B. µs zu skalieren.

- Sende dann ein einziges definiertes Byte oder Wort. Ein Wert wie 0xC1 
oder 0x85 oder 0xA3 so ist recht geeignet, weil daraus ein Bitmuster wie 
10100001 oder 10000101 oder 10100011 erzeugt wird. aus diesem Bitmuster 
kann man dann ermitteln, welches das erste Bit ist, ob es an der 
erwarteten Position kommt (SPI-Mode).

- Wie sind bei den Messungen die Masseclips angeschlossen? Die sollten 
ebenso wie die Tastköpfe alle recht dicht am ADC aufgeklemmt sein. Also 
nicht irgendwo 30cm weit weg am Netzteil. Oder dass gar nur 1 
Masseklemme von den 4 angeklemmt ist.

von Chris N. (chris_n854)


Angehängte Dateien:

Lesenswert?

Lothar M. schrieb:
> Chris N. schrieb:
>> Mir ist dann aufgefallen
> - Hast du vorneweg mal das Bittiming kontrolliert? Zeig dafür mal nur
> das erste Byte auf der gesamten Bildschirmbreite an. Und versuch mal,
> die Zeitskala auf etwas Menschenlesbares wie z.B. µs zu skalieren.

Danke für die Antwort!
Die Zeitskala ist jetzt auf us skaliert, hoffe das kann man jetzt besser 
erkennen!


> - Sende dann ein einziges definiertes Byte oder Wort. Ein Wert wie 0xC1
> oder 0x85 oder 0xA3 so ist recht geeignet, weil daraus ein Bitmuster wie
> 10100001 oder 10000101 oder 10100011 erzeugt wird. aus diesem Bitmuster
> kann man dann ermitteln, welches das erste Bit ist, ob es an der
> erwarteten Position kommt (SPI-Mode).

ich habe jetzt 0x85 gesendet und auf dem Bildausschnitt ist der Beginn 
der Nachricht zu sehen, wie kann ich das jetzt beurteilen? Im Datenblatt 
stehen ja eine Menge an Zeiten.. Muss ich die alle einzeln Überprüfen?

> - Wie sind bei den Messungen die Masseclips angeschlossen? Die sollten
> ebenso wie die Tastköpfe alle recht dicht am ADC aufgeklemmt sein. Also
> nicht irgendwo 30cm weit weg am Netzteil. Oder dass gar nur 1
> Masseklemme von den 4 angeklemmt ist.

Die ADC-Platine steckt in einem Breadboard und die Oszi Anschlüsse sind 
nicht weiter als 5cm von einander entfernt, ich habe Alle Anschlüsse an 
einen Draht der direkt am GND von der ADC-Platine verbunden ist, 
angeschlossen.


Nochmal zur Hintergrundinfo: ADC-Platine und Raspberrypi liegen keine 
10cm auseinander und sind mit möglichst kurzen Leitungen verbunden, der 
ADC sitzt auf einem Breadboard, da ich leider nur diesen Raspi besitze 
und dort nichts anlöten möchte/kann (habe angst die Pins zu verhunzen 
und unbrauchbar zu machen für andere Projekte)

Vielen Dank für die Hilfe!!!

von Jobst M. (jobstens-de)


Lesenswert?

Chris N. schrieb:
> Beim auslesen des ADC erhalte ich immer die gleiche Nachricht,
> unabhängig davon was ich vorher gesendet habe.

Schon mal ein CRC hinterher geschickt? Steht auch im Datenblatt!
Bzw. CRC abgeschaltet?

Nachtrag: Doch, Du hast Recht, das DaBla ist eine Katastrophe.

Gruß
Jobst

: Bearbeitet durch User
von Chris N. (chris_n854)


Lesenswert?

Jobst M. schrieb:
> Chris N. schrieb:
>> Beim auslesen des ADC erhalte ich immer die gleiche Nachricht,
>> unabhängig davon was ich vorher gesendet habe.
>
> Schon mal ein CRC hinterher geschickt? Steht auch im Datenblatt!
> Bzw. CRC abgeschaltet?

Hallo Jobst, danke für deine Antwort!

ich habe bereits festgestellt, dass nur der Beginn der Nachricht immer 
gleich ist.
Der ADC sitzt noch auf Werkseinstellungen. Wie schicke ich ein CRC 
hinterher? Sende ich dafür eine extra "Nachricht" oder kommt das in das 
Data-Array von dem gesendeten Command hinten dran? Oder schickt das der 
ADC wenn es aktiviert ist?

> Nachtrag: Doch, Du hast Recht, das DaBla ist eine Katastrophe.
>
> Gruß
> Jobst

Vielen Dank, das gibt mir Hoffnung, dass ich das Teil nochmal zum laufen 
bekomme.

: Bearbeitet durch User
von Klaus S. (kseege)


Lesenswert?

Chris N. schrieb:
> das gibt mir Hoffnung, dass ich das Teil nochmal zum laufen
> bekomme.

Wieso sollte das nicht funktionieren? Es geht immer nur darum, die 
Geduld nicht zu verlieren. Wenn man die hat, gibt eine Maschine zum 
Schluß immer nach, es sei denn, man stellt sich zu dämlich an :-)))

Die erste Hürde ist die richtige Wahl der 2 Parameter Phase und Polarity 
für den SPI-Mode. Laut Datenblatt muß Phase=0 und Polarity=1 sein. Dafür 
war der erste von Lothar angeregte Test für das erste Byte gedacht. Das 
wäre jetzt Deine Aufgabe, das nachzuprüfen. Es ist im Datenblatt auch 
explizit erklärt: SCK ist im Ruhezustand LOW und bei steigender Flanke 
werden die Daten übernommen. Wie man aus Deinem Oszillogramm sieht, 
wechselt aber ausgerechnet bei steigender Flanke MOSI seinen Pegel! Also 
ideal für Mißverständnisse, das kann nur mit 0,001% Wahrscheinlichkeit 
funktionieren. Dein SPI-Mode im Raspi ist also falsch eingestellt. Also 
muß erstmal SPI-Mode 1 eingestellt werden. Das Datenblatt lese ich gern 
für Dich (weil ich dabei auch was lerne), aber fremde Libraries sind mir 
Graus, da kann ich nicht helfen. Vielleicht findet sich jemand Anderes, 
der diese Library kennt und verwendet.

Du solltest also in der Librarybeschreibung nach dem Setzen des 
SPI-Modes suchen. Es gibt 4 verschiede Modi, wenn man die Beschreibung 
nicht versteht, kann man einfach die 4 Modi durchprobieren. Wenn SCK im 
Ruhezustand LOW ist und die Daten auf MOSI bei fallender SCK-Flanke 
geändert werden (damit sie bei steigender Flanke stabil sind!), bist Du 
richtig.

Wenn Du das hingekriegt hast, kann es weitergehen.


Gruß Klaus (der soundsovielte)

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.