Author Topic: i2c und serial Interferenz?  (Read 22749 times)

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
i2c und serial Interferenz?
« on: November 13, 2013, 10:52:31 PM »
Salut,

ich habe diese Thema hier in Network platziert, da ich i2c schon als Netz betrachte.
Mein Problem ist: Ich habe zwei arduinos mit i2c verbunden. Da sie direkt nebeneinander stehen, habe ich keine Pull-up Widerstände verwendet.
Als debugging tool verwende ich Serial.print Statements. Die i2c Kommandos des Master kommen alle Sekunde und schicken bis zu 16 Byte. Den Serial Port starte ich mit 115200 bps. Der Slave senden keine Daten.
Ich habe nun beobachtet, dass der sendende Arduino ewig auf eine i2c Ausführung wartet, wenn der Slave zu viele Ausgaben über Serial macht. Einfaches auskommentieren der Serial.print Statements entscheidet ob der Master arbeitet oder hängt.
Mir scheint es so, als würde ich irgend eine einfache Sache falsch machen. Hat jemand eine Idee?

Ciao, Mathias

dinoi

  • freakyfriday
  • Sr. Member
  • *
  • Posts: 441
  • Karma: +7/-0
    • Dinoi
Re: i2c und serial Interferenz?
« Reply #1 on: November 14, 2013, 11:40:01 AM »
Hallo Mathias,

das habe ich auch schon festgestellt, dass der Serial.print Zeit braucht. Ich denke relativ viel. Bei einer LED Matrix mit zwei Shiftregister konnte ich das auch schon feststellen. Sobald das Serial.print durchläuft passten die Zyklen nicht mehr miteinander.

Bei Deinem Szenario ist jedoch das nicht ganz verständlich woher das Problem kommt. Das I2C Protokoll kenne ich nicht im Detail, sendet dabei der Slave irgendwelche Bestätigungen oder Taktzeichen?

Gruss Reto

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: i2c und serial Interferenz?
« Reply #2 on: November 14, 2013, 02:37:12 PM »
Salut Reto,

es sieht sehr nach einem Handshakeproblem aus. In den Beispielen sehe ich nur code, wo einer sendet und der andere lauscht. Hast DU Code gesehen, wo ich einen Handshake zwischen Master und Slave mache, so dass der Master erst wieder sendet, wenn der Slave den letzten Befehl quittiert hat?

Aufrufe von Serial.print innerhalb der WireEvent Routine sind komplett zu vermeiden ...

Ciao, Mathias

dinoi

  • freakyfriday
  • Sr. Member
  • *
  • Posts: 441
  • Karma: +7/-0
    • Dinoi
Re: i2c und serial Interferenz?
« Reply #3 on: November 14, 2013, 08:33:07 PM »
Hallo Mathias,

nein leider habe ich das auch noch nicht gesehen. Das ganze ist somit eher Unsicher. Wie du sagst sollte er erst wieder senden nachdem er das ok erhalten hat, ähnlich den TCP/IP Paketen.

Auch hier steht dazu nichts:

http://arduino.cc/en/Tutorial/MasterWriter

Alternativ könntest Du auch die Serial Schnittstelle verwenden Rx/Tx. Dazu gibt es auch Beispiele im Netz.

Gruss Reto

microtherion

  • freakyfriday
  • Full Member
  • *
  • Posts: 163
  • Karma: +13/-0
Re: i2c und serial Interferenz?
« Reply #4 on: November 14, 2013, 08:54:39 PM »
Mein Problem ist: Ich habe zwei arduinos mit i2c verbunden. Da sie direkt nebeneinander stehen, habe ich keine Pull-up Widerstände verwendet.

So weit ich I2C verstehe, sind die Pull-ups absolut obligatorisch, weil das Protokoll nie ein 1 schickt sondern nur 0 oder Z.

Quote
Den Serial Port starte ich mit 115200 bps.

Vielleicht könntest Du es auch mit einer langsameren Rate probieren.

Gruss
Matthias

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: i2c und serial Interferenz?
« Reply #5 on: November 15, 2013, 04:42:21 PM »
Salut,

ich konnte inzwischen das Problem finden: Ich wollte den Code so schreiben, dass der Arduino Kommandos vom i2c bus als auch von der seriellen Schnittstelle annimmt. Sobald ich die SerialEvent auskommentiere, läuft die i2c Schnittstelle problemlos. Auch sollte man keine Ausgaben via Serial.print machen, so lange man sich in der Eventroutine befindet, welche mit Wire.onReceive() registriert wurde. Hier kommt es dann auch zu Aussetzern, wenn die serielle Schnittstelle arbeite und über i2c Daten kommen.
Ausserdem habe ich die nette Buffer Grenze von 32 Byte kennen gelernt, was bedeuet, dass man zwischen BeginTransmission udn EndTransmission maximal 32 bytes senden kann (ohne am Quellcode von Wire herumzubasteln)

Können eigentlich zwei Arduinos, welche als Slaves bei einem dritten Arduino angemeldet sind, miteinander über i2c kommunizieren?

Ciao, Mathias

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: i2c und serial Interferenz?
« Reply #6 on: November 15, 2013, 07:37:17 PM »
Salut,

hier noch ein netter Trick, den ich gefunden habe, wenn man nicht zu viel Zeit auf Bitshifts verschwenden will:
I2C Sender Seite:
Code: [Select]
union u_tag {
    byte b[4];
    long l;
  } u;

  long num = 123456;
  u.l = num;
  Wire.beginTransmission(_slaveADR);
  Wire.write(u.b[0]);
  Wire.write(u.b[1]);
  Wire.write(u.b[2]);
  Wire.write(u.b[3]);
  Wire.endTransmission();

