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.
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
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?
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.
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.
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.
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.
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.
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.
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
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.
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.
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!!!
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
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.
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)