Kaip veikia „I2C“ ryšys ir kaip jį naudoti su „Arduino“

Šioje pamokoje sužinosime, kaip veikia „I2C“ ryšio protokolas, taip pat pateiksime praktinį pavyzdį su „Arduino Board“ ir jutikliu, kuris naudoja šį protokolą. Galite žiūrėti šį vaizdo įrašą arba perskaityti toliau pateiktą rašytinę pamoką.

REKOMENDUOJAMAS
8 geriausi „Arduino“ pradedančiųjų rinkiniai pradedantiesiems 2019 m
Apžvalga


„I2C“ komunikacijos magistralė yra labai populiari ir plačiai naudojama daugelio elektroninių prietaisų, nes ją galima lengvai įgyvendinti daugelyje elektroninių konstrukcijų, kuriai reikalingas ryšys tarp pagrindinio ir kelių vergų įrenginių ar net kelių pagrindinių įrenginių. Lengvai įgyvendinama tuo, kad norint bendrauti iki beveik 128 (112) įrenginių, naudojant 7 bitų adresavimą, reikia tik dviejų laidų, o naudojant 10 bitų adresavimą – iki beveik 1024 (1008) įrenginių.

„I2C-Communication-Overview“

Kaip tai veikia


Kaip tai įmanoma, tiek daug prietaisų bendraujant tik su laidais? Kiekvienas įrenginys turi iš anksto nustatytą ID arba unikalų įrenginio adresą, todėl kapitonas gali pasirinkti, su kuriais įrenginiais bus bendraujama.

Du laidai arba linijos vadinami nuosekliuoju laikrodžiu (arba SCL) ir nuosekliaisiais duomenimis (arba SDA). SCL linija yra laikrodžio signalas, sinchronizuojantis duomenų perdavimą tarp I2C magistralės įrenginių ir generuojamas pagrindinio įrenginio. Kita eilutė yra SDA linija, perduodanti duomenis.

Šios dvi linijos yra „atviro nutekėjimo“, o tai reiškia, kad prie jų reikia pritvirtinti varžtus, kad linijos būtų aukštos, nes I2C magistralės prietaisai yra aktyvūs žemai. Dažniausiai naudojamos rezistorių vertės yra nuo 2K didesniam greičiui esant maždaug 400 kbps, iki 10K mažesniam greičiui, esant maždaug 100 kbps.

„I2C-Communication“ - kaip tai veikia

I2C protokolas


Duomenų signalas perduodamas 8 bitų sekomis. Taigi, įvykus ypatingai paleidimo sąlygai, ateina pirmųjų 8 bitų seka, nurodanti vergo, kuriam siunčiami duomenys, adresą. Po kiekvienos 8 bitų sekos seka bitai, vadinami patvirtinimu. Po pirmojo patvirtinimo bitų daugeliu atvejų ateina kita adresavimo seka, tačiau šį kartą – vidiniams vergo įrenginio registrams. Iškart po adresavimo sekų seka duomenų sekas tiek, kiek duomenys yra visiškai išsiųsti ir baigiasi specialia sustabdymo sąlyga.
I2C-Bendravimas-Protokolas

Pažvelkime dar atidžiau į šiuos įvykius. Pradžios sąlyga įvyksta, kai duomenų linija nukrenta žemai, o laikrodžio linija vis dar aukšta. Po to prasideda laikrodis ir kiekvienas duomenų bitas perduodamas per kiekvieną laikrodžio impulsą.

Įrenginys, adresuojantis seką, pirmiausia pažymi reikšmingiausią bitą (MSB) ir baigiasi mažiausiai reikšmingu bitu (LSB), ir jį iš tikrųjų sudaro 7 bitai, nes 8tūkst bitai naudojami nurodant, ar šeimininkas rašys vergui (logika žemai), ar skaitys iš jo (logika aukštai).

„I2C-Bits-Protocol“

Kitą bitą AKC / NACK naudoja vergas, nurodydamas, ar jis sėkmingai gavo ankstesnę bitų seką. Taigi šiuo metu pagrindinis prietaisas perduoda SDA linijos valdymą vergo įrenginiui ir, jei vergo įrenginys sėkmingai gavo ankstesnę seką, jis atitrauks SDA liniją iki sąlygos, vadinamos patvirtinimu. Jei vergas netraukia SDA linijos žemyn, ši sąlyga vadinama „Not Acknowledge“ ir reiškia, kad jis sėkmingai negavo ankstesnės sekos, kurią gali sukelti kelios priežastys. Pavyzdžiui, vergas gali būti užimtas, gali nesuprasti gautų duomenų ar komandos, nebegali gauti daugiau duomenų ir pan. Tokiu atveju pagrindinis įrenginys nusprendžia, kaip jis veiks toliau.

„I2C-Bits-Protocol_ADXL-X-Axis-Example“ pavyzdys

Kitas yra vidinių registrų adresavimas. Vidiniai registrai yra vergo atmintyje esančios vietos, kuriose yra įvairios informacijos ar duomenų. Pavyzdžiui, ADX345 akselerometras turi unikalų įrenginio adresą ir papildomus vidinius registrų adresus X, Y ir Z ašims. Taigi, jei norime perskaityti X ašies duomenis, pirmiausia turime išsiųsti įrenginio adresą ir tada tam tikrą X ašies vidinio registro adresą. Šiuos adresus galite rasti jutiklio duomenų lape.

Po adresavimo, duomenų perdavimo sekos prasideda arba nuo pagrindinio, arba iš vergo, atsižvelgiant į pasirinktą R / W bitų režimą. Po to, kai duomenys bus visiškai išsiųsti, perdavimas baigsis sustabdymo sąlyga, kuri atsiranda, kai SDA linija eina iš žemos į aukštą, o SCL linija yra aukšta.


