La gestione degli “input” costituisce parte fondamentale per molti progetti basati su Arduino. Quando il numero di input da gestire cresce, cresce anche il numero di ingressi digitali necessari per tracciare correttamente lo stato di ogni singolo segnale in ingresso. Ma come fare se il numero di input da gestire supera il numero di ingressi disponibili? E’ necessario trovare un modo per ridurre il numero di ingressi/uscite impiegati sulla scheda.

 

 

Il multiplexer

Un metodo semplice e rapido per ridurre il numero di linee dati occupate su Arduino è utilizzare un multiplexer.

La funzione dei multiplexer è quella di fornire in uscita un segnale scelto tra n segnali dati diponibili in ingresso in funzione dell’impostazione dei segnali di selezione.

Esempio multiplexer 8:1

In altre parole impostando determinati segnali di selezione (s) si seleziona uno degli ingressi disponibili (i) e il multiplexer fornirà in uscita (u) un valore pari a quello dell’ingresso selezionalto.

Nel caso del multiplexer preso ad esempio è chiaro come il numero di pin necessari per gestire gli ingressi si dimezzi: otto ingressi potranno essere gestiti con quattro pin in/out di Arduino: un pin in input sarà collegato all’uscita del multiplexer e tre in output saranno collegati ai segnali di selezione.

 

La scelta del multiplexer: DM74150N

Il progetto illustrato in questo articolo prevede di costruire un tastierino a 16 tasti quindi è richiesta la gestione di 16 input contemporaneamente. Volendo realizzare il tutto con l’ausilio di un multiplexer, datasheets alla mano, abbiamo deciso di utilizzare un DM74150N: un multiplexer realizzato in un singolo chip capace di selezionare 1 tra 16 segnali in ingresso. La sua “tabella di verità” è la seguente:

Tabella vertià del DM74150N
(Fonte: datasheet © 2000 Fairchild Semiconductor Corporation)

 

Impostando livelli H e L ai pin A, B, C e D (pin di selezione) si istruirà il chip su quale dei 16 ingressi portare in uscita. Come si noterà l’uscita è il complemento dell’ingresso selezionato, cioè se l’ingresso selezionato è H l’uscita è L e viceversa.

Questo significa che se per il tastierino vogliamo una uscita H quando un tasto è premuto, il pin di quel tasto dovrà essere tenuto a H e portato a L solo in caso di pressione.

 

La resistenza di “pullup”

L’obiettivo è raggiungibile tramite una resistenza di “pull-up” collegata tra l’alimentazione e il pin di ingresso del multiplexer.

Con l’interruttore S1 aperto l’ingresso del multiplexer è H quindi l’uscita, quando l’ingresso in questione è selezionato, sarà L. Con l’interruttore S1 chiuso il pin di ingresso verrà collegato a massa, cioè forzato a un valore L, di conseguenza l’uscita sarà H.

 

Collegamento con Arduino

E’ il momento di collegare il tutto e verificare il funzionamento del circuito. Per semplificare la figura, nello schema che segue sono collegati solo 2 dei 16 interruttori previsti per il tastierino ma il principio è il medesimo della versione completa. Per testare il corretto funzionamento degli input sono presenti 2 led: led1 e led2 che dovranno accendersi rispettivamente alla pressione dei pulsanti: pulsante1 e pulsante2.

 

 

Lo sketch di prova

Lo sketch di prova di questo circuito dovrà verificare la pressione dei 2 pulsanti e nel caso uno di essi sia premuto dovrà accendere il rispettivo led. Per fare tutto ciò è necessario innanzitutto impostare correttamente le linee di input e di output:

 

void setup()
{
  // Imposta in ingresso il pin 6
  pinMode(D6, INPUT);
 
  // Imposta in uscita i pin di controllo del MUX
  pinMode(D2, OUTPUT);     
  pinMode(D3, OUTPUT);     
  pinMode(D4, OUTPUT);     
  pinMode(D5, OUTPUT);     

  // Imposta a 0000 le linee di selezione del MUX
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
  digitalWrite(D4, LOW);
  digitalWrite(D5, LOW);

  // Imposta in uscita i pin di controllo dei LED
  pinMode(D9,  OUTPUT);
  pinMode(D10, OUTPUT);

  // Imopsta le linee di controllo dei LED a 00
  digitalWrite(D9,  LOW);
  digitalWrite(D10, LOW);

 }

 

Terminato il setup, è possibilie procedere alla scrittura della funzione loop() che effetua una scansione della tastiera e se è stato premuto il pulsante 0 o il pulsante 1 attiva rispettivamente l’uscita 9 o 10 per accendere i led in modo appropriato.

I pin D2,D3,D4,D5 impostati in OUTPUT controllano l’indirizzo del multiplexer, il pin D6 in INPUT riceve l’output del multiplexer. Se D6 è alto allora tasto premuto, quindi imposto ad alto il pin del led corrispondente al tasto analizzato; viceversa se D6 è basso il tasto non è premuto, quindi imposto a basso il pin del led corrispondente.

 

void loop()
{
    byte t;

    for(t=0;t<16;t++)
    {
      digitalWrite(2, (t & 1)?HIGH:LOW);
      digitalWrite(3, (t & 2)?HIGH:LOW);
      digitalWrite(4, (t & 4)?HIGH:LOW);
      digitalWrite(5, (t & 8)?HIGH:LOW);

      delay(1);

      if(digitalRead(6)==HIGH)
      {
        if(t==0)
          digitalWrite(9,HIGH);

        if(t==1)
          digitalWrite(10,HIGH);
      }
      else
      {
        if(t==0)
          digitalWrite(9,LOW);

        if(t==1)
          digitalWrite(10,LOW);
      }
    }
}

 

In questo esempio sono stati cablati solo 2 dei 16 input e lo sketch di prova si limita ad analizzare esclusivamente lo stato dei due pulsanti collegati. Lo schema è però replicabile con semplicità per tutti i pulsanti necessari fino a un massimo di 16.

 

Una realizzazione concreta

Verificato il principio di funzionamento passiamo dal prototipo di test su breadbord a un prototipo completo su millefori. Tutti i 16 pulsanti sono posizionati sulla scheda e collegati da un lato a massa e dall’altro al rispettivo piedino del multiplexer. I piedini di alimentazione, di selezione e di output del multiplexer sono riportati a un header attraverso il quale interfacciare la tastiera con Arduino.

 

Conclusioni e prossimi passi

Abbiamo verificato come, attraverso l’utilizzo di multiplexer e di semplici accorgimenti da utilizzare nel codice dello sketch, si possa aumentare anche considerevolmente il numero di input digitali di Arduino.

I prossimi passi saranno la realizzazione di una libreria che permetta di astrarre il multiplexer e la tastiera semplificandone l’utilizzo nello sketch attraverso la definizione di una classe multiplexer e di una classe keyboard.