[RISOLTO] Shift Register, cosa succede tra latch LOW e HIGH?

Buongiorno a tutti.

Stavo osservando - per ora online - il 74HC595. Avendo una scheda relè a 16 canali della Sainsmart, volevo capire se potevo sfruttare il mio Arduino UNO R3, oppure se passare p.es. ad una MEGA2560. Sciogliendo qualche dubbio potrei capire se questo componente risponde a quello che cerco e investire tempo per svilupparci qualcosa.

Lo scenario potrebbe essere questo:

  • devo controllare 16 relè che comandano 16 lampadine, posizionati su una scheda esterna che ha ingressi fotoaccoppiati
  • voglio inserire il multiplexing, tramite p.es. il 74HC595 per risparmiare pin sulla UNO

I dubbi
Cosa succede fisicamente alle uscite del multipl. tra le istruzioni latch LOW e latch HIGH?

http://arduino.cc/en/Tutorial/ShftOut12 con 3 righe commentate

void registerWrite(int whichPin, int whichState) {
// the bits you want to send
  byte bitsToSend = 0;

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);             // ----------------------------------> LOW

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

    //turn on the output so the LEDs can light up: //------------------------> TURN ON?!
  digitalWrite(latchPin, HIGH);             // ----------------------------------> HIGH

}

In altre parole, il mio dubbio è se le uscite già settate HIGH subiscono delle variazioni, magari per microsecondi (?), in attesa di ricevere in ingresso i "nuovi" bit.

Se dovessi chiudere (=attivare), p.es., 6 relè di quei 16 della scheda, poi dover attivarne un altro, gli altri 6 con uscita già HIGH (o LOW come nel mio caso, avendo una scheda a logica invertita), come si comportano? Rimangono HIGH sempre?
Le ipotetiche 6 lampadine già accese non avrebbero nessun effetto?

Altro scenario è invece l'uso della scheda relè come "pilota" per relè passo-passo (tipo Finder 20.22 mi pare). In pratica i relè della scheda lavorano sulle bobine dei relè che portano i carichi.

In questo secondo scenario, i relè della scheda non sono attivi per la maggior parte del tempo e inviano semplicemente un impulso, simulando la pressione di un banale pulsante.

Anche qui il dubbio è che nell'aggiornamento del 74HC595 succeda qualcosa alle uscite già settate con istruzioni precedenti.

Grazie

ciao
ho lavorato con 74hc595 il latch L serve a mettere il shift nella condizione di ricevere il byte e H per presentare il byte alle uscite, durante le ricezione non cambia lo stato delle uscite

Ok, grazie.

Quindi non mi devo aspettare, nel caso, nessun "sfarfallamento" sui carichi.

Ottimo.

Ciao

Al posto di multiplexare perché non metti i 2 595 in serie e carichi ogni volta i dati per entrambi ( 16 bit) ? ? ?
Ciao Uwe

uwefed,

intendi in daisy-chain?

