Raspberry Pi

17) GPIO expander

POZOR

Všechny návody a příklady na této stránce
 platí pro Raspberry Pi verze 1 
(starší verze bez dvou montážních otvorů v desce) 

Novější verze 2 (s 512MB pamětí) má trochu jinak číslované některé
vývody na GPIO konektoru.

Popis rozdílů obou variant je zde: http://elinux.org/....28GPIO.29

Pokud máte málo GPIO portů, není problém si nějaké přidat.
Potřebujete k tomu jen jeden obvod - MCP23017

Tento obvod rozšíří počet vstupně výstupních portů Raspíčka o 16. A protože komunikuje po sběrnici I2C, nebude potřeba ani žádný další GPIO port přímo na RasPi.

Navíc díky nastavitelnému tříbitovému adresování by neměl být problém pospojovat k sobě až 8 takovýchto obvodů (to je dohromady 128 ovládacích vstupně / výstupních vodičů)

Stránky, ze kterých jsem vycházel, jsou zde:

http://nathan.chantrell.net/20120519/raspberry-pi-and-the-mcp23017-i2c-io-expander
http://nathan.chantrell.net/20120602/raspberry-pi-io-expander-board/

Expander je sice schopný pracovat s napájecím napětím 3,3V, ale kvůli zvýšení proudu, který je schopný expander ovládat, je lepší ho napájet 5V.
Při zvýšení napájecího napětí však může dojít k tomu, že se napětí 5V bude objevovat i na portu I2C. Takovéto napětí by však mohlo Raspíčko zničit. Proto je třeba ještě navíc připojit komunikační sběrnici přes obvod, který oddělí napěťové úrovně 3,3V a 5V.
Jednoduché a levné řešení je popsáno tady::
   http://nathan.chantrell.net/20120610/raspberry-pi-and-i2c-devices-of-different-voltage/
Jsou to jen 2 tranzistory FET. 
Vysvětlení principu tohoto "Level Shifteru" ve slovenčině je zde: http://mcu.cz/news.php?extend.1013

Místo FETů je možné použít integrované obvody, které jsou pro tuto funkci přímo určené - například PCA9306

 

Ve schématu jsou použity tranzistory N-FET s diodou. Já jsem použil typ BS107, ale na přesném typu asi moc nezáleží.
Odpory jsou pro Pull-Up (já jsem použil 100K).

 

V případě, že budete napájet expander z 5V, je možné spínat i o trochu větší zátěž, než ze samotných GPIO pinů na RasPi.
Expander zvládá max. 25mA na pin  a max. 125mA na celý obvod.
Výstupní porty se nastavují na 0V= logická "0", nebo na 5V= logická "1".
Takže POZOR, nezavádět tyto výstupní signály zpět na GPIO port v RasPi - ten pracuje jen s napětím do 3,3V.

 

Zastavím se ještě u toho adresování. Pomocí různých kombinací logických stavů na adresovacích pinech expanderu (piny 15,16,17) je možné měnit adresu tohoto obvodu. Není dobré nechávat piny nezapojené. Pokud z nějakého důvodu potřebujete změnit adresu, připojte pin, který má být v "1" na +5V (napájecí napětí).


Hardware

Mojí původní "bastl" desku jsem musel kompletně předělat. Už se mi na ní nevešly všechny potřebné součástky.

"Áčkovou" stranu expanderu (GPA0 až GPA7) jsem nastavil jako výstupní. Připojil jsem k ní 7 LEDek a jeden pípák (BMT1206UX). Sice v popisu udávají jeho proud až 30mA, ale když jsem měřil ten proud, který přes ten pípák skutečně teče při 5V, bylo to asi 11mA, takže ho expander bez problému s rezervou utáhne (má povolených 25mA). A protože to pískání je dost nepříjemné, přidal jsem tam ještě propojku, pomocí které je možné ten pípák odpojit.

