Programmare cubo led 4x4x4 con due 74HC595

è tutto scritto in quel link, lo hai letto? smiley-razz )

Quale link? :relaxed:

ciclo iniziale ...

  1. spegni tutti gli strati
  2. impulso LOW su SCLR (pulisce il registro)
  3. invio stringa su SI e clock su SCK
  4. impulso alto su RCK (passa i dati in latch, poi deve tornare basso per mantenerli)
  5. abilita strato 1

da qui in poi ...

  1. impulso LOW su SCLR (pulisce il registro, ma i dati delle uscite sono mantenuti dai latch)
  2. invio stringa su SI e clock su SCK
  3. spegni strato 1
  4. impulso alto su RCK (passa i dati in latch, poi deve tornare basso per mantenerli)
  5. abilita strato 2

torna ad 1) ... ecc ...

Tu lo piloti in questo modo

Non è che ci abbia capito molto :sweat_smile:
Comunque io prima accendo il livello (che non è connesso ad uno shift register), poi abbasso il latch, passo i dati (nella funzione c'è sia il bit di clock che quello del serial input) e poi riattivo il latch

toti94:

è tutto scritto in quel link, lo hai letto? smiley-razz )

Quale link? :relaxed:

Scusa, "pagina". La pagina di spiegazione del comando bitSet.

@etemenanki:
No, va bene come fa per gli s/r in serie.
I pin di latch e di clock sono tutti connessi fra di loro, quando mandi low il latch lo fai per tutti i registri, ogni colpo di clock manda avanti di 1 posizione i registri di tutti gli shift register per cui dopo l'8° bit, il 9° passa dal primo al secondo shift automaticamente. Alla fine della sequenza, ritirando su il segnale del latch tutti gli shift presentano il registro sui loro pin.
Ovviamente questo discorso è valido se le connessioni sono fatte come si deve... :wink:

Le connessioni le ho riviste 10mila volte =(
poi scusa perchè con la funzione "uno_per_uno()" va tutto bene e con gli altri non molto? :S

Ripartiamo da capo....

  1. serve lo schema elettrico. Magari hai sbagliato qualcosa e non te ne accorgi perché per te è giusto ma in realtà è sbagliato.
  2. serve lo sketch completo di uno_per_uno() - non hai messo il setup ed il loop, vediamoli.

leo72:
...
I pin di latch e di clock sono tutti connessi fra di loro, quando mandi low il latch lo fai per tutti i registri ...

Si, ma se colleghi insieme RCK e SCK, le uscite saranno sempre una posizione spostate rispetto allo shift interno ... dal datasheet :wink: ST Microelectronics 387709, DS datasheet pdf " ... If both clocks are connected together, the shift register state will always be one clock pulse ahead of the storage register. ... "

In genere la sequenza che ho postato si usa per rendere piu "fluido" il passaggio dei dati, e per evitare questo problema ... prima cancelli lo shift per essere sicuro che non rimangano vecchi dati, poi mandi le due stringhe negli shift, poi dai un singolo impulso all'RCK per passare i dati dallo shift al latch in un colpo solo, poi puoi rifare il tutto per le stringhe successive mentre il latch ti tiene i dati di prima sulle uscite ... se il latch lo passi nelle "pause" fra lo spegnimento di uno strato e l'accensione del successivo, in teoria anche l'animazione dovrebbe risultare piu fluida e regolare, senza sovrapposizione di stati ... e dato che sia la cancellazione che il latch dovrebbero richiedere solo un paio di cicli di clock, non ci dovrebbero essere pause avvertibili ...

Non sapevo di questa cosa. Io ho sempre fatto come detto (latch su low, spedizione con shiftout dei byte per tutti gli shift register e poi latch su high) e non mai avuto problemi, forse perché le mie necessità erano differenti, nel senso che non avevo bisogno di animazioni ultraveloci.

Si, funziona anche cosi, ma solo perche' il 595 usa dei flip-flop D come latch (mi ero confuso anch'io pensando che avessi collegato insieme i due clock) ... la procedura di cui parlavo io si usava principalmente per trasferire dati sui bus, usando normali shift register ... in quel modo, infatti, quando il latch cambia, cambia tutto in una volta, senza sovrapposizioni di bit, ed e' predicibile (sai in quale momento cambia e puoi sincronizzarci gli ingressi del bus).

