Popularul protocol I2C permite a două sau mai multe plăci Arduino să comunice. Descoperiți cum să le conectați și să le codificați.
În timp ce un singur Arduino poate îndeplini multe sarcini, unele proiecte pot necesita utilizarea mai multor plăci pentru a gestiona diferite funcționalități. Deci, pentru a permite transferul de date între cele două microcontrolere, trebuie configurat un protocol de comunicare precum CAN, SPI, I2C sau UART.
În acest ghid, vom acoperi elementele de bază ale modului în care funcționează I2C, conexiunile hardware și implementarea software necesară pentru a configura două plăci Arduino ca dispozitive master și slave I2C.
Ce este I2C?
Inter-Integrated Circuit (I2C) este un protocol de comunicare utilizat pe scară largă în sistemele încorporate și microcontrolere pentru a permite transferul de date între dispozitive electronice. Spre deosebire de SPI (Serial Peripheral Interface), I2C vă permite să conectați mai mult de un dispozitiv master la o magistrală cu un singur sau mai multe dispozitive slave. A fost folosit pentru prima dată de Philips și este cunoscut și sub numele de protocol de comunicație Two Wire Interface (TWI).
Cum funcționează comunicarea I2C?
I2C folosește două linii bidirecționale: Serial Data (SDA) și Serial Clock (SCL) pentru a transfera date și a sincroniza comunicația între dispozitive. Fiecare dispozitiv conectat la magistrala I2C are o adresă unică care îl identifică în timpul comunicării. Protocolul I2C permite mai multor dispozitive să partajeze aceeași magistrală, iar fiecare dispozitiv poate acționa ca master sau slave.
Comunicarea este inițiată de dispozitivul principal, iar adresarea incorectă a dispozitivelor slave poate cauza erori în transfer. Consultați ghidul nostru detaliat despre cum funcționează comunicațiile seriale UART, SPI și I2C pentru a vă oferi un context.
Un avantaj major al comunicației I2C care merită remarcat este flexibilitatea pe care o oferă atunci când vine vorba de gestionarea energiei. Dispozitivele care funcționează la diferite niveluri de tensiune pot comunica în continuare eficient cu ajutorul schimbătorilor de tensiune. Aceasta înseamnă că dispozitivele care funcționează la 3,3 V au nevoie de schimbători de tensiune pentru a se conecta la o magistrală I2C de 5 V.
Biblioteca Wire
Biblioteca Wire este o bibliotecă Arduino încorporată care oferă funcții pentru a comunica prin I2C. Folosește doi pini - SDA și SCL - pe placa Arduino pentru comunicarea I2C.
Pini I2C de pe Arduino Uno:
Pini Arduino Nano I2C:
Pentru a utiliza biblioteca, trebuie să includeți Sârmă.h fișier antet la începutul schiței dvs. Arduino.
#include
Biblioteca Wire oferă funcții pentru a iniția comunicarea cu un dispozitiv I2C, a trimite date și a primi date. Câteva funcții importante pe care ar trebui să le cunoașteți includ:
- Wire.begin(): folosit pentru a se alătura magistralei I2C și a iniția comunicarea.
- Wire.beginTransmission(): folosit pentru a specifica adresa slave și pentru a începe o transmisie.
- Wire.write(): folosit pentru a trimite date către dispozitivul I2C.
- Wire.endTransmission(): folosit pentru a termina transmisia și a verifica erorile.
- Wire.requestFrom(): folosit pentru a solicita date de la dispozitivul I2C.
- Wire.available(): folosit pentru a verifica dacă sunt disponibile date pentru a fi citite de pe dispozitivul I2C.
- Wire.read(): folosit pentru a citi date de pe dispozitivul I2C.
Folosește Wire.beginTransmission() funcția pentru a seta adresa senzorului, care este inserată ca argument. De exemplu, dacă adresa senzorului este 0x68, ai folosi:
Sârmă.începeTransmisie(0x68);
Configurare hardware Arduino I2C
Pentru a conecta două plăci Arduino folosind I2C, veți avea nevoie de următoarele componente hardware:
- Două plăci Arduino (master și slave)
- Breadboard
- Fire jumper
- Două rezistențe pull-up de 4,7kΩ
Conectați SDA și SCL pinii ambelor plăci Arduino la o placă. Conectați rezistențele de tragere între SDA și SCL ace și 5V șină de alimentare pe placa de breadboard. În cele din urmă, conectați cele două panouri împreună folosind fire jumper.
Circuitul Arduino Uno
Circuitul Arduino Nano
Configurarea plăcilor Arduino ca dispozitive master și slave I2C
Folosește Wire.requestFrom() funcție pentru a specifica adresa dispozitivului slave cu care dorim să comunicăm. Apoi utilizați Wire.read() funcția de obținere a datelor de la dispozitivul slave.
Codul dispozitivului principal:
#include
golînființat(){
Sârmă.ÎNCEPE(); // se alătură magistralei i2c
Serial.ÎNCEPE(9600); // pornește serialul pentru ieșire
}
golprimiteDate(){
int adresa = 8;
int bytesToRead = 6;
Sârmă.o cerere de la(adresă, bytesToRead);
in timp ce (Sârmă.disponibil()) {
char date = Sârmă.citit();
Serial.imprimare(date);
}
întârziere(500);
}
golbuclă(){
receiveData();
}
The Wire.onReceive() funcția este utilizată pentru a specifica ce trebuie făcut atunci când slave primește date de la dispozitivul master. În codul de mai sus, Wire.available() funcția verifică dacă datele sunt disponibile și Wire.read() funcția citește datele trimise de dispozitivul principal.
Codul dispozitivului slave:
#include
golînființat(){
Sârmă.ÎNCEPE(8); // se alătură magistralei I2C cu adresa 8
Sârmă.onReceive(receiveEvent); // apelează receiveEvent când se primesc date
}
golbuclă(){
întârziere(100);
}
golreceiveEvent(int octeți){
Sârmă.scrie("Buna ziua "); // răspunde cu un mesaj de 6 octeți așa cum se aștepta de către master
}
Trimiterea și primirea datelor utilizând I2C
În acest exemplu, să citim temperatura de la un senzor de temperatură DHT11 interfațat cu Arduino slave și să o imprimăm pe monitorul serial al Arduino principal.
Să modificăm codul pe care l-am scris mai devreme pentru a include măsurarea temperaturii pe care o vom trimite apoi către placa principală prin magistrala I2C. Placa principală poate citi apoi valoarea pe care am trimis-o, apoi o poate afișa pe monitorul serial.
Codul dispozitivului principal:
#include
golînființat(){
Sârmă.ÎNCEPE();
Serial.ÎNCEPE(9600);
Serial.println("Maestru inițializat!");
}
golbuclă(){
Sârmă.o cerere de la(8, 1); // Solicită date de temperatură de la slave
dacă (Sârmă.disponibil()) {
octet temperatura = Sârmă.citit(); // Citiți datele de temperatură de la slave
Serial.imprimare("Temperatura: ");
Serial.imprimare(temperatura);
Serial.println(„°C”);
}
întârziere(2000); // Așteptați 2 secunde înainte de a solicita din nou temperatura
}
Codul dispozitivului slave:
#include
#include#defini DHTPIN 4 // Pin conectat la senzorul DHT
#defini DHTTYPE DHT11 // Tipul senzorului DHT
DHT dht(DHTPIN, DHTTYPE);
octet temperatura;golînființat(){
Sârmă.ÎNCEPE(8); // Adresa slavei este 8
Sârmă.la cerere(cerereEvent);
dht.ÎNCEPE();
}golbuclă(){
întârziere(2000); // Așteptați 2 secunde pentru ca DHT să se stabilizeze
temperatura = dht.citesteTemperatura(); // Citiți temperatura de la senzorul DHT
}
golrequestEvent(){
Sârmă.scrie(temperatura); // Trimite datele de temperatură către master
}
Puteți personaliza acest cod pentru a se potrivi oricăror senzori pe care îi aveți în proiectul dvs. sau chiar puteți afișa valorile senzorului pe un modul de afișare pentru fă-ți propriul termometru de cameră și umiditate.
Adresare slave cu I2C pe Arduino
Pentru a citi valorile componentelor adăugate la o magistrală I2C într-un astfel de proiect, este important să includeți adresa slave corectă la codificare. Din fericire, Arduino oferă o bibliotecă de scanare care simplifică procesul de identificare a slave adrese, eliminând necesitatea de a verifica fișele de date lungi ale senzorilor și confuzia online documentație.
Utilizați următorul cod pentru a identifica adresa oricărui dispozitiv slave prezentă pe magistrala I2C.
#include
// Includeți biblioteca Wire pentru comunicarea I2C golînființat(){
Sârmă.ÎNCEPE(); // Inițializați comunicarea I2C
Serial.ÎNCEPE(9600); // Inițializați comunicația serială cu o viteză de transmisie de 9600
in timp ce (!Serial); // Așteptați stabilirea conexiunii seriale
Serial.println(„\nScaner I2C”); // Imprimă un mesaj care indică începutul scanării I2C
}golbuclă(){
octet eroare, adresa; // Declara variabile pentru a stoca erori și adrese de dispozitiv
int nDispozitive; // Declara o variabilă pentru a stoca numărul de dispozitive găsiteSerial.println("Scanare..."); // Imprimă un mesaj care indică începutul scanării I2C
nDispozitive = 0; // Setați numărul de dispozitive găsite la 0
pentru (adresa = 1; adresa < 127; adresa++) { // Iterează peste toate adresele I2C posibile
Sârmă.începeTransmisie(abordare); // Începe o transmisie la adresa curentă
eroare = Sârmă.finalTransmisie(); // Încheiați transmisia și stocați orice eroridacă (eroare == 0) { // Dacă nu au fost găsite erori
Serial.imprimare(„Dispozitiv I2C găsit la adresa 0x”); // Imprimă un mesaj care indică faptul că a fost găsit un dispozitiv
dacă (adresa < 16) Serial.imprimare("0"); // Dacă adresa este mai mică de 16, adăugați un 0 inițial pentru formatare
Serial.imprimare(adresă, HEX); // Tipăriți adresa în format hexazecimal
Serial.println(" !"); // Imprimă un mesaj care indică faptul că a fost găsit un dispozitiv
nDispozitive++; // Creșteți numărul de dispozitive găsite
}
altfeldacă (eroare == 4) { // Dacă a fost găsită o eroare
Serial.imprimare(„Eroare necunoscută la adresa 0x”); // Imprimați un mesaj care indică o eroare
dacă (adresa < 16) Serial.imprimare("0"); // Dacă adresa este mai mică de 16, adăugați un 0 inițial pentru formatare
Serial.println(adresă, HEX); // Tipăriți adresa în format hexazecimal
}
}
dacă (nDispozitive == 0) { // Dacă nu au fost găsite dispozitive
Serial.println(„Nu s-au găsit dispozitive I2C\n”); // Imprimă un mesaj care indică că nu au fost găsite dispozitive
}
altfel { // Dacă au fost găsite dispozitive
Serial.println("terminat\n"); // Imprimă un mesaj care indică sfârșitul scanării I2C
}
întârziere(5000); // Întârzie cu 5 secunde înainte de a începe următoarea scanare
}
Extindeți-vă proiectul astăzi
Interfața a două plăci Arduino folosind protocolul de comunicare I2C oferă o modalitate flexibilă și eficientă de a realiza sarcini complexe care nu pot fi gestionate de o singură placă. Cu ajutorul bibliotecii Wire, comunicarea între cele două plăci folosind I2C este ușoară, permițându-vă să adăugați mai multe componente la proiectul dumneavoastră.