Go Down

Topic: Programmare cubo led 4x4x4 con due 74HC595 (Read 14852 times) previous topic - next topic

toti94

Quote
Beh, allora c'è qualcosa che non funziona...
Se li accendi tutti funziona, se li accendi alternati no. Ed accendendoli in sequenza 1 ad uno?

Sisi ho usato lo sketch che me li accende uno ad uno in sequenza (lo sketch sta su)
e funziona bene
Quote

Lavora su singoli bit, imposti il bit in posizione "n" del byte x.
I bit vanno di posizione da 0 a 7, da destra verso sinistra (il bit meno significativo a sta destra):
7.6.5.4.3.2.1.0


se quindi ad esempio voglio accendere il 6° led mi basta scrivere bitset(7, byte) e dichiaro prima la variabile byte=B0000000; ?

toti94

ancora problemi ç_ç
scrivendo questo codice
Code: [Select]
digitalWrite(npn[0], HIGH);
  digitalWrite(latch, LOW);
  shiftOut(data, clock, MSBFIRST, 0b00000010);
  shiftOut(data, clock, MSBFIRST, 0b00000000);
  digitalWrite(latch, HIGH);

dovrebbe accendermi il 7° led giusto?
invece mi accende con luce maggiore il 6° e con luce fioca il 7° ..... ho pensato quindi ad un problema nei collegamenti, li ho rivisti e nessun filo si tocca, inoltre ho grattato anche un po' con la punta del giravite fra i due pin in caso ci sia qualche cosa che li metta a contatto, ma niente.
Però usando lo sketch che li accende uno per uno sequenzialmente, questo problema non me lo da :| .... sto uscendo pazzo mi sa

lo sketch uno per uno è questo
Code: [Select]
void uno_per_uno()
{
  int i; //contatore
  for(i=0;i<4;i++)
{
  digitalWrite(npn[i], HIGH); //attivo il livello corrispondente al contatore
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b10000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b01000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00100000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00010000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00001000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000100); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000010); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000001); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b10000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b01000000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00100000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00010000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00001000); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000100); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000010); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(latch, LOW); //latch basso per passare la serie di bit
  shiftOut(data, clock, MSBFIRST, 0b00000000); //prima serie di bit dello 74HC595 n°1
  shiftOut(data, clock, MSBFIRST, 0b00000001); //seconda serie di bit dello 74HC595 n°2
  digitalWrite(latch, HIGH); //riattivo il latch per attivare le uscite
  delay(pausa); //pausa
 
  digitalWrite(npn[i], LOW);//disattivo il livello

}
}


leo72


se quindi ad esempio voglio accendere il 6° led mi basta scrivere bitset(7, byte) e dichiaro prima la variabile byte=B0000000; ?

La variabile da passargli è la variabile che poi passi agli shift register.
Ed hai invertito i parametri, prima si passa la variabile e poi la posizione del led da accendere. Per accendere il 6° led si deve passare il valore 5, perché le posizioni partono da 0 (ma è tutto scritto in quel link, lo hai letto?  :P )

Esempio:
Code: [Select]
byte miaVar = 0;
bitSet(miaVar, 5); //accendo il led in posizione 5, ossia il 6°
shiftOut(data, clock, MSBFIRST, miaVar);

leo72


invece mi accende con luce maggiore il 6° e con luce fioca il 7°

Te lo fa con un solo piano oppure su tutti e 4?

Etemenanki

#19
Jun 24, 2013, 06:38 pm Last Edit: Jun 24, 2013, 06:39 pm by Etemenanki Reason: 1
Aspetta, leggendo 595 mi viene un dubbio ... ma le sequenze di pilotaggio glie le passi correttamente ? ... perche' non e' uno shift/latch, e' uno shift/store/3state ... non ti so scrivere lo sketch, ma la sequenza piu logica per pilotare uno di quelli e' questa:

(partendo con SCK, SI e RCK bassi, G sempre basso, non usando le uscite 3state):

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 ?
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

toti94

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

Quale link?  :smiley-slim:
Quote
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   :smiley-sweat:
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

leo72


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

Quale link?  :smiley-slim:

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...  ;)

toti94

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

leo72

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.

Etemenanki


...
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 ;) http://pdf.datasheetcatalog.com/datasheets/320/387709_DS.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 ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

leo72

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.

Etemenanki

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 ;)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

toti94

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 >_<

Etemenanki

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 :P :D

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 ;)
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

toti94

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?

Go Up