Popularni I2C protokol omogućuje komunikaciju dviju ili više Arduino ploča. Otkrijte kako ih povezati i kodirati.

Iako jedan Arduino može izvršiti mnoge zadatke, neki projekti mogu zahtijevati korištenje više od jedne ploče za rukovanje različitim funkcionalnostima. Dakle, da bi se omogućio prijenos podataka između dva mikrokontrolera, mora se postaviti komunikacijski protokol kao što je CAN, SPI, I2C ili UART.

U ovom ćemo vodiču pokriti osnove rada I2C-a, hardverske veze i softversku implementaciju potrebnu za postavljanje dviju Arduino ploča kao I2C master i slave uređaja.

Što je I2C?

Inter-Integrated Circuit (I2C) široko je korišten komunikacijski protokol u ugrađenim sustavima i mikrokontrolerima za omogućavanje prijenosa podataka između elektroničkih uređaja. Za razliku od SPI (Serial Peripheral Interface), I2C vam omogućuje povezivanje više od jednog glavnog uređaja na sabirnicu s jednim ili više podređenih uređaja. Prvi ga je upotrijebio Philips, a poznat je i kao komunikacijski protokol Two Wire Interface (TWI).

instagram viewer

Kako funkcionira I2C komunikacija?

I2C koristi dvije dvosmjerne linije: Serial Data (SDA) i Serial Clock (SCL) za prijenos podataka i sinkronizaciju komunikacije između uređaja. Svaki uređaj spojen na I2C sabirnicu ima jedinstvenu adresu koja ga identificira tijekom komunikacije. Protokol I2C omogućuje da više uređaja dijeli istu sabirnicu, a svaki uređaj može djelovati kao glavni ili podređeni.

Komunikaciju inicira master uređaj, a pogrešno adresiranje slave uređaja može uzrokovati pogreške u prijenosu. Pogledajte naš detaljni vodič o kako funkcioniraju serijske komunikacije UART, SPI i I2C da vam dam neki kontekst.

Glavna prednost I2C komunikacije vrijedna pažnje je fleksibilnost koju nudi kada je u pitanju upravljanje napajanjem. Uređaji koji rade na različitim razinama napona još uvijek mogu učinkovito komunicirati uz pomoć mjenjača napona. To znači da uređaji koji rade na 3,3 V trebaju mjenjače napona za spajanje na 5 V I2C sabirnicu.

Žičana knjižnica

Wire biblioteka je ugrađena Arduino biblioteka koja pruža funkcije za komunikaciju preko I2C. Koristi dva pina—SDA i SCL—na Arduino ploči za I2C komunikaciju.

I2C pinovi na Arduino Uno:

Arduino Nano I2C pinovi:

Da biste koristili biblioteku, morate uključiti Žica.h datoteku zaglavlja na početku vaše Arduino skice.

#uključiti

Biblioteka Wire pruža funkcije za pokretanje komunikacije s I2C uređajem, slanje podataka i primanje podataka. Neke važne funkcije koje biste trebali znati uključuju:

  • Wire.begin(): koristi se za pridruživanje I2C sabirnici i pokretanje komunikacije.
  • Wire.beginTransmission(): koristi se za određivanje slave adrese i početak prijenosa.
  • Wire.write(): koristi se za slanje podataka na I2C uređaj.
  • Wire.endTransmission(): koristi se za završetak prijenosa i provjeru grešaka.
  • Wire.requestFrom(): koristi se za traženje podataka od I2C uređaja.
  • Wire.available(): koristi se za provjeru jesu li podaci dostupni za čitanje s I2C uređaja.
  • Wire.read(): koristi se za čitanje podataka s I2C uređaja.

Koristiti Wire.beginTransmission() funkcija za postavljanje adrese senzora, koja je umetnuta kao argument. Na primjer, ako je adresa senzora 0x68, koristili biste:

Žica.započeti prijenos(0x68);

Postavljanje hardvera Arduino I2C

