Populární protokol I2C umožňuje komunikaci dvou nebo více desek Arduino. Zjistěte, jak je propojit a kódovat.

Zatímco jediné Arduino může plnit mnoho úkolů, některé projekty mohou vyžadovat použití více než jedné desky pro zpracování různých funkcí. Aby byl umožněn přenos dat mezi dvěma mikrokontroléry, musí být nastaven komunikační protokol jako CAN, SPI, I2C nebo UART.

V této příručce pokryjeme základy toho, jak I2C funguje, hardwarová připojení a softwarovou implementaci potřebnou k nastavení dvou desek Arduino jako I2C master a slave zařízení.

Co je I2C?

Inter-Integrated Circuit (I2C) je široce používaný komunikační protokol ve vestavěných systémech a mikrokontrolérech, který umožňuje přenos dat mezi elektronickými zařízeními. Na rozdíl od SPI (Serial Peripheral Interface) vám I2C umožňuje připojit více než jedno hlavní zařízení ke sběrnici s jedním nebo více podřízenými zařízeními. Poprvé byl použit společností Philips a je také známý jako komunikační protokol TWI (Two Wire Interface).

instagram viewer

Jak funguje komunikace I2C?

I2C používá dvě obousměrné linky: Serial Data (SDA) a Serial Clock (SCL) pro přenos dat a synchronizaci komunikace mezi zařízeními. Každé zařízení připojené ke sběrnici I2C má jedinečnou adresu, která jej identifikuje během komunikace. Protokol I2C umožňuje více zařízením sdílet stejnou sběrnici a každé zařízení může fungovat jako master nebo slave.

Komunikace je zahájena hlavním zařízením a nesprávné adresování podřízených zařízení může způsobit chyby při přenosu. Podívejte se na našeho podrobného průvodce na jak funguje sériová komunikace UART, SPI a I2C abych vám dal nějaký kontext.

Hlavní výhodou I2C komunikace, která stojí za zmínku, je flexibilita, kterou nabízí, pokud jde o správu napájení. Zařízení, která pracují na různých úrovních napětí, mohou stále efektivně komunikovat pomocí měničů napětí. To znamená, že zařízení pracující při 3,3 V potřebují pro připojení k 5V I2C sběrnici měniče napětí.

The Wire Library

Knihovna Wire je vestavěná knihovna Arduino, která poskytuje funkce pro komunikaci přes I2C. Pro komunikaci I2C používá dva piny – SDA a SCL – na desce Arduino.

I2C piny na Arduino Uno:

Piny Arduino Nano I2C:

Chcete-li používat knihovnu, musíte zahrnout Wire.h hlavičkový soubor na začátku vaší Arduino skici.

#zahrnout

Knihovna Wire poskytuje funkce pro zahájení komunikace se zařízením I2C, odesílání dat a přijímání dat. Některé důležité funkce, které byste měli znát, zahrnují:

  • Wire.begin(): používá se pro připojení ke sběrnici I2C a zahájení komunikace.
  • Wire.beginTransmission(): používá se k zadání adresy podřízeného zařízení a zahájení přenosu.
  • Wire.write(): používá se k odesílání dat do zařízení I2C.
  • Wire.endTransmission(): slouží k ukončení přenosu a kontrole chyb.
  • Wire.requestFrom(): používá se k vyžádání dat ze zařízení I2C.
  • Wire.available(): používá se ke kontrole, zda jsou k dispozici data ke čtení ze zařízení I2C.
  • Wire.read(): používá se ke čtení dat ze zařízení I2C.

Použijte Wire.beginTransmission() funkce pro nastavení adresy senzoru, která se vloží jako argument. Například pokud je adresa senzoru 0x68, použili byste:

Drát.začítPřenos(0x68);

Nastavení hardwaru Arduino I2C

Pro připojení dvou desek Arduino pomocí I2C budete potřebovat následující hardwarové komponenty:

  • Dvě desky Arduino (master a slave)
  • Breadboard
  • Startovací dráty
  • Dva 4,7kΩ pull-up odpory

