Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Wie funktioniert die I2C-Kommunikation? Arduino- und I2C-Tutorial

In diesem Tutorial lernen wir, wie das I2C-Kommunikationsprotokoll funktioniert, und wir werden ein praktisches Beispiel dafür mit dem Arduino-Board und einem Sensor erstellen, der dieses Protokoll verwendet. Sie können sich das folgende Video ansehen oder das schriftliche Tutorial unten lesen.

Übersicht

Der I2C-Kommunikationsbus ist sehr beliebt und wird häufig von vielen elektronischen Geräten verwendet, da er leicht in vielen elektronischen Designs implementiert werden kann, die eine Kommunikation zwischen einem Master und mehreren Slave-Geräten oder sogar mehreren Master-Geräten erfordern. Die einfache Implementierung ergibt sich aus der Tatsache, dass nur zwei Drähte für die Kommunikation zwischen bis zu fast 128 (112) Geräten bei Verwendung der 7-Bit-Adressierung und bis zu fast 1024 (1008) Geräten bei Verwendung der 10-Bit-Adressierung erforderlich sind.

Wie I2C funktioniert

Wie ist es möglich, eine Kommunikation zwischen so vielen Geräten mit nur zwei Kabeln zu ermöglichen? Nun, jedes Gerät hat eine voreingestellte ID oder eine eindeutige Geräteadresse, sodass der Master auswählen kann, mit welchen Geräten kommuniziert wird.

Die beiden Drähte oder Leitungen werden Serial Clock (oder SCL) und Serial Data (oder SDA) genannt. Die SCL-Leitung ist das Taktsignal, das die Datenübertragung zwischen den Geräten auf dem I2C-Bus synchronisiert und vom Master-Gerät generiert wird. Die andere Leitung ist die SDA-Leitung, die die Daten trägt.

Die beiden Leitungen sind „Open-Drain“, was bedeutet, dass Pull-up-Widerstände an ihnen angebracht werden müssen, damit die Leitungen hoch sind, da die Geräte auf dem I2C-Bus aktiv niedrig sind. Üblicherweise verwendete Werte für die Widerstände reichen von 2 K für höhere Geschwindigkeiten bei etwa 400 kbps bis 10 K für niedrigere Geschwindigkeiten bei etwa 100 kbps.

I2C-Protokoll

Das Datensignal wird in Folgen von 8 Bit übertragen. Nachdem also eine spezielle Startbedingung eintritt, kommt die erste 8-Bit-Folge, die die Adresse des Slaves angibt, an den die Daten gesendet werden. Nach jeder 8-Bit-Sequenz folgt ein Bit namens Acknowledge. Nach dem ersten Acknowledge-Bit folgt in den meisten Fällen eine weitere Adressierungssequenz, diesmal jedoch für die internen Register des Slave-Geräts. Unmittelbar nach den Adressierungssequenzen folgen so viele Datensequenzen, bis die Daten vollständig gesendet sind, und es endet mit einer speziellen Stoppbedingung.

Schauen wir uns diese Ereignisse noch genauer an. Die Startbedingung tritt auf, wenn die Datenleitung auf Low fällt, während die Taktleitung noch High ist. Danach startet die Uhr und jedes Datenbit wird bei jedem Taktimpuls übertragen.

Die Geräteadressierungssequenz beginnt mit dem höchstwertigen Bit (MSB) zuerst und endet mit dem niederwertigsten Bit (LSB) und besteht eigentlich aus 7 Bits, weil das 8 te Bit wird verwendet, um anzuzeigen, ob der Master in den Slave schreibt (logisch niedrig) oder von ihm liest (logisch hoch).

Das nächste Bit AKC/NACK wird von der Slave-Vorrichtung verwendet, um anzuzeigen, ob sie die vorherige Bitfolge erfolgreich empfangen hat. Zu diesem Zeitpunkt übergibt das Master-Gerät also die Kontrolle über die SDA-Leitung an das Slave-Gerät, und wenn das Slave-Gerät die vorherige Sequenz erfolgreich empfangen hat, wird es die SDA-Leitung auf den als Bestätigung bezeichneten Zustand herunterziehen. Wenn der Slave die SDA-Leitung nicht herunterzieht, wird die Bedingung Not Acknowledge genannt und bedeutet, dass er die vorherige Sequenz nicht erfolgreich empfangen hat, was mehrere Gründe haben kann. Beispielsweise könnte der Slave beschäftigt sein, die empfangenen Daten oder Befehle nicht verstehen, keine weiteren Daten empfangen und so weiter. In einem solchen Fall entscheidet das Master-Gerät, wie es weiter vorgeht.

