Aumentare le uscire digitali di Arduino con uno Shift register 74HC595

Lo shift register 74HC595 è un registro a scorrimento, che collegato ad Arduino ci permette di aggiungere 5 output digitali al nostro progetto, dico 5 e non 8 perché 3 pin di Arduino andranno utilizzati per il collegamento appunto con il registro, in questo post vedremo il suo funzionamento testandolo con un codice di esempio e come collegarlo ad Arduino.

Lo shift register 74HC595 è un registro di tipo SIPO che significa Serial In Parallel Output, questo vuol dire che riceve i dati in modo seriale e li ridistribuisce in modo parallelo sulle sue 8 uscite.

Pinout shift register 74HC595

74HC595 pinout
Collegamenti Arduino – shift register 74HC595

arduino_74HC595_collegamenti

Vediamo cosa sono e a cosa servono i piedini dello shift register 74HC595:

MR sta per master reclear, questo pin possiamo collegarlo direttamente a Vcc in quanto se collegato a Gnd resetterebbe le nostre uscire.

OE sta per output enable, questo pin collegato direttamente a Gnd abilita le uscite, ed a noi è quello che interessa.

Q7” questo pin viene denominato Serial Output, e ci permette di collegare in cascata eventuali altri registri permettendoci di aumentare ancora il nostro numero di output.

Q0, Q1, Q2, …, Q7 come è facilmente intuibile si tratta degli 8 output del registro.

DS sta per data serial, su questo piedino invieremo un bit per volta al registro, bit che successivamente andranno a settare le uscite del registro.

SH_CP questo pin è lo shift clock, ci servirà per comunicare al registro ogni volta che invieremo un bit: “Ehy, ti ho inviato un bit!

ST_CP questo pin è lo storage clock in alcuni registri viene detto latch, dopo aver inviato tutti e gli 8 bit al registro, ci servirà per comunicare al registro : “Ehy, ti ho inviato tutti i bit, puoi disporli sulle uscite!

shift register 74HC595

shift register 74HC595

A questo punto dovrebbe essere già chiaro come scrivere poche semplice righe di codice per utilizzare uno shift register 74HC595 con Arduino.
Fondamentalmente bisogna porre lo shift_clock e lo storage_clock a LOW ed inviare gli 8 bit al registro uno per volta scanditi singolarmente da un segnale di shift_clock tramite un semplice ciclo for, dopodiché basta settare su HIGH lo storage clock e dato che abbiamo preventivamente collegato output_enable a Gnd, ci ritroveremo subito con le uscite dello shift register settate per come noi abbiamo inviato i nostri bit.

Adesso vi consiglio di leggere anche questo articolo che descrive come lavorare con i bits perché lo ritengo fondamentale per poter lavorare e comprendere al meglio uno shift register.

Una cosa che bisogna tenere in considerazione quando inviamo i bit al registro è che saranno disposti al contrario di come noi li invieremo, cosa vuol dire?
Se dichiariamo ad esempio un byte in Arduino in questo modo byte x = 1; che corrisponde in binario a 00000001 ed iniziamo a trasferire i bit al registro da quello più significativo MSB anziché dal bit meno significativo LSB che nel nostro caso si tratta di un bit alto cioè un 1, ci ritroveremo sulle uscite del registro la sequenza in modo invertito 10000000 più precisamente: troveremo l’1 sull’uscita Q0 anziché sull’uscita Q7 … perché questo??? Ciò è dovuto a causa dello shift! Quando inviamo il primo bit, questo sarà posizionato in corrispondenza dell’uscita Q0 ma successivamente quando invieremo il secondo bit, quello inviato precedentemente sarà spostato (appunto si chiama Shift Register) in corrispondenza di Q1 ed il secondo andrà a posizionarsi in corrispondenza di Q0 e così via fino all’ottavo bit.

Come funziona lo shift register 74HC595?
Vediamo un illustrazione, ho preparato un disegno per chiarirvi meglio l’idea del funzionamento del 74HC595:

