Fehler beim Initiieren der I2C-Kommunikation zwischen Arduino und 3,3-V-Slave

Ich versuche, in die kapazitive Sensorik einzusteigen und benötige daher eine stabile Kommunikation zwischen einem Arduino und einem TI FDC2114 , der bereits auf einem EVM gelötet ist. Beide unterstützen I2C, und wegen der unterschiedlichen Betriebsspannung von 5 V für den Arduino und 3,3 V für den FDC verwende ich einen PCA9512A bidirektionalen Level-Shifter und 10k-Pullups auf 5 V (Arduino Mega intern) sowie auf 3,3 V.

Beim Scannen der Adresse des FDC bekomme ich manchmal eine positive Antwort (ACK auf dem letzten Takt nach der angeforderten 7-Bit-Adresse), aber meistens ein NACK. Selbst wenn ich ein ACK erhalte, kann der FDC einige Sekunden später den SDA nicht mehr auf 0 V herunterziehen und ich bekomme wieder NACK. Bei NACK kann es helfen, SDA und SCL unter Spannung abzuziehen und wieder einzustecken, aber es funktioniert nicht immer. Ich habe bereits alle Kabel gewechselt, also sollte es kein mechanisches Problem sein. Ich habe auch beobachtet, dass die Spitzenspannung bei SCL 3,4 V und bei SDA mehr als 3,6 V beträgt, aber ich weiß nicht, ob dies zu Problemen führen kann und woher die Spannungsdifferenz stammt.

Bei Verwendung der mitgelieferten MCU des EVM gibt es überhaupt keine Probleme. Was übersehe ich, warum funktioniert es nicht zuverlässig?

Verdrahtung

Könntest du mal einen Schaltplan deines Setups posten? Bleistift-Schaltplan oder Whiteboard-Zeichnung würde ausreichen. Steckbrettfoto würde nicht reichen (zumindest nicht alleine).
Ein einfacher Test für einen I2C-Bus besteht darin, den Strom zu messen, um SDA oder SCL mit einem Multimeter auf GND zu ziehen. Messen Sie sowohl die 5-V-Seite als auch die 3,3-V-Seite, das sind 4 Ströme. Sie sollten 3mA nicht überschreiten. Ein Steckbrett kann schlechte Verbindungen haben. Lange Kabel könnten die Signale stören. Hast du ein 3,3V Arduino Board? Entweder ein Arduino Due oder Zero oder ein einfaches Arduino mit 3,3 V und 8 MHz? Die 3,6 V sind zu viel, es könnte eine falsche Verkabelung sein.
(a) " Ich habe auch festgestellt, dass die Spitzenspannung bei SCL 3,4 V und bei SDA mehr als 3,6 V beträgt . Bitte aktualisieren Sie zusätzlich zur Bereitstellung des bereits angeforderten Schaltplans Ihre Frage, um genau zu erklären, wie Sie diese Spannungen beobachtet haben, z. B. Oszilloskop? Spitzenwerte auf einem Multimeter? Etwas anderes? Und erklären Sie , wo Sie diese Spannungen beobachtet haben (zeigen Sie diese Punkte im schematischen Diagramm). (b) Haben Sie Zugang zu einem Oszilloskop und Erfahrung damit? Wenn dies der Fall ist, liefern Sie während des I2C-Scans bitte Trace-Bilder (idealerweise einschließlich SDA und SCL) sowohl von der 5-V-Seite als auch von der 3,3-V-Seite des PCA9512A.
Ich habe dem Startpost einen einfachen Schaltplan hinzugefügt. Arduino und FDC teilen eine gemeinsame Basis. Die Drähte sind nicht länger als 20 cm, daher sollte dies kein Problem darstellen. Ich habe ein 2-Kanal-Oszilloskop verwendet. SCL auf dem ersten und SDA auf dem zweiten Kanal. Ich habe den Unterschied zwischen HIGH und LOW sowohl bei SDA als auch bei SCL gemessen, was zu 3,6 V führte (einige Spitzen bis zu 3,9 V!). Außerdem sind SDA sowie SCL ein perfektes Rechtecksignal. Ich habe diese Punkte direkt vor SDAOUT und SCLOUT beobachtet. Trace-Bilder werde ich am Mittwoch hochladen, da es nicht mein eigenes Oszilloskop ist. Gleiches gilt für die Messung von Strömen.
Wenn ich mir diesen Schaltplan ansehe, habe ich ein paar Punkte, darunter: (a) Der Schaltplan scheint unvollständig zu sein, z. B. zeigt er nicht, wie der ACCPin am PCA9512A angeschlossen ist. (b) Der physische Ort der Kondensatoren ist wichtig. (c) Sie sagten: " 10k Pullups bis 5V (Arduino Mega intern) " Ein Arduino Mega verwendet die ATmega1280 MCU, aber seine Spezifikation (siehe Seite 355) besagt, dass die internen Pullup-Widerstände irgendwo zwischen 20k und 50k liegen. (e) Ich freue mich darauf, die Oszilloskopspuren zu sehen.
@J.Mustard Ich denke, das Problem liegt nicht bei SDA-OUT und SCL-OUT, sondern bei SDA-IN und SCL-IN. Der interne Pullup-Widerstand ist zu groß. Welche Frequenz verwendest du? Hast du es mit einem niedrigeren Wert versucht?
Haben alle drei Geräte eine solide, gemeinsame Basis?

