Forum: Mikrocontroller und Digitale Elektronik I2C Poti Ansteuerung


von Mike (Gast)


Lesenswert?

Hallo Zusammen,
heute wollte ich mal einen alternativen Baustein testen, den Intersil 
X9118 mit 1024 Schritten via I2C.

Nun habe ich folgendes Problem. Das Einstellen des Wipers funktioniert 
einwandfrei. ID&&R/W-Bit + 0xa0 + 2Byte meines Wertes

Das funktioniert auch, laut Messgerät am Wiper-Pin.

Nun möchte ich diesen Wert auslesen. Laut Datenblatt entspricht das 
Config-Byte 0x80.

ID&&R/W-Bit + 0x80 und müsste als Antwort 2 Bytes erhalten. Jedoch 
erhalte ich nichts. Als würde das Gerät eine Art "Lock" haben. Habe ich 
da was übersehen? Bei der Verschaltung gibt es nichts Spektakuläres.

Danke vorab für Tipps.

von Joe F. (easylife)


Lesenswert?

R/W bit falsch gesetzt?
Stop condition innerhalb der 4 Bytes beim Read?
Mach mal einen Screenshot mit einem Speicheroszi oder Logic-Analyzer von 
deinem Read-Zugriff.

von Mike (Gast)


Lesenswert?

Read und write sowie stop condition laufen automatisch. Ich arbeite mit 
einer Software, deren Treiber automatisch die Bits setzt. Daran liegt es 
definitiv nicht

von Wolfgang (Gast)


Lesenswert?

Mike schrieb:
> ID&&R/W-Bit + 0x80 und müsste als Antwort 2 Bytes erhalten. Jedoch
> erhalte ich nichts. Als würde das Gerät eine Art "Lock" haben.

Und was passiert dabei auf dem Bus?

von Mike (Gast)


Lesenswert?

Nichts. Merkwürdigerweise funktioniert das lesen des Data Wiper 
Registers, aber das lesen des Registers selbst mit 0x80 nicht.

von Joe F. (easylife)


Lesenswert?

Mike schrieb:
> Nichts.

Deine Software liefert dir nichts.
Aber auf dem Bus wird etwas passieren.
Deswegen fragen wir hier auch nach weiteren Informationen, ansonsten ist 
kein Erkenntnisgewinn zu erwarten.

Guck, was auf dem Bus (elektrisch) passiert, und lasse uns daran 
teilhaben.
Ein häufiger Fehler sind auch falsche Pullups.
Jeweils 2.2K für SDA und SCL sind eine gute Wahl.

von Mike (Gast)


Lesenswert?

Die pullups sind km BeagleBone Black integriert. Der write Befehl geht, 
nur das lesen nicht

von Joe F. (easylife)


Lesenswert?

Mike schrieb:
> Die pullups sind km BeagleBone Black integriert.

Und welchen Wert haben die?

> Der write Befehl geht, nur das lesen nicht

das wurde glaube ich inzwischen klar.


Setze mal die I2C Clock deutlich runter, so auf 10 KHz. Wenn es dann 
geht, schließt du mal parallel zu den im BeagleBone Black vorhandenen 
Pullups weitere 2.2K an.
Ich habe jetzt keine Lust für dich zu recherchieren, ob beim Beaglebone 
Black viel zu schwache interne Prozessor-Pullups verwendet werden, oder 
andere Pullups (4.7K? 10K) verbaut sind.

Wenn es dann mit den 2.2K auch bei 400KHz geht, lag es daran.

Ausserdem sollte dir deine Software auch mitteilen, ob bei der 
Übertragung Fehler passiert sind (fehlendes ACK z.B.).

von Mike (Gast)


Lesenswert?

Ich werde es morgen mal versuchen. Die Software teilt mir lediglich eine 
i/o Fehler mit. Der Befehl wird garnicht erst Gesendet bzw. geschrieben. 
Demnach erhalte ich auch keine Antwort. Das Lesen des Daten Registers 
funktioniert jedoch, wobei hier wiederum immer 65535 resultiert. Wie 
dieser Wert zustande kommt, ist mir unklar.

von Wolfgang (Gast)


Lesenswert?

Mike schrieb:
> Das Lesen des Daten Registers funktioniert jedoch, wobei hier wiederum
> immer 65535 resultiert.

Das würde ich mal als stabiles 0xFFFF, also lauter Einsen 
interpretieren. Bist du sicher, dass der Wert so aus dem Datenregister 
über den Bus kommt oder liefert dir da deine Software einen ungültigen 
Wert?

