Programmare cubo led 4x4x4 con due 74HC595

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:

Oggi mi ero messo a giocare con un paio di 595 ed un pò di led... appena montato tutto, scrivo uno sketch velocissimo per fare accendere tutti i led... Risultato: tutti SPENTI :stuck_out_tongue_closed_eyes:
Ricontrollo, ed avevo invertito i segnali dati ai pin MR e OE ]:smiley:
Metto tutto a posto, riprovo.... led impazziti, che si accendono a caso. Addirittura, sfilando il cavo del segnale di clock, lampeggiano tutti i led.... :sweat_smile:
Ricontrollo tutto altre 10 volte e poi? Avevo sbagliato il programma: dichiaravo i pin 5/6/7 per latch, clock e dati mentre avevo collegato i fili sui pin 6/7/8 :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

Questo per dirti che anche riguardando spesso sembra tutto fatto bene ma poi l'erroruccio è dietro l'angolo. Ah, ti confesso che avevo pensato a te, non so però se più come ad uno iettatore o ad un compagno di sventura :wink:

hahahahahahahahaha spero come compagno di sventura ahahahaha XD
Ora controllo per la 100sima volta :slight_smile:

Prova cosi, per curiosita' (ho fatto copia incolla dal tuo, ho solo cambiato un paio di linee) ... in teoria dovrebbe (se funziona :P) accenderti i 4 led sulle colonne esterne , passandoli di strato in strato (mettici tu dei delay della durata che vuoi per rallentarlo se vuoi controllare)

void cubo()
{
  
  shiftOut(data, clock, MSBFIRST, 0b10010000); 
  shiftOut(data, clock, MSBFIRST, 0b00001001);
  digitalWrite(npn[0], LOW);
  digitalWrite(npn[1], LOW);
  digitalWrite(npn[2], LOW);
  digitalWrite(npn[3], LOW);
  digitalWrite(latch, HIGH);
  digitalWrite(latch, LOW); 
  digitalWrite(npn[0], HIGH);
  digitalWrite(canc, LOW);
  digitalWrite(canc, HIGH);

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

}

Bada che anch'io sto imparando ora, quindi non mi ritengo responsabile se i miei tentativi causano risultati imprevedibili, fumo e/o fuoco, la zombificazione del vicinato, o il lancio di una testata nucleare dalla nazione vicina come rappresaglia, ok ? :wink: XD

EDIT: per trasformare il blocco di 4 righe che scrive tutti 0 sulle uscite, c'e' un modo per mandare lo stesso comando contemporaneamente a tutte e 4 le uscite ? (sul reference non ho trovato nulla a proposito di questo) ... oppure bisogna per forza definire una subroutine esterna e richiamarla ogni volta ? ...

per trasformare il blocco di 4 righe che scrive tutti 0 sulle uscite, c'e' un modo per mandare lo stesso comando contemporaneamente a tutte e 4 le uscite ? (sul reference non ho trovato nulla a proposito di questo) ... oppure bisogna per forza definire una subroutine esterna e richiamarla ogni volta ? .

Non ho capito di quale blocco parli :\

Comunque il tuo sketch funziona a dovere XD mi accende le 4 colonne agli angoli.
Quindi l'errore è nei miei sketch xD

Però modificando la prima serie e l'ultima serie di bit viene tutto scombinato >_>
Inoltre volevo chiedere, in questo sketch ho usato male la funzione bitset?

void colonne(int pausa)
{
  byte address_1= B00000000;
  byte address_2= B00000000;
  
  for(i=0;i<16;i++)
  {
    if(i<8)
    bitSet(i, address_1);
    else
    bitSet(i, address_2);
    
    digitalWrite(canc, HIGH);
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, address_1); 
    shiftOut(data, clock, MSBFIRST, address_2);
    digitalWrite(latch, HIGH);
    digitalWrite(latch, LOW); 
    digitalWrite(npn[0], HIGH);
    digitalWrite(npn[1], HIGH);
    digitalWrite(npn[2], HIGH);
    digitalWrite(npn[3], HIGH);
    digitalWrite(canc, LOW);
    digitalWrite(canc, HIGH);
    delay(pausa);
  }
}

toti94:
in questo sketch ho usato male la funzione bitset?

L'hai usata in modo strano... :sweat_smile:
bitSet accetta 2 parametri: la variabile su cui lavorare e la posizione del bit da impostare ad 1. Esempio:

bitSet(miaVar, 2);

Tu non ho capito invece come la stai usando :*

byte address_1= B00000000;
bitSet(i, address_1);

In pratica prima dichiaro il byte, poi setto su 1 il bit corrispondente al contatore del ciclo, da 0 a 7 sulla prima serie e da 7 a 15 sulla seconda serie :\

Allora hai invertito i parametri.

toti94:

per trasformare il blocco di 4 righe che scrive tutti 0 sulle uscite, c'e' un modo per mandare lo stesso comando contemporaneamente a tutte e 4 le uscite ? (sul reference non ho trovato nulla a proposito di questo) ... oppure bisogna per forza definire una subroutine esterna e richiamarla ogni volta ? .

Non ho capito di quale blocco parli :\

Mi riferivo a:

digitalWrite(npn[0], LOW);
digitalWrite(npn[1], LOW);
digitalWrite(npn[2], LOW);
digitalWrite(npn[3], LOW);

Per spegnere tutti gli strati ... mi chiedevo se fosse possibile con una digitalwrite sola passare lo stesso parametro a 4 o piu pin diversi (sul reference non ho trovato nulla a proposito di questo), o se fosse meglio creare una subroutine e richiamarla ogni volta ...

o fai ogni volta un ciclo così:

for(i=0;i<4;i++)
{
 digitalWrite(npn[i], LOW);
}

oppure questo ciclo lo inserisci in una funzione che chiami spegni_livelli() e ogni volta te la richiami, altri modi non li conosco :\

Si, era quello che intendevo ... una funzione esterna o un ciclo, non c'e' apparentemente modo di passare lo stesso comando a piu pin contemporaneamente con una sola digitalwrite ... grazie.