Hallo alle miteinander Ich habe ein komisches problem mit einer I2C verbindung. Ein Master (Arduino) sendet jeweils 4 bytes über den I2C bus, 3 datenbytes und eine checksum. Am bus hängen momentan 2 slaves (2x attiny24 mit dem USI code von Don Blake). Der Master am einen Ende der Leitung hat einen Pullup von 2k, der Slave am Ende der Leitung einen von 5k. Die Leitung ist 5-Adrig, 2m lang und nebst GND, SCL und SDA noch zwei adern mit 230VAC. I2C clock ist bei 10kHz. Problem: nach einigen hundert bis tausend commands kommt es immer wieder vor, dass der master sich mit dem TWI-errorcode "0x38 = Arbitration lost in SLA+W or data bytes" meldet. Bei einem erneuten senden der bytes reagiert der Slave nicht und der master bleibt deshalb hängen. Ich denke die Ursache liegt im Rauschen der Leitung, sodass der Master eine kollision detektiert oder der slave einen falschen Befehl empfängt und anfängt dem Master reinzufunken. Kennt jemand dieses Problem und weiss die genaue Ursache oder noch besser: eine Lösung?
dede schrieb: > Die Leitung ist > 5-Adrig, 2m lang und nebst GND, SCL und SDA noch zwei adern mit 230VAC. Grusel... Was ist das für eine Leitung, Isolierung zwischen den Adern ausreichend?
Isolierung der Adern ist mit 500VAC angegeben, müsste eigentlich reichen ;)
Dede, versuch's doch mal mit geringerer Bitrate. Ausserdem würde ich mich auf einen Pullup pro Leitung beschränken. Bei zwei Pullups an derselben Leitung bilden eine VCC-Schleife und begünstigen Einstreuungen. mare_crisium
Jens Martin schrieb: > Geht es denn mit einem kurzen Kabel ohne 230~ ? Ja, bei einem Test mit kurzem Kabel (ca. 30cm) ohne 230V hats problemlos funktioniert. Das mit den pullups hatte ich anfangs anders, die pullups am ender der Leitung haben die kommunikation eher verbessert, der Fehler trat danach weniger schnell auf, viel geholfen hats aber nicht.
I²C ist eigentlich zur Kommunikation auf verschiedenen Komponenten AUF einer Platine gedacht. Für größere Strecken ist I²C schlichtweg nicht vorgesehen. Versuchs mal probeweise mit I²C-Bus-Extendern. Gibts von verschiedenen Firmen, unter anderem glaube ich auch von Texas Instruments. Also einfach mal samples ordern und versuchen. Die 230V begünstigen natürlich auch nicht unbedingt. Wenn du ein Oszi hast schau dir mal den Signalverlauf an. Und zwar bei 2m + 230V und bei den 30cm. Da wirste schöne Unterschiede feststellen.
dede, dann stimme ich Michl zu. Du solltest es mit Busextendern versuchen (z.B. dem PCA9513 oder dem PCA9515). Reiche Auswahl findest Du hier http://www.nxp.com/#/page/content=[f=/dynamic/datasheets/tid-71114_sid-41735/data.xml] mare_crisium
nicht Gast schrieb: > dede schrieb: >> Die Leitung ist >> 5-Adrig, 2m lang und nebst GND, SCL und SDA noch zwei adern mit 230VAC. > Grusel... Was ist das für eine Leitung, Isolierung zwischen den Adern > ausreichend? Doppel-Grusel. Warscheinlich ist dann die GND-Leitung gleich auch noch der Schutzleiter. Daß es nicht funktioniert, ist kein Wunder. Daß es funktioniert, wäre aber ein Wunder. Peter
Bei einer Single-Master Implementierung wird Arbitration nicht gebraucht. Einfach alle Abfragen auf USIDC auskommentieren! Aber ich stimme Peter zu - I2C und 230V im gleichen Kabel sind einfach gruselig.
Klaus 2m5 schrieb: > I2C und 230V im gleichen Kabel sind einfach gruselig. Und schon I²C und "2m" sind grenzwertigst... ;-) Man sollte sich immer im Hinterkopf behalten, dass der IIC für "Inter-IC" Kommunikation (Fernsehgeräte, Videogräte, Autoradios...) ausgelegt wurde.
Lothar Miller schrieb: > Und schon I²C und "2m" sind grenzwertigst... ;-) Kommt auf die Taktrate an. Als erstes würde ich einen Pullup wegnehmen und den anderen auf 1 kOhm runtersetzen.
Danke für die vielen Antworten. Also dass I2C nur für kurze Leitungen gemacht wurde ist wohl richtig, anscheinend wird aber auch z.b. bei HDMI Kabeln eine TWI Verbindung zwischen den Geräten geführt, was ja auch problemlos zu funktionieren scheint. Gelesen hab ich schon, dass man anscheinend Leitungen bis 10m problemlos betreiben kann, wenn man die taktrate runter nimmt und kleinere pullups verwendet. Dass ein pullup auf beiden Seiten der Leitung stören soll versteh ich nicht. Vcc wird ja nicht über die Leitung übertragen. Jeder Slave wird über 230V gespiesen und hat seinen eigenen 5V-regler. Nur die GND leitung, SCL, SDA sowie 230VAC sind auf der leitung. Schutzerdung brauch ich nicht, die Gehäuse sind aus Holz (hmm, nicht wirklich Feuersicher merk ich grad...). Die kommunikation funktioniert eigentlich ziemlich gut, es tritt nur alle paar hundert bytes ein NACK auf, womit ich problemlos leben kann. Das eigentliche Problem besteht darin, dass der Slave ein "Arbitration lost" im master verursacht (vermutlich ist läuft der timer durch ein rauschen im clock zu früh ab und er zieht den SDA runter) und danach nicht mehr reagiert. Wenn ich jetzt einfach eine STOP condition erzeuge falls der Fehler detektiert wird und dann wieder sende, wartet der Master vergeblich auf ein ACK nach dem START. So wie ich die Programmierung von Don Blake verstehe, müsste der Slave bei detektiertem STOP wieder auf ein START reagieren, tut er aber nicht. Der bleibt irgendwo hängen und ich finde nicht raus wo, da es ja keine unendlichen while-loops in der programmierung gibt, die nicht auf ein STOP reagieren. Ich werde mir die Signale mal auf dem Oszi anschauen, habe das zwas schon gemacht, jedoch auf Master seite, die können ja beim Slave ganz anders ankommen...
Irgendeine Schaltstörung auf den 230V koppelt kapazitiv ein und erzeugt für den Slave einen zusätzlichen SCL-Impuls. Der Slave legt nun sein ACK zu früh an und der Master erkennt die Kollision. Der Master kann aber kein Stop senden, da der Slave ja SDA auf low zieht. Du mußt also das HW-TWI abschalten und per SW-I2C einen SCL-Puls generieren und dann versuchen, Stop zu senden. Erst dann ist der Slave wieder adressierbar. Trotzdem ist 230V und Niederspannung auf dem selben Kabel verboten. Peter
Hab mal mein oszi angehängt, die signale kommen absolut sauber beim Slave an, taktrate 40kHz.
Auf der Software-Seite zu suchen ist sicherlich auch kein Fehler. Wenn ein Spike den Bus aufhängt, sollte eine Softwaremaßnahme dagegen helfen.
Peter Dannegger schrieb: > Trotzdem ist 230V und Niederspannung auf dem selben Kabel verboten. Genau so ist es. - K.A. warum der Frager so einen groben Unfug treibt. Separates Kabel für die Daten, dann geht I2C vermutlich auch über 2 Meter.
Ein einfacher Workaround wäre: 1. TWI Modul am Master abschalten. 2. Am Master SDA als Input und SCL als Output konfigurieren. 3. SCL im TWI Takt so lange toggeln bis SDA wieder high ist 4. TWI wieder initialisieren und weiter machen ... Ist zwar nicht schön, aber sehr effektiv um den Bus respektive den Slave wieder in Gang zu kriegen ... Grüße, Michael
Michael L. schrieb: > Peter Dannegger schrieb: >> Trotzdem ist 230V und Niederspannung auf dem selben Kabel verboten. > > Genau so ist es. - K.A. warum der Frager so einen groben Unfug treibt. Den unfug treib ich, weil ich nicht zwei leitungen ziehen will, sieht unschön aus im Wohnzimmer. Wenn alles fehlschlägt werd ich wohl oder übel ein kabel mit paarverseilten und isolierten leitern suchen müssen... was ich da bis jetzt gefunden habe ist entweder nicht bis 400V betreibbar oder nur in grau erhältlich, ich will aber ein schwarzes kabel. Hab mittlerweilen einiges versucht. Der Slave stürzt nun nicht mehr ab, da ich dort den TWI bei ausbleiben von daten auf "RECEIVE START" mode setze. Wenn ich die Arduino TWI library (interruptbasiert) verwende, läuft die kommunikation einige sekunden, auch bei Taktraten von über 100kHz. Dann ist aber fertig. Bei der Sendemethode aus dem Atmega datenblatt (ohne TWI interrupt) funktionierts eher weniger. Meistens kommt der Fehler 0x20 = kein ACK bei der adresse, sonst kommt 0x30 =kein ACK bei den Daten (adresse aber erfolgreich übertragen). So alle paar hundert versuche kommt mal ein Befehl komplett durch, dann gibts aber datenübertragungsfehler, die checksum stimmt nicht. Irgendwo muss da zuviel noise sein, obwohl die Signale am Oszi sauber aussehen. Gibt es eine Möglichkeit die HIGH und LOW pegel von atmelchips einzustellen? Dann könnte ich den Slave auf noise weniger empfindlich machen. Alternative werde ich versuchen einen hardware filter einzubauen. Ich bin mir ziemlich sicher, dass die probleme von noise kommen, denn bei höheren clockrates funktioniert die kommunikation besser als bei tiefen (da geht gar nix) was heisst, dass der Slave vermutlich mehr clocks sieht als der Master sendet und darum keine Daten bestätigt.
update: habe mit Filterung experimentiert, ein RC Filter am SDA pin macht das Ganze schon viel stabiler (einige Minuten fehlerfrei). Es scheint wirklich zu viel noise auf dem Bus zu haben, eingefangen über die AC leitung. Wenn ich z.B. die Lampe an der selben Steckdose ausschalte, bleibt die Kommunikation hängen. Da muss wohl auch noch eine Drossel an den AC Eingang. Aber etwas ist noch ganz komisch: in meiner Softwareroutine wird der Bus nach einer Übertragung nicht freigegeben, sondern beide Leitungen sind Low (im gegensatz zur standard Arduino TWI library). Ich habe den code mit diesem abgeglichen: http://www.nongnu.org/avr-libc/user-manual/group__twi__demo.html nach einem STOP bleiben aber beide Leitungen low...
Ok, problem gelöst: 1. der clock darf nicht zu tief sein da sonst das signalrauschen stärker reinspielt 2. Eine drossel auf der AC linie dämpft das Rauschen ein bisschen 3. Die Arduino TWI library stürzt öfters mal ab wenn noise auf dem Bus vorhanden ist. Diese reset funktion schafft abhilfe: void resetTWI(void) //resets TWI pins and registers { TWCR &= ~(1<<TWEN); //disable TWI //release TWI lines: pinMode(18, INPUT); pinMode(19, INPUT); digitalWrite(18, HIGH); //activat internal pullups digitalWrite(19, HIGH); delay(1); //wait for the lines to be released Wire.begin(); //TWI reinitialize TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; //set TWI frequency (if necessary) // Serial.println("TWI reset"); }
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.