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!

null

Az ábrán zöld karikával jelölve a szabadon programozható GPIO tüskék

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

null

Az MCP 23017 lábkiosztása

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.

null

LED és nyomógomb bekötése MCP23017 segítségével

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:

null

Az i2cdetect eredménye

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!