A Raspberry Pi GPIO portja 17 darab szabadon programozható ki- illetve bemeneti tüskét tartalmaz. Ezeket különböző programozási környezetekből (Scratch, Python, stb.) könnyen tudod programozni. Működésük nagyon egyszerű, a tüske két logikai állapotot (True/ False, High/Low) vehet fel, ezeket fizikailag feszültségszintek reprezentálják, 0V, illetve 3,3V. Ez utóbbira fontos figyelni, mert eltérően egyéb eszközöktől (pl. Arduino) ahol a logikai True – High szintet 5V reprezentálja, a Raspberry 3,3V-os logikával működik. Amennyiben a Pi a GPIO portot kimenetként használja, ez nem okoz problémát, bemeneti üzemmódban azonban gondoskodnod kell arról, hogy a bemenetre érkező jel ne lépje túl a 3,3V-ot, mert az a bemenet tönkremeneteléhez vezethet!
A rendelkezésre álló ki- illetve bemenetek száma megfelelőnek tűnik, de lehetséges olyan projekt, ahol több csatlakozási pontra lenne szükséged, vagy célszerűbb lenne a csatlakoztatott berendezéssel valamilyen buszon keresztül kommunikálni, pl. 16×2 LCD kijelző.
Ezekben az esetekben a legegyszerűbb megoldás egy un. „I/O buszbővítő” alkalmazása, amit a Pi-hez az i2c vagy az SPI buszon keresztül tudsz csatlakoztatni.
A következő példákban egy MCP23017 típusú buszbővítő ic-t fogok bemutatni.
Az MCP23017
A buszbővítő 16 programozható portot „ad hozzá” a meglévő GPIO protokhoz, mindössze két (a 3-as illetve az 5-ös) tüske felhasználásával. Ezek a Pi SCL illetve SDA csatlakozói.
Figyelembe véve, hogy a Pi-re nem csak egy buszbővítő csatlakoztatható, hiszen az A0, A1, A2 lábakon az eszköz címezhető, így további ic-k csatlakoztatásával nagyszámú további I/O port áll a rendelkezésedre.
Az MCP23017 16 db. I/O csatlakozói két 8 bites csoportba, un. „bank”-be tartoznak, az „A” illetve a „B” jelzésűbe. Ha be akarod állítani, hogy az egyes bank-ek egyes bitjei ki- vagy bemenetek legyenek, egy hexadecimális értéket kell küldj a megfelelő bank un. adatirány regiszterének. Az IODIRA (0x00) az A, az IODIRB (0x01) regiszter a B bank bitjeit állítja. A megfelelő regiszterbe töltött bitek beállítják az adatirányt, az 1-es érték bemenet, a 0-s kimenet. Ha például a 0-ás, 1-es és a 7-es csatornákat kimenetnek, a maradék csatornát bemenetnek akarod használni, akkor az 10000011 bináris érték hexadecimális megfelelőjét kell az adatirány regiszterekbe töltened: 0x83 hex. Az összes csatorna kimenetként való beállítása a 0x00 érték feltöltésével tehető meg.
Az alábbi példában 3 db. LED illetve egy nyomógomb csatlakozik az MCP23017-es bővítőre. A LED-eket itt is a megszokott 330-ohmos korlátozó ellenállásokon keresztül kötöttem az ic első (GPA) 8bites portjára, a kimenetek a GPA0, GPA1, GPA2 csatornák.
A nyomógombnál alkalmazott ellenállás értéke 10kohm, alaphelyzetben a bemenetet „lehúzza” GND potenciálra, azaz a tápegység negatív szintjére. Ha megnyomjuk a gombot, a bemenet értéke magas szint, azaz 3,3V lesz, logikai HIGH/TRUE érték.
Bekötés
IC lábak | |
Pin 9 (VDD) | 3.3V |
Pin 10 (VSS) | GND |
Pin 12 (SCL) | Pin 5 Pi GPIO |
Pin 13 (SDA) | Pin 3 Pi GPIO |
Pin 18 (Reset) | 3.3V |
Pins 15, 16 & 17 (címzés) | GND |
Az MCP23017 engedélyezése és tesztelése
A buszbővítő használatához engedélyezned kell az Raspberry Pi i2c buszát. Ezt a Beállítások/Raspberry Pi Configuration/Interfaces panelon tudod megtenni, az I2C Enable rádió gomb bekattintásával.
Ha ezek után a terminálban kiadod a
sudo i2cdetect -y 1
parancsot, a következő eredményt fogod látni:
A táblázat azt mutatja, hogy egy darab csatlakoztatott i2c eszközöd van, a 0x20-as címen (dec 32). Ez annak a következménye, hogy a bekötésnél a három címvezetéket A0, A1 illetve A2 GND-re, azaz logikai alacsony szintre kötöttük. A címvezetétek magas szintre kapcsolásával különböző címeket tudnánk beállítani, így egyszerre több buszbővítőt is alkalmazhatnánk.
Tesztprogram a kimenetek tesztelésésre
Az alábbi program egy ciklussal megvalósított számláló, a decimális értéket az i2c buszra már bináris formátumban írja ki a bus.write_byte_data parancs.Az eredményt három LED jelzi ki.
import smbus import time bus = smbus.SMBus(1) DEVICE = 0x20 # Device address (A0-A2) IODIRA = 0x00 # Pin direction register OLATA = 0x14 # Register for outputs GPIOA = 0x12 # Register for inputs # Set all GPA pins as outputs by setting # all bits of IODIRA register to 0 bus.write_byte_data(DEVICE,IODIRA,0x00) # Set output all 7 output bits to 0 bus.write_byte_data(DEVICE,OLATA,0) for MyData in range(1,8): # Count from 1 to 8 which in binary will count # from 001 to 111 bus.write_byte_data(DEVICE,OLATA,MyData) print (MyData) time.sleep(1) # Set all bits to zero bus.write_byte_data(DEVICE,OLATA,0)
Tesztprogram a bemenetek tesztelésésre
Az alábbi program az A bank utolsó bemenetét használja egy nyomógom folyamatos kiolvasására (a többi csatorna adatiránya kimenet). A gomb lenyomása esetén a „gomb lenyomva” felirat jelenik meg a terminál ablakban.
import smbus import time #bus = smbus.SMBus(0) # Rev 1 Pi uses 0 bus = smbus.SMBus(1) # Rev 2 Pi uses 1 DEVICE = 0x20 # Device address (A0-A2) IODIRA = 0x00 # Pin direction register GPIOA = 0x12 # Register for inputs # Set first 7 GPA pins as outputs and # last one as input. bus.write_byte_data(DEVICE,IODIRA,0x80) # Loop until user presses CTRL-C while True: # Read state of GPIOA register MySwitch = bus.read_byte_data(DEVICE,GPIOA) print MySwitch if MySwitch =128: print("gomb lenyomva") time.sleep(1)
A két forráskód letölthető:
A cikkben használt MCP23017 portbővítő IC megvásárolható a MálnaPC Webshopjában!