VIDI Project X #53:
Povećajte broj dostupnih GPIO pinova VIDI X-a

Neki projekti zahtijevaju veći broj pinova nego ih imate na raspolaganju na samome VIDI X mikroračunalu. Jedno od rješenja kako ih povećati je MCP23017. No što nam on donosi?

Povećajte broj ulazno-izlaznih pinova korištenjem IO EXPANDER MCP23017 modula

 

MCP23017 je 16-bitni I2C I/O ekspander sa serijskim I2C sučeljem. Što to točno znači? Prisjetimo se. 16-bitni broj ima 16 bitova. Dakle ima 16 znamenaka koje mogu biti nule (0) ili jedinice (1). Time dobijemo jednu 16-bitnu vrijednost. Ako bi svi pinovi bili u logičkom stanju TRUE (ili HIGH, visoki kako se to još kaže), čitali bismo 16-bitnu vrijednost kao 1111111111111111. Kada bi svi bili u LOW stanju, čitali bismo njihovu 16-bitnu vrijednost kao 0000000000000000 (šesnaest nula).

Bitno je razumjeti da se ovdje ne radi o modulu koji će pročitati analognu vrijednost i onda je prikazati u 16 bitnoj varijanti, nego su svi pinovi digitalni.

No kako na slici vidite da su pinovi raspoređeni u dva reda, označena s A i B, onda možemo reći da dobivamo dvije 8-bitne vrijednosti. Ovaj čip može se iskoristiti za povećanje broja I/O pinova na bilo kojem mikrokontroleru koji koristi I2C komunikaciju.

Iz iste obitelji čipova postoji još i MCP23S17 koji koristi SPI komunikaciju te komunicira puno brže od ovog našega s I2C komunikacijom. MCP23S17 može komunicirati SPI sabirnicom brzinom od 10 MHz, dok ova naša IC2 verzija, MCP23017, radi na brzinama od 100 kHz, 400 kHz i 1,7 MHz. Također radi na naponu od 1,8V do 5,5V, što nam govori da je bez nekih modifikacija pogodan za korištenje na VIDI X-u koji radi na 3,3 V.

MCP23017 ima interne pull-up otpornike za svaki ulazni pin, podesivo želite li ih koristiti ili ne, tako da nema potrebe za dodavanjem vanjskih pull-up otpornika za tipke ili druge ulazne komponente. Pull-up otpornici su vrijednosti 100 kΩ.

Kako bismo MCP23017 mogli pravilno koristiti, potrebno je znati njegovu I2C (I kvadrat C) adresu.

 

Na slici vidimo kako modul ima 16 pinova. Svaki od njih može biti nula ili jedinica.

 

Prisjetimo se I2C komunikacije

I2C komunikacijski protokol koristi dvije žice za razmjenu informacija. Jedan se koristi za signal takta (SCL – Signal CLock), a drugi za slanje i primanje podataka (SDA – Signal DAta). Što duži kabel koristite, to će vam signal takta morati biti sporiji.

Na mnogim modulima linija SDA također može biti označena kao SDI ili MOSI, a linija SCL kao SCK.

SDA i SCL vodovi aktivni su kada je njihovo stanje 0 (LOW), pa ih treba spajati putem otpornika. Tipične vrijednosti otpornika za uređaje od 5 V su 4,7 kΩ tj. 2,4 kΩ za uređaje koji koriste 3,3 V. Duljina kabela će utjecati na kvalitetu veze. U ovom projektu uspjeli smo postići I2C vezu bez korištenja otpornika, no stabilniju vezu smo ostvarili uz korištenje pull-up otpornika od 5 kΩ ili čak 10 kΩ za kabel dužine 1 metar. Kako su pinovi GPIO32 i GPIO33 na koje ćemo spajati ovaj čip u ADC1 grupi GPIO pinova kojoj pripadaju GPIO32, GPIO33, GPIO34, GPIO35, GPIO36 i GPIO39 (Vidi X, odnosno ESP32 ima i ADC2 grupu pinova kojima pripadaju GPIO0, GPIO2, GPIO4, GPIO12, GPIO13, GPIO14, GPIO15 i GPIO27), a spojite i neke senzore ili sl. na druge GPIO pinove iz iste ADC grupe, bit će potrebno prilagoditi vrijednost pull-up otpornika na recimo 5 kΩ ako s 10 kΩ I2C veza ne radi stabilno i obratno.

Povezivanje I2C uređaja na ESP32 vrlo je jednostavno. Povezujete GND na GND, SDA na SDA, SCL na SCL i 3,3-voltno napajanje na 3,3 V, osim kada koristite modul koji koristi 5-voltno napajanje te ga tada povezujete s 5-voltnim napajanjem.

Pretkonfigurirani pinovi za I2C komunikaciju kod ESP32 čipa su GPIO21 i GPIO22 te je tako postavljeno za gotovo sve biblioteke koje ćete pronaći na internetu.

