Priljubljeni protokol I2C omogoča komunikacijo dveh ali več plošč Arduino. Odkrijte, kako jih povezati in kodirati.

Medtem ko lahko en sam Arduino opravi številne naloge, lahko nekateri projekti zahtevajo uporabo več kot ene plošče za obravnavanje različnih funkcij. Za omogočanje prenosa podatkov med obema mikrokontrolerjema mora biti torej nastavljen komunikacijski protokol, kot je CAN, SPI, I2C ali UART.

V tem priročniku bomo obravnavali osnove delovanja I2C, povezave strojne opreme in implementacijo programske opreme, potrebne za nastavitev dveh plošč Arduino kot glavne in podrejene naprave I2C.

Kaj je I2C?

Interintegrirano vezje (I2C) je široko uporabljen komunikacijski protokol v vgrajenih sistemih in mikrokrmilnikih za omogočanje prenosa podatkov med elektronskimi napravami. Za razliko od SPI (Serial Peripheral Interface) vam I2C omogoča povezavo več kot ene glavne naprave na vodilo z eno ali več podrejenimi napravami. Prvi ga je uporabil Philips in je znan tudi kot komunikacijski protokol Two Wire Interface (TWI).

instagram viewer

Kako deluje komunikacija I2C?

I2C uporablja dve dvosmerni liniji: serijske podatke (SDA) in serijsko uro (SCL) za prenos podatkov in sinhronizacijo komunikacije med napravami. Vsaka naprava, povezana z vodilom I2C, ima edinstven naslov, ki jo identificira med komunikacijo. Protokol I2C omogoča, da več naprav deli isto vodilo in vsaka naprava lahko deluje kot glavna ali podrejena.

Komunikacijo sproži glavna naprava, nepravilno naslavljanje pomožnih naprav pa lahko povzroči napake pri prenosu. Oglejte si naš poglobljen vodnik o kako delujejo serijske komunikacije UART, SPI in I2C da vam dam nekaj konteksta.

Glavna prednost komunikacije I2C, ki jo je vredno omeniti, je prilagodljivost, ki jo ponuja, ko gre za upravljanje porabe energije. Naprave, ki delujejo na različnih nivojih napetosti, lahko še vedno učinkovito komunicirajo s pomočjo preklopnikov napetosti. To pomeni, da naprave, ki delujejo pri 3,3 V, potrebujejo prestavne naprave za povezavo s 5 V vodilom I2C.

Žična knjižnica

Knjižnica Wire je vgrajena knjižnica Arduino, ki nudi funkcije za komunikacijo prek I2C. Za komunikacijo I2C uporablja dva zatiča – SDA in SCL – na plošči Arduino.

I2C zatiči na Arduino Uno:

Arduino Nano I2C zatiči:

Če želite uporabljati knjižnico, morate vključiti Žica.h datoteko glave na začetku vaše skice Arduino.

#vključujejo

Knjižnica Wire ponuja funkcije za začetek komunikacije z napravo I2C, pošiljanje in prejemanje podatkov. Nekatere pomembne funkcije, ki jih morate poznati, vključujejo:

  • Wire.begin(): uporablja se za pridružitev vodilu I2C in začetek komunikacije.
  • Wire.beginTransmission(): uporablja se za določitev podrejenega naslova in začetek prenosa.
  • Wire.write(): uporablja se za pošiljanje podatkov v napravo I2C.
  • Wire.endTransmission(): uporablja se za zaključek prenosa in preverjanje napak.
  • Wire.requestFrom(): uporablja se za zahtevanje podatkov iz naprave I2C.
  • Wire.available(): uporablja se za preverjanje, ali so podatki na voljo za branje iz naprave I2C.
  • Wire.read(): uporablja se za branje podatkov iz naprave I2C.

Uporabi Wire.beginTransmission() funkcijo za nastavitev naslova senzorja, ki je vstavljen kot argument. Na primer, če je naslov senzorja 0x68, bi uporabili:

Žica.začeti prenos(0x68);

Nastavitev strojne opreme Arduino I2C