Antworten (6)

Problem gelöst!

Ich habe versucht, den FDC mit einem Arduino Mini Pro 3,3V zum Laufen zu bringen und hatte das gleiche Problem wie zuvor.

Am Ende war die Lösung einfach: Der FDC hat einen Shutdown-Pin (SD), der ihn bei HIGH in den Ruhezustand versetzt und bei LOW aktiv setzt. Als ich SD mit GND verbunden habe, sind alle Probleme verschwunden. Jetzt habe ich ein stabiles Signal zwischen Arduino Mini Pro 3,3V und FDC2114. Ich denke, es würde auch mit dem Arduino Mega und Level Shifter funktionieren, aber ich kann es nicht testen.

Danke nochmal für deine Hilfe.

Es tut mir leid, dass ich die letzten Tage nicht geantwortet habe. Anscheinend funktioniert der PCA9512A nicht mehr, da auf der 3,3V-Seite weder ein Takt- noch ein Datensignal vorhanden ist. Daher habe ich einen Arduino Mini Pro 3,3V bestellt, um das Problem der Pegelverschiebung zu vermeiden, obwohl es besser wäre, das Problem zu lösen, anstatt es nur zu vermeiden. Aber ich möchte in meinem Projekt vorankommen, also scheint dies der schnellste Weg zu sein.

Aber ein paar Punkte zur Klarstellung: In den Schaltplänen sind die Klimmzüge auf der 5V-Seite falsch. Sie sind intern, nicht extern, wie das Bild vermuten lässt. Außerdem sind sie tatsächlich 10k, weil es ein Arduino Mega 2560 ist. Alle Geräte haben eine solide gemeinsame Basis. Ich habe Frequenzen zwischen 100 kHz und 400 kHz ausprobiert, aber keine davon schien zu funktionieren. Der ACC-Pin wird durch einen 10k-Widerstand auf 3,3 V hochgezogen, was Anstiegszeitbeschleuniger ermöglicht. Die Kondensatoren sind so nah wie möglich am FDC.

Da der Levelshifter defekt ist, kann ich keine Tracebilder hochladen. Das tut mir leid, aber trotzdem danke für deine Hilfe.

