Aumentare il numero di uscite di Arduino

Spesso imbattendoci nella progettazione dei nostri prototipi, specialmente quelli di una certa complessità, dobbiamo affrontare il problema del limitato numero di ingressi/uscite di cui dispone il nostro Arduino ( in particolare Arduino UNO ). Consideriamo ad esempio di quanti pin dobbiamo utilizzare per pilotare un display a 7 segmenti, un certo numero di led, e così via. Per risolvere tale problema esistono degli integrati chiamati “Shift Register” (registri a scorrimento) come i 74HC595, i quali permettono di pilotare 8 uscite utilizzando solamente 3 pin dell’ arduino. Questi modelli poi posso essere collegati in cascata fra di loro aumentando notevolmente le uscite di cui abbiamo bisogno per il nostro progetto. Il 74HC595 appartiene alla categoria dei registri SIPO ( Serial Input-Parallel Output ) che tradotto significa semplicemente che i bit su questo integrato entrano uno dopo l’altro ed escono tutti insieme contemporaneamente. La comunicazione fra arduino e il 74HC595 avviene in tre fasi e su tre pin :

  1. un pin di arduino invia un segnale allo shift register sul pin SH_CP  (Shift Register Clock Pin) per attivare l’invio dei bit (pin 11)
  2. un pin di arduino invia fisicamente i bit allo shift register sul pin DS  (Serial Data Input) (pin 14)
  3. un pin di arduino invia un segnale allo shift register sul pin ST_CP (chiamato anche LATCH ) per rendere disponibili i bit contemporaneamente in uscita (pin12)

Nella tabella sottostante si possono osservare le funzioni dei pin dell’integrato 74HC595 preso come esempio.

 

74HC595 pinout

 

 

Di seguito viene riportato lo schema di collegamento tra un Arduino e l’integrato 74HC595. Oltre ai terminali 11-12-14, si noti il pin 10 (Master Reset) collegato al positivo di alimentazione e  il pin 13 (Output Enable) collegato a massa. Infine, il teminale Q7′ (Serial Data Output) viene lasciato libero e usato nel caso si decide di mettere in cascata un secondo Shift Register.

Per quanto riguarda la programmazione di Arduino, si procede nello stabilire i pin che de devono essere collegati allo shift register, il byte da inviare e l’utilizzo della funzione ShiftOut[…] con i relativi parametri.

Ecco il codice relativo allo schema riportato in figura:

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

// memorizzo nell' array i valori che di volta in volta assumono le uscite dell'integrato
byte uscita[] = {0b11111111, 0b11111110, 0b11111100, 0b11111000, 0b11110000,
                 0b11100000, 0b11000000, 0b10000000, 0b00000000
                };



void setup() {

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);


}

void loop() {

  for (int i = 0; i <= 8; i++)
  {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, uscita[i]);
    digitalWrite(latchPin, HIGH);
    delay(100);
  }

  delay(200);

  for (int i = 8; i >= 0; i--)
  {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, uscita[i]);
    digitalWrite(latchPin, HIGH);
    delay(100);
  }

    delay(200);
}

 

Nel codice faccio uso del pin 12 per inviare il segnale per attivare il 74HC595 al ricevimento dei bit, il pin 11 sul quale transiteranno i bit  ed infine il pin 8  per inviare il segnare che comunica all’integrato di trasferire in uscita i bit inviati. Creo un Array tipo byte dove memorizzo tutti i livelli logici che desideriamo assumere. I valori dell’Array sono scritti in forma binaria per far intuire più facilmente la configurazione dei pin d’uscita del 74HC595 . Infatti, se prendiamo ad esempio il primo valore “0b11111111” vediamo che inizialmente tutti i pin dello Shift Register sono impostati a livello logico 1, quindi tutti i led saranno accesi.  Il secondo valore  “0b11111110” pone il pin Q0 a livello logico 0 e quindi il led ad esso collegato verrà spento e così in sequenza per i pin Q1,Q2,Q3,Q4,Q5,Q6,Q7.  Ricordo che nella scrittura binaria i bit si leggono da destra a sinistra. Attraverso un ciclo for()… eseguo per ogni bit da inviare tutte le fasi necessarie attraverso la funzione shiftOut(). Questa riceve come argomenti due dei tre pin suddetti , il byte che si vuole inviare e il parametro MSBFIRST (Most Significant Bit First) o LSBFIRST (Least Significant Bit First) a seconda dell’ordine in cui devono essere posti i bit in uscita. Nell’esempio riportato i bit si presentano in uscita esattamente come li inviamo.I valori dell’ Array possono essere scritti anche in forma decimale o esadecimale a seconda delle proprie comodità.

 

Il video seguente mostra il funzionamento del codice