Připojte SDA a SCL kolíky obou desek Arduino na prkénko. Připojte pull-up odpory mezi SDA a SCL špendlíky a 5V napájecí lišta na prkénku. Nakonec spojte dvě prkénka dohromady pomocí propojovacích vodičů.

Obvod Arduino Uno

Nano obvod Arduino

Kredit obrázku: Dokumentace Arduino I2C

Nastavení desek Arduino jako I2C Master a Slave zařízení

Použijte Wire.requestFrom() funkce pro zadání adresy podřízeného zařízení, se kterým chceme komunikovat. Poté použijte Wire.read() funkce pro získání dat z podřízeného zařízení.

Hlavní kód zařízení:

#zahrnout
prázdnotazaložit(){
Drát.začít(); // připojit se k i2c sběrnici
Seriál.začít(9600); // spuštění sériového výstupu pro výstup
}
prázdnotapřijímatData(){
int adresa = 8;
int bytesToRead = 6;
Drát.žádostOd(adresa, bytesToRead);
zatímco (Drát.dostupný()) {
char údaje = Drát.číst();
Seriál.tisk(data);
}
zpoždění(500);
}
prázdnotasmyčka(){
přijmoutData();
}

The Wire.onReceive() Funkce se používá k určení, co se má dělat, když slave přijme data z hlavního zařízení. Ve výše uvedeném kódu je Wire.available() funkce zkontroluje, zda jsou k dispozici data, a Wire.read() funkce čte data odeslaná hlavním zařízením.

Kód slave zařízení:

#zahrnout
prázdnotazaložit(){
Drát.začít(8); // připojte se ke sběrnici I2C s adresou 8
Drát.onReceive(receiveEvent); // volání přijímané události při příjmu dat
}
prázdnotasmyčka(){
zpoždění(100);
}
prázdnotapřijmoutUdálost(int bajtů){
Drát.napsat("Ahoj "); // odpoví zprávou o délce 6 bajtů, jak očekává master
}

Odesílání a příjem dat pomocí I2C

V tomto příkladu odečteme teplotu z teplotního senzoru DHT11 propojeného s podřízeným Arduinem a vytiskneme ji na sériovém monitoru hlavního Arduina.

Upravme kód, který jsme napsali dříve, aby zahrnoval měření teploty, které pak odešleme na hlavní desku přes sběrnici I2C. Hlavní deska pak může přečíst hodnotu, kterou jsme odeslali, a poté ji zobrazit na sériovém monitoru.

Hlavní kód zařízení:

#zahrnout
prázdnotazaložit(){
Drát.začít();
Seriál.začít(9600);
Seriál.println("Hlavní inicializováno!");
}
prázdnotasmyčka(){
Drát.žádostOd(8, 1); // Vyžádání údajů o teplotě od slave
-li (Drát.dostupný()) {
byte teplota = Drát.číst(); // Načtení údajů o teplotě z podřízeného zařízení
Seriál.tisk("Teplota:");
Seriál.tisk(teplota);
Seriál.println("°C");
}
zpoždění(2000); // Počkejte 2 sekundy, než znovu požádáte o teplotu
}

Kód slave zařízení:

#zahrnout
#zahrnout

#definovat DHTPIN 4 // Pin připojený k senzoru DHT
#definovat DHTTYPE DHT11 // Typ snímače DHT
DHT dht(DHTPIN, DHTTYPE);
byte teplota;

prázdnotazaložit(){
Drát.začít(8); // Adresa slave je 8
Drát.NA ZNAMENÍ(requestEvent);
dht.začít();
}

prázdnotasmyčka(){
zpoždění(2000); // Počkejte 2 sekundy, než se DHT stabilizuje
teplota = dht.readTeplota(); // Čtení teploty ze senzoru DHT
}

prázdnotarequestEvent(){
Drát.napsat(teplota); // Odeslání údajů o teplotě na master
}