Comunque per il 595 il trasferimento avviene solo sul fronte positivo dell'impulso di clock, quindi in teoria e' indifferente il riportare il latch a LOW per memorizzare i dati ... ti funziona lo stesso, perche' trasferisci tutto nel momento in cui lo mandi HIGH ... con i diversi latch piu comuni, quelli cosiddetti "trasparenti" invece, se non usi la procedura corretta, i dati in uscita cambiano man mano che i bit dello shift vengono caricati (nel senso che invece di trasferire lo shift al buffer solo sul fronte di salita, le uscite sono connesse, ad esempio, allo shift quando il latch e' a LOW e vengono latchate solo quando il pin di latch e' a HIGH, quindi se li usassi nello stesso modo avresti uno sfarfallio di tutti i led durante i cicli di shiftout ... con il 595 invece, mandare il latch a HIGH dopo aver caricato i dati, o dargli un solo impulso e riportarlo a LOW, e' la stessa cosa ... non serve neppure che lo porti a LOW mentre carichi i dati nello shift, e' sufficente l'impulso alla fine :wink:

Non ho uno schema ordinato :S però ho fatto questo su fritzing giusto per farvi vedere i collegamenti tra i due s/r e le due colonne e due livelli, ho lasciato stare i collegamenti con i pin di arduino perchè poi quelli dipendono dal programma

Ma quindi come dovrei scrivere nello sketch per fare quello che dice Etemenanki .... non sono così preparato in materia per capire al 100% quello che ha detto >_<

Allora, connessioni: i due pin 10 assieme (clear degli shift) ad un'uscita che chiamerai "canc" o simile (per cancellare gli shift prima di scriverci una nuova sequenza di bit) ... i due pin 11 (SCK) assieme ed all'uscita "clock" ... i due pin 12 (RCK) assieme, ed all'uscita "latch" ... i due pin 13 assieme ed a massa ... il pin 14 del primo shift all'uscita "data", il pin 14 del secondo shift al pin 9 del primo shift ...

Io ancora non riesco a scrivere uno sketch decente, quindi posto solo le sequenze logiche, poi tu controllale ed inseriscile nel tuo sketch, anche perche' sto andando a mente e non ho nulla di pronto per testarle qui, ok ?

blocco degli azzeramenti preliminari: va eseguito solo una volta all'accensione, serve per azzerare tutto in modo da essere sicuri di partire con tutto a zero ... magari non e' indispensabile, ma male non fa :stuck_out_tongue: :smiley:

digitalWrite(npn[1], LOW); //spegne strato
digitalWrite(npn[2], LOW); //spegne strato
digitalWrite(npn[3], LOW); //spegne strato
digitalWrite(npn[4], LOW); //spegne strato
digitalWrite(canc, LOW); //cancella shift
digitalWrite(canc, HIGH); //sblocca canc
digitalWrite(latch, HIGH); //azzera latch (passandogli tutti gli 0 dello shift)
digitalWrite(latch, LOW); //blocca latch

...

inizio dei cicli, sequenza logica dei comandi:

shiftOut(data, clock, MSBFIRST, 0b10101010); //primo 74HC595
shiftOut(data, clock, MSBFIRST, 0b10101010); //secondo 74HC595
digitalWrite(latch, HIGH); //passa shift al latch
digitalWrite(latch, LOW); //azzera pilotaggio latch (le uscite non cambiano)
digitalWrite(npn[1], HIGH);//attiva strato

...

per passare i dati da uno strato all'altro:

