I2C is het busprotocol of de technologie waarmee een microcontroller met veel sensoren of actuatoren kan communiceren. Dankzij de juiste software kun je bovendien verschillende microcontrollers met elkaar verbinden en communiceren. Per I2C-bus is er doorgaans maar één master die via het bijbehorende adres data kan opvragen of versturen naar een slave.
In een van mijn projecten wilde of wil ik meerdere microcontrollers met elkaar verbinden. Hiervoor zijn verschillende bustechnologieën geschikt. I2C is echter vrijwel de enige die rechtstreeks wordt ondersteund door vrijwel elke moderne microcontroller zonder aanvullende hardwarevereisten. De keuze viel dus al snel op I2C.
Met behulp van I2C werden of zijn nu meerdere microcontrollers met elkaar verbonden. De master kan eenvoudig een commando naar elke individuele slave sturen. Om dit te doen, stuurt u eenvoudigweg het slave-adres en het gewenste commando over de bus. Alle slaves luisteren naar wat er op de bus gebeurt, maar alleen de slave met het bijbehorende adres reageert op het verzonden commando. Tot nu toe gaat het goed.
Maar wat als de master een commando naar alle slaves wil sturen? Om bijvoorbeeld een commando synchroon op alle slaves te starten? Als er twee of drie slaven zijn, kunt u toch elke slaaf afzonderlijk informeren. De verwerkingssnelheid is meestal zo snel dat u geen groot tijdsverschil merkt tussen uitvoeringen op de individuele slaves. Als u deze procedure echter met 100 slaves gebruikt, zult u snel merken dat de laatst aangemelde slave aanzienlijk later start dan de eerste slave.
De oplossing voor dit probleem is het I2C-broadcastadres. Dit is een adres waar elke slaaf op de bus naar luistert. Om dit te activeren hoeft u alleen maar een controlebit in te stellen. Zo werkt het tenminste met Arduino's op basis van Atmel-processors. 🙂
Hoe je dit bit kunt instellen, wordt beschreven in het volgende artikel.
Schakel I2C-broadcast in voor I2C-slaves
Om ervoor te zorgen dat alle deelnemers op de I2C-bus over de hele linie op de hoogte kunnen worden gesteld, is er een broadcast-adres van “0”. De nul is daarom duidelijk gedefinieerd als het adres voor uitgezonden berichten en mag door geen enkele andere slaaf worden gebruikt.
Standaard reageert een microcontroller niet op dit adres. Deze moet eerst worden geactiveerd door het instellen van de bijbehorende besturingsbit. Het enige wat u hoeft te doen is de volgende regel in de “setup()”-functie van uw programmacode in te voegen.
TWAR = (adres << 1) | 1; // luister naar uitgezonden berichten inschakelen
In een volledige I2C-initialisatiefunctie zou het er bijvoorbeeld zo uit kunnen zien
leegte init_i2c() { Wire.begin(adres); TWAR = (adres << 1) | 1; // luisteren naar uitgezonden berichten inschakelen Wire.onReceive(i2c_receive_event); Serial.print(F("I2C: I2C-slave geïnitialiseerd op adres: ")); Serial.println(adres); }
Algemene informatie over I2C en interrupts
Een gebeurtenis op de I2C-bus veroorzaakt altijd een interrupt, die de reguliere stroom van uw microcontroller onderbreekt. De programma-uitvoering springt daarom kortstondig van het reguliere programmaverloop naar de interruptroutine. U moet uw verblijf daar echter zo kort mogelijk houden. Daarom is het “gebruikelijke praktijk” om een “vlag” in te stellen binnen de interruptroutine. Deze “vlag” is eigenlijk gewoon een Booleaanse variabele die is ingesteld op “true”. Terug in het hoofdprogramma van uw microcontroller kunt u nu regelmatig controleren of deze variabele is ingesteld.
Als dat zo is, kunt u nu de ontvangen gegevens of opdrachten lezen en overeenkomstig reageren.
Overigens: binnen de interruptroutines mag u geen “Serial.print…” of vergelijkbare tijdrovende commando's gebruiken.
Meer informatie
http://forum.arduino.cc/index.php?topic=183699.0
http://www.gammon.com.au/forum/?id=10896&reply=1#reply1
Veel plezier met het project
Ik hoop dat alles werkte zoals beschreven. Zo niet, of als je vragen of suggesties hebt, laat het me weten in de commentaren. Ik zal dit dan zo nodig aan het artikel toevoegen.
Ideeën voor nieuwe projecten zijn altijd welkom. 🙂
PS Veel van deze projecten - vooral de hardwareprojecten - kosten veel tijd en geld. Natuurlijk doe ik dit omdat ik het leuk vind, maar als je het cool vindt dat ik de informatie met je deel, dan zou ik blij zijn met een kleine donatie aan het koffiefonds. 🙂