Za povezavo dveh plošč Arduino z uporabo I2C boste potrebovali naslednje komponente strojne opreme:

  • Dve plošči Arduino (master in slave)
  • Breadboard
  • Premostitvene žice
  • Dva vlečna upora 4,7 kΩ

Povežite SDA in SCL zatiči obeh plošč Arduino na mizo. Povežite vlečne upore med SDA in SCL zatiči in 5V napajalna tirnica na mizi. Nazadnje povežite dve testni plošči s premostitvenimi žicami.

Arduino Uno vezje

Arduino nano vezje

Avtorstvo slike: Dokumentacija Arduino I2C

Nastavitev plošč Arduino kot glavne in podrejene naprave I2C

Uporabi Wire.requestFrom() funkcijo za določitev naslova podrejene naprave, s katero želimo komunicirati. Nato uporabite Wire.read() funkcijo za pridobivanje podatkov iz podrejene naprave.

Glavna koda naprave:

#vključujejo
prazninanastaviti(){
Žica.začeti(); // pridruži se vodilu i2c
Serijski.začeti(9600); // začni serijsko za izhod
}
prazninareceiveData(){
int naslov = 8;
int bytesToRead = 6;
Žica.requestFrom(naslov, bytesToRead);
medtem (Žica.na voljo()) {
char podatki = Žica.prebrati();
Serijski.tiskanje(podatki);
}
zamuda(500);
}
prazninazanka(){
prejemanje podatkov ();
}

The Wire.onReceive() funkcija se uporablja za določanje, kaj storiti, ko podrejena naprava prejme podatke od glavne naprave. V zgornji kodi je Wire.available() funkcija preveri, ali so podatki na voljo, in Wire.read() funkcija prebere podatke, ki jih pošlje glavna naprava.

Koda podrejene naprave:

#vključujejo
prazninanastaviti(){
Žica.začeti(8); // pridruži se vodilu I2C z naslovom 8
Žica.onReceive(receiveEvent); // pokliči receiveEvent, ko so podatki prejeti
}
prazninazanka(){
zamuda(100);
}
prazninareceiveEvent(int bajtov){
Žica.pisati("zdravo "); // odgovori s sporočilom 6 bajtov, kot pričakuje master
}

Pošiljanje in prejemanje podatkov z uporabo I2C

V tem primeru odčitajmo temperaturo s temperaturnega senzorja DHT11, povezanega s podrejenim Arduinom, in jo natisnimo na serijski monitor glavnega Arduina.

Spremenimo kodo, ki smo jo napisali prej, da bo vključevala meritev temperature, ki jo bomo nato poslali na glavno ploščo prek vodila I2C. Glavna plošča lahko nato prebere vrednost, ki smo jo poslali, in jo nato prikaže na serijskem monitorju.

Glavna koda naprave:

#vključujejo
prazninanastaviti(){
Žica.začeti();
Serijski.začeti(9600);
Serijski.println("Master inicializiran!");
}
prazninazanka(){
Žica.requestFrom(8, 1); // Zahtevaj podatke o temperaturi od podrejenega
če (Žica.na voljo()) {
bajt temperatura = Žica.prebrati(); // Branje podatkov o temperaturi iz podrejenega
Serijski.tiskanje("Temperatura:");
Serijski.tiskanje(temperatura);
Serijski.println("°C");
}
zamuda(2000); // Počakajte 2 sekundi, preden ponovno zahtevate temperaturo
}

Koda podrejene naprave:

#vključujejo
#vključujejo

#opredeliti DHTPIN 4 // Pin povezan s senzorjem DHT
#opredeliti DHTTYPE DHT11 // Vrsta senzorja DHT
DHT dht(DHTPIN, DHTTYPE);
bajt temperatura;

prazninanastaviti(){
Žica.začeti(8); // Podrejeni naslov je 8
Žica.na zahtevo(requestEvent);
dht.začeti();
}

prazninazanka(){
zamuda(2000); // Počakajte 2 sekundi, da se DHT stabilizira
temperatura = dht.readTemperature(); // Odčitajte temperaturo s tipala DHT
}