digitalWrite(canc, LOW); //cancella shift
digitalWrite(canc, HIGH); //sblocca canc
shiftOut(data, clock, MSBFIRST, 0b01010101); //primo 74HC595
shiftOut(data, clock, MSBFIRST, 0b01010101); //secondo 74HC595
digitalWrite(npn[1], LOW);//spegne strato 1
digitalWrite(latch, HIGH); //passa shift al latch
digitalWrite(latch, LOW); //azzera pilotaggio latch
digitalWrite(npn[2], HIGH);//attiva strato 2

... e cosi via ... come ho detto, e' solo la sequenza logica, devi trasformarla tu in uno sketch :wink:

ma cancellando lo shift si spegneranno i led accesi prima?
cioè se io volessi accendere prima 3 led in un piano e poi 3 su un altro, se uso canc dello shift poi i primi 3 led si spengono?

I primi 3 led si spengono quando spegni lo strato precedente per accendere quello successivo, ovviamente ... se vuoi tenere accesi led su strati differenti devi riscrivere le loro stringhe quando il multiplex ti riaccende quello strato.

Ad esempio, metti di voler tenere accesi il led 1 sulo strato 1, il led 2 sullo strato 2, il led 3 sullo strato 3 ed il led 4 sullo strato 4 ... la tua sequenza di multiplexing e':

spedisco stringa 1 allo shift -> accendo strato 1 -> azzero shift, spedisco sequenza 2 allo shift (nel frattempo il led 1 rimane acceso perche' e latchato) -> spengo strato 1 -> latch -> accendo strato 2 -> azzero, spedisco sequenza 3 allo shift -> spengo strato 2 -> latch -> accendo strato 3 -> azzero, spedisco sequenza 4 allo shift -> spengo strato 3 -> latch -> accendo strato 4 -> torno all'inizio ... e cosi via ...e' la persistenza visiva che te li fa vedere tutti accesi, in realta' il multiplex te li accende e spegne ad ogni passaggio, sempre, anche quando vuoi accendere un singolo led ...

Prima di cambiare le connessioni vorrei capire meglio XD
Quindi devo prendere i due pin 10 degli s/r e collegarli entrambi su un solo pin di arduino?
poi quindi quando invio la serie di bit devo fare:

invio prima serie
accendo il piano
azzero (settando high i due pin 10)
latch su low per memorizzare
invio seconda
accendo piano
azzero
latch

e così via?

i pin 10 ora a me sono collegati a +5V

Quando su un pin vedi un segno "-" vuol dire che quel pin è attivato da un segnale basso.
Vedi che MR ha il segno sopra, per cui se lo metti su High non resetti i chip, per resettarli devi metterli su low.

Allora ... i pin 10 sono il reset degli shift register interni, nel funzionamento normale vanno tenuti ad 1, e quando gli dai un'impulso a 0 cancella la parte shift register (o se preferisci, ci scrive tutti 0 ... il che potrebbe velocizzare lo sketch ogni volta che le due stringhe sono tutte a 0, ma questo e' un'altro discorso ;)) ... lo si usa per essere sicuri di partire con tutti i registri a 0, ma NON cancella le uscite perche' quelle sono memorizzate nel banco dei flip-flop, per cancellare tutte le uscite devi prima mettere tutti i registri a 0 (impulso a 0 su SCLK), poi latcharle (impulso ad 1 su RCK) ... questo lo fai una volta sola all'inizio del programma per essere sicuro di partire con tutto a 0, non e' indispensabile.

Si, se vuoi usare la funzione di cancellazione fra una stringa e l'altra, devi scollegare i due pin 10 dal positivo e collegarli ad una delle uscite di arduino (che puoi chiamare clear o in qualsiasi altro modo vuoi) ... a questa uscita che deve rimanere alta durante il funzionamento normale, mandi impulsi bassi solo quando vuoi cancellare la parte shift register, subito prima di inviare la nuova stringa di dati.

Come dice anche leo, quando sul datasheet vedi degli ingressi con il nome con sopra una riga, significa "negato", cioe' che funziona in negativo ... un'ingresso normale si abilita dandogli un 1, mentre un'ingresso negato si abilita dandogli uno 0 ... in questo caso, il reset degli shift rimane ad 1 nel funzionamento normale e resetta quando va a 0 ... lo stesso per i pin 13, G negato, che per far funzionare le uscite deve essere a 0 (se lo metti ad 1, apre le uscite in 3state)

Nella tua sequenza di multiplexing, per inviare i dati, partendo con tutto a 0 e gli strati spenti

invii i due shiftout
mandi un'impulso positivo su RCK (il che memorizza i dati dello shift nel latch, poi riporti a zero RCK)
abiliti lo strato corrispondente a quella sequenza (diciamo 1)
mandi un'impulso 0 sui pin 10 (cancelli gli shift, le uscite rimangono accese perche' sono memorizzate nel latch)
invii i due successivi shiftout
spegni lo strato 1
invii un'impulso positivo su RCK (memorizza la nuova stringa nel latch)
accendi lo strato 2