"Béčkovou" stranu jsem nastavil jako vstupní. Připojil jsem na ní 6 tlačítek ze staré klávesnice. 2 piny jsem nechal volné (místo tlačítek jsem na ně dal jen propojky). Pořadí tlačítek zatím není důležité. Já jsem to připojil tak, jak to jde popořadě:
 GPB7 = tlačítko F1
 GPB6 = tlačítko nahoru
 GPB5 = tlačítko Insert
 GPB4 = tlačítko vlevo
 GPB3 = tlačítko dolu
 GPB2 = tlačítko vpravo
 GPB1 = propojka
 GPB0 = propojka


(Expandér je ten dlouhý obvod vedle kterého jsou LEDky. Menší obvod  v zelené patici je A/D převodník. Ten není připojen na expander, ale přímo na GPIO v RasPi. Displej je také připojený přímo na konektor v RasPi. Potenciometr je na nastavení kontrastu displeje. Na desce je také konektor pro teplotní čidlo - to je ten žluto-oranžovo-červený kablík. Taky je tam připravený konektor I2C pro modul s hodinami reálného času. Dva poslední porty GPIO, které mi z RasPi ještě zbyly, jsem prozatím osadil dvěma mikrospínači.)


Software:

Nejdříve je třeba povolit komunikaci I2C. Pokud jste to ještě neudělali při připojování modulu hodin reálného času, tak postupujte takto:

sudo nano /etc/modprobe.d/raspi-blacklist.conf

