Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Hoe I2C-communicatie werkt? Arduino en I2C-zelfstudie

In deze tutorial leren we hoe het I2C-communicatieprotocol werkt en we zullen er ook een praktisch voorbeeld van maken met het Arduino-bord en een sensor die dit protocol gebruikt. Je kunt de volgende video bekijken of de schriftelijke tutorial hieronder lezen.

Overzicht

De I2C-communicatiebus is erg populair en wordt veel gebruikt door veel elektronische apparaten omdat het gemakkelijk kan worden geïmplementeerd in veel elektronische ontwerpen die communicatie vereisen tussen een master en meerdere slave-apparaten of zelfs meerdere master-apparaten. De eenvoudige implementatie komt met het feit dat er slechts twee draden nodig zijn voor communicatie tussen maximaal bijna 128 (112) apparaten bij gebruik van 7 bits adressering en tot bijna 1024 (1008) apparaten bij gebruik van 10 bits adressering.

Hoe I2C werkt

Hoe is het mogelijk, een communicatie tussen zoveel apparaten met slechts draden? Welnu, elk apparaat heeft een vooraf ingestelde ID of een uniek apparaatadres, zodat de master kan kiezen met welke apparaten zal communiceren.

De twee draden of lijnen worden Serial Clock (of SCL) en Serial Data (of SDA) genoemd. De SCL-lijn is het kloksignaal dat de gegevensoverdracht tussen de apparaten op de I2C-bus synchroniseert en wordt gegenereerd door het hoofdapparaat. De andere lijn is de SDA-lijn die de gegevens draagt.

De twee lijnen zijn "open-drain", wat betekent dat er pull-up-weerstanden aan moeten worden bevestigd, zodat de lijnen hoog zijn omdat de apparaten op de I2C-bus laag actief zijn. Veelgebruikte waarden voor de weerstanden zijn van 2K voor hogere snelheden bij ongeveer 400 kbps, tot 10K voor lagere snelheden bij ongeveer 100 kbps.

I2C-protocol

Het datasignaal wordt overgedragen in reeksen van 8 bits. Dus nadat er een speciale startconditie is opgetreden, komt de eerste 8 bits-reeks die het adres aangeeft van de slave waarnaar de gegevens worden verzonden. Na elke 8 bits reeks volgt een bit genaamd Acknowledge. Na het eerste Acknowledge-bit komt in de meeste gevallen een andere adresseringsreeks, maar dit keer voor de interne registers van het slave-apparaat. Direct na de adresreeksen volgen de gegevensreeksen net zoveel totdat de gegevens volledig zijn verzonden en het eindigt met een speciale stopvoorwaarde.

Laten we deze gebeurtenissen nog eens nader bekijken. De startconditie treedt op wanneer de datalijn laag wordt terwijl de kloklijn nog steeds hoog is. Hierna start de klok en wordt elke databit tijdens elke klokpuls overgedragen.

De adresreeks van het apparaat begint met de meest significante bit (MSB) eerst en eindigt met de minst significante bit (LSB) en het is eigenlijk samengesteld uit 7 bits omdat de 8 de bit wordt gebruikt om aan te geven of de master naar de slave zal schrijven (logisch laag) of ervan zal lezen (logisch hoog).

De volgende bit AKC/NACK wordt door het slave-apparaat gebruikt om aan te geven of het de vorige reeks bits met succes heeft ontvangen. Dus op dit moment geeft het master-apparaat de besturing van de SDA-lijn over aan het slave-apparaat en als het slave-apparaat de vorige reeks met succes heeft ontvangen, zal het de SDA-lijn naar beneden trekken naar de toestand die Acknowledge wordt genoemd. Als de slaaf de SDA-regel niet naar beneden trekt, wordt de voorwaarde Not Acknowledge genoemd, wat betekent dat hij de vorige reeks niet met succes heeft ontvangen, wat verschillende redenen kan hebben. De slave kan bijvoorbeeld bezet zijn, de ontvangen gegevens of opdracht niet begrijpen, geen gegevens meer ontvangen enzovoort. In zo'n geval bepaalt het masterapparaat hoe het verder gaat.

Het volgende is de adressering van de interne registers. De interne registers zijn locaties in het geheugen van de slave die verschillende informatie of gegevens bevatten. De ADX345 Accelerometer heeft bijvoorbeeld een uniek apparaatadres en daarnaast interne registeradressen voor de X-, Y- en Z-as. Dus als we de gegevens van de X-as willen lezen, moeten we eerst het apparaatadres verzenden en vervolgens het specifieke interne registeradres voor de X-as. Deze adressen zijn te vinden in de datasheet van de sensor.

Na de adressering beginnen de gegevensoverdrachtsequenties ofwel vanaf de master of de slave, afhankelijk van de geselecteerde modus bij het R/W-bit. Nadat de gegevens volledig zijn verzonden, eindigt de overdracht met een stopconditie die optreedt wanneer de SDA-lijn van laag naar hoog gaat terwijl de SCL-lijn hoog is.

Voorbeeld

Als voorbeeld gebruik ik het GY-80 breakout board dat uit 5 verschillende sensoren bestaat en het GY-521 breakout board dat uit 3 verschillende sensoren bestaat. We kunnen dus gegevens krijgen van 8 verschillende sensoren met slechts twee draden met de I2C-bus.