Za spajanje dvije Arduino ploče pomoću I2C, trebat će vam sljedeće hardverske komponente:

  • Dvije Arduino ploče (master i slave)
  • Breadboard
  • Premosne žice
  • Dva pull-up otpornika od 4,7 kΩ

Spojite SDA i SCL pinovi obje Arduino ploče na matičnu ploču. Spojite pull-up otpornike između SDA i SCL igle i 5V strujna tračnica na matičnoj ploči. Na kraju, spojite dvije matične ploče pomoću premosnih žica.

Arduino Uno sklop

Arduino Nano krug

Kredit za sliku: Arduino I2C dokumentacija

Postavljanje Arduino ploča kao I2C master i slave uređaja

Koristiti Wire.requestFrom() funkciju za određivanje adrese podređenog uređaja s kojim želimo komunicirati. Zatim upotrijebite Wire.read() funkcija za dobivanje podataka s podređenog uređaja.

Glavni kod uređaja:

#uključiti
poništitipostaviti(){
Žica.početi(); // pridruži se i2c sabirnici
Serijski.početi(9600); // pokreni serijski za izlaz
}
poništitiprimanje podataka(){
int adresa = 8;
int bytesToRead = 6;
Žica.zahtjevOd(adresa, bytesToRead);
dok (Žica.dostupno()) {
char podaci = Žica.čitati();
Serijski.ispisati(podaci);
}
odgoditi(500);
}
poništitipetlja(){
primi podatke();
}

The Wire.onReceive() funkcija se koristi za određivanje što učiniti kada podređeni uređaj primi podatke od glavnog uređaja. U gornjem kodu, Wire.available() funkcija provjerava jesu li podaci dostupni i Wire.read() funkcija čita podatke koje šalje glavni uređaj.

Šifra podređenog uređaja:

#uključiti
poništitipostaviti(){
Žica.početi(8); // pridružite se I2C sabirnici s adresom 8
Žica.onReceive(primiDogađaj); // poziv receiveEvent kada su podaci primljeni
}
poništitipetlja(){
odgoditi(100);
}
poništitireceiveEvent(int bajtova){
Žica.pisati("zdravo "); // odgovara porukom od 6 bajtova kako očekuje glavni
}

Slanje i primanje podataka korištenjem I2C

U ovom primjeru, očitajmo temperaturu s temperaturnog senzora DHT11 povezanog s podređenim Arduinom i ispišite je na serijskom monitoru glavnog Arduina.

Modificirajmo kod koji smo ranije napisali da uključi mjerenje temperature koje ćemo zatim poslati glavnoj ploči preko I2C sabirnice. Glavna ploča tada može pročitati vrijednost koju smo poslali, a zatim je prikazati na serijskom monitoru.

Glavni kod uređaja:

#uključiti
poništitipostaviti(){
Žica.početi();
Serijski.početi(9600);
Serijski.println("Master inicijaliziran!");
}
poništitipetlja(){
Žica.zahtjevOd(8, 1); // Zahtijeva podatke o temperaturi od slave
ako (Žica.dostupno()) {
bajt temperatura = Žica.čitati(); // Čitanje podataka o temperaturi od slave
Serijski.ispisati("Temperatura: ");
Serijski.ispisati(temperatura);
Serijski.println("°C");
}
odgoditi(2000); // Pričekajte 2 sekunde prije ponovnog traženja temperature
}

Šifra podređenog uređaja:

#uključiti
#uključiti

#definirati DHTPIN 4 // Pin spojen na DHT senzor
#definirati DHTTYPE DHT11 // Vrsta DHT senzora
DHT dht(DHTPIN, DHTTYPE);
bajt temperatura;

poništitipostaviti(){
Žica.početi(8); // Slave adresa je 8
Žica.na zahtjev(requestEvent);
dht.početi();
}

poništitipetlja(){
odgoditi(2000); // Pričekajte 2 sekunde da se DHT stabilizira
temperatura = dht.čitajTemperatura(); // Očitavanje temperature s DHT senzora
}

