Vernetzung zweier Mikrocontroller über I2C-Bus
Der I2C-Bus . . .
- ist ein zweiadriger Bus, bestehend aus Taktleitung (SCL) und
Datenleitung (SDA)
- I²C, für englisch Inter-Integrated Circuit
- im Deutschen gesprochen als: "I-Quadrat-C" oder "I-Zwo-C"
- im Englischen: "I-Squared-C" oder "I-Two-C"
- Atmel nennt ihn "TWI"
- ist als Master-Slave-Bus konzipiert
- Der Master sendet und ein Slave reagiert darauf. Oder ein
Master fragt und ein Slave antwortet darauf.
- Mehrere Slaves (standard: 112 / max: 1136) aber auch
(seltener) mehrere Master sind möglich.
Jeder Slave hat eine eigene Adresse.
- Geschwindigkeit: von 100 kbit/s (Standard Mode) bis 3,4
Mbit/s (High Speed Mode)
Experiment 1:
Arduino1 (Master) sendet an Arduino2 (Slave) eine Information
über I2C-Bus.
Was soll passieren?
- Arduino 1 (Master) bekommt über den Seriellen Monitor ein H
oder ein L eingegeben
- dieses L oder H sendet er an Arduino 2 (Slave)
- Arduino 2 reagiert darauf mit an/aus seiner LED an Pin 13
(das ist seine On-Board-LED)
Bauen Sie folgende Schaltung auf:
Lade folgenden Code in den Master:
#include <Wire.h> //I2C-Bibliothek
void setup(){
Serial.begin(9600);
Wire.begin();
//I2C-Aktivierung
}
void loop(){
while(
Serial.available() ) {
char c =
Serial.read();
if(c ==
'H') {
Wire.beginTransmission(5);
//I2C: an Adresse 5 senden
Wire.write('H');
Wire.endTransmission();
}
else if(c
== 'L') {
Wire.beginTransmission(5);
Wire.write('L');
Wire.endTransmission();
}
}
}
Lade folgenden Code in den Slave:
#include <Wire.h>
void setup(){
//I2C-Adresszuweisung: Slave 5
Wire.begin(5);
//Handler für das I2C-Empfangsereignis
festlegen (siehe unten)
Wire.onReceive(receiveEvent);
pinMode(13,OUTPUT);
digitalWrite(13,LOW); // Bord-LED
}
void loop(){} // derzeit nix drin hier (siehe
unten)
void receiveEvent(int howMany){
while(Wire.available())
{
char c = Wire.read();
if(c == 'H')
{
digitalWrite(13,HIGH);
}
else if(c == 'L')
{
digitalWrite(13,LOW);
}
}
}
Weshalb ist hier nichts in der loop()?
In der loop() könnte gewöhnlicher Quelltext stehen, der wie
immer abgearbeitet werden würde..
Die Funktion bzw. Methode receiveEvent()ist
ein sogenannter Ereignis-Handler (auch: Event-Handler).
Diese Funktion bzw. Methode wird immer dann ausgeführt, wenn ein
Datenpaket über I2C angekommen ist.
Stünde in der loop() Quelltext, der abgearbeitet wird, wird
diese Abarbeitung kurz unterbrochen, wenn ein Empfangsereignis
statt fand. Eine solche Unterbrechung nennt man "Interrupt".
Experiment 2:
Arduino1 (Master) empfängt von Arduino2 (Slave) Daten über
I2C-Bus
Was soll passieren?
- Arduino 1 (Master) fragt Daten von Arduino 2 (Slave) ab
- diese Daten gibt der Master im Seriellen Monitor aus
Die Schaltung ist dieselbe, wie im 1. Experiment:
Lade folgenden Code in den Master:
//i2c Master Code
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
Wire.requestFrom(5,10); //Adesse:5,
Anzahl der Zeichen: 10
while(Wire.available())
{
char c = Wire.read();
Serial.print(c);
}
}
void loop()
{
// hier steht jetzt mal nix
}
Lade folgenden Code in den Slave:
//i2c Slave Code
#include <Wire.h>
void setup()
{
Wire.begin(5);
Wire.onRequest(requestEvent);
}
void loop()
{
delay(100);
}
void requestEvent()
{
Wire.write("1234567890");// diese
Daten sollen übermittelt werden
}
Mögliche Denkansätze und Aufgaben:
• ein weiterer Slave soll
hinzugefügt werden
• Nutzen von Slaves als
Porterweiterungen (digital/analog In/Out)
• Nutzen von Slaves als LCD-
und andere Ausgabeeinheiten
|