Hast du die 0xFFFF mit vernünftigem I2C-Protokoll als elektrisches 
Signal auf dem Bus gesehen? Sonst häng auch mal ein Oszi an und guck dir 
die Signalqualität an. Wie lang ist dein Bus und wie schnell taktest du 
ihn?

von Sebi (Gast)


Lesenswert?

Guten Morgen,
zu den Pullups habe ich auf Seite 85 des Datenblattes einen Eintrag 
gefunden: https://cdn-shop.adafruit.com/datasheets/BBB_SRM.pdf

Aus dem Text wird jedoch nicht ersichtlich, wie grpß die internen 
Pullups sind.

von Sebi (Gast)


Lesenswert?

i2cdump liefert mir folgendes:

 i2cdump -y  1 0x29
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX    XXXXXXXXXXXXXXXX
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

von Jobst M. (jobstens-de)


Lesenswert?

Mike schrieb:
> ID&&R/W-Bit + 0x80 und müsste als Antwort 2 Bytes erhalten.

START ID+write ACK 0x80 ACK STOP START ID+read ACK Byte1 ACK Byte2 NACK 
STOP

?!


Gruß

Jobst

von W.A. (Gast)


Lesenswert?

Sebi schrieb:
> Aus dem Text wird jedoch nicht ersichtlich, wie grpß die internen
> Pullups sind.

Seit der Erfindung des Spannungsteilers kann man soetwas nachmessen.

Ein Widerstand von  z.B. 2.2kΩ als Last an dem Bus und Nachmessen des 
Buspegels mit und ohne Widerstand gibt dir den Wert des Pull-Up 
Widerstandes. Um zu gucken, ob da noch irgendwer am Bus zieht, empfiehlt 
es sich, die Versorgungsspannung ebenfalls zu messen.

von Sebi (Gast)


Lesenswert?

Mit einem 2,2k auf VDD erhalte ich 3,395V. Ohne den Wiederstand 3.209V

von Peter D. (peda)


Lesenswert?

Mike schrieb:
> Nun möchte ich diesen Wert auslesen.

Ich hab mal ins Datenblatt gesehen, das Ding ist nicht I2C-kompatibel, 
sondern fährt beim Lesen ein abweichendes Protokoll.

Lt. I2C-Standard muß der Master direkt nach dem Slave-ACK auf das 
RW_Bit=1 auf Lesen umschalten.
Der IC will dann aber noch das Kommando gesendet haben und erst danach 
gelesen werden und das kann kein Standard-I2C.

Ein Lesen geht daher nur, wenn man dieses non-I2C zu Fuß (Bit-Banging) 
mit 2 IO-Pins programmiert.

von Sebi (Gast)


Lesenswert?

Also beddeutet das, dass es zwar über I2C ansteuerbar ist, jedoch nicht 
mit dem Standard-Protokoll? Falls ich es doch verwenden möchte, bleibt 
mir lediglich der Schreibbefehl, der ja funktioniert. Das Auslesen 
müsste ich dann über einen ADC regeln. Oder gibt es doch eine 
Möglichkeit es über I2C zu betreiben? Mit den Standard I2C-Treibern?

von Jens W. (jensw)


Lesenswert?

Wir kennen leider deinen Code nicht.
Vergleiche mal zu einem EEPROM.
Da wird beim Read auch erst per Write Befehl die Adresse gesendet, auf 
der gelesen werden soll. Danach kommt ein Repeated Start mit dem Read 
Kommando.
Vielleicht funktioniert das.

Du könntest uns auch deinen Code posten. Vielleicht hast du auch nur 
irgendwas übersehen.

Grüße, Jens

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> Das Auslesen
> müsste ich dann über einen ADC regeln.

Was !? 8-/

Nein. Zwei Leitungen, wie bei I²C. Nur dass Du die I²C-Hardware des 
Controllers nicht verwenden kannst, sondern das Protokoll zu Fuß 
erzeugen musst.

Normalerweise ist die Datenrichtung bei I²C nach dem R/W-Bit festgelegt.
Zum lesen muss also zunächst geschrieben werden, was man vom Chip will 
und dann kann man nach einer erneuten Verbindung mit R/W = 1 die Daten 
vom Chip lesen. Ich hatte das weiter oben schon angedeutet.

Dein Chip wechselt während der Kommunikation die Datenrichtung. Das 
macht eine ordnungsgemäße I²C-Schnittstelle nicht mit.

Daher musst Du das Protokoll händisch abwickeln. Also Portpins auf H / L 
legen oder als Eingang schalten und auslesen. Bitbanging nennt man diese 
Herangehensweise.


Gruß

Jobst

von Sebi (Gast)


Lesenswert?