poništitirequestEvent(){
Žica.pisati(temperatura); // Slanje podataka o temperaturi masteru
}

Možete prilagoditi ovaj kod kako bi odgovarao senzorima koje imate u svom projektu ili čak prikazati vrijednosti senzora na modulu zaslona za napravite vlastiti sobni termometar i vlagomjer.

Slave adresiranje s I2C na Arduinu

Za čitanje vrijednosti iz komponenti dodanih na I2C sabirnicu u takvom projektu, važno je da uključite ispravnu slave adresu prilikom kodiranja. Srećom, Arduino nudi biblioteku skenera koja pojednostavljuje proces identifikacije slave adresama, čime se eliminira potreba za prebiranjem po podužim podatkovnim listovima senzora i zbunjujućim internetom dokumentacija.

Upotrijebite sljedeći kod za identifikaciju bilo koje adrese podređenog uređaja prisutnog na I2C sabirnici.

#uključiti // Uključite biblioteku Wire za I2C komunikaciju

poništitipostaviti(){
Žica.početi(); // Inicijalizirati I2C komunikaciju
Serijski.početi(9600); // Inicijalizirajte serijsku komunikaciju s brzinom prijenosa podataka od 9600
dok (!Serijski); // Pričekajte da se uspostavi serijska veza
Serijski.println("\nI2C skener"); // Ispis poruke koja označava početak I2C skeniranja
}

poništitipetlja(){
bajt greška, adresa; // Deklarirajte varijable za pohranu pogrešaka i adresa uređaja
int nUređaji; // Deklarirajte varijablu za pohranjivanje broja pronađenih uređaja

Serijski.println("Skeniranje..."); // Ispis poruke koja označava početak I2C skeniranja

nUređaji = 0; // Postavite broj pronađenih uređaja na 0
za (adresa = 1; adresa < 127; adresa++) { // Iteracija preko svih mogućih I2C adresa
Žica.započeti prijenos(adresa); // Započni prijenos na trenutnu adresu
pogreška = Žica.endTransmission(); // Završi prijenos i pohrani sve pogreške

ako (greška == 0) { // Ako nisu pronađene greške
Serijski.ispisati("I2C uređaj pronađen na adresi 0x"); // Ispis poruke koja pokazuje da je uređaj pronađen
ako (adresa < 16) Serijski.ispisati("0"); // Ako je adresa manja od 16, dodajte početnu 0 za potrebe oblikovanja
Serijski.ispisati(adresa, HEX); // Ispis adrese u heksadecimalnom formatu
Serijski.println(" !"); // Ispis poruke koja pokazuje da je uređaj pronađen

nDevices++; // Povećaj broj pronađenih uređaja
}
drugoako (greška == 4) { // Ako je pronađena greška
Serijski.ispisati("Nepoznata pogreška na adresi 0x"); // Ispis poruke koja pokazuje da je pronađena pogreška
ako (adresa < 16) Serijski.ispisati("0"); // Ako je adresa manja od 16, dodajte početnu 0 za potrebe oblikovanja
Serijski.println(adresa, HEX); // Ispis adrese u heksadecimalnom formatu
}
}
ako (nUređaji == 0) { // Ako uređaji nisu pronađeni
Serijski.println("Nije pronađen nijedan I2C uređaj\n"); // Ispis poruke koja pokazuje da uređaji nisu pronađeni
}
drugo { // Ako su uređaji pronađeni
Serijski.println("gotovo\n"); // Ispis poruke koja označava kraj I2C skeniranja
}
odgoditi(5000); // Odgodi 5 sekundi prije početka sljedećeg skeniranja
}

Proširite svoj projekt danas

Povezivanje dviju Arduino ploča korištenjem I2C komunikacijskog protokola nudi fleksibilan i učinkovit način za postizanje složenih zadataka koji se ne mogu riješiti na jednoj ploči. Uz pomoć Wire knjižnice, komunikacija između dvije ploče pomoću I2C je laka, što vam omogućuje dodavanje više komponenti vašem projektu.