A népszerű I2C protokoll lehetővé teszi két vagy több Arduino kártya kommunikációját. Fedezze fel, hogyan kapcsolhatja össze és kódolhatja őket.
Míg egyetlen Arduino sok feladatot el tud végezni, egyes projektek egynél több táblát igényelhetnek a különböző funkciók kezeléséhez. Tehát a két mikrokontroller közötti adatátvitel lehetővé tételéhez be kell állítani egy kommunikációs protokollt, például CAN, SPI, I2C vagy UART.
Ebben az útmutatóban bemutatjuk az I2C működésének alapjait, a hardverkapcsolatokat és a két Arduino kártya I2C master és slave eszközként történő beállításához szükséges szoftvermegvalósítást.
Mi az I2C?
Az Inter-Integrated Circuit (I2C) a beágyazott rendszerekben és mikrokontrollerekben széles körben használt kommunikációs protokoll, amely lehetővé teszi az elektronikus eszközök közötti adatátvitelt. Az SPI-vel (Serial Peripheral Interface) ellentétben az I2C lehetővé teszi egynél több master eszköz csatlakoztatását egy vagy több slave eszközzel rendelkező buszhoz. Először a Philips használta, és két vezetékes interfész (TWI) kommunikációs protokollként is ismert.
Hogyan működik az I2C kommunikáció?
Az I2C két kétirányú vonalat használ: a soros adatot (SDA) és a soros órát (SCL) az adatok átvitelére és az eszközök közötti kommunikáció szinkronizálására. Minden, az I2C buszra csatlakoztatott eszköz egyedi címmel rendelkezik, amely azonosítja azt a kommunikáció során. Az I2C protokoll lehetővé teszi több eszköz megosztását ugyanazon a buszon, és mindegyik eszköz mesterként vagy slaveként működhet.
A kommunikációt a master eszköz kezdeményezi, és a slave eszközök helytelen címzése átviteli hibákat okozhat. Tekintse meg részletes útmutatónkat a hogyan működik az UART, SPI és I2C soros kommunikáció hogy némi kontextust adjak.
Az I2C kommunikáció egyik fő előnye, amelyet érdemes megjegyezni, a rugalmasság, amelyet az energiagazdálkodás terén kínál. A különböző feszültségszinteken működő eszközök továbbra is hatékonyan tudnak kommunikálni a feszültségváltók segítségével. Ez azt jelenti, hogy a 3,3 V-on működő eszközöknek feszültségváltókra van szükségük az 5 V-os I2C buszhoz való csatlakozáshoz.
A Wire Library
A Wire könyvtár egy beépített Arduino könyvtár, amely funkciókat biztosít az I2C-n keresztüli kommunikációhoz. Két érintkezőt – SDA-t és SCL-t – használ az Arduino kártyán az I2C kommunikációhoz.
I2C érintkezők az Arduino Uno-n:
Arduino Nano I2C tűk:
A könyvtár használatához tartalmaznia kell a Vezeték.h fejlécfájlt az Arduino vázlat elején.
#tartalmazza
A Wire könyvtár funkciókat biztosít az I2C eszközzel való kommunikáció kezdeményezéséhez, adatok küldéséhez és fogadásához. Néhány fontos funkció, amelyeket tudnia kell:
- Wire.begin(): az I2C buszhoz való csatlakozásra és a kommunikáció kezdeményezésére szolgál.
- Wire.beginTransmission(): a slave cím megadására és az átvitel megkezdésére szolgál.
- Wire.write(): adatok küldésére szolgál az I2C eszközre.
- Wire.endTransmission(): az átvitel befejezésére és a hibák ellenőrzésére szolgál.
- Wire.requestFrom(): adatok kérésére szolgál az I2C eszközről.
- Wire.available(): annak ellenőrzésére szolgál, hogy rendelkezésre állnak-e adatok az I2C eszközről olvasásra.
- Wire.read(): adatok olvasására szolgál az I2C eszközről.
Használja a Wire.beginTransmission() függvény az érzékelő címének beállításához, amely argumentumként kerül beszúrásra. Például, ha az érzékelő címe 0x68, a következőket használnád:
Huzal.startTransmission(0x68);
Arduino I2C hardverbeállítás
Két Arduino kártya I2C segítségével történő csatlakoztatásához a következő hardverkomponensekre lesz szüksége:
- Két Arduino tábla (master és slave)
- Kenyértábla
- Jumper vezetékek
- Két 4,7kΩ-os felhúzó ellenállás
Csatlakoztassa a SDA és SCL mindkét Arduino tábla csapjait egy kenyérvágódeszkához. Csatlakoztassa a felhúzó ellenállásokat a SDA és SCL csapok és a 5V tápsín a kenyérsütőtáblán. Végül csatlakoztassa a két kenyérsütőtáblát áthidaló vezetékekkel.
Arduino Uno áramkör
Arduino nano áramkör
Az Arduino táblák beállítása I2C Master és Slave eszközként
Használja a Wire.requestFrom() függvény segítségével megadhatjuk annak a slave eszköznek a címét, amellyel kommunikálni szeretnénk. Ezután használja a Wire.read() funkciót az adatok lekéréséhez a slave eszközről.
Mester készülék kódja:
#tartalmazza
üresbeállít(){
Huzal.kezdődik(); // csatlakozás az i2c buszhoz
Sorozatszám.kezdődik(9600); // sorozat indítása a kimenethez
}
üresData Data(){
int cím = 8;
int bytesToRead = 6;
Huzal.kérésFel(cím, bytesToRead);
míg (Huzal.elérhető()) {
char adatok = Huzal.olvas();
Sorozatszám.nyomtatás(adat);
}
késleltetés(500);
}
üreshurok(){
ReceiveData();
}
A Wire.onReceive() A funkció megadja, hogy mit kell tenni, ha a slave adatokat kap a mester eszköztől. A fenti kódban a Wire.available() funkció ellenőrzi, hogy rendelkezésre állnak-e adatok, és a Wire.read() funkció beolvassa a mester eszköz által küldött adatokat.
Slave eszköz kódja:
#tartalmazza
üresbeállít(){
Huzal.kezdődik(8); // csatlakozzon az I2C buszhoz a 8-as címmel
Huzal.onReceive(receiveEvent); // a ReceiveEvent hívása adatfogadáskor
}
üreshurok(){
késleltetés(100);
}
üresgetEvent(int bájt){
Huzal.ír("Helló "); // 6 bájtos üzenettel válaszol, ahogy azt a mester elvárja
}
Adatok küldése és fogadása I2C használatával
Ebben a példában olvassuk le a hőmérsékletet egy DHT11 hőmérséklet-érzékelőről, amely a slave Arduino-hoz kapcsolódik, és nyomtassa ki a fő Arduino soros monitorán.
Módosítsuk a korábban írt kódot, hogy tartalmazza a hőmérséklet mérést, amelyet aztán az I2C buszon keresztül elküldünk a főkártyára. A főkártya ezután beolvassa az általunk küldött értéket, majd megjeleníti a soros monitoron.
Mester készülék kódja:
#tartalmazza
üresbeállít(){
Huzal.kezdődik();
Sorozatszám.kezdődik(9600);
Sorozatszám.println("A mester inicializálva!");
}
üreshurok(){
Huzal.kérésFel(8, 1); // Hőmérsékletadatok kérése a slave-től
ha (Huzal.elérhető()) {
byte hőmérséklet = Huzal.olvas(); // Hőmérsékletadatok olvasása a slave-től
Sorozatszám.nyomtatás("Hőfok: ");
Sorozatszám.nyomtatás(hőfok);
Sorozatszám.println("° C");
}
késleltetés(2000); // Várjon 2 másodpercet, mielőtt ismét lekérné a hőmérsékletet
}
Slave eszköz kódja:
#tartalmazza
#tartalmazza#meghatározni DHTPIN 4 // DHT-érzékelőhöz csatlakoztatott tű
#meghatározni DHTTYPE DHT11 // DHT-érzékelő típusa
DHT dht(DHTPIN, DHTTYPE);
byte hőfok;üresbeállít(){
Huzal.kezdődik(8); // A slave címe 8
Huzal.kérésre(requestEvent);
dht.kezdődik();
}üreshurok(){
késleltetés(2000); // Várjon 2 másodpercet, amíg a DHT stabilizálódik
hőmérséklet = dht.Hőmérséklet olvasása(); // Hőmérséklet leolvasása a DHT-érzékelőről
}
üresrequestEvent(){
Huzal.ír(hőfok); // Hőmérsékletadatok küldése a mesternek
}
Testreszabhatja ezt a kódot, hogy megfeleljen a projektben esetleg használt érzékelőknek, vagy akár megjelenítheti az érzékelő értékeket egy kijelzőmodulon készítsen saját szobahőmérőt és páratartalommérőt.
Slave címzés I2C-vel Arduino-n
Ha egy ilyen projektben egy I2C buszhoz hozzáadott összetevőkből szeretne értékeket olvasni, fontos, hogy kódoláskor a megfelelő slave címet adja meg. Szerencsére az Arduino olyan szkenner könyvtárat kínál, amely leegyszerűsíti a szolga azonosításának folyamatát címeket, kiküszöböli a hosszadalmas szenzor adatlapok átvizsgálását és a zavaró online folyamatot dokumentáció.
Használja a következő kódot az I2C buszon található szolga eszközök címének azonosítására.
#tartalmazza
// Tartalmazza a Wire könyvtárat az I2C kommunikációhoz üresbeállít(){
Huzal.kezdődik(); // Inicializálja az I2C kommunikációt
Sorozatszám.kezdődik(9600); // A soros kommunikáció inicializálása 9600-as adatátviteli sebességgel
míg (!Sorozatszám); // Várja meg, amíg a soros kapcsolat létrejön
Sorozatszám.println("\nI2C szkenner"); // Nyomtasson egy üzenetet, amely jelzi az I2C szkennelés megkezdését
}üreshurok(){
byte hiba, cím; // Változók deklarálása a hibák és az eszközcímek tárolására
int nDevices; // Változó deklarálása a talált eszközök számának tárolásáraSorozatszám.println("Szkennelés..."); // Nyomtasson egy üzenetet, amely jelzi az I2C szkennelés megkezdését
nEszközök = 0; // Állítsa be a talált eszközök számát 0-ra
számára (cím = 1; cím < 127; cím++) { // Iteráció az összes lehetséges I2C címen
Huzal.startTransmission(cím); // Küldés indítása az aktuális címre
hiba = Huzal.end Transmission(); // Az átvitel befejezése és az esetleges hibák tárolásaha (hiba == 0) { // Ha nem találtunk hibát
Sorozatszám.nyomtatás("I2C eszköz található a 0x címen"); // Nyomtasson egy üzenetet, amely jelzi, hogy egy eszközt találtak
ha (cím < 16) Sorozatszám.nyomtatás("0"); // Ha a cím 16-nál kisebb, formázási célból adjon hozzá egy kezdő 0-t
Sorozatszám.nyomtatás(cím, HEX); // Nyomtassa ki a címet hexadecimális formátumban
Sorozatszám.println(" !"); // Nyomtasson egy üzenetet, amely jelzi, hogy egy eszközt találtak
nDevices++; // Növelje a talált eszközök számát
}
másha (hiba == 4) { // Ha hibát találtak
Sorozatszám.nyomtatás("Ismeretlen hiba a 0x címen"); // Nyomtasson ki egy üzenetet, amely jelzi, hogy hibát talált
ha (cím < 16) Sorozatszám.nyomtatás("0"); // Ha a cím 16-nál kisebb, formázási célból adjon hozzá egy kezdő 0-t
Sorozatszám.println(cím, HEX); // Nyomtassa ki a címet hexadecimális formátumban
}
}
ha (nEszközök == 0) { // Ha nem található eszközök
Sorozatszám.println("Nem található I2C eszköz\n"); // Nyomtasson egy üzenetet, amely jelzi, hogy nem található eszközök
}
más { // Ha eszközöket találtak
Sorozatszám.println("kész\n"); // Nyomtasson egy üzenetet, amely jelzi az I2C szkennelés végét
}
késleltetés(5000); // Késleltessen 5 másodpercet a következő vizsgálat megkezdése előtt
}
Bővítse projektjét még ma
Két Arduino kártya összekapcsolása az I2C kommunikációs protokoll segítségével rugalmas és hatékony módot kínál olyan összetett feladatok elvégzésére, amelyeket egyetlen kártya nem képes kezelni. A Wire könyvtár segítségével egyszerűbbé válik a kommunikáció a két tábla között az I2C használatával, lehetővé téve további komponensek hozzáadását a projekthez.