Spomenuti SDA pin kod VIDI X mikrokontrolera je GPIO21, dok je SCL postavljen na GPIO22, no kako je na GPIO21 postavljen DC (data clock) pin ILI9341 LCD-a, a na GPIO22 spojen CS (chip select) pin za SD karticu, potrebno je koristiti neke druge pinove za I2C komunikaciju ako želite koristiti TFT ILI9341 LCD VIDI X-a. Kao zamjenski pinovi, bit će dostatni bilo koji PWM pinovi. Dakle, ako želite koristiti ekran, kao što ga koristimo u ovoj radionici te pretkonfigurirane pinove potrebno je postaviti na neke druge. Mi smo odabrali GPIO32 i GPIO33, iako smo mogli odabrati bilo koji ulazno-izlazni pin s PWM (Power Width Modulation) sposobnostima.

Kako bi komunicirali s modulima putem I2C veze, potrebno je znati njihovu I2C adresu. I2C adresu ćete saznati uz pomoć i2c_scan.ino skice koju možete preuzeti s Vidilabova GitHub repozitorija: https://github.com/VidiLAB-com/Vidi-X/tree/master/i2c_scan.

U spomenutoj skici definirali smo pinove za I2C komunikaciju naredbama:

#define I2C_SDA 33
#define I2C_SCL 32

Sada I2C senzor spajate umjesto gumbiju A i B VIDI X mikroračunala prema priloženoj shemi na pinove GPIO32 i GPIO33. Svakako ne zaboravite spojiti GND pin te pin 3V3 napajanja.

Adresu modula koju dobijemo na serijsku konzolu treba zapisati kako bismo je mogli koristiti za daljnju komunikaciju.

 

Gore lijevo nalaze se 3 otpornika ispod kojih je lemni spoj ili popularno, jumper.

 

Na slici, gore lijevo, primijetite 3 otpornika ispod kojih se nalazi spomenuti jumper. Kada su sva tri otpornika ovako spojena dobivamo I2C adresu 0x27. Odlemite li sva tri spoja, dobit ćete 0x20, a kombinacijom vrijednosti između 0x21 i 0x26. Time dolazimo do zaključka kako je moguće koristiti ukupno 8 ovakvih modula s jednim VIDI X mikroračunalom (moguće je i više, no o tome nekom drugom prilikom, da ne zakompliciramo previše jednostavnu priču).

 

Biblioteka

Za korištenje ovog modula trebat ćete i biblioteku. Iako postoje mnoge biblioteke na internetu za istu namjenu, isprobavanjem mnogih zaključili smo kako dobro radi biblioteka imena MCP23017_WE s GitHUB adrese: https://github.com/wollewald/MCP23017_WE/tree/master.
Instalirajte je u Arduino IDE pritiskom CTRL + SHIFT + I i upisivanjem MCP23017 u tražilicu, a zatim klikom na install gumb.

 

U moru biblioteka za MCP23017 donosimo vam onu s najboljim opcijama za korištenje.

 

Minimalni primjer koda koji radi

Nakon što ste otvorili osnovni primjer mcp23017_basic_input_output iz ponuđenih primjera, potrebno je ovako modificirati nekoliko prvih linija koda kako bi kod proradio:

#include <Wire.h>
#include <MCP23017.h>
#define MCP_ADDRESS 0x27
#define I2C_SDA 33
#define I2C_SCL 32

MCP23017 myMCP = MCP23017(MCP_ADDRESS);
int wT = 1000; // wT = waiting time

void setup(){
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL, 100000); // wake up I2C bus
…

 

Otvorite osnovni primjer mcp23017_basic_input_output iz ponuđenih primjera.

Dakle promijenili smo I2C adresu u našu koju smo dobili putem ranije pokrenute skice za otkrivanje I2C adresa.

Zatim smo definirali I2C pinove koje ćemo koristiti za našu I2C komunikaciju.

Definirali smo objekt myMPC modula MPC23017 bez korištenje reset pina, iako možete koristiti i reset pin ako ga spojite na neki od slobodnih pinova VIDI X mikroračunala.

myMCP.Init(); inicijalizira objekt s nekim unaprijed postavljenim vrijednostima
myMCP.setPinMode( pin, port, direction ); slično Arduino pinMode funkciji, pri čemu se port dodaje kao parametar, kao direction možete koristiti: INPUT/OUTPUT/INPUT_PULLUP, OFF/ON ili 0/1 (“0”= ULAZ, “1” = IZLAZ)
myMCP.setPortMode( value, port ); postavite pinMode za cijeli port; value je naveden kao binarni broj (npr. 0b01011110)
myMCP.setPortMode( value, port, INPUT_PULLUP); kod ove varijante svi ulazni pinovi interno se povlače prema gore; nema utjecaja na izlazne pinove.
myMCP.setPin( pin, port, level ); slično funkciji digitalWrite; dopušteni parametri su: 0/1, OFF/ON, LOW/HIGH
myMCP.setPort( value, port ); digitalWrite za cijeli port; ima smisla napisati value jer je naveden kao binarni broj (npr. 0b01011110)
myMCP.togglePin( pin, port ); prebacuje pin iz LOW u HIGH ili iz HIGH u LOW
myMCP.setPinX( pin, port, direction, level ); proširena verzija funkcije setPin ili kombinacija setPinMode i setPin
myMCP.setPortModeX( direction, value, port ); raširena verzija za funkciju setPort
myMCP.setAllPins( port, level ); postavlja sve pinove porta na LOW ili HIGH

 

Funkcije koje se koriste za čitanje statusa pina u su:

myMCP.getPin( pin, port ); vraća razinu navedenog pina kao bool tj. jedan bit
myMCP.getPort( port ); vraća status navedenog porta kao bajt tj. u ovom primjeru kao niz od osam bitova

 

Modul ima i dva interupt pina, za svaki port po jedan. Kako ih koristiti saznajte iz dokumentacije i primjera na GitHub stranicama biblioteke: https://github.com/wollewald/MCP23017_WE.

Priloženi testni kod na VidiLAB-ovu GitHUB profilu prikazuje primjer postavljanja pinova A kanala u stanje HIGH ili LOW, a zatim njihovu vrijednost pokazuje na LCD ekranu VIDI X mikroračunala. Crveno ispisana je vrijednost direktno pročitana s A porta, iako je on postavljen kao izlazni port, dok su plavo ispisane vrijednosti pročitane s B porta koji je postavljen kao ulazni port i direktno spojen na pinove izlaznog A porta, pa tako čita njihovo stanje.

Ista očitanja s oba porta šalju se i na serijsku konzolu PC računala.

 

Shema spajanja

Ovi dodatni spojevi od A4–A7 (koji ustvari prema ovoj shemi nemaju ledice na sebi) do B8–B11 su opcionalni, a ovdje su iz razloga što se, ako neki GPIO pinovi ostanu nespojeni, ponekada dogodi da njihovo stanje bude plutajuće, pa ne možemo odrediti je li ono HIGH ili LOW, nego se proizvoljno mijenja. Iz tog razloga ih je dobro negdje usidriti.

Najčešće se vežu za GND putem jačeg (od recimo 10 kΩ ili 100 kΩ) PULL-DOWN otpornika. Dovoljna vam je samo jedna žica s kojom možete eksperimentirati te proizvoljno spojiti bilo koji pin B porta s bilo kojim pinom A porta, no samo kada su jedni postavljeni kao OUTPUT, a drugi kao INPUT. Nemojte spajati pinove ako su oba pina postavljena kao OUTPUT jer će to napraviti kratki spoj i time uništiti MCP23017 modul.

 

Shema spajanja LED dioda putem I2C sabirnice MCP23017 expander modula. Otpornik od 330 oma služi kako ne bismo opteretili GPIO pinove MCP23017 expander modula ukoliko LED koristi više struje nego što mu MPC23017 može isporučiti.
Spojevi B porta na A port su opcionalni. Dovoljna vam je samo jedna žica s kojom možete eksperimentirati te proizvoljno spojiti bilo koji pin B porta s bilo kojim pinom A porta, no samo kada su jedni postavljeni kao OUTPUT, a drugi kao INPUT.

 

Nikako ne smijemo zaboraviti postaviti switcheve u poziciju za korištenje expansion slota, kao na slici. Dakle BTN_A i BTN_B postavljamo u poziciju USE EXP. kako bi ih koristili za I2C sabirnicu, dok TOUCH_IRQ ostaje u USE EXP. poziciji kako bi mogli uploadati nove skice na VIDI X.

 

Nekoliko primjera za iskoristiti MCP23017 modul?

Spajanje 16 LED dioda očiti je primjer kao i spajanje 16 tipki. Time zapravo dolazimo do zaključka kako ledice vrlo lako možemo zamijeniti Relay modulom, pa koristeći MCP23017 kontrolirati 16 relejnih sklopki. No postoje mnogi projekti koji bi bili teško izvedivi bez ovakvog modula.
Odlična primjena ovog modula bila bi u izradi tipkovnice gdje kombinacijom 8 × 8 pinova možete dobiti 64 različite tipke. Iz tog razloga se za izradu tipkovnica s većim brojem tipki koristi više od jednog modula.

Ovakvi moduli potrebni su i za pokretanje 7-segmentnog LED displaya koji za jednu znamenku treba 7 žica + GND, odnosno 8 uključimo li i decimalnu točku koja se obično nalazi na takvom displayu. Dakle, jedan MCP23017 modul mogao bi pokretati dvije znamenke 7-segmentnog LED displaya.

Odlično bi bilo spojiti 16 komada ILI9341 TFT LCD ekrana na način da CS pinovi budu spojeni na MCP23017 dok ostatak SPI komunikacije ostaje, kao i do sada, spojeno na VIDI X pinove. Ukoliko vam baš na svima treba i touch screen funkcionalnost, možete spojiti ukupno 8 komada ILI9341 LCD ekrana na jedan MCP23017 modul.