U kunt deze componenten op een van de onderstaande sites krijgen:

  • ADXL345 3-assige versneller…………………………………………………………
  • 2 in 1:MPU6050 6-assige gyroscoop en versnellingsmeter …………………
  • 3 in 1:GY-80 9-assige magnetische veldversnellingsgyroscoop……… Amazon 
  • 3 in 1: GY-86 10DOF MS5611 HMC5883L MPU6050-module……… Banggood  / AliExpress

Hier is hoe we de planken verbinden. De Serial Clock-pin van het Arduino-bord wordt verbonden met de Serial Clock-pinnen van de twee breakout-boards, hetzelfde geldt voor de Serial Data-pinnen en we zullen de boards van stroom voorzien met de Gnd en de 5V-pin van het Arduino-bord. Merk op dat we hier geen pull-up-weerstanden gebruiken omdat de breakout-kaarten dat al hebben.

Om nu met deze chips of sensoren te kunnen communiceren, moeten we hun unieke adressen weten. We kunnen ze vinden in de datasheets van de sensoren. Voor het GY-80 breakout board hebben we de volgende 4 adressen:een hexadecimale 0x53 voor de 3 Axis Accelerometer sensor, een hexadecimale 0x69 voor de 3 Axis Gyro, een hexadecimale 0x1E voor de 3 Axis Magnetometer en een hexadecimale 0x77 voor de Barometer en Thermometer sensor.

Voor het GY-521 breakout board hebben we maar één adres en dat is een hexadecimale 0x68. We kunnen de adressen ook ophalen of controleren met behulp van de Arduino I2C Scanner-schets die te vinden is op de officiële Arduino-website. Dus hier, als we die schets uploaden en uitvoeren, krijgen we de adressen van de aangesloten apparaten op de I2C-bus.


Sensor                                             Artikelnummer                                     I2C-adres

3 Axis Accelerometer                   Analoge apparaten ADXL345                   0x53                  Gegevensblad

3 Axis GyroST                                Micro-elektronica L3G4200D              0x69                  Datasheet

3-assige magnetometer                  Honeywell MC5883L                           0x1E                  Datasheet

Barometer + Thermometer        Bosch BMP085                                     0x77                  Gegevensblad


Nadat we de adressen van de apparaten hebben gevonden, moeten we ook de adressen van hun interne registers vinden om de gegevens ervan te kunnen lezen. Als we bijvoorbeeld de gegevens voor de X-as van de 3 Axis Accelerometer-sensor van het GY-80 breakout-bord willen lezen, moeten we het interne registeradres vinden waar de gegevens van de X-as zijn opgeslagen. Uit het gegevensblad van de sensor kunnen we zien dat gegevens voor de X-as feitelijk zijn opgeslagen in twee registers, DATAX0 met een hexadecimaal adres 0x32 en DATAX1 met een hexadecimaal adres 0x33.

Arduino I2C-code

Laten we nu de code maken die de gegevens voor de X-as zal krijgen. We zullen dus de Arduino Wire Library gebruiken die in de schets moet worden opgenomen. Hier moeten we eerst het sensoradres en de twee interne registeradressen definiëren die we eerder hebben gevonden. De Wire.begin() functie zal de draadbibliotheek starten en we moeten ook de seriële communicatie starten omdat we de seriële monitor zullen gebruiken om de gegevens van de sensor weer te geven.

In de loop() we beginnen met de Wire.beginTransmission() functie die de overdracht naar de specifieke sensor, de 3 Axis Accelerometer in ons geval, zal beginnen. Dan met de Wire.write() functie vragen we om de specifieke gegevens van de twee registers van de X-as. De Wire.endTransmission() beëindigt de verzending en verzendt de gegevens uit de registers. Nu met de Wire.requestFrom() functie zullen we de verzonden gegevens of de twee bytes van de twee registers opvragen.

De Wire.available() functie retourneert het aantal bytes dat beschikbaar is voor ophalen en als dat aantal overeenkomt met onze gevraagde bytes, in ons geval 2 bytes, met behulp van de Wire.read() functie lezen we de bytes uit de twee registers van de X-as. Aan het einde zullen we de gegevens afdrukken in de seriële monitor. Hier zijn die gegevens, maar houd er rekening mee dat dit onbewerkte gegevens zijn en dat er wat wiskunde moet worden gedaan om de juiste waarden van de X-as te krijgen. Je kunt daar meer details over vinden in mijn volgende tutorial voor het gebruik van versnellingsmeters met het Arduino-bord, omdat ik deze tutorial niet wil overbelasten omdat het belangrijkste doel was om uit te leggen hoe de Arduino I2C-communicatie werkt.

/*  
 *  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);
}Code language: Arduino (arduino)

Productieproces

  1. Arduino I2C-communicatie met Raspi 2 WIOT
  2. Een Arduino-energiemonitor en datalogger bouwen
  3. Temperatuur- en vochtigheidsdatalogger
  4. Python3- en Arduino-communicatie
  5. Hoe NMEA-0183 te gebruiken met Arduino
  6. Arduino-zelfstudie:JARVIS v1 | Hoe maak je een huisautomatisering
  7. Een Arduino multithreaden (Protothreading Tutorial)
  8. nRF24L01 – Hoe het werkt, Arduino-interface, circuits, codes
  9. Arduino en MPU6050 versnellingsmeter en gyroscoop zelfstudie
  10. Oriëntatie volgen met Arduino en ADXL345 Accelerometer
  11. Arduino en HC-12 draadloze communicatiemodule voor lange afstand