ich habe derzeit diverse Sensoren sowie ein LCD-Display via I2C an einen Arduino Pro Mini angebunden. Das funktioniert soweit.
Diese Sensoren möchte ich nun ebenfalls über einen zweiten Arduino Pro Mini am I2C Bus auslesen, um diese Daten auf einer SD-Karte via SPI zu loggen.
Hier unten ist für ein besseres Verständnis eine kleine Skizze angehängt. Derzeit läuft Arduino B mit den Sensoren und dem LCD-Display, Arduino A möchte ich nun via I2C mit anbinden.
Geht das irgendwie ? Nach meinem Verständnis müssten da dann beide Arduinos Master sein, und die Sensoren wie üblich Slave. Aber beide als Master ist m.W. doch nicht erlaubt ?! Und als Slave kann ein Arduino doch keine Daten von den Sensoren holen, oder verstehe ich da was falsch ?
Der Code passt nicht in einen einzelnen Pro Mini, und ein Mega2560 ist für die Anwendung in einem Modellfugzeug von den Abmessungen zu groß. Außerdem ist für mich interessant, den Datenloggerteil bei Bedarf einfach entfernen zu können. (Wobei ein Teensy 3.1 mich zugegebenermaßen schon schwach machen könnte...)
Die Kabellänge zwischen den beiden Arduinos ist ca. 20 cm, also kein Problem für I2C.
Wenn ich Dein Bild richtig verstehe, müsste aber Arduino A auch als Slave zu betreiben sein. Also: Arduino B holt sich die Daten von den Sensoren und schreibt sie zum Arduino A. Der speichert sie auf der SD-Karte.
Hallo,
der Multi-master Thread aus Deinem Link hört sich interessant an, ich muß das dann mal testen.
Ich wollte erst mal generell hören, ob meine Architektur überhaupt Sinn macht.
Den Arduino A als Slave zu betreiben wie von Dir vorgeschlagen wäre eine Rückfalloption. Ich wollte aber gerne den Code auf Arduino B möglichst wenig antasten, einerseits wg. Speicherplatzknappheit, andererseits um die Loopdurchlaufzeiten nicht zu verlängern.
Naja zugegebenermaßen dürfte letzteres hier nicht ganz so kritisch werden.
Scherheinz:
Es gibt immer nur ein Master. Wie sollte denn sonst das Timing funktionieren? A weiß ja nicht wann B kommuniziert und funkt dazwischen.
Sowohl die I2C Spezifikationen, als auch die Arduino Wire Lib erlauben den Multimaster Modus.
Ich sehe da kein wirkliches Problem.
Wobei ich allerdings schon von einem Bug in der I2C Hardware des ATMegas gehört habe, welcher zu Deadlocks führt. Dieser dürfte aber erst bei mehr als 2 Mastern zum tragen kommen.
Betreibe selber einen Bus mit 4 Mastern. Bisher noch keine Probleme.
Hallo,
bei dem Link von Agmue zum englischsprachigem Forum kommt mir ein bisschen Zweifel, ob das nicht einfach nur dehalb funktioniert, weil hier nur sehr zeitunkritische Aktionen auf dem I2C stattfinden. (Info über einen Tastendruck)
@combie: Bei Deinem Bus mit 4 Mastern: Hast Du da viel Traffic auf dem Bus mit nenneneswerter Wahrscheinlichkeit von Kollisionen zwischen den Mastern ?
Ich rufe bei meinem Arduino "B" halt 2-3 Sensoren mit je 3 Werten alle 100-200 ms ab, und wenn ich das mit Arduino "A" wiederhole, dann wird der Bus schon recht belebt. Größere Blockierungen des Arduino B wären wirklich schlecht.
Ich muss mal nachmessen, wieviel Zeit der eigentliche Transfer für einen Arduino braucht.
Das auch via I2C angebundene LCD ist nur in zeitunkritischen Momenten in Betrieb.
Tütenflieger: @combie: Bei Deinem Bus mit 4 Mastern: Hast Du da viel Traffic auf dem Bus mit nenneneswerter Wahrscheinlichkeit von Kollisionen zwischen den Mastern ?
Nein, eher nicht.
Wenig Betrieb.
Aber ich kann dir die Situation beschreiben, in der der Fehler auftreten soll:
Ein Master beansprucht den Bus
Zwei weitere Master warten darauf, dass der aktuelle Master den Bus frei gibt.
In dem Moment, wo der aktive Master den Bus frei gibt, belegen beide wartenden Master den Bus gleichzeitig.
Dieses soll dann zur Blockade des Busses führen.
Ein Betrieb mit max. 2 Mastern kann also nicht zu dem Fehler führen.
Scherheinz:
Es gibt immer nur ein Master. Wie sollte denn sonst das Timing funktionieren?
Erklären kann ich es nicht, hier habe ich aber englischen Lesestoff gefunden.
combie:
Sowohl die I2C Spezifikationen, als auch die Arduino Wire Lib erlauben den Multimaster Modus.
Ich sehe da kein wirkliches Problem.
"Wire.begin();" ohne Adresse legt ja den Master-Modus fest, wie geht das dann mit zweien? Anders gefragt, wie geht Master-Modus mit Adresse?
Und weil ich schon beim Fragen bin: Geht das auch mit "TinyWireM.begin();"?
Tütenflieger:
Größere Blockierungen des Arduino B wären wirklich schlecht.
"A" als Slave hätte den Vorteil, dass "B" nur Daten liefert, wenn es ins Timing passt. Oder Du spendierst eine Datenleitung zwischen "A" und "B", wo "B" "A" mitteilt, ich habe jetzt Zeit, dass du Daten holst.
Anders gefragt, wie geht Master-Modus mit Adresse?
Öhhmmm....
Wire.begin(55); eröffnet den Slave Mode.
Die benötigten Callbacks initialisieren
Ab jetzt kann der Arduino1 als Slave den I2C bedienen.
Aber das kann den Arduino1 nicht hindern, jederzeit mit Hilfe von Wire.requestFrom(56 , 2); 2 Byte vom Slave 56 zu holen, oder per Wire.beginTransmission(56); den Transport von Daten zum Slave 56 einzuleiten
Auf dem anderen Arduino könnte es dann so aussehen:
Wire.begin(56); eröffnet den Slave Mode.
Die benötigten Callbacks initialisieren
Ab jetzt kann der Arduino2 als Slave den I2C bedienen.
Aber das kann den Arduino2 nicht hindern, jederzeit mit Hilfe von Wire.requestFrom(55 , 2); 2 Byte vom Slave 55 zu holen, oder perWire.beginTransmission(55); den Transport von Daten zum Slave 55 einzuleiten
Beachten sollte man, dass der Buss evtl. nach einem Datentransport gehalten werden muss, damit kein anderer Master dazwischen quatscht. Sowohl Wire.endTransmission() als auch Wire.requestFrom() bieten die Möglichkeit.
combie:
Aber das kann den Arduino1 nicht hindern, jederzeit mit Hilfe von Wire.requestFrom(56 , 2); 2 Byte vom Slave 56 zu holen, oder per Wire.beginTransmission(56); den Transport von Daten zum Slave 56 einzuleiten.
Das probiere ich aus, Danke! 8) Kann aber etwas dauern ...