shift_register_funzionamento

Come possiamo fare dunque per ovviare al problema dei bit invertiti??
In modo abbastanza semplice, sfruttiamo direttamente il ciclo for utilizzato in ogni caso per l’iterazione della lettura dei bit che compongono il nostro Byte, partendo come di consueto da un indice pari a 0, dato che a noi interessa proprio inziare la lettura del Byte dal bit con indice zero, cioè il bit denominato LSB… per leggere un bit in una data posizione del Byte o più in generale di una variabile è abbastanza facile, abbiamo già a disposizione per Arduino una funzione chiamata bitRead(), basta passare in argomento il Byte che a noi interessa e la posizione del bit da leggere ricordandoci che le posizioni per i bit non vanno da 1 a 8 ma da 0 a 7, appunto per questo il for parte da 0 e non da 1.
Quindi nel codice ci ritroveremo un punto con una situazione del genere:

for(int=0; i<8; i++) {
  bitRead(myByte,i);
}

in questo modo andremo a leggere prima il bit con indice zero, poi quello con indice uno, ecc.. fino a quello con indice 7.

Ecco un piccolo video che ho realizzato per farvi vedere il funzionamento:

Questo è lo sketch con il codice di esempio che ho utilizzato per ottenere gli effetti visti nel video…

Buon lavoro e alla prossima 😉

const int DS_pin = 10;
const int STCP_pin = 11;
const int SHCP_pin = 12;
byte x;


void setup()
{
  pinMode(DS_pin, OUTPUT);
  pinMode(SHCP_pin, OUTPUT);
  pinMode(STCP_pin, OUTPUT);

  delay(250);
}


void loop()
{
  for (int i = 0; i < 5; i++)  scaletta(100);  off(1000);
  for (int i = 0; i < 8; i++)  tenda(100);     off(1000);
  for (int i = 0; i < 15; i++) allBlink(100);  off(1000);
}


void writeRegister(unsigned long myDelay)
{
  digitalWrite(STCP_pin, LOW);

  for (byte i = 0; i < 8; i++) {
    digitalWrite(SHCP_pin, LOW);
    if (bitRead(x, i))  digitalWrite(DS_pin, HIGH);
    else              digitalWrite(DS_pin, LOW);

    digitalWrite(SHCP_pin, HIGH);
  }

  digitalWrite(STCP_pin, HIGH);
  digitalWrite(STCP_pin, LOW);
  digitalWrite(SHCP_pin, LOW);

  delay(myDelay);
}


void scaletta(int pause)
{
  x = B00000001; writeRegister(pause);
  x = B00000011; writeRegister(pause);
  x = B00000111; writeRegister(pause);
  x = B00001111; writeRegister(pause);
  x = B00011111; writeRegister(pause);
  x = B00111111; writeRegister(pause);
  x = B01111111; writeRegister(pause);
  x = B11111111; writeRegister(pause);
  x = B01111111; writeRegister(pause);
  x = B00111111; writeRegister(pause);
  x = B00011111; writeRegister(pause);
  x = B00001111; writeRegister(pause);
  x = B00000111; writeRegister(pause);
  x = B00000011; writeRegister(pause);
  x = B00000001; writeRegister(pause);
  x = B00000000; writeRegister(pause);
}


void tenda(int pause)
{
  x = B00011000; writeRegister(pause);
  x = B00111100; writeRegister(pause);
  x = B01111110; writeRegister(pause);
  x = B11111111; writeRegister(pause);
  x = B01111110; writeRegister(pause);
  x = B00111100; writeRegister(pause);
  x = B00011000; writeRegister(pause);
  x = B00000000; writeRegister(pause);
}


void allBlink(int pause)
{
  x = B11111111; writeRegister(pause);
  x = B00000000; writeRegister(pause);
}


void off(int pause)
{
  x = B00000000; writeRegister(pause);
}

Una risposta a “Aumentare le uscire digitali di Arduino con uno Shift register 74HC595”

I commenti sono chiusi.