Lektorált tananyag, ami a BKF Digitális és Kollaboratív Művészet (DIKOM) pályázatnak keretén belül valósult meg.
Szerző: Harsányi Réka, Társszerző: Juhász Márton András, Lektor: Fernezelyi Márton
Az I2C, vagy más néven TWI (Two Wire Interface) egy soros buszrendszer, amit a Philips fejlesztett ki, hogy mikrokontrollerekhez alacsony sebességű perifériákat két vezeték használatával lehessen illeszteni. Ilyen eszközök például a Maxim által gyártott csatornabővítők (MAX6956 I2C-t 20 párhuzamos I/O csatornává alakít), LED meghajtók, adatátalakítók (pl. digitalizálók), Microchip által gyártott soros EEPROM-ok (legnagyobb 1Mbyte-os), vagy az NXP termékei: órák, memóriák, audio és video jelfeldolgozók, szintátalakítók.
A buszon keresztül sok eszközt csatlakoztathatunk
A buszokra általánosságban az a jellemző, hogy az eszközök megosztoznak az adatvezetékeken, ezért minden eszköznek rendelkeznie kell egy címmel, ami megkülönbözteti a többi buszhoz kapcsolt egységtől. Az I2C esetén a címzés eszköztől függően kétféle lehet, 7 vagy 8 bites. Az utóbbi esetben 7 bit a tényleges címet kódolja, míg a 8. bit arról ad információt, hogy a címen írás vagy olvasás folyik. A Wire könyvtár mindkét típust támogatja. Az adatvezetékeket rendre SDA (Serial Data) és SCL (Serial Clock) neveket viselik, míg az egyiken a szinkronitást fenntartó órajel, a másikon a szekvenciális adat jelenik meg bitenként. Az Arduino mikrokontrollere fizikailag tartalmaz csatolófelületet a buszhoz, aminek kivezetései UNO – és megelőző típusok – esetében az (analóg bemenetként is használható) A4 (SDA) és A5 (SCL).
Ezen a busztípuson kétféle eszköztípus, egy mester (Master) és a címek elfogyásáig tetszőleges mennyiségű szolga (slave) eszköz kommunikálhat. A mester eszköz az, aki adott címen végrehajthat írást vagy olvasást, a szolgák pedig, akik a mester parancsait követik. A könyvtár alapbeállítása szerint a mester az Arduino, de ha könyvtár inicializálásakor címet adunk neki, akkor szolgaként is tudjuk használni – ez akkor lehet hasznunkra, ha olyan hálózatot szeretnénk építeni, amihez I2C eszközök is és több Arduino is csatlakozik (lásd 13.2. ábra). Ha képesek vagyunk a buszon a konfliktusokat kezelni, több mesteregység használata is elképzelhető.
A könyvtár függvényei:
begin()
Inicializálja az I2C kommunikációt. Ha nem adunk meg neki külön címet, automatikusan az Arduino lesz a mester, ellenkező esetben a megadott címen szolgaként fog működni.
Szintaxisa:
Wire.begin(address).
Paramétere:
address: 7 bites cím.
requestFrom()
A mester által használt parancs, hogy bájtokat kérjen valamelyik szolgaeszköztől. Az eszközök válaszait az available() vagy read() függvényekkel kezelhetjük. Az I2C eszközök közötti működésbeli különbségek áthidalására ez a függvény elfogad bemenetként bool típusú változót. Ami ha igaz (alapállapot), akkor a lekérés után STOP jelet küld, és nem kommunikál a buszon, ha hamis, akkor RESTART jelet küld, és nem szabadítja fel a buszt.
Szintaxisa:
Wire.requestFrom(address, quantity),
Wire.requestFrom(address, quantity, stop).
Paraméterei:
address: 7 bites cím,
quantity: lekérdezendő bájtok száma,
stop: bool változó.
available()
Visszaadja az olvasásra kész bájtok számát. Mestereszközön requestFrom() után kell meghívni, szolgaeszközön pedig az onReceive() kezelőben.
Szintaxisa:
Wire.available().
read()
Beolvassa a soron következő bájtot.
Szintaxisa:
Wire.read().
Arduino kód: 60wire01
write()
Küld egy bájtot a szolgaeszközről a mestertől kapott kérésre válaszul – vagy a beginTransmission() és endTransmission között használva a mestereszközről küld egy bájtot valamelyik szolgának.
Szintaxisa:
Wire.write(value),
Wire.write(string),
Wire.write(data, length).
Paraméterei:
value: bájtként küldendő érték,
string: bájtok sorozata,
data: length hosszúságú bájtok tömbje.
Arduino kód: 61wire02
beginTransmission()
Adatküldés inicializálása szolgaeszköz felé, a bájt értékének megadása a write() függvénnyel, endTransmission() küldi végül el.
endTransmission()
Elküldi a beginTransmission()-nel hívott címre a write()-ban megadott értékeket. Egy bájtot ad vissza, ami ötféle érték lehet:
0: sikeres átvitel,
1: az adat nem fér bele az átviteli tárolóba,
2: a címről nem érkezett válasz,
3: az adatot nem fogadták,
4: egyéb hiba.
Szintaxisa:
Wire.endTransmission(),
Wire.endTransmission(stop) (stop – lásd feljebb).
onReceive()
Szolgaeszközön regisztrál egy függvényt, amit végre kell hajtania, ha a mestertől bármi érkezik.
Szintaxisa:
onReceive(handler).
Paramétere:
handler: a függvény, amit végre kell hajtania.
onRequest()
Szolgaeszközön regisztrál egy függvényt, amit végre kell hajtania, ha a mestereszköz adatot szeretne lekérdezni.
Szintaxisa:
onReceive(handler).
Paramétere:
handler: a függvény, amit végre kell hajtania.
A gyakorlatban például nagyon hasznos I2C eszköznek bizonyul a digitális potméter, amivel kiterjeszthetjük az Arduino analóg kimeneteinek számát, vagy programozhatóvá alakíthatunk olyan analóg áramköröket, mint egy erősítő vagy rádió.
Digitális potméter funkcionális rajza
A digitális potméter egy integrált áramkör (IC – Integrated Circuit), amiben az I2C protokollt értelmező vezérlő, elektronikus kapcsolók és számtalan különféle értékű ellenállás kapott helyet (13.3. ábra AD5171 típusú áramkör).
Az AD5171 lábkiosztása
A 13.3. és 13.4. ábrák összevetésével el tudjuk képzelni, hogy az áramkör fizikai lábaihoz mely funkciók társulnak – ezeket a rajzokat a gyártó biztosítja. GND (ground v. föld) a potenciál alapja, Vdd a tápfeszültség, SCL (Serial Clock) az órajel, SDA (Serial Data) az adatvonal, AD0 (Address), amivel beállíthatjuk az eszköz címét a buszon, A és B a potméter két „szélső” kivezetése, míg W a közepe. Változtassuk egy LED fényerejét I2C buszon kommunikáló digitális potméter segítségével!
Amire szükségünk lesz:
- Arduino,
- AD5171 (DIP tokozású),
- LED,
- 220 ohmos ellenállás,
- 2 db 4,7 kiloohmos ellenállás,
- próbapanel,
- vezetékek.
Kapcsolás:
Kössük az IC tápvezetékeit értelemszerűen az Arduino földjéhez és + 5 V jelölésű kivezetéséhez! Az A4 és A5 csatornákat 4,7 kiloohmos ellenálláson keresztül szintén a + 5 V-hoz. Ezek az úgynevezett felhúzó ellenállások, amik stabilizálják a busz vonalait. Ezután illesszük A4-et az IC SDA (5.) lábához, A5-öt az SCL (4.) lábához. A potmétert használjuk feszültségosztónak és a közepéről hajtsuk meg a LED-et a 220 ohmos soros ellenálláson keresztül. AD0-t, ha földre kötjük, a címet 44-re, ha + 5 V-ra kötjük, 45-re állítja.
AD5171 bekötése az Arduinoba
Arduino kód: 62wirepoti
- - - - - - - - - -