V editoru, který se tímto příkazem otevře, se musí zakomentovat dvě řádky (připsat před ně "dvojkřížek"  # ), jak je vidět na následujícím obrázku:

 

 

Pak se musí nainstalovat tento nástroj

sudo apt-get install i2c-tools
 

Po instalaci je třeba zavést ovladač:

sudo modprobe i2c-dev
Tento příkaz pro zavedení ovladače je dobré přidat do nějakého skriptu, který se spouští při startu RasPi. 
Pak bude expander přístupný okamžitě po startu.

Pak je možné se pomocí nástroje i2cdetect podívat, na které adrese se expandér hlásí.

Za příkazem i2cdetect se zadává číslo I2C kanálu. Starší varianta RaspberyPi (s 256MB pamětí) má na GPIO konektoru vyvedený kanál číslo 0. Pokud používáte novější verzi RasPi (varianta s 512MB pamětí), změňte si číslo kanálu na 1.

Pokud budete mít všechny adresovací piny v "0", bude se hlásit na adrese 0x20. Jestli některý z pinů nastavíte na "1", objeví se expandér někde jinde:

(všechny adresní piny v "0" => adresa je 0x20)

(adresní pin A0 v "1" => adresa je 0x21)

Pomocí nástroje i2c-tools je pak možné s expandérem komunikovat.

Například nastavení celého portu GPA pro výstup se provede takto:

sudo i2cset -y 0 0x20 0x00 0x00
Formát parametrů je následující:
0 = číslo kanálu I2C sběrnice /dev/i2c-0 (novější varianta RaspberryPi (512MB) bude mít číslo sběrnice 1)
0x20 = adresa obvodu
0x00 = adresa registru, který nastavuje směr GPA
0x00 = všech 8 bitů v GPA bude výstupních - Každý bit v GPA může být 0(výstup), nebo 1(vstup) 

Konkrétní nastavení jednotlivých pinů na "1", nebo "0" se provede potom takto:

sudo i2cset -y 0 0x20 0x12 0xFF

0x12 je adresa registru "A" a poslední číslo udává, které bity budou v "1" a které v "0".
Pro tento příklad se všechny bity na portu GPA nastaví na "1" (0xFF = "11111111").
Pokud by bylo třeba nastavit každý druhý bit na "1" a zbytek na "0", bylo by poslední číslo  0xAA (to je "10101010")

 

Pokusný skript pro testování výstupního portu GPA by mohl vypadat třeba takto:
 (Je to psané záměrně takhle jednoduše, aby bylo na první pohled vidět, jak to funguje. )

#!/bin/sh

sudo i2cset -y 0 0x20 0x00 0x00

sudo i2cset -y 0 0x20 0x12 0x01
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x02
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x04
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x08
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x10
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x20
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x40
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x80
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x00
sleep 1


sudo i2cset -y 0 0x20 0x12 0x80
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xC0
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xE0
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xF0
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xF8
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xFC
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xFE
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0xFF
sleep 0.3
sudo i2cset -y 0 0x20 0x12 0x00
sleep 1



exit 0

 A tohle je výsledek po spuštění skriptu (pokud nemáte zapnutý zvuk, tak prozradím, že na začátku a na konci skriptu je slyšet pípnutí od pípáka):

(Video se stáhne po kliknutí)

Odkaz na YouTube


Nastavení portu GPB pro vstup se provede podobně:

sudo i2cset -y 0 0x20 0x01 0xFF
Číslo sběrnice a adresa obvodu je stejná, jako při nastavování GPA
0x01 =  adresa registru, který nastavuje směr GPB
0xFF = všech 8 bitů v GPB bude vstupních - I tady může být každý bit výstupní (0), nebo vstupní (1).

Aktuální hodnota toho portu GPB se čte takto: 

sudo i2cget -y 0 0x20 0x13
0x13 je adresa registru "B".
Výsledkem volání příkazu je hexadecimální kód, který po převedení na binární kód udává stav jednotlivých pinů.

 

Testovací skript pro tlačítka jsem napsal takhle:


#!/bin/sh

# podle verze vaseho raspicka si zmente cislo i2c kanalu

sudo i2cset -y 0 0x20 0x01 0xFF   # Starsi verze RasPi (256MB) 
#sudo i2cset -y 1 0x20 0x01 0xFF  # Novejsi verze RasPi (512MB)


while [ True ]
do

  tlf=""   # tlacitko F1
  tlu=""   # tlacitko NAHORU (Up)
  tli=""   # tlacitko INSERT
  tll=""   # tlacitko VLEVO (Left)
  tld=""   # tlacitko DOLU (Down)
  tlr=""   # tlacitko VPRAVO (Right)

  stavgpb=`sudo i2cget -y 0 0x20 0x13` # Starsi verze RasPi (256MB) 
  #stavgpb=`sudo i2cget -y 1 0x20 0x13` # Novejsi verze RasPi (512MB)


  if [ $(($stavgpb & 128)) -eq "0" ]; then tlf="F1" ;fi
  if [ $(($stavgpb & 64)) -eq "0" ]; then tlu="Nahoru" ;fi
  if [ $(($stavgpb & 32)) -eq "0" ]; then tli="Insert" ;fi
  if [ $(($stavgpb & 16)) -eq "0" ]; then tll="Vlevo" ;fi
  if [ $(($stavgpb & 8)) -eq "0" ]; then tld="Dolu" ;fi
  if [ $(($stavgpb & 4)) -eq "0" ]; then tlr="Vpravo" ;fi


  echo " Stisknuta tlacitka : "  $tlf  $tlu  $tli  $tll  $tld  $tlr

  sleep 0.5

done

 Výstup tohoto skriptu vypadá pak nějak takto (je možné stisknout i několik tlačítek najednou a skript to pozná):

 

 

 

A tady je schéma celého obvodu a jeho připojení k RasPi
 (Na GPA a GPB si samozřejmě podle potřeby můžete připojit co chcete. Tohle je schéma, jak jsem měl ten expandér připojený já.)

 


Doplnění 16.9.2012

Když jsem si přečetl celý katalogový list k expanderu, zjistil jsem, že Pull-Up odpory (ty, které jsou připojeny jednou stranou na vstupní piny expanderu a druhou stranou na +5V) vůbec nejsou potřeba.

Expander totiž obsahuje tyto odpory uvnitř, akorát je potřeba aby se správným příkazem připojily.

Pro výše uvedený příklad s portem "B" nastaveným všemi piny na vstup, se vnitřní Pull-Up odpory připojí takto:

sudo i2cset -y 0 0x20 0x0D 0xFF

 


Doplnění 22.11.2012

Doplněno schéma připojení expanderu ke sběrnici I2C pomocí dvou FETů, které zajišťuje bezpečné rozdělení sběrnice na třívoltovou a pětivoltovou část.


Doplnění 5.2.2013

Doplnění upozornění na změnu označení I2C kanálu v novější verzi RasPi (512MB).

 


úvodní strana webu AstroMiK.org

poslední úprava stránky 20.2.2013