@SamGibson (ja, aber der 10-kOhm-Widerstand befindet sich auf der ArduinoMega2560-Platine: dh es werden 10 kOhm parallel zum internen 50-kOhm-Pullup vorhanden sein. Aber vielleicht sind 10 kOhm immer noch zu groß für Hochgeschwindigkeitsübertragungen).
@next-hack - Danke, ich kann jetzt die Verwirrung zwischen dem OP sehen, das "intern" sagt, was ich so interpretiert habe, dass gesagt wurde, die 10-kΩ-Klimmzüge seien intern in der MCU (was Sie und ich zustimmen, dass sie es nicht sind) vs. " on-board", was zusätzliche Widerstände beschreiben würde, die auf der Leiterplatte angebracht sind. Die integrierten 10-kΩ-Pullups parallel zu den MCU-internen 20 kΩ-50 kΩ ergeben effektiv 6,67 kΩ-8,33 kΩ, was für 100 kHz "Standard" I2C bis zu etwa 150 pF Buskapazität in Ordnung sein sollte, aber für 400 kHz "schnell" marginal ist Modus" I2C oben nur etwa 50pF, also hängt alles von der Verkabelung ab. Ich werde meine früheren Kommentare löschen und verbessern.
J. Mustard - Nach dem hilfreichen Kommentar von next-hack sehe ich jetzt die Verwirrung - Sie sagten "intern", was "auf der Arduino-Leiterplatte" bedeutet; Ich dachte, Sie meinten "intern zur MCU". Meine aktualisierten Kommentare lauten also: (a) Die beiden Kondensatoren auf dem Schaltplan hätten in der Nähe des PCA9512 sein sollen, nicht des FDC (da Sie bereits eine Entkopplung auf der FDC-EVM-Leiterplatte haben), obwohl vielleicht der von Ihnen verwendete PCA9512-Breakout bereits eingeschaltet war. Platinenentkopplung auch. (b) Beachten Sie bei der Auswahl von I2C-Klimmzügen die Informationen hier und hier .

Der Arduino hat bereits eingebaute Pullup-Widerstände. Dies kann seine Fähigkeit beeinträchtigen, die Leinen weit genug nach unten zu ziehen. Deaktivieren Sie entweder die integrierten Pullups oder entfernen Sie die externen 10-kΩ-Pullups und sehen Sie, ob sich die Situation verbessert.

Ja, separate 10k-Pull-ups werden auf der Arduino-Seite des Schaltplans angezeigt. Wie ich jedoch in einem früheren Kommentar hervorgehoben habe, behauptet der Text der Frage , dass die 10k-Klimmzüge auf 5 V intern sind , was dem widerspricht. Außerdem sind die internen ATmega1280-Pullup-Widerstände nicht 10k. Kurz gesagt, es gibt zu viele Ungereimtheiten, um sicher zu sein, wie die Situation in Bezug auf Klimmzüge wirklich ist! Die Oszilloskop-Trace-Bilder, die ich angefordert habe und die uns vom OP heute erwartet wurden, zeigen, ob der Arduino die I2C-Signale nicht herunterziehen kann (ich bezweifle, dass dies bei diesen Werten der Fall sein wird).
Die internen Widerstände sind 20k - 50k.

Hier sind einige Ideen, sorry, wenn Sie sie bereits in Betracht gezogen haben.

Ihr Problem ist möglicherweise kein elektrisches, es könnte logisch sein. Der von Ihnen verwendete I2C-Pegelumsetzer wurde entwickelt, um die START- und STOP-Bedingungen auf dem Bus zu erkennen. Wenn Ihre Software also falsch ist, ist es denkbar, dass sich der Puffer nicht im richtigen Modus befindet.

Wenn Sie die I2S-Kommunikation starten, versuchen Sie, jeder Operation ein START-Bit gefolgt von einem STOP-Bit voranzustellen. Das sollte den Puffer auf den richtigen Zustand zurücksetzen. Untersuchen Sie dann Ihren I2C-Code, um festzustellen, ob es ein Problem bei der Handhabung der STOP-Bedingungen gibt. Verwenden Sie genügend Verzögerungen, damit Ihre I2C-Kommunikationsgeschwindigkeit nicht zu hoch ist. 400kHz sollten zuverlässig funktionieren.

Stellen Sie schließlich in Ihrem I2C-Code im Arduino den Ausgang nicht auf hoch, wenn Sie einen hohen Pegel übertragen möchten. Stellen Sie stattdessen den Pin (SDA oder SCL) ein, der eingegeben werden soll, dann kümmern sich die Widerstände darum, die Pins hoch zu ziehen. Wenn es Ihnen möglich ist, die SDA- und SCL-Pins niemals hoch zu treiben, können Sie den Pegelumsetzer vollständig entfernen und nur den Widerstands-Pull-up auf 3,3 Volt für diese Pins verwenden. 3,3 Volt in den Arduino-Eingangspins sollten hoch genug sein, um einen hohen Zustand zu erkennen.