Si, ho visto anche questo, però volevo prima essere certo che nel mandare latch LOW non ci fossero variazioni sugli output già settati da uno shiftOut precedente (mi riferisco all'esempio al primo post).

Ora che ne sono certo, penso di provare proprio con 2 595 e gestire 16 uscite con 3 pin.

Il passo successivo sarà gestire 8-16 ingressi digitali con pochi pin!

Grazie

andreino:
Ok, grazie.

Quindi non mi devo aspettare, nel caso, nessun "sfarfallamento" sui carichi.

Ottimo.

Ciao

questo problema, come mi hanno spiegato nel forum, lo risolvi usando il pin OE mettendolo a +5v attraverso una resistenza e che manderai L con un pin di arduino

stefa24:
questo problema, come mi hanno spiegato nel forum, lo risolvi usando il pin OE mettendolo a +5v attraverso una resistenza e che manderai L con un pin di arduino

Puoi mettere un riferimento alla spiegazione (interessa anche a me) perché vorrei capire meglio la storia dell'OE in quanto pensavo che bastasse tenerlo HIGH o LOW con il solito pin di arduino senza utilizzare la resistenza di pull-up.
Ciao e grazie

ciao
la discussione era questa
http://forum.arduino.cc/index.php/topic,264753.0.html
allegato lo schema dell'applicazione

trapianto_completo_1.pdf (28.1 KB)

L'output enable (OE), in questo caso negato, serve per abilitare o disabilitare le uscite ... se e' LOW, trasferisci all'uscita lo stato del latch (cioe', le varie uscite sono LOW o HIGH a secondo del byte che avevi memorizzato nel latch), mentre se lo metti HIGH, le uscite si disconnettono (vanno in stato di alta impedenza, il che e' un po come se non fossero collegate a nulla, volanti)

Invece il pin LATCH (che qualche datasheet nomina stupidamente STCP, altri RCK, ed altri LC, tanto per confondere un po le idee agli utenti e fare casino inutilmente :stuck_out_tongue: :D) memorizza lo stato del registro seriale che hai appena caricato nel buffer (e ovviamente, se OE e' LOW, te lo manda immediatamente alle uscite) ... e' ovvio che se, ad esempio, tu hai accesa l'uscita 1, e vuoi accendere anche la 3, senza spegnere la 1, il byte che devi mandare deve contenere entrambe le uscite accese ... poi, quando dai l'impulso al pin LATCH, il nuovo valore viene trasferito immediatamente al buffer e alle uscite, e l'uscita 3 si accende senza che la 1 si spenga o sfarfalli ... e cosi via ...

Sarebbe anche buona cosa prevedere sempre un'impulso sul CLEAR del registro prima di mandare ogni nuovo byte, in modo da essere sicuri che non si creino casini (tanto le uscite non cambiano finche' non dai l'impulso di latch)

@stefa24: grazie, non mi ero imbattuto in quel 3d

@Etemenanki: molto interessante, questo conferma ancora di più che le uscite rimangono stabili. Invece non mi è chiaro l'uso dell'impulso sul CLEAR: intendi un H/L in pochi micros.? E lo si fa tra latch L e latch H? Grazie

@stefa24: Grazie del link

Se non ho capito male le risposte di uwe la resistenza di pullup serve solo nel momento della programmazione per il problema del pin in alta impedenza se poi nello sketch definisci ilpin come output occorre settare comunque correttamente lo stato a HIGH o LOW in base al comportamento che si vuol ottenere.
Tra l'altro stavo valutanto per un mio progetto di lasciare liberi i pin indicati nell'altro 3d per evitare problemi in fase di riprogrammazione del 328 ma chiaramente si può fare solo se si hanno altri pin a disposizione.
Ciao

si la resistenza di pullup su OE serve a evitare lo sfarfallio in fase di programmazione che poi mandi low nel setup

per risolto, grazie.

L'impulso su clear azzera lo stato dello shift register interno (ma senza cambiare lo stato delle uscite, che sono latchate) ... non sarebbe indispensabile, ma di solito si preferisce usarlo per azzerare il registro prima di inviargli un nuovo dato (per evitare qualsiasi tipo di problemi), oppure puo essere usato per azzerare tutte le uscite senza dover mandare uno o piu byte di tutti zeri (invece di fare shiftout con tutti zeri e poi latch, si fa semplicemente clear e latch ... per noi non ha molta importanza il risparmio di tempo, ma in circuiti molto veloci si, oppure se hai parecchi registri in daisy-chain da azzerare tutti quanti ...)

EDIT: inoltre ti permette di partire sempre all'accensione da una condizione nota, invece di rischiare di avere azionamenti random al power-up :wink:

interessante anche questo clear!

Infatti, dovendo gestire una scheda a 16 relè con logica invertita, avrei proprio la necessità di partire con un HIGH su tutte le uscite del/dei 595:

ti permette di partire sempre all'accensione da una condizione nota

una "condizione nota" può essere HIGH o LOW oppure solo LOW?

Perchè appena sopra dici:

puo essere usato per azzerare tutte le uscite senza dover mandare uno o piu byte di tutti zeri (invece di fare shiftout con tutti zeri e poi latch, si fa semplicemente clear e latch

quindi mi sembra di capire che con CLEAR/LATCH si porta solo a zero.

E' corretto?

Inoltre, questo "impulso" è costituito da 2 istruzioni consecutive senza delay?

Grazie

Si, per condizione nota intendo LOW, perche' di solito si preferisce partire sempre con tutto a zero, per sicurezza ... se ti serve tutto HIGH (anche se non immagino perche'), devi per forza dare lo shiftout con tutti 1 e poi latch ...

tutto a HIGH perchè così i relè della scheda a 16 canali non scattano

tra l'altro ho momentaneamente ovviato a questo problema, che si manifesta durante il reset/accensione/programmazione, utilizzando un relè singolo di altra scheda per non dare i +12V (quello si mettendo LOW il relativo pin) fino al setup(), dove finalmente mando HIGH il relè singolo e do tensione alla scheda a 16 canali, dopo aver messo HIGH le uscite di Arduino.

Le uscite HIGH sono "di riposo" per i 16 relè. Con brevi impulsi LOW-HIGH chiudo-apro e controllo il relè passo-passo. Mi è appena arrivata e per ora mi sono arrangiato così :blush:

Se il CLEAR sul 595 porta le uscite tutte a LOW, nel mio specifico caso non mi è utile.

Vabbè, comunque si tratta delle fasi di accensione, portare HIGH 8(+8) uscite non è un problema di tempi.

grazie mille!

Quindi hai dei rele' che scattano mandandogli gli ingressi a LOW ... allora ti viene buono il pin OE ...

Dato che OE ti cambia lo stato delle uscite da "connesse" a "disconnesse" (in realta', alta impedenza, ma parliamo di parecchi megaohm, quindi e' come se fossero scollegate), puoi usare delle resistenze di pullup sulle uscite, tipo da 22K, e partire all'accensione con il pin OE a HIGH (anche lui con una resistenza di pullup, e chiudendolo a massa attraverso un transistor collegato a collettore aperto, che ti evita di attivarlo per sbaglio se Arduino parte con tutte le uscite basse) ... mandi il tuo treno di bit alti al registro, lo trasferisci al latch, e solo a quel punto abiliti OE, che ti trasferisce il latch alle uscite (che essendo gia alte, rimangono alte ed evitano che i rele' scattino da soli all'accensione) ... inoltre in questo modo, se devi comandare uno spegnimento di tutti i rele' assieme di colpo per qualsaisi motivo, emergenza o altro, ti basta rimandare alto OE, le uscite si aprono, e le resistenze di pullup sulle uscite ti spengono tutti i rele assieme :wink:

EDIT: ti ho buttato giu uno schemino di principio al volo, ma controllalo perche' e' proprio fatto di corsa ... le resistenze sulle uscite vanno bene da 22K, R4 da 100K, le altre 3 da 10K, il condensatore da 100nF (se non usi il reset, la resistenza ed il condensatore si mettono per dare un'impulso di reset all'accensione e basta, se invece vuoi usarlo nel tuo sketch, le togli e porti fuori i pin insieme su un'uscita di Arduino), il transistor inverte l'uscita di Arduino in modo da evitare che OE si attivi quando accendi (per attivarlo, devi pilotare il transistor con HIGH)

Etemenanki:
Quindi hai dei rele' che scattano mandandogli gli ingressi a LOW ... allora ti viene buono il pin OE ...

esatto, è questa SainSmart 16canali 12V (appena presa, ci sto giocando)

Dato che OE ti cambia lo stato delle uscite da "connesse" a "disconnesse" (in realta', alta impedenza, ma parliamo di parecchi megaohm, quindi e' come se fossero scollegate), puoi usare delle resistenze di pullup sulle uscite, tipo da 22K, e partire all'accensione con il pin OE a HIGH (anche lui con una resistenza di pullup, e chiudendolo a massa attraverso un transistor collegato a collettore aperto, che ti evita di attivarlo per sbaglio se Arduino parte con tutte le uscite basse) ... mandi il tuo treno di bit alti al registro, lo trasferisci al latch, e solo a quel punto abiliti OE, che ti trasferisce il latch alle uscite (che essendo gia alte, rimangono alte ed evitano che i rele' scattino da soli all'accensione) ... inoltre in questo modo, se devi comandare uno spegnimento di tutti i rele' assieme di colpo per qualsaisi motivo, emergenza o altro, ti basta rimandare alto OE, le uscite si aprono, e le resistenze di pullup sulle uscite ti spengono tutti i rele assieme :wink:

ottimo

in particolare, nel mio caso, non metto i carichi direttamente su questi relè, ma su relè Finder tipo da barra DIN. In questo modo i relè della scheda scattano per una frazione di tempo, giusto per dare l'impulso al relè in quadro.

Garantire di averli tutti HIGH (=relè in scheda non scatta-->relè in quadro non ne risente [il rischio è tenere eccitata la bobina senza accorgersene!]) per il 99.99% del tempo è molto comodo.

Appena mi arrivano dei 595 voglio provare. Sul lato prettamente pratico, voglio vedere cosa succede proprio durante l'avvio di Arduino.

I relè della scheda sono alimentati a parte a 12V, mentre gli ingressi sono fotoaccoppiati. All'avvio di tutto il sistema, mi troverei con la scheda relè alimentata e probabilmente (?) gli ingressi LOW con conseguente attivazione del relè (-->corrente alla bobina dei relè in quadro), prima ancora di aver mandato OE HIGH (nel setup()? o anche prima?). Poi immagino mando tutto HIGH e i relè tornano a riposo, liberando la bobina, con il risultato di aver invertito tutte le luci di casa! :-X

EDIT: ti ho buttato giu uno schemino di principio al volo, ma controllalo perche' e' proprio fatto di corsa ... le resistenze sulle uscite vanno bene da 22K, R4 da 100K, le altre 3 da 10K, il condensatore da 100nF (se non usi il reset, la resistenza ed il condensatore si mettono per dare un'impulso di reset all'accensione e basta, se invece vuoi usarlo nel tuo sketch, le togli e porti fuori i pin insieme su un'uscita di Arduino), il transistor inverte l'uscita di Arduino in modo da evitare che OE si attivi quando accendi (per attivarlo, devi pilotare il transistor con HIGH)

grazie, è una gentilezza che mi hai rivolto più volte, grazie mille

ps: non credo di essere in grado di valutare (!) un tuo schema (!) :blush:

EDIT: sto riguardando lo schema, se ho capito bene le resistenze R6-R20 hanno proprio lo scopo di impedire all'accensione quello che ho ipotizzato sopra, cioè avere per un breve tempo gli ingressi "non-HIGH"

mi rimane il dubbio di cosa succede nella pratica, dando corrente simultaneamente a tutto (Arduino, scheda relè, ecc.)

grazie