Als nächstes folgt die Adressierung der internen Register. Die internen Register sind Orte im Speicher des Slaves, die verschiedene Informationen oder Daten enthalten. Beispielsweise hat der ADX345-Beschleunigungsmesser eine eindeutige Geräteadresse und zusätzliche interne Registeradressen für die X-, Y- und Z-Achse. Wenn wir also die Daten der X-Achse lesen wollen, müssen wir zuerst die Geräteadresse und dann die jeweilige interne Registeradresse für die X-Achse senden. Diese Adressen können dem Datenblatt des Sensors entnommen werden.

Nach der Adressierung beginnen die Datenübertragungssequenzen je nach gewähltem Modus am R/W-Bit entweder vom Master oder vom Slave. Nachdem die Daten vollständig gesendet wurden, endet die Übertragung mit einer Stoppbedingung, die eintritt, wenn die SDA-Leitung von Low auf High wechselt, während die SCL-Leitung High ist.

Beispiel

Als Beispiel verwende ich das Breakout-Board GY-80, das aus 5 verschiedenen Sensoren besteht, und das Breakout-Board GY-521, das aus 3 verschiedenen Sensoren besteht. So können wir Daten von 8 verschiedenen Sensoren mit nur zwei Drähten mit dem I2C-Bus erhalten.

Sie können diese Komponenten von einer der folgenden Websites beziehen:

  • ADXL345 3-Achsen-Beschleuniger………………………………………………………
  • 2 in 1:MPU6050 6-Achsen-Gyroskop &Beschleunigungsmesser …………………
  • 3 in 1:GY-80 9-Achsen-Magnetfeld-Beschleunigungsgyroskop……… Amazon 
  • 3 in 1: GY-86 10DOF MS5611 HMC5883L MPU6050-Modul ………Banggood  / AliExpress

So verbinden wir die Platinen. Der Serial Clock Pin des Arduino Boards wird mit den Serial Clock Pins der beiden Breakout Boards verbunden, das gleiche gilt für die Serial Data Pins und wir werden die Boards mit dem Gnd und dem 5V Pin vom Arduino Board versorgen. Beachten Sie, dass wir hier keine Pull-up-Widerstände verwenden, da die Breakout-Boards dies bereits tun.

Um nun mit diesen Chips oder Sensoren zu kommunizieren, müssen wir ihre eindeutigen Adressen kennen. Wir können sie aus den Datenblättern der Sensoren entnehmen. Für das Breakout-Board GY-80 haben wir die folgenden 4 Adressen:eine hexadezimale 0x53 für den 3-Achsen-Beschleunigungssensor, eine hexadezimale 0x69 für den 3-Achsen-Gyro, eine hexadezimale 0x1E für das 3-Achsen-Magnetometer und eine hexadezimale 0x77 für das Barometer und Thermometer Sensor.

Für das Breakout-Board GY-521 haben wir nur eine Adresse und das ist ein hexadezimales 0x68. Wir können die Adressen auch mit der Arduino I2C Scanner-Skizze abrufen oder überprüfen, die auf der offiziellen Arduino-Website zu finden ist. Wenn wir also hier diese Skizze hochladen und ausführen, erhalten wir die Adressen der angeschlossenen Geräte auf dem I2C-Bus.


Sensor                                             Teilenummer                                     I2C-Adresse

3-Achsen-Beschleunigungsmesser                   Analog Devices ADXL345                   0x53                  Datenblatt

3-Achsen-GyroST                                Microelectronics L3G4200D              0x69                  Datenblatt

3-Achsen-Magnetometer                  Honeywell MC5883L                           0x1E                  Datenblatt

Barometer + Thermometer        Bosch BMP085                                     0x77                  Datenblatt


Nachdem wir die Adressen der Geräte gefunden haben, müssen wir auch die Adressen ihrer internen Register finden, um die Daten von ihnen zu lesen. Wenn wir beispielsweise die Daten für die X-Achse vom 3-Achsen-Beschleunigungssensor des GY-80-Breakout-Boards lesen möchten, müssen wir die interne Registeradresse finden, an der die Daten der X-Achse gespeichert sind. Aus dem Datenblatt des Sensors können wir entnehmen, dass die Daten für die X-Achse tatsächlich in zwei Registern gespeichert sind, DATAX0 mit einer hexadezimalen Adresse 0x32 und DATAX1 mit einer hexadezimalen Adresse 0x33.

