I2C ist das Busprotokoll bzw. Technologie über die ein Mikrocontroller mit vielen Sensoren oder Aktoren kommunizieren kann. Dank der richtigen Software könnt Ihr so auch verschiedene Mikrocontroller untereinander verbinden und kommunizieren lassen. Dazu gibt es normalerweise pro I2C-Bus nur einen Master der über die entsprechende Adresse Daten von einem Slave anfordern oder zu diesem senden kann.
In einem meiner Projekte wollte bzw. will ich mehrere Mikrocontroller miteinander verbinden. Dazu sind mehrere Bustechnologien geeignet. I2C ist aber fast die einzige die ohne zusätzliche Hardware-Anforderungen von so ziemlich jedem modernen Mikrocontroller direkt unterstützt wird. Somit viel die Wahl schnell auf I2C.
Mittels I2C waren bzw. sind nun also mehrere Mikrocontroller miteinander verbunden. Der Master kann leicht einen Befehl an jeden einzelnen Slave senden. Dazu wird einfach die Slave-Adresse und der gewünschte Befehl über den Bus gesendet. Alle Slaves hören dabei zu was auf dem Bus so vor sich geht, aber nur der Slave mit der entsprechenden Adresse reagiert auch auf den gesendeten Befehl. Soweit so gut.
Aber was wenn der Master einen Befehl an alle Slaves senden will? Zum Beispiel um einen Befehl synchron auf allen Slaves zu starten? Bei zwei oder drei Slaves kann man noch jeden Slave einzeln informieren. Die Verarbeitungsgeschwindigkeit ist meistens so schnell, dass man keine große Zeitabweichung zwischen den Ausführungen auf den einzelnen Slaves merkt. Wenn man dieses Verfahren jedoch bei 100 Slaves nutzt wird man schnell feststellen, dass der letzte benachrichtigte Slave wesentlich später startet als der erste Slave.
Die Lösung für dieses Problem ist die I2C Broadcast Adresse. Diese ist eine Adresse auf die jeder Slave auf dem Bus hört. Um dies zu aktivieren müsst Ihr lediglich ein Kontroll-Bit setzen. So funktioniert es zumindest bei Arduinos die auf Atmel-Prozessoren basieren. 🙂
Wie Ihr dieses Bit setzen könnt ist im folgenden Artikel beschrieben.
I2C-Broadcast für I2C-Slaves aktivieren
Damit alle Teilnehmer auf dem I2C-Bus pauschal benachrichtigt werden können, gibt es die Broadcast-Adresse “0”. Die Null ist also fest definiert als die Adresse für Broadcast-Nachrichten und sollte auch von keinem anderen Slave genutzt werden.
Standardmäßig reagiert ein Mikrocontroller aber nicht auf diese Adresse. Dies muss erst aktiviert werden indem Ihr das entsprechende Kontroll-Bit setzt. Dazu müsst Ihr lediglich folgende Zeile in die “setup()” Funktion Eures Programmcodes einfügen.
TWAR = (adress << 1) | 1; // enable listening on broadcast messages
In einer kompletten I2C-Initialisierungsfunktion könnte dies zum Beispiel so aussehen
void init_i2c() { Wire.begin(adress); TWAR = (adress << 1) | 1; // enable listening on broadcast messages Wire.onReceive(i2c_receive_event); Serial.print(F("I2C: I2C-Slave initialized at address: ")); Serial.println(adress); }
Generelles zu I2C und Interrupts
Ein Ereignis auf dem I2C-Bus ruft immer einen Interrupt auf, welcher den regulären Ablauf Eures Mikrocontrollers unterbricht. Die Programmausführung hüpft also kurz aus dem Ablauf des regulären Programms in die Interrupt-Routine. Den Aufenthalt darin solltet Ihr aber so kurz wie möglich halten. Deswegen ist es “gängige Praxis” innerhalb der Interrupt-Routine eine “Flag” zu setzen. Diese “Flag” ist eigentlich nur eine Boolsche Variable, welche dort auf “true” gesetzt wird. Zurück in dem Haupt-Programmablauf Eures Mikrocontrollers könnt Ihr nun regelmäßig prüfen ob diese Variable gesetzt ist.
Falls ja, könnt Ihr nun die empfangenen Daten bzw. Befehle auslesen und entsprechend reagieren.
Übrigens: Ihr solltet innerhalb der Interrupt-Routinen auch keine “Serial.print…” oder ähnliche Zeit-fressenden Befehle nutzen.
Weiterführende Informationen
http://forum.arduino.cc/index.php?topic=183699.0
http://www.gammon.com.au/forum/?id=10896&reply=1#reply1
Viel Spaß mit dem Projekt
Ich hoffe bei euch hat alles wie beschrieben funktioniert. Falls nicht oder ihr Fragen oder Anregungen habt lasst es mich in den Kommentaren bitte wissen. Ich trage dies dann ggf. in den Artikel nach.
Auch Ideen für neue Projekte sind immer gerne willkommen. 🙂
P.S. Viele dieser Projekte - besonders die Hardwareprojekte - kosten viel Zeit und Geld. Natürlich mache ich das weil ich Spaß daran habe, aber wenn Du es cool findest, dass ich die Infos dazu mit Euch teile, würde ich mich über eine kleine Spende an die Kaffeekasse freuen. 🙂