Ve svém druhém příspěvku jsem ukazoval, jak rozsvítit LED připojenou na GPIO. Je to snadné, že? Tak teď to bude znovu, ale složitěji.
Přímé připojení vstupů a výstupů na GPIO porty RPi je hezké (a na výuku/předvádění je to super), ale má to dva háčky:
- Není zcela zjevné, kolik proudu je možno z jednotlivých GPIO krátkodobě a dlouhodobě odebírat – a když to přeženete, nedopadne to dobře.
- Většina „bastlířského“ světa funguje na pětivoltové logice – a pokud přivedete 5 V na vstup, můžete RPi říct jen „pápá“.
Oba tyto problémy lze vyřešit například použitím I2C GPIO expandéru. Pod označením MCP23009-E/P najdete 8-bitový I2C port expander s otevřeným kolektorem – tj. čip, který má na straně RPi jeden I2C port a směrem ven nabízí 8 I/O portů. Každý z portů si můžete nastavit jako vstupní nebo výstupní.
Port nakonfigurovaný jako vstup je tolerantní k pětivoltové logice, tj. korektně přežije spolupráci s TTL zařízením.
Port nakonfigurovaný jako výstup má tyto parametry:
- Je tolerantní k 5 V signálům.
- Má maximální proud 25 mA (a součet přes celý čip nesmí přesáhnout 200 mA).
- Má otevřený kolektor – tj. když je na něm logická 0, je sepnutý na zem; když je na něm logická 1, není připojený nikam. Tj. logickou jedničku dosáhnete tím, že výstup přes odpor připojíte k napájení. Kouzlo tohoto řešení je v tom, že při připojení odporu k 3.3V můžete komunikovat se zařízeními s třívoltovou logikou; při připojení odporu k 5 V můžete komunikovat s běžnými TTL (5 V) zařízeními.
Takže to zapojíme:
- Napájení obvodu na +3.3V a na GND.
- I2C SDA a SCL na odpovídající výstupy na expanzním konektoru.
- Dále zde máme /RESET – aby se obvod nahodil, musí tam být logická 1 = přes odpor na +3.3V.
- Kouzelný vstup ADDR určuje, jakou adresu na I2C sběrnici čip obsadí. Je analogový (!!!) a umožňuje tak jedním drátem určit jednu z osmi adres (=až osm těchto expandérů na jedné I2C sběrnici). Pro zjednodušení si s tím nebudeme hrát a připojíme ADDR na GND = základní adresa 0x20.
- GP0 až GP7 jsou jednotlivé GPIO vstupy/výstupy.
- Ostatní nožičky necháme volné.
Mezi +5 V a pin GP0 zapojíme odpor 330 ohm a LEDku. Tj. LED bude svítit, pokud na GP0 bude „0“ = připojeno na zem. Opačně by to nefungovalo – otevřený kolektor, viz výše.
Jako vedlejší efekt tohoto cvičení jsem si chtěl vyzkoušet nějaký nástroj na kreslení schémátek. Zde tedy je výstup z aplikace Fritzing. Vypadá jako vhodná na podobná malování – má hotové moduly i např. pro RPi, nepájivé kontaktní pole má logiku a automaticky propojuje součástky. Kreslí se v tom rychle a pohodlně.
Zapojeno máme, co teď s tím?
Po bootu se RPi zeptáme, zda je tam něco nového na I2C sběrnici.
pi@raspberrypi ~ $ i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: 20 — — — — — — — — — — — — — — —
30: — — — — — — — — — — — — — — — —
40: — — — — — — — — 48 — — — — 4d — —
50: — — — — — — — — — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: — — — — — — — —
Na adrese 0x20 vidíme nové zařízení. 0x48 a 0x4d jsou teplotní čidla z minulého dílu.
Nastavíme registr IODIRA (0), který určuje, zda jsou piny vstupní nebo výstupní. 1 = vstup, 0 = výstup. Pro komunikac použijeme i2cset, kterému předáme parametry:
- -y = neptej se na nic
- 0 = sběrnice 0
- 0x20 = adresa čipu na sběrnici
- 0 = adresa registru v čipu
- 0xfe = hodnota, co nastavujeme (1111 1110)
- b = zapisujeme 1 byte
pi@raspberrypi ~ $ i2cset -y 0 0x20 0 0xfe b
LED se rozvítila! Defaultní hodnota výstupního pinu je totiž „0“.
No a teď můžeme blikat LEDkou. Piny se ovládají v registru OLATA (0x0a).
pi@raspberrypi ~ $ i2cset -y 0 0x20 0x0a 0x01 b
(1 = zhasnuto)
pi@raspberrypi ~ $ i2cset -y 0 0x20 0x0a 0x00 b
(0 = svítí)
pi@raspberrypi ~ $ i2cset -y 0 0x20 0x0a 0x01 b
(1 = zhasnuto)
Kdybych chtěl číst stav vstupních pinů, je to k nalezení v registru GPIOA (0x09).
Takže děláme stejnou práci, jako na začátku. Blikáme LEDkou. Ale daleko sofistikovaněji než předtím.
Tipy a triky:
- Od stejného výrobce se dá pořídit MCP23017, což je 16-bitová verze téhož. Více nožiček a více pinů, stejná logika ovládání.
- Chci-li nastavit jen jeden bit nějakého I2C registru, příkaz i2cset na to má volbu „mask“ – maskou řeknete, které bity chcete nastavit; i2cset si hodnotu ostatních bitů načte z čipu a pak je doplní do zapisovaného bajtu.
1 = I2C čidla teploty z minulého článku
2 = MCP23009-E/P
3 = LEDka. Bliká na rozkaz.
4+5 = 1-wire bus adaptér a čidlo DS18B20 – bude v dalším článku, stay tuned
zdravím děkuju za článek, dříve než jsem ho však našel udělal jsem si to sam:( škoda.
mám však jednu otázku. nemohu zaboha příjít na to, jak mám ovládat pouze jeden pin expanderu.
například:
odešlu přikaz i2cset -y 0 0x20 0x13 0xff
což znamená zápis 1111 1111 a všech 8 gpio B je sepnuto.
ja chci zapsat 0 na pin 1B tak odešlu i2cset -y 0 0x20 0x13 0xfe, takže 1111 1110 a pin 1B ma hodnotu nula.
je nějak možné, aby jsem zapsal pouze hodnotu pro pin 1B a ostatni zustaly stejné?
Ano, je to možné a píšu to v článku.
chci zapsat 0 na pin 1B tak odešlu
i2cset -y 0 0×20 0×13 0 1
Poslední hodnota je maska – do kterých bitů zapisuješ. Cituju návod: „The mask parameter, if specified, describes which bits of value will be actually written to data-address. Bits set to 1 in the mask are taken from value, while bits set to 0 will be read from data-address and thus preserved by the operation.“
Chviličku jsem se stím pral a podařilo se mi to, ale s jiným zápisem.
např:
pro zapsání 1 na 1B
i2cset -y -m 0x01(0000 0001) 0 0x20 0x13 0xff
nebo pro zapsání 1 na 4B
i2cset -y -m 0x08(0000 1000) 0 0x20 0x13 0xff
třeba to někomu pomůže
bezva řešení. Nevíte náhodou někdo o tom kde se dá MCP23009-E/P koupit v Praze ? Nechce se mi platit 200,- za poštovné za součástku za necelých 50,-….
zdravim, chcel by som sa spytat ci ten expander mozem nahradit niecim takymto:
MCP23016-I/SP
http://www.gme.sk/mcp23016-i-sp-p433-288
v elektronike som uplny zaciatocnik…
s krizkem po funuse – tak kdyby to resil nekdo dalsi:
MCP23016 I-SP pouzit lze, ovsem musel jsem pridat odpor a kondik pro vstup CLK; zapojeni pinu je jine a adresace registru take. napr. prepnuti IODIR0 na out: i2cset -y 0 0x20 6 0xfe b .. viz datasheet
Znovu jsem si četl celý článek a…z číny mi jdou tyhle dvě vychytávky..
http://www.dx.com/p/keyes-3-3v-5v-ttl-logic-level-converter-module-red-334669
to mám na propojení arduina s RPi B+. A na I2C zařízení http://www.dx.com/p/iic-i2c-level-conversion-module-compatible-with-3-5v-system-sensor-blue-197198#.VIbhPdJhnjs
prostě tohle píchnu do pole, spojím pár částí pole a napíchám tam klidně 50 I2C věcí co nebudu řešit jestli jsou na 5V nebo 3,3V…..
dá se konfigurovat MCP23009 aby po připojení na napájení byly nastaveny piny na výstup a byla na nich 0
Myslím, že ne. Ono by to bylo z principu nebezpečné – stávající stav (vysoká impedance po zapnutí) nemůže nic zničit.