Mit der verwendeten Kontrollsoftware wird das aber nicht funktionieren, 
da die I2C-Treiber hier bereits geschrieben sind. Ich kann lediglich die 
Bits für die Geräte-ID und die Konfigurationsbits setzen. Das R/W-Bit 
ist beispielsweise fest. Jenachdem ob ich eine Input oder Output 
funktion wählen, wird das Bit automatisch gesetzt. Ich muss im Protokoll 
lediglich die ID angeben, gefolgt von den Config-Bits, in meinem Fall 
zum Lesen 0x80 und der Anzahl der Bytes, die ich als Antwort erhalte. 
Aber laut Protokolldatei ist bei Lesevorgang bereits das Schreiben der 
Konfigurationsbits nicht erfolgreich.

von Jens W. (jensw)


Lesenswert?

Hallo nochmal,

entweder (siehe weiter oben habe ich das schon erwähnt) vergleiche mit 
einem EEPROM,
oder (am Besten) postest du den Code.

Wenn ein Ansprechen eines EEPROMs funktioniert (vielleicht gibt es hier 
schon eine Implementierung für dein Board) kannst du das für deinen 
Baustein übernehmen (natürlich mit Anpassung der Adressen).

Ansonsten musst du deine Treiber anpassen und kannst halt nicht auf 
etwas fertiges zurück greifen.

Gruß, Jens

von Sebi (Gast)


Lesenswert?

Das Ansprechen eines MCP4725 funktioniert einwandfrei. Ich sehe auch 
keine Unterschied zum X 9118, was den Lesevorgang betrifft. Es gibt 
keine Code. ich gebe einfach als Parameter die oben genannten Werte ein. 
Es hat bisher mit zahlreichen anderen Bausteinen einwandfrei 
funktioniert.

von Sebi (Gast)


Lesenswert?

Bzw. ich sehe nur, dass eigentlich das ACK nach dem zweiten Byte vom 
Master umgeschaltet werden müsste, was hier nicht passiert. Ich werde 
mich mal mit dem Thema näher befassen, wobei die Treiber umschreiben 
nicht das Problem ist, sondern die tatsache, dass ich diese dann für 
Standard-ICs nicht verwenden kann.

von Joe F. (easylife)


Lesenswert?

Sebi schrieb:
> Mit der verwendeten Kontrollsoftware wird das aber nicht funktionieren,
> da die I2C-Treiber hier bereits geschrieben sind.

Sebi schrieb:
> wobei die Treiber umschreiben
> nicht das Problem ist, sondern die tatsache, dass ich diese dann für
> Standard-ICs nicht verwenden kann.

Heisst du eigentlich nur heute "Sebi", und morgen wieder "Mike"?

Gib uns doch bitte mal ein wenig mehr Hintergrundinformationen.

Ein Oszilloskop oder Logic-Analyzer scheint dir offenbar nicht zur 
Verfügung zu stehen, richtig?

Um welche Platform / welchen I2C Treiber handelt es sich denn? Evtl. 
kann man sich den Request ja irgendwie aus vorhandenen Funktionen 
zusammenbasteln. Viele APIs erlauben die Kontrolle über die 
start/stop/repeated-start Konditionen.

: Bearbeitet durch User
von Sebi (Gast)


Lesenswert?

Könnte ich den Wert über i2c-tools unter Linux abrufen? Wenn ich für den 
Leser Zugriff zuerst 0x80 schreibe, erhalte ich ein write error, da 0x80 
laut i2cdump "xx" ist, also nicht belegt. Erst ab 0xa0 bis 0xf0 scheint 
es zu funktioniert.

von Wolfgang (Gast)


Lesenswert?

Sebi schrieb:
> Mit einem 2,2k auf VDD erhalte ich 3,395V. Ohne den Wiederstand 3.209V

Wieso auf VDD. Wenn du den Widerstand parallel zum Pull-Up schaltest, 
kannst du doch mit der Methode den Wert vom Pull-Up nicht bestimmen. 
High bleib high, wenn keine Last dran hängt :-)

Aber immerhin scheint dein VDD also bei gut 3.3V zu liegen.

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> Wenn ich für den
> Leser Zugriff zuerst 0x80 schreibe

Natürlich geht das nicht!

Du sagst der Schnittstelle, dass Du lesen möchtest und schreibst dann?
Möchtest Du die Elektronik belügen?


Gruß

Jobst

von Sebi (Gast)


Lesenswert?

I'm vorherigen Beitrag hiess es, man muss das Kommando senden und dann 
erhält man die Antwort

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> I'm vorherigen Beitrag hiess es, man muss das Kommando senden und dann
> erhält man die Antwort