Tento kód můžete přizpůsobit tak, aby vyhovoval jakýmkoli senzorům, které můžete mít ve svém projektu, nebo dokonce zobrazit hodnoty senzorů na zobrazovacím modulu, abyste vyrobit si vlastní pokojový teploměr a vlhkoměr.

Slave Addressing s I2C na Arduinu

Chcete-li číst hodnoty z komponent přidaných do sběrnice I2C v takovém projektu, je důležité, abyste při kódování zahrnuli správnou adresu slave. Naštěstí Arduino nabízí knihovnu skenerů, která zjednodušuje proces identifikace slave adresy, což eliminuje potřebu probírat zdlouhavé datové listy snímačů a matoucí online dokumentace.

Pomocí následujícího kódu identifikujte adresu libovolného podřízeného zařízení na sběrnici I2C.

#zahrnout // Zahrnout knihovnu Wire pro komunikaci I2C

prázdnotazaložit(){
Drát.začít(); // Inicializuje komunikaci I2C
Seriál.začít(9600); // Inicializuje sériovou komunikaci s přenosovou rychlostí 9600
zatímco (!Seriál); // Počkejte na navázání sériového připojení
Seriál.println("\nI2C skener"); // Vytiskne zprávu o zahájení skenování I2C
}

prázdnotasmyčka(){
byte chyba, adresa; // Deklaruje proměnné pro ukládání chyb a adres zařízení
int nDevices; // Deklaruje proměnnou pro uložení počtu nalezených zařízení

Seriál.println("Snímání..."); // Vytiskne zprávu o zahájení skenování I2C

nZařízení = 0; // Nastaví počet nalezených zařízení na 0
pro (adresa = 1; adresa < 127; adresa++) { // Iterujte všechny možné adresy I2C
Drát.začítPřenos(adresa); // Zahájení přenosu na aktuální adresu
chyba = Drát.konecPřenos(); // Ukončete přenos a uložte všechny chyby

-li (chyba == 0) { // Pokud nebyly nalezeny žádné chyby
Seriál.tisk("Zařízení I2C nalezeno na adrese 0x"); // Vytiskne zprávu, že bylo nalezeno zařízení
-li (adresa < 16) Seriál.tisk("0"); // Pokud je adresa menší než 16, přidejte úvodní 0 pro účely formátování
Seriál.tisk(adresa, HEX); // Vytiskne adresu v hexadecimálním formátu
Seriál.println(" !"); // Vytiskne zprávu, že bylo nalezeno zařízení

nDevices++; // Zvyšte počet nalezených zařízení
}
jiný-li (chyba == 4) { // Pokud byla nalezena chyba
Seriál.tisk("Neznámá chyba na adrese 0x"); // Vytiskne zprávu oznamující, že byla nalezena chyba
-li (adresa < 16) Seriál.tisk("0"); // Pokud je adresa menší než 16, přidejte úvodní 0 pro účely formátování
Seriál.println(adresa, HEX); // Vytiskne adresu v hexadecimálním formátu
}
}
-li (nZařízení == 0) { // Pokud nebyla nalezena žádná zařízení
Seriál.println("Nebyla nalezena žádná zařízení I2C\n"); // Vytiskne zprávu, že nebyla nalezena žádná zařízení
}
jiný { // Pokud byla nalezena zařízení
Seriál.println("hotovo\n"); // Vytiskne zprávu oznamující konec skenování I2C
}
zpoždění(5000); // Zpoždění o 5 sekund před zahájením dalšího skenování
}

Rozšiřte svůj projekt ještě dnes

Propojení dvou desek Arduino pomocí komunikačního protokolu I2C nabízí flexibilní a efektivní způsob dosažení složitých úkolů, které nemůže zvládnout jediná deska. S pomocí knihovny Wire je komunikace mezi dvěma deskami pomocí I2C snadná a umožňuje vám přidat do projektu další komponenty.