Kaip pavyzdį naudosiu GY-80 pertraukimo lentą, kurią sudaro 5 skirtingi jutikliai, ir GY-521 pertraukiamąją lentą, kurią sudaro 3 skirtingi jutikliai. Taigi mes galime gauti duomenis iš 8 skirtingų jutiklių, turinčių tik du laidus su I2C magistrale.

GY --- 80 ir-GY --- 521 adresai

Šiuos komponentus galite gauti bet kurioje iš toliau nurodytų svetainių:

  • ADXL345 3 ašių greitintuvas ……………………………………………………… „Amazon“ / „Banggood“ / „AliExpress“
  • 2 viename: 6 ašių giroskopas ir akselerometras MPU6050 ………………… „Amazon“ / „Banggood“ / „AliExpress“
  • 3 iš 1: GY-80 9 ašių magnetinio lauko pagreičio giroskopas… „Amazon“
  • „3 viename“: GY-86 10DOF MS5611 HMC5883L MPU6050 modulis… Banggoodas / „AliExpress“

Atskleidimas: tai yra filialų nuorodos. Kaip „Amazon“ partneris uždirbu iš kvalifikuotų pirkimų.

Štai kaip sujungsime lentas. „Arduino“ plokštės nuoseklaus laikrodžio kaištis bus sujungtas su dviejų išardymo plokščių nuoseklaus laikrodžio kaiščiais, tas pats pasakytina ir apie „Serial Data“ kaiščius, o plokštes maitinsime „Arndino“ plokštės „Gnd“ ir 5 V kaiščiu. Atkreipkite dėmesį čia, kad nenaudojame traukimo rezistorių, nes pertraukiamosios plokštės jau yra.

„I2C-and-Arduino-Circuit-Schematics“

Dabar, norėdami bendrauti su šiais lustais ar jutikliais, turime žinoti jų unikalius adresus. Juos galime rasti iš jutiklių duomenų lapų. GY-80 pertraukimo lentai turime šiuos 4 adresus: šešioliktainis 0x53 3 ašių akselerometro jutikliui, šešioliktainis 0x69 3 ašies giroskopui, šešioliktainis 0x1E 3 ašies magnetometrui ir šešioliktainis 0x77 barometrui ir termometrui. jutiklis.

GY-521 pramušimo lentai turime tik vieną adresą ir tai yra šešioliktainis skaičius 0x68. Adresus taip pat galime gauti arba patikrinti naudodami „Arduino I2C Scanner“ eskizą, kurį galite rasti oficialioje „Arduino“ svetainėje. Taigi, jei įkelsime ir vykdysime tą eskizą, I2C magistralėje gausime prijungtų įrenginių adresus.


Jutiklio dalies numeris I2C adresas

3 ašių akselerometro analoginiai įtaisai ADXL345 0x53 duomenų lapas

3 ašių „GyroST Microelectronics L3G4200D 0x69“ duomenų lapas

3 ašių magnetometro „Honeywell MC5883L 0x1E“ duomenų lapas

Barometras + termometras „Bosch BMP085 0x77“ duomenų lapas


Radę įrenginių adresus, taip pat turime rasti jų vidinių registrų adresus, kad galėtume nuskaityti jų duomenis. Pavyzdžiui, jei norime perskaityti X ašies duomenis iš 3 ašių akselerometro jutiklio, esančio GY-80 pertraukimo plokštėje, turime rasti vidinio registro adresą, kuriame saugomi X ašies duomenys. Iš jutiklio duomenų lapo galime pamatyti, kad X ašies duomenys iš tikrųjų saugomi dviejuose registruose: DATAX0 su šešioliktainiu adresu 0x32 ir DATAX1 su šešioliktainiu adresu 0x33.


Dabar sukurkime kodą, kuris gaus X ašies duomenis. Taigi naudosime „Arduino Wire Library“, kuri turi būti įtraukta į eskizą. Pirmiausia turime apibrėžti jutiklio adresą ir du vidinius registrų adresus, kuriuos anksčiau radome. Wire.begin () funkcija inicijuos „Wire“ biblioteką, taip pat turime inicijuoti nuoseklųjį ryšį, nes naudosime nuoseklųjį monitorių rodydami duomenis iš jutiklio.

Viduje konors kilpa () mes pradėsime nuo „Wire.begin“ perdavimas () funkcija, kuri pradės perdavimą tam tikram jutikliui, mūsų atveju – 3 ašių akselerometrui. Tada su Wire.write () funkcija, mes paprašysime konkrečių duomenų iš dviejų X ašies registrų. „Wire.endTransmission“ () baigs perdavimą ir perduos duomenis iš registrų. Dabar su Wire.requestFrom () Mes paprašysime perduotų duomenų arba dviejų baitų iš dviejų registrų.

Wire.available () funkcija grąžins galimų gauti baitų skaičių ir, jei šis skaičius sutaps su mūsų prašomais baitais, mūsų atveju – 2 baitais, naudojant Wire.read () Funkciją mes perskaitysime baitus iš dviejų X ašies registrų. Pabaigoje duomenis atspausdinsime serijiniame monitoriuje. Štai šie duomenys, tačiau nepamirškite, kad tai yra neapdoroti duomenys ir norint atlikti teisingas X ašies vertes, reikia atlikti tam tikrą matematiką. Daugiau informacijos apie tai galite rasti kitoje mano akselerometrų naudojimo su „Arduino Board“ pamokoje, nes nenoriu perkrauti šios mokymo programos, nes jos pagrindinis tikslas buvo paaiškinti, kaip veikia „Arduino I2C“ ryšys.

/*  
 *  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);
}

Parašykite komentarą