Ja, aber keine I²C konforme Hard- / Software wird das mitmachen.
Dir wurde ja schon gesagt, dass Dich selber um das Protokoll kümmern 
musst.


Gruß

Jobst

von Sebi (Gast)


Lesenswert?

Ich habe mir den X9118 nochmal angeschaut. Ich verstehe es irgendwie 
nicht. Ich sende die Geräte-ID. Der Slave quittiert. Dann sende ich 
0x80. Der Slave quittiert. Dann folgen die zwei Bytes. Im Prinzip 
arbeiten andere Bausteine wie der MCP4725 genau so. Ich sende die ID, 
dann wird vom Slave quittiert.

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> Ich sende die Geräte-ID. Der Slave quittiert. Dann sende ich
> 0x80. Der Slave quittiert. Dann folgen die zwei Bytes.

Wenn Du auch diese beiden Bytes sendest, dann ist es I²C konform.
Aber Du sendest sie nicht, Du möchtest sie empfangen. Das geht so nach 
I²C nur mit erneutem Start.


Sebi schrieb:
> Im Prinzip
> arbeiten andere Bausteine wie der MCP4725 genau so.

Nein. Dort kannst Du immer nur in einer Richtung arbeiten. Wie bei I²C 
vorgesehen.


Gruß

Jobst

von Sebi (Gast)


Lesenswert?

Also wenn ich mir den read-Vorgang anschaue, erhalte ich zwar 5 Bytes 
als Antwort, muss aber dennoch den slave ansprechen und die ID senden. 
Bei anderen Bausteinen die dem AD527x ist das auch nicht anders. Ich 
spreche das Device an gefolgt von der entsprechenenden Register Adresse 
und erhalte dann die Antwort. Verstehe den Unterschied nicht.

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> Also wenn ich mir den read-Vorgang anschaue, erhalte ich zwar 5 Bytes
> als Antwort,



> muss aber dennoch den slave ansprechen und die ID senden.

Das musst Du immer!
Nach START kommt IMMER die SlaveID + R/W, gefolgt von einer Bestätigung 
vom Slave.
Und dann werden entweder Daten vom Master geschrieben (R/W = 0) oder vom 
Slave gesendet (RW = 1).
UND DAS WECHSELT INNERHALB EINER ÜBERTRAGUNG AUCH NICHT!!!


> Bei anderen Bausteinen die dem AD527x ist das auch nicht anders.

DOCH!

> Ich
> spreche das Device an gefolgt von der entsprechenenden Register Adresse
> und erhalte dann die Antwort.

Du schreibst aber in der selben Verbindung dann nicht.


> Verstehe den Unterschied nicht.

Nochmal der Unterschied:

Dein X9118:
1
START SlaveID + R/W=? SlaveACK DatenVomMaster SlaveAck DatenVomSlave MasterACK DatenVomSlave MasterNACK STOP

I²C Device:
1
START SlaveID + R/W=0 SlaveACK DatenVomMaster SlaveAck STOP START SlaveID + R/W=1 SlaveACK DatenVomSlave MasterACK DatenVomSlave MasterNACK STOP


Ja, wenn Du es nun nicht hast, dann gebe ich auch auf ...
Dann mach was anderes ...


Gruß

Jobst

von Sebi (Gast)


Lesenswert?

Ok, ich glaube, dass ich das jetzt verstehe. Bei dem AD527x empfängt der 
Slave die Konfigurationsbytes. Nach dem STOp beginnt eine neue 
Übertragung mit R/~W=1. Bei dem X 9118 passiert dies während einer 
Übertragung.

von Sebi (Gast)


Lesenswert?

Könnte man per Hand unter Debian (Raspberry, Beaglebone) das ganze in 
C/C++ testweise umsetzen? Oder ist das doch mehr Aufwand? Muss ich dafür 
andere GPIOs wählen oder funktioniert das auch über die 
I2C-Schnittstelle von Raspberry Pi/Beaglebone? Mit den i2ctools wird es 
wohl nicht funktionieren.

von Jobst M. (jobstens-de)


Lesenswert?

Sebi schrieb:
> Oder ist das doch mehr Aufwand? Muss ich dafür
> andere GPIOs wählen oder funktioniert das auch über die
> I2C-Schnittstelle von Raspberry Pi/Beaglebone?

Du benötigst 2 Portpins, welche Du separat bedienen kannst. Sie müssen 
OpenCollector mit Pullup sein.

Dann solltest Du durch setzen und abfragen der Pins unter Beachtung der 
Zeiten eigentlich recht schnell zum Ziel kommen.



Gruß

Jobst

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.