e cosi via ...

leo: MR ? ... sui miei datasheet non c'e' nessun pin segnato MR, suppongo che intendi SCLR ? (il reset degli shift ?)

Ok ora mi è chiaro xD
Scusate l'ignoranza :sweat_smile:
Ora cambio i collegamenti e scrivo lo sketch e vifarò sapere xD

Etemenanki:

leo: MR ? ... sui miei datasheet non c'e' nessun pin segnato MR, suppongo che intendi SCLR ? (il reset degli shift ?)

http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf
vedi figura fig. 5, pag. 4

e poi tabella 2, pag. 6:
MR 10 master reset (active LOW)

ciao
comunque entrambi sono sul pin 10

stefano

Si, ho visto ... su entrambi i datasheet che ho io i nomi sono diversi dal tuo, ma le funzioni sono le stesse, chi ha stampato quel datasheet si e' limitato a cambiare i nomi ai pin ...

SCLR diventa MR ... RCK diventa STCP ... CLK diventa SHCP ... SI diventa DS ... G diventa OE ... ecc ... alla faccia dello "standard" :stuck_out_tongue: XD

Ecco qui, ho collegato i due pin 10 ad un pin di arduino.
Ma lo sketch cubo() continua a non andare bene D:
Però come al solito lo sketch uno_per_uno() funziona a dovere
lo sketch è questo:

void cubo()
{
  digitalWrite(canc, HIGH);
  digitalWrite(latch, LOW); 
  
  shiftOut(data, clock, MSBFIRST, 0b00000000); 
  shiftOut(data, clock, MSBFIRST, 0b10000000);
  digitalWrite(latch, HIGH);
  digitalWrite(latch, LOW); 
  digitalWrite(npn[0], HIGH);
  digitalWrite(canc, LOW);
  digitalWrite(canc, HIGH);

  shiftOut(data, clock, MSBFIRST, 0b1001000); 
  shiftOut(data, clock, MSBFIRST, 0b00001001);
  digitalWrite(latch, HIGH);
  digitalWrite(latch, LOW); 
  digitalWrite(npn[1], HIGH);
  digitalWrite(canc, LOW);
  digitalWrite(canc, HIGH);
  
  shiftOut(data, clock, MSBFIRST, 0b1001000); 
  shiftOut(data, clock, MSBFIRST, 0b00001001);
  digitalWrite(latch, HIGH);
  digitalWrite(latch, LOW); 
  digitalWrite(npn[2], HIGH);
  digitalWrite(canc, LOW);
  digitalWrite(canc, HIGH);
  
  shiftOut(data, clock, MSBFIRST, 0b11111001); 
  shiftOut(data, clock, MSBFIRST, 0b10011111);
  digitalWrite(latch, HIGH);
  digitalWrite(latch, LOW); 
  digitalWrite(npn[3], HIGH);
  
  digitalWrite(latch, HIGH);
}

ovviamente nel loop() ho semplicemente scritto cubo();

Continuano a non accendersi i contorni del cubo led ma altri led :expressionless: