Non ci sono prodotti a carrello.
Sperimentiamo con il popolare I/O expander della Microchip, attraverso una scheda applicabile anche su breadboard, interfacciabile con Arduino.
Esistono varie situazioni pratiche in cui occorre gestire numerosi segnali e attuatori con un microcontrollore, che perรฒ non ha sufficienti pin di I/O; in tali situazioni รจ utile ricorrere a quegli integrati noti come I/O expander, la cui funzione รจ serializzare un certo numero di linee di input e output cosรฌ da controllarle tramite un solo I/O, ovvero una linea di comunicazione seriale come puรฒ essere la comune e diffusissima IยฒC-Bus, presente in molti microcontrollori e, non ultime, nelle schede Arduino.
Per rispondere allโesigenza di moltiplicare (espandere, appunto, come dice il termine โexpanderโ…) le linee di I/O, abbiamo realizzato la breakout board basata su MCP23017, che proponiamo in questo articolo, sulla quale troviamo tale integrato Microchip che รจ appunto un I/O expander a 16 bit, oltre allโhardware minimo per farlo funzionare, che nel caso specifico consiste in un dip-switch e qualche resistore di pull-up.
Ciรฒ diventerร piรน chiaro guardando lo schema elettrico della scheda, che trovate in queste pagine.
Infine, per darvi unโidea di cosa si puรฒ realizzare con un I/O expander, vi proporremo un esempio applicativo dove la breakout board pilota una serie relรฉ (otto in tutto) montati su una scheda pilotabile tramite livelli TTL o la pressione di pulsanti.
Ma andiamo con ordine ed analizziamo lo schema circuitale.
Schema elettrico dell’I/O expander
Come potete vedere, la breakout board รจ qualcosa di estremamente essenziale, perchรฉ a bordo vi troviamo lโintegrato MCP23017 in versione DIP (a montaggio tradizionale) con riportati sulle piazzole laterali, che sul PCB sono a passo 2,54 mm in previsione del montaggio di pin-strip per lโinserzione in altre schede o su breadboard, tutti i piedini ad eccezione dei tre per lโimpostazione dei bit meno significativi dellโindirizzo IยฒC-Bus di periferica.
Pertanto รจ stato previsto un dip-switch a 3 vie (siglato SW1 nello schema elettrico) per impostare lโindirizzo di comunicazione sullโIยฒC-Bus, i cui piedini A0, A1, A2, sono provvisti di resistori di pull-up che a dip-switch aperti li mantengono a livello logico alto.
Riepilogando, tutti i pin relativi agli I/O dei registri A e B sono stati portati in esterno su pin strip maschi. Questi pin sono stati disposti su entrambi i lati per poter connettere la nostra scheda con facilitร , ad esempio alla scheda relรฉ cod. RELAY8CH della Futura Elettronica, ma ovviamente sono pin I/O digitali, pertanto si puรฒ collegare tutto ciรฒ che si vuole, nei limiti della corrente e tensione supportati dallโintegrato MCP23017.
Oltre ai pin strip laterali a passo 2,54 mm, che permettono di ospitare il modulo anche in una breadboard, sono stati previsti altri 4 pin su uno strip (sempre a passo 2,54 mm) chiamato I2C, per poter collegare al bus direttamente nella parte superiore del modulo. Resta inteso che i soli pin laterali sono sufficienti per tutta la comunicazione e interfacciamento con il modulo, pertanto i quattro pin del connettore I2C sono posti in parallelo a quelli giร esistenti sulla scheda.
Notate che sul circuito stampato, per praticitร i pin del registro A sono stati riportati su un lato e quelli del B si trovano sul lato opposto, sempre nellโottica di semplificare le connessioni.
I piedini facenti capo al bus IยฒC sono stati riportati sul pin-strip siglato I2C, insieme al positivo 5V e alla massa; entrambi sono provvisti di pull-up.
Il reset dellโI/O-expander nella nostra breakout board non รจ utilizzato, quindi per disattivarlo abbiamo posto il relativo piedino (il 18, RSTโฆ) a livello logico alto mediante il resistore R4.
Tra i pin laterali della scheda troviamo anche ripetute le linee GND e +5V.
Lโelemento principale del circuito รจ chiaramente lโMCP23017, che possiamo considerare un convertitore IยฒC-Bus/parallelo, prodotto dalla Microchip (siglato U1); lโintegrato, del quale vedete lo schema a blocchi interno in Fig. 1, funziona come periferica (Slave) del bus IยฒC e supporta le due modalitร di input e output.
Nella prima permette di trasferire sul bus, su richiesta del dispositivo Master IยฒC-Bus, gli stati degli I/O del registro A e del B in formato seriale, un byte per ciascun registro; nella seconda, invece, va ad impostare le linee di I/O convertendo i dati in arrivo sul bus IยฒC nello stato corrispondente delle linee dei registri A e B.
Lโintegrato MCP23017 fornisce unโespansione I/O seriale/parallela generica a 16 bit ed รจ disponibile in due versioni: quella qui utilizzata, dotata di interfaccia IยฒC-Bus e la MCP23S17, variante ad interfaccia SPI.
Il chip รจ un I/O-expander a 16 bit, ripartiti in due porte da 8 bit ciascuna, interfacciato mediante IยฒC-Bus; questo significa che con due soli fili, riferiti a massa, consente di acquisire lo stato di ben 16 linee (modalitร input) ovvero impostare lo stato logico di esse (modalitร output).
Le linee di I/O sono, per impostazione predefinita, funzionanti come input.
LโMCP23017 รจ costituito da piรน registri in configurazione a 8 bit per ingresso, uscita e selezione della polaritร . Il master di sistema puรฒ abilitare gli I/O come ingressi o uscite scrivendo i bit di configurazione I/O (IODIRA/B) corrispondenti.
I dati per ogni ingresso o uscita sono conservati nel corrispondente registro di ingresso o di uscita.
La polaritร di registro Input Port puรฒ essere invertita mediante il Polarity Inversion Register.
Tutti i registri possono essere letti dal master di sistema.
La porta I/O a 16 bit รจ funzionalmente composta da due porte a 8 bit, ossia port A e port B, cui fanno capi i piedini, rispettivamente 21รท28 e 1รท8.
LโMCP23X17 puรฒ essere configurato per funzionare nelle modalitร a 8 bit o 16 bit; dispone inoltre dei due pin di interrupt, INTA e INTB, che possono essere associati alle rispettive porte (INTA per il Port A e INTB per Port B9 o possono essere assoggettati allโoperazione logica OR in modo che entrambi i pin si attivino se entrambe le porte determinano un interrupt.
Lโuscita di interrupt puรฒ essere configurata per lโattivazione in due condizioni (che si escludono a vicenda):
โข quando uno stato di input รจ diverso dal suo corrispondente stato del registro della porta di ingresso; questa condizione รจ utilizzata per indicare al master di sistema che un stato di ingresso รจ cambiato;
โข quando lo stato di un ingresso รจ diverso dal valore preconfigurato del registro (registro DEFVAL).
Le linee di interrupt INTA e INTB possono essere configurate come active-high, active-low oppure open-drain. Il registro Interrupt Capture acquisisce i valori delle porte nel momento in cui si attiva lโinterrupt, memorizzando cosรฌ la condizione che ha causato lโinterrupt.
Il Power-on Reset (POR) imposta i registri sui loro valori predefiniti e inizializza la macchina a stati del dispositivo.
La necessitร di funzionare in modalitร bidirezionale si deve al fatto che ogni periferica IยฒC-Bus deve sia poter leggere (per esempio i comandi) sia poter inviare i dati acquisiti, ad 8+8 bit, lungo il bus.
Come tutte le unitร per IยฒC-Bus, lโMCP23017 permette di impostarne lโindirizzo in un range di 8 indirizzi ed allo scopo dispone dei pin A0, A1, A2, i quali consentono di impostare gli address dellโunitร Slave, se indirizzata direttamente dal Bus IยฒC; queste linee si impostano ciascuna mediante un interruttore del dip-switch SW1, per facilitare lโimpostazione del caso: ogni dip chiuso imposta lo zero logico sul rispettivo address, mentre, viceversa, un dip aperto determina lo stato logico 1.
La possibilitร di definire otto indirizzi consente di affacciare fino a otto I/O-expander sullo stesso bus e controllare quindi un massimo di 128 I/O con tre sole linee.
Lโintero circuito prende alimentazione dal contatto 5V (in realtร abbiamo due contatti: 1 e 15, disposti sui lati lunghi della breakout board) riferita a massa (contatti GND, ossia 2 e 23 delle file laterali).
Con questo hardware, il funzionamento รจ il seguente: ogni volta che riceve una stringa lungo la linea SDA dellโIยฒC-Bus (scandita dal segnale di clock sulla linea SCL) lโintegrato MCP23017 esegue il comando ivi contenuto (in questo caso quello che indica di caricare il byte di dati) e dispone le 8 linee di uscita IOA0รทIOA7 e IOB0รทIOB7 come i relativi bit, ovvero IOA0 assumerร lo stato del primo bit del byte 1, IOA1 quello del secondo e via di seguito.
Analogamente avverrร su IOB0รทIOB7, che rispecchieranno pari-pari i bit del secondo byte dati.
Naturalmente la conversione e presentazione sulle uscite avviene solo a condizione che la stringa ricevuta contenga lโindirizzo IยฒC-Bus corrispondente a quello impostato, mediante i dip-switch dellโSW1, per lโU1. Alla ricezione di ogni stringa lโintegrato aggiorna lo stato delle proprie uscite e i rispettivi livelli logici determinano lโaccensione (o la permanenza nello stato di riposo) dei LED componenti i segmenti del display; se non viene inviata alcuna stringa successivamente, il display mantiene il numero visualizzato, perchรฉ le uscite dellโintegrato MCP23017 sono dotate di latch.
Quanto esposto vale per la modalitร output, ossia in scrittura dello stato dei due byte IยฒC-Bus sui registri di uscita A e B; se invece il comando proveniente dal bus รจ di lettura, lโMCP23017 acquisisce lo stato degli I/O di ciascun registro e genera due byte, contenenti il primo lo stato di IOA0รทIOA7 e il secondo la condizione logica di IOB0รทIOB7, quindi li invia lungo il bus IยฒC come risposta.
Per ogni applicazione cui vorrete destinare la breakout board, nella Tabella 1, vi riportiamo la corrispondenza tra gli address e lโimpostazione dei dip-switch.
Piano di montaggio dell’espansione
Elenco Componenti:
R1, R2, R3, R4, R5, R6: 4,7 kohm C1: 100 nF ceramico SW1: Dip-switch 3 vie U1: MCP23017-E/SP Varie: - Zoccolo 14+14 - Pin strip Maschio 12 vie (2 pz.) - Pin strip Maschio 4 vie (1 pz.) - Circuito stampato S1650 (61x23 mm)
Utilizziamo l’I/O espander con MCP23017 con Arduino
La breakout board nasce per essere interfacciata a un microcontrollore, giacchรฉ tipicamente gli I/O-expander vengono utilizzati da dispositivi provvisti di interfaccia seriale a IยฒC-Bus; siccome Arduino supporta questo bus, abbiamo realizzato un esempio di codice per leggere gestire gli I/O dellโMCP23017 tramite Arduino.
Rendiamo disponibile il codice di esempio nella pagina dell’I/O expander (FT1650) affinchรฉ possiate scaricarlo e scriverlo nella vostra scheda tramite lโIDE.
Questo sketch sostanzialmente consente di scrivere lo stato del registro Port A in funzione di un byte inviato da Arduino lungo il bus, i cui bit corrispondono allo stato letto sul Port B, che stavolta funziona da ingresso.
Per dare allโesempio unโapplicazione concreta, abbiamo deciso di utilizzare gli stati logici degli I/O del Port A, che qui opereranno come uscite digitali, per pilotare una scheda a relรฉ; nello specifico, bisogna collegare le 8 linee di comando delle uscite a relรฉ della scheda RELAY8CH della Futura Elettronic al banco I/O del Port A, mentre al Port B sono da collegare 8 pulsanti normalmente aperti, aventi in comune il polo collegato a GND.
Per realizzare questa applicazione occorre collegare Arduino UNO, la breakout board, la scheda relรฉ e i pulsanti, come mostrato nello schema di cablaggio proposto in Fig. 2.
Trattandosi di normalissimi pulsanti (nello specifico, normalmente aperti) e non avendo elettronica esterna, sono state abilitate le pull-up interne dellโMCP (mediante libreria) in modo da gestirli e riconoscere il cambiamento di stato, in questo modo abbiamo attivato lโuscita rispettiva quando il pulsante viene portato a massa (GND).
Per realizzare tutto ciรฒ, รจ stato scritto un codice molto semplice basato su Arduino UNO, sfruttando la libreria Adafruit, la quale, come vedete nel Listato 1, viene inclusa nella prima riga dello sketch con lโistruzione:
Listato 1
#include <Adafruit_MCP23X17.h> Adafruit_MCP23X17 mcp; int i = 0; int OUT[] = { 7, 6, 5, 4, 3, 2, 1, 0 }; //Rappresenta il PIN dellโMCP23017 (A7...A0) int IN[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; //Rappresenta il PIN dellโMCP23017 (B0...B7) int STATO[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; //Per ogni uscita viene salvato lo stato ad ogni commutazione void setup() { Serial.begin(9600); Serial.println(โMCP23017 INPUT / OUTPUTโ); if (!mcp.begin_I2C(0x20)) //0x20 รจ lโindirizzo dellโMCP23017 con A0=A1=A2 > ON(GND) { Serial.println(โMCP Errore!โ); //Se lโMCP non viene trovato si visualizza lโerrore while (1); } //Pin del banco A come uscite e del banco B come ingressi //La variabile STATO a 0 ad indicare uscite a riposo for (i = 0; i & lt; 8; i = i + 1) { mcp.pinMode(OUT[i], OUTPUT); mcp.pinMode(IN[i], INPUT_PULLUP); STATO[i] = 0; } } //******************* L O O P ********************** void loop() { String Testo_Debug = โโ; for (i = 0; i & lt; 8; i = i + 1) { //Se pulsante premuto o uscita non attivata, la attivo if ((mcp.digitalRead(IN[i]) == 0) & amp; & amp; (STATO[i] == 0)) { STATO[i] = 1; Testo_Debug = โPulsanteโ + String(i + 1) + โpremutoโ; Serial.println(Testo_Debug); mcp.digitalWrite(OUT[i], HIGH); } //Se pulsante rilasciato e uscita attivata, la porto a riposo if ((mcp.digitalRead(IN[i]) == 1) & amp; & amp; (STATO[i] == 1)) { STATO[i] = 0; Testo_Debug = โPulsanteโ + String(i + 1) + โrilasciatoโ; Serial.println(Testo_Debug); mcp.digitalWrite(OUT[i], LOW); } } delay(10); }
Resta inteso che prima di poter caricare il codice nella memoria di programma della nostra Arduino รจ indispensabile scaricare la libreria dal sito www.adafruit.com e installarla mediante il Gestore delle librerie incluso nellโIDE, o semplicemente estrarre il contenuto del file ZIP e copiare quindi lโintera cartella โAdafruit_MCP23017_Arduino_Libraryโ allโinterno della directory โlibrariesโ normalmente presente allโinterno del sistema operativo al percorso โDocumenti\Arduino\librariesโ.
Caricata la libreria, sarร sufficiente caricare il nostro codice di esempio e caricarlo allโinterno della scheda dopo aver scelto la corretta porta COM dal menu โStrumentiโ dellโIDE.
Nel codice viene richiesto lโinvio di un byte allโMCP23017, contenente lo stato dei pulsanti e i relativi dati vengono elaborati e quindi scritti su un byte diretto allโintegrato, che imposterร lo stato delle linee del Port A in maniera stabile, fino al refresh.
Affinchรฉ lโinterfacciamento funzioni รจ necessario impostare correttamente i dip-switch A0, A1 e A2 perchรฉ se al sensore non venisse assegnato lโindirizzo 0x20, verrebbe mostrato un messaggio di errore sulla seriale; lโaddress della breakout board si assegna con la combinazione 000 dei tre bit A0, A1, A2, quindi chiudendo a massa tutti e tre i dip-switch.
Se volete modificare lโindirizzo riferitevi alla solita Tabella 1, fermo restando che dovrete modificare lโaddress scritto nello sketch.