" [...] Verwenden Sie für diese Pins nur den Widerstands-Pull-up auf 3,3 Volt. 3,3 Volt in den Arduino-Eingangspins sollten hoch genug sein, um einen hohen Zustand zu erkennen. " Leider nicht. Der Logikpegelschwellenwert für den ATmega1280 (wie er auf dem vom OP erwähnten Arduino Mega verwendet wird) ist auf dessen Datenblatt Seite 362, Tabelle 31-7, dargestellt. Beachten Sie, dass Vih mindestens 0,7 x Vcc beträgt. Mit der MCU Vcc = 5 V beträgt der I2C Vih also (0,7 x 5 =) 3,5 V. Daher sind 3,3 V, wie Sie vorgeschlagen haben, nicht hoch genug.

Beginnen Sie mit einer einfacheren Schaltung - Sie verwenden ein 5-V-Arduino - verwenden Sie einfach ein 3,3-V-Arduino und Ihr 3,3-V-Slave-Gerät. Der atmega328 ist für den 2-5-V-Betrieb bei verschiedenen Geschwindigkeiten ausgelegt. Wenn Sie also Quarz und Eingang austauschen möchten, können Sie den vorhandenen wiederverwenden. Überprüfen Sie einfach das Datenblatt, welche Geschwindigkeiten bei welchen Spannungen ausgeführt werden sollen. Ich habe gelesen, dass einige Leute Glück haben, sogar mit nur 3,3 V auf volle 20 MHz zu gehen. Mit nur dem Arduino und dem Slave-Gerät können Sie sich der Schaltung sicherer sein und die Skizze richtig zum Laufen bringen. Fügen Sie der Schaltung nachträglich Komplexität hinzu, wenn Sie aus irgendeinem Grund das 5-V-Arduino verwenden müssen. Die chinesischen Ebay-Klone funktionieren eigentlich sehr gut, basieren aber normalerweise auf dem atmel 32u4, der USB eingebaut hat, um die Kosten für einen externen Chip zu vermeiden. Der größte Nachteil für sie ist, dass der Versand einen Monat dauert.

Entfernen Sie den Pegelwandler!

Da I2C-Treiber Open-Drain sind, können Sie sie ohne Pegelwandler anschließen.

I2C-Bustreiber sind „Open Drain“, was bedeutet, dass sie die entsprechende Signalleitung auf Low ziehen, aber nicht auf High treiben können.

Ref.: https://learn.sparkfun.com/tutorials/i2c/i2c-at-the-hardware-level

Hm, stimmt. Ich dachte, dass die Worte "bereits gelötet" bedeuten, dass kein Hardware-Mod möglich ist. Aber wenn kann, dann ja.
I2C-Pegelkonverter gibt es aus einem bestimmten Grund :-) Ich habe der Antwort von PkP einen Kommentar hinzugefügt, in dem erklärt wird, warum im Design des OP eine Art Pegelkonverter / Übersetzer benötigt wird (der vom OP ausgewählte scheint dafür zu kompliziert zu sein Situation, aber das ist ein anderes Thema). Die Natur von Open-Drain-Treibern ermöglicht I2C-Funktionen wie Clock-Stretching und Multi-Master-Betrieb, ändert jedoch nichts an der Tatsache, dass verschiedene Geräte Einschränkungen hinsichtlich ihrer maximalen Eingangsspannung, Vih / Vil usw. haben. Warum glauben Sie das? ein I2C-Bus ohne Pegelwandler stößt hier an die Gerätegrenzen?
Ja, es gibt einen Grund für Pegelwandler, aber dann befinden Sie sich außerhalb der Arbeitsparameter, was das Design des OP nicht ist.
" [...] das ist, wenn Sie außerhalb der Arbeitsparameter liegen, was das Design des OP nicht ist. " Ich bin respektvoll anderer Meinung. Das Datenblatt des FDC2114 zeigt, dass seine Eingänge nicht 5V-tolerant sind. Daher muss es einen I2C-Bus mit Pull-Ups zu seinem Vdd verwenden, nicht höher . Wie ich in meinem Kommentar zu PkP erklärt habe, ist eine Spannungsübersetzung erforderlich, um einen zuverlässigen Betrieb im OP-Design zu erreichen, bei dem 3,3 V vom 5-V-ATmega1280 nicht garantiert als "hoch" (Vih = 0,7 x Vcc) angesehen werden. Siehe vorherige Frage: I2C: 3,3-V- und 5-V-Geräte ohne Pegelverschiebung am 3,3-V-Bus?