Da array a shift register

Ciao a tutti. Ho la necessità di trasferire i valori contenuti in un array ad uno shift register, ma non ho trovato esempi di come fare.

Il mio array è di 8 elementi ciascuno dei quali può avere valore 0 o 1 e vorrei trasferirlo allo shift register per attivare le uscite relative (i valori nell'array possono cambiare in qualsiasi momento).

Mi aiutate?

Immagino che stiamo parlando di uno shift register serial-to-parallel, giusto?

In tal caso, cicla su tutti gli elementi dell'array con un for, e per ognuno setta il serial input dello SR al valore corrispondente e dai un impulso al clock.

Alla fine dai un impulso al latch, eventualmente.

A parole è facile, ma il codice non è molto peggio ;).

ShiftOut

Io ho approcciato lo sketch in questo modo, tuttavia ho dei problemi:

#define LATCHPIN    4    // Shift Register LATCH
#define DATAPIN     2    // Shift Register DATA
#define CLOCKPIN    5    // Shift Register CLOCK
#define OEPIN       3    // Shift Register |OUT ENABLE

// Array uscite valvole
byte statoEV[8] = {0, 1, 0, 0, 0, 0, 0, 1};

byte tempEV = 0;

void setup()
{
  pinMode(DATAPIN, OUTPUT);
  pinMode(LATCHPIN, OUTPUT);
  pinMode(CLOCKPIN, OUTPUT);
  pinMode(OEPIN, OUTPUT);
  digitalWrite(OEPIN, LOW); //Attiva le uscite dello SR
}

void loop()
{
  for (int j = 0; j < 8; j++)
  {
    digitalWrite(LATCHPIN, LOW);
    shiftOut(DATAPIN, CLOCKPIN, MSBFIRST, statoEV[j]);
    delay(150);
  }
      digitalWrite(LATCHPIN, HIGH);
}

La sequenza di accensione delle uscite è sequenziale sul primo led, mantenendo gli altri spenti.
Io vorrei che gli 8 led si accendessero in funzione dello stato 0 o 1 del relativo bit nell’array…

vbextreme: ShiftOut

Avrei una piccola domanda: I pin che si configurano all'interno della funzione shiftOut sono fissi o possono variare? (eg.2,3,4,5?) O bisogna rifarsi alla pienidatura del proprio Arduino?

Tutorial
tutorial

Innanzitutto O usi shiftOut() O usi un ciclo for e piloti i pin a mano.

Il problema è che shiftOut() si attende un byte in ingresso e setta i pin dello shift register in base ai suoi bit, mentre tu parti con un array di byte. Per cui o usi un byte al posto dell'array e shiftOut(), o tieni l'array com'è e piloti latch, clock e data "a mano".

I pin sono quelli che vuoi tu, quelli a cui hai collegato i vari segnali dello SR insomma. OE puoi anche metterlo direttamente a massa se va bene che lo SR sia sempre attivo.

#define LATCHPIN    4    // Shift Register LATCH
#define DATAPIN     2    // Shift Register DATA
#define CLOCKPIN    5    // Shift Register CLOCK
#define OEPIN       3    // Shift Register |OUT ENABLE

// Array uscite valvole
byte statoEV[8] = {0, 1, 0, 0, 0, 0, 1, 1};

byte tempEV = 0;

void setup()
{
  pinMode(DATAPIN, OUTPUT);
  pinMode(LATCHPIN, OUTPUT);
  pinMode(CLOCKPIN, OUTPUT);
  pinMode(OEPIN, OUTPUT);
}

void loop()
{
  for (int j = 8; j >= -1; j--)
  {
    digitalWrite(LATCHPIN, LOW);
    digitalWrite(CLOCKPIN, HIGH);
    digitalWrite(DATAPIN, statoEV[j]);
    digitalWrite(CLOCKPIN, LOW);
  }
  digitalWrite(LATCHPIN, HIGH);
}

Così funziona bene, tuttavia ho dovuto impostare in maniera "errata" la condizione del for: per me dovrebbe essere:

for (int j = 7; j >= 0; j--)

tuttavia così non mi spedisce tutti i bit, mentre con

for (int j = 8; j >= -1; j--)

me li restituisce corretti.

Perche?

Dentro al for togli il latch e fai le cose in questa sequenza: - scrivi data - metti clock basso - metti clock alto

Dopo il for: - metti latch basso - metti latch alto

Funziona Perfettamente!

Grazie mille!