CD74HC4067 16 Channel Analog Multiplexer Demultiplexer

CD74HC4067 16 Channel Analog Multiplexer Demultiplexer


Non abbiamo abbastanza PIN di ingresso o di uscita sul nostro microcontrollore? Si può usare un CD74HC4067.
Infatti il CD74HC4067 è un Multiplexer / Demultiplexer analogico / digitale a 16 canali.
Questo chip può essere utilizzato come un interruttore rotante: instrada internamente il pin comune SIG a uno dei pin a 16 canali Yxx.
Funziona con segnali sia digitali che analogici.
Le connessioni funzionano in entrambe le direzioni.
Se il pin EN è posto:
– HIGH la comunicazione tra il pin Yxx scelto verso SIG è abilitata (funziona in maniera bidirezionale, come fosse un cavo).
– LOW la comunicazione tra il pin Yxx scelto verso SIG è interrotta

Per selezionare una delle 16 uscite Yxx si utilizzano i 4 pin S0-S3, impostando i giusti HIGH e LOW come da tabella.

Si può quindi utilizzare una sola uscita Yxx alla volta.

Tabella indirizzamenti:
Il datasheet completo è scaricabile da qui.

Poiché il CD74HC4067 funziona anche con segnali digitali si può usare per reindirizzare i dati seriali a livello TTL da o verso più dispositivi.
Si può ad esempio utilizzarlo per collegare il pin TX di 16 dispositivi a un pin RX del microcontrollore.
È quindi possibile selezionare uno di quei 16 dispositivi da ascoltare.
Se si vuole attivare una comunicazione a due vie, si può aggiungere un secondo CD74HC4067 e collegare il pin TX del microcontrollore verso il pin RX dei 16 dispositivi.

UTILIZZO CON ARDUINO

Per utilizzare il CD74HC4067 in modalità OUTPUT con Arduino si può usare, ad esempio, il seguente schema:

Lo sketch utilizzabile è il seguente:

const int SPin[4] = {3, 4, 5, 6}; // 4 Pin usati per inviare il codice binario
const int EPin = 2; /* Pin Enable
                      - se impostato HIGH interrotto fisicamente il collegamento tra il pin SIG e quello Yxx scelto
                      - se impostato LOW viene stabilito il collegamento tra il pin SIG e quello Yxx scelto */

const int SIG = 9; // SIG pin

const int STable[16][4] = {
  // Crea un Array con i valori binari da richiamare in base al canale Y scelto
  // s0, s1, s2, s3, canale
  {0,  0,  0,  0}, // Y0
  {1,  0,  0,  0}, // Y1
  {0,  1,  0,  0}, // Y2
  {1,  1,  0,  0}, // Y3
  {0,  0,  1,  0}, // Y4
  {1,  0,  1,  0}, // Y5
  {0,  1,  1,  0}, // Y6
  {1,  1,  1,  0}, // Y7
  {0,  0,  0,  1}, // Y8
  {1,  0,  0,  1}, // Y9
  {0,  1,  0,  1}, // Y10
  {1,  1,  0,  1}, // Y11
  {0,  0,  1,  1}, // Y12
  {1,  0,  1,  1}, // Y13
  {0,  1,  1,  1}, // Y14
  {1,  1,  1,  1}  // Y15
};

void YSelect(int Y){
  digitalWrite(SPin[0], STable[Y][0]);
  digitalWrite(SPin[1], STable[Y][1]);
  digitalWrite(SPin[2], STable[Y][2]);
  digitalWrite(SPin[3], STable[Y][3]);
}

void setup() {
  pinMode(EPin, OUTPUT);// Inizializza EPin come OUTPUT
  digitalWrite(EPin, LOW); // presetta EPin LOW, leggere la nota all'inizio del programma per i dettagli
  
  pinMode(SIG, OUTPUT); // Inizializza SIG come OUTPUT
  digitalWrite(SIG, HIGH); // Presetta SIG HIGH, serve per il nostro esperimeto poi andrà settato a seconda delle necessità

  for (int i = 0; i < 4; i++)
  {
    pinMode(SPin[i], OUTPUT); // Inizializza tutti gli Spin come OUTPUT
    digitalWrite(SPin[i], LOW); // Setta tutti gli Spin LOW
  }
}

void loop() {
  YSelect(0); // modificare il valore da 0 a 15 per cegliere quale pin Y selezionare
}

Per selezionare il canale Yxx basterà cambiare il numero all’interno delle parentesi della righa:

YSelect(0);

e vedrete accendersi il LED corrispondente.

EFFETTO “SUPERCAR”

Per chi si ricorda lo scanner della famosa auto KITT degli anni ’80, con una piccola modifica al precedente sketch, possiamo simulare il suo famoso scanner…

Basta modificare la parte del void loop() così:

void loop() {
  int ritardo = 80;
  for (int i = 0; i < 16; i++)
  {
    YSelect(i);
    delay(ritardo);
  }
  for (int i = 15; i > 0; i--)
  {
    YSelect(i);
    delay(ritardo);
  }
}

Per utilizzare il CD74HC4067 in modalità INPUT con Arduino si può usare, ad esempio, il seguente schema:

Lo sketch utilizzabile è il seguente:

const int SPin[4] = {3, 4, 5, 6}; // 4 Pin usati per inviare il codice binario
const int EPin = 2; /* Pin Enable
                      - se impostato HIGH interrotto fisicamente il collegamento tra il pin SIG e quello Yxx scelto
                      - se impostato LOW viene stabilito il collegamento tra il pin SIG e quello Yxx scelto */
                      
const int SIG = 9; // SIG pin

const int STable[16][4] = {
  // Crea un Array con i valori binari da richiamare in base al canale Y scelto
  // s0, s1, s2, s3, canale
  {0,  0,  0,  0}, // Y0
  {1,  0,  0,  0}, // Y1
  {0,  1,  0,  0}, // Y2
  {1,  1,  0,  0}, // Y3
  {0,  0,  1,  0}, // Y4
  {1,  0,  1,  0}, // Y5
  {0,  1,  1,  0}, // Y6
  {1,  1,  1,  0}, // Y7
  {0,  0,  0,  1}, // Y8
  {1,  0,  0,  1}, // Y9
  {0,  1,  0,  1}, // Y10
  {1,  1,  0,  1}, // Y11
  {0,  0,  1,  1}, // Y12
  {1,  0,  1,  1}, // Y13
  {0,  1,  1,  1}, // Y14
  {1,  1,  1,  1}  // Y15
};

void YSelect(int Y) {
  digitalWrite(SPin[0], STable[Y][0]);
  digitalWrite(SPin[1], STable[Y][1]);
  digitalWrite(SPin[2], STable[Y][2]);
  digitalWrite(SPin[3], STable[Y][3]);
}

void setup() {
  pinMode(13, OUTPUT);

  pinMode(EPin, OUTPUT);// Inizializza EPin come OUTPUT
  digitalWrite(EPin, LOW); // presetta EPin LOW, leggere la nota all'inizio del programma per i dettagli

  pinMode(SIG, INPUT_PULLUP); // Inizializza SIG come INPUT_PULLUP

  for (int i = 0; i < 4; i++)
  {
    pinMode(SPin[i], OUTPUT); // Inizializza tutti gli Spin come OUTPUT
    digitalWrite(SPin[i], LOW); // Setta tutti gli Spin LOW
  }

}

void loop() {
  YSelect(15); // modificare il valore da 0 a 15 per cegliere quale pin Y selezionare
  int stato;
  stato=digitalRead(SIG);
  digitalWrite(13,stato); // invia direttamente la lettura del pin SIG sul LED connesso al pin 13

}