Arduino-I2C-Code

Lassen Sie uns nun den Code erstellen, der die Daten für die X-Achse erhält. Wir werden also die Arduino Wire Library verwenden, die in die Skizze aufgenommen werden muss. Hier müssen wir zuerst die Sensoradresse und die zwei internen Registeradressen definieren, die wir zuvor gefunden haben. Das Wire.begin() Funktion initiiert die Wire-Bibliothek und wir müssen auch die serielle Kommunikation initiieren, da wir den Serial Monitor verwenden werden, um die Daten vom Sensor anzuzeigen.

In der Schleife() Wir beginnen mit Wire.beginTransmission() Funktion, die die Übertragung an den jeweiligen Sensor, in unserem Fall den 3-Achsen-Beschleunigungsmesser, beginnt. Dann mit dem Wire.write() Funktion fragen wir die jeweiligen Daten aus den beiden Registern der X-Achse ab. Die Wire.endTransmission() beendet die Übertragung und überträgt die Daten aus den Registern. Jetzt mit Wire.requestFrom() Funktion fordern wir die übertragenen Daten bzw. die zwei Bytes aus den beiden Registern an.

Die Wire.available() Die Funktion gibt die Anzahl der für den Abruf verfügbaren Bytes zurück und wenn diese Anzahl mit unseren angeforderten Bytes übereinstimmt, in unserem Fall 2 Bytes, unter Verwendung von Wire.read() Funktion lesen wir die Bytes aus den beiden Registern der X-Achse. Am Ende drucken wir die Daten in den seriellen Monitor. Hier sind diese Daten, aber denken Sie daran, dass dies Rohdaten sind und einige Berechnungen erforderlich sind, um die richtigen Werte der X-Achse zu erhalten. Weitere Details dazu finden Sie in meinem nächsten Tutorial zur Verwendung von Beschleunigungsmessern mit dem Arduino-Board, da ich dieses Tutorial nicht überladen möchte, da sein Hauptziel darin bestand, zu erklären, wie die Arduino I2C-Kommunikation funktioniert.

/* * How I2C Communication Protocol Works - Arduino I2C Tutorial * * by Dejan, www.HowToMechatronics.com * */ #include <Wire.h> int ADXLAddress = 0x53; // Device address in which is also included the 8th bit for selecting the mode, read in this case. #define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register. #define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register. #define Power_Register 0x2D // Power Control Register int X0,X1,X_out; void setup() { Wire.begin(); // Initiate the Wire library Serial.begin(9600); delay(100); // Enable measurement Wire.beginTransmission(ADXLAddress); Wire.write(Power_Register); // Bit D3 High for measuring enable (0000 1000) Wire.write(8); Wire.endTransmission(); } void loop() { Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor //Ask the particular registers for data Wire.write(X_Axis_Register_DATAX0); Wire.write(X_Axis_Register_DATAX1); Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers Wire.requestFrom(ADXLAddress,2); // Request the transmitted two bytes from the two registers if(Wire.available()<=2) { // X0 = Wire.read(); // Reads the data from the register X1 = Wire.read(); } Serial.print("X0= "); Serial.print(X0); Serial.print(" X1= "); Serial.println(X1); } Codesprache:Arduino (arduino)

Herstellungsprozess

  1. Arduino I2C-Kommunikation mit Raspi 2 WIOT
  2. So bauen Sie einen Arduino-Energiemonitor und einen Datenlogger
  3. Temperatur- und Feuchtigkeitsdatenlogger
  4. Python3- und Arduino-Kommunikation
  5. So verwenden Sie NMEA-0183 mit Arduino
  6. Arduino-Tutorial:JARVIS v1 | So erstellen Sie eine Hausautomation
  7. Multithreading eines Arduino (Protothreading-Tutorial)
  8. nRF24L01 – Wie es funktioniert, Arduino-Schnittstelle, Schaltkreise, Codes
  9. Arduino und MPU6050 Beschleunigungsmesser und Gyroskop-Tutorial
  10. So verfolgen Sie die Orientierung mit Arduino und dem ADXL345-Beschleunigungsmesser