prazninarequestEvent(){
Žica.pisati(temperatura); // Pošlji podatke o temperaturi glavnemu
}

To kodo lahko prilagodite tako, da bo ustrezala senzorjem, ki jih imate v projektu, ali celo prikažete vrednosti senzorjev na prikazovalnem modulu, da naredite svoj sobni termometer in merilnik vlage.

Podrejeno naslavljanje z I2C na Arduinu

Za branje vrednosti iz komponent, dodanih vodilu I2C v takem projektu, je pomembno, da pri kodiranju vključite pravilen podrejeni naslov. Na srečo Arduino ponuja knjižnico optičnega bralnika, ki poenostavlja postopek identifikacije podrejenega naslove, s čimer se odpravi potreba po brskanju po dolgih podatkovnih listih senzorjev in zmedi na spletu dokumentacijo.

Uporabite naslednjo kodo za identifikacijo katerega koli naslova podrejene naprave, ki je prisoten na vodilu I2C.

#vključujejo // Vključite knjižnico Wire za komunikacijo I2C

prazninanastaviti(){
Žica.začeti(); // Inicializacija komunikacije I2C
Serijski.začeti(9600); // Inicializacija serijske komunikacije s hitrostjo prenosa 9600 baud
medtem (!Serijski); // Počakajte, da se vzpostavi serijska povezava
Serijski.println("\nI2C Scanner"); // Natisnite sporočilo, ki označuje začetek skeniranja I2C
}

prazninazanka(){
bajt napaka, naslov; // Deklariraj spremenljivke za shranjevanje napak in naslovov naprav
int nDevices; // Deklarirajte spremenljivko za shranjevanje števila najdenih naprav

Serijski.println("Skeniranje ..."); // Natisnite sporočilo, ki označuje začetek skeniranja I2C

nNaprave = 0; // Nastavite število najdenih naprav na 0
za (naslov = 1; naslov < 127; naslov++) { // Ponovi vse možne naslove I2C
Žica.začeti prenos(naslov); // Začetek prenosa na trenutni naslov
napaka = Žica.endTransmission(); // Končajte prenos in shranite morebitne napake

če (napaka == 0) { // Če ni bilo najdenih nobenih napak
Serijski.tiskanje("Naprava I2C najdena na naslovu 0x"); // Natisni sporočilo, ki označuje, da je bila najdena naprava
če (naslov < 16) Serijski.tiskanje("0"); // Če je naslov manjši od 16, dodajte prvo 0 za namene oblikovanja
Serijski.tiskanje(naslov, HEX); // Natisnite naslov v šestnajstiški obliki
Serijski.println(" !"); // Natisni sporočilo, ki označuje, da je bila najdena naprava

nDevices++; // Povečanje števila najdenih naprav
}
drugačeče (napaka == 4) { // Če je bila najdena napaka
Serijski.tiskanje("Neznana napaka na naslovu 0x"); // Natisni sporočilo, ki označuje, da je bila najdena napaka
če (naslov < 16) Serijski.tiskanje("0"); // Če je naslov manjši od 16, dodajte prvo 0 za namene oblikovanja
Serijski.println(naslov, HEX); // Natisnite naslov v šestnajstiški obliki
}
}
če (nNaprave == 0) { // Če ni bila najdena nobena naprava
Serijski.println("Najdena ni bila nobena naprava I2C\n"); // Natisni sporočilo, ki nakazuje, da ni bila najdena nobena naprava
}
drugače { // Če so bile najdene naprave
Serijski.println("končano\n"); // Natisnite sporočilo, ki označuje konec skeniranja I2C
}
zamuda(5000); // Zakasnitev za 5 sekund pred začetkom naslednjega skeniranja
}

Razširite svoj projekt še danes

Povezovanje dveh plošč Arduino z uporabo komunikacijskega protokola I2C ponuja prilagodljiv in učinkovit način za doseganje zapletenih nalog, ki jih ni mogoče obravnavati z eno samo ploščo. S pomočjo knjižnice Wire je komunikacija med obema ploščama, ki uporabljata I2C, preprosta, kar vam omogoča, da svojemu projektu dodate več komponent.