i2c Empfänger:
Code: [Select]
union u_tag {
    byte b[4];
    long l;
  } u;
  u.b[0] = Wire.read();
  u.b[1] = Wire.read();
  u.b[2] = Wire.read();
  u.b[3] = Wire.read();
  Serial.println(u.l);

Dieser union Overlay spart einem das Zerrupfen und Zusammenbauen der bytes!

Ciao, Mathias

MathiasW

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 614
  • Karma: +13/-0
    • my Arduino page
Re: i2c und serial Interferenz?
« Reply #7 on: November 16, 2013, 11:51:10 AM »
Salut,

seit Monaten habe ich die Idee dass man einen Arduino mit TFT Display doch auch über i2c ansteuern könnte. Ich habe nun eine kleine Library geschrieben, welche man statt der UTFT library verwendet. Dann werden die UTFT Kommandos über i2c geschickt und der angeschlossene Arduino gibt sie dann an das TFT weiter. Die Ausführungsgeschwindigkeit ist erstaunlich schnell. Einzig beim Kommando drawPixel() wird jedes Pixel via i2c übertragen, was die Sache schon sehr verlangsamt. Außerdem sind aufgrund der 32 byte buffer-Limitation von i2c nur Texte bis 16 Character Länge möglich.
Das schöne daran ist, dass man einen fertigen Sketch, welcher UTFT verwendet nicht gross verändern muss. Man muss nur das Includefile von UTFT.h auf i2cUTFT.h ändern und den Constructor i2cUTF statt UTFT aufrufen. Das dabei erstellte Object myGLCD stellt die UTFT Komandos bereit und schickt sie über i2c an den anderen Arduino.
Die erste lauffähige Version, welche den kompletten Democode von UTFT abspielt ist auf meiner Homepage

Ciao, Mathias

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: i2c und serial Interferenz?
« Reply #8 on: November 18, 2013, 03:05:43 AM »
Hallo Matthias,

Außerdem sind aufgrund der 32 byte buffer-Limitation von i2c nur Texte bis 16 Character Länge möglich.

Die 32 Bytes Puffer-Grösse sind eine Limitation der Wire-Bibliothek und nicht des I2C-Busses. Wenn Du die in Wire.h hochsetzt, kannst Du auch ein Vielfaches davon übertragen. Alternativ könntest Du es in mehrere Meldungen verpacken und einen "Fortsetzung folgt"-Byte-Wert definieren.

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Re: i2c und serial Interferenz?
« Reply #9 on: November 18, 2013, 03:15:18 AM »
ich konnte inzwischen das Problem finden: Ich wollte den Code so schreiben, dass der Arduino Kommandos vom i2c bus als auch von der seriellen Schnittstelle annimmt. Sobald ich die SerialEvent auskommentiere, läuft die i2c Schnittstelle problemlos. Auch sollte man keine Ausgaben via Serial.print machen, so lange man sich in der Eventroutine befindet, welche mit Wire.onReceive() registriert wurde. Hier kommt es dann auch zu Aussetzern, wenn die serielle Schnittstelle arbeite und über i2c Daten kommen.

Das kommt daher, dass die onReceive-Routine im Interrupt-Kontext aufgerufen wird. Wenn Du dann Ausgaben auf die serielle Schnittstelle machst, füllt das erst mal den Puffer. Sollte es aber dabei zu einem Puffer-Überlauf kommen, bist Du in einer Endlos-Schleife gefangen, weil der Serial-Code wartet, bis der nächste Interrupt der seriellen Schnittstelle den Puffer zu leeren beginnt. Da aber im Interrupt-Kontext weitere Interrupts gesperrt sind, wird es nie dazu kommen. Also: während der Abarbeitung eines Interrupt-Handlers nie Ausgaben auf die serielle Schnittstelle machen, sonst wird das nie zuverlässig laufen.

Können eigentlich zwei Arduinos, welche als Slaves bei einem dritten Arduino angemeldet sind, miteinander über i2c kommunizieren?

Normalerweise nur über den Master, der dann als Vermittler agiert. Theoretisch wäre noch die Möglichkeit eines Multmaster-Betriebs in der I2C-Spezifikation vorgesehen und der ATmega hätte sogar Unterstützung dafür, aber leider keine der mir bekannten Arduino-Bibliotheken. Das Thema ist auch relativ heikel, die meisten Leute, die damit Erfahrung haben, raten dringend davon ab.

arduinopraxis

  • freakyfriday
  • Hero Member
  • *
  • Posts: 553
  • Karma: +11/-0
  • Arduino Praxiseinstieg (4.Auflage)
    • Arduino Praxiseinstieg, 4. Auflage
Re: i2c und serial Interferenz?
« Reply #10 on: November 19, 2013, 11:17:21 AM »
Quote
eit Monaten habe ich die Idee dass man einen Arduino mit TFT Display doch auch über i2c ansteuern könnte. Ich habe nun eine kleine Library geschrieben, welche man statt der UTFT library verwendet.
Coole Idee.
Kann ich gut gebrauchen für mein Netzteilprojekt da ich recht knapp an digitalen Pins bin  ;)

Ich werde deine Library austesten und gebe dir dann Feedback.

Gruss
Thomas