Nuova libreria 74HC595 per controllo display LCD ed uscite digitali

Ciao a tutti. Durante lo sviluppo di un progettino, mi sono imbattuto nello "studio" degli shif register, in particolare del 74HC595. Inizialmente l'ho usato per espandere le uscite digitali di Arduino. Successivamente ho usato lo stesso chip per "risparmiare" pin nel collegamento di un display LCD 16x4. Il problema è che non ho trovato nessuna libreria in grado di gestire entrambe le cose sulla stessa serie di 745HC595, infatti c'è una versione modificata della liquidcrystal per comandare i display attraverso lo shift register, ma non permette di gestire in contemporanea le uscite digitali oltre al fatto che i pin utilizzabili sono limitati. Visto che non ho trovato nulla di pronto ho dedicato alcuni giorni alla scrittura di una libreria fatta apposta per questo scopo.
Permette di gestire fino a 256 shift register in serie, usando qualunque pin di Arduino; su ogni singolo 74HC595 potete metterci un display oppure sfruttare le 8 uscite digitali. Ho scritto un articoletto sul mio blog per spiegarne il funzionamente, per ora solo in italiano, per cui non vi annoio con ulteriori dettagli. Lo trovate qui:

In fondo all'articolo c'è il link per il download della libreria.

Non ho idea di quante persone possano essere interessate a questo tipo di libreria, comunque se c'è qualche anima pia che ha voglia / tempo di provarla, mi farebbe un grosso favore se mi desse un feedback per farmi avere osservazioni su eventuali bachi, richiesta di nuove funzioni, compatibilità con i vari display.

Come da richiesta riporto qui la pagina di mantenimento della libreria, creata dopo questo post e i vostri suggerimenti: www.mcmajan.com/mcmajanwpr/?page_id=1636

Ciao, Stefano

Quando mi serve un lcd uso sempre uno shift register per risparmiare pin, ti faccio volentieri da tester.
Attuamente uso la libreria shiftlcd, funziona bene ma non permette di collegare altri shift register in cascata.
Un altro grosso difetto consiste nel fatto che non riesce a gestire il controllo della retroilluminazione anche se è previsto nella libreria; appena si prova a spegnere o ad accendere il led il display inizia a dare di matto visualizzando caratteri strani. Per ora l'unico rimedio per gestire la retroilluminazione è sacrificare un altro pin di arduino.

Vedendo i tuoi collegamenti ho notato che il led per la retroilluminazione del display non è collegato allo shift register nonostante ci sono 2 uscite libere (Q0,Q2).
Sarebbe davvero utile se si potesse sfruttare un'uscita per gestire la retroilluminazione, basterebbe aggiungere un NPN (con una resistenza) allo schema e due funzioni alla libreria, ad esempio setBacklightOn e setBacklightOff.
Pensi sia fattibile?
Intanto mi scarico la libreria e ti prometto di fare un pò di test, ho un progettino caldo caldo :wink:

Ottimo. Il bello di condividere con gli altri il proprio lavoro è proprio il condividere punti di vista diversi. Ho lasciato Q0 e Q2 liberi per rendere lo schema di collegamento compatibile con la LiquidCrystal modificata, in questo modo è possibile cambiare sketch senza variare i collegamenti hardware.
Anche se non c'è una funzione specifica puoi comunque sfruttare le due uscite libere, se parti dall'esempio che ho messo nel mio articolo ti basta fare:
My595.bitWrite(Buffer[X],Y,LOW);
My595.Send595();
Dove X indica il numero di shift register (lo 0 è il primo, poi 1,2,....), Y è l'uscita libera da controllare (o / 2) e LOW / HIGH è il livello di uscita. Con Send595 vengono inviati tutti i dati alla catena di shift register per cui viene aggiornato lo stato dell'uscita.
A parte la compatibilità hardware c'è un'altro motivo per cui non ho ancora pensato cosa fare delle uscite 0 e 2. Non ho ancora provato, ma in teoria se allo stesso shift register collego tre display usando gli stessi collegamenti ma collegando il pin Enable dei due display aggiuntivi alle uscite 0 e 2, dovrei essere in grado di comandare ben tre display con un solo shif register....peccato che non ho i display e non posso provare :slight_smile:

Ciao, complimenti per il lavoro svolto e grazie per averlo condiviso. Spero che più di qualcuno possa fare dei test impegnativi, ma il nostro BUD Pelletta è già un validissimo tester, in modo da confermare la piena funzionalità, a quel punto bisognerebbe fare in modo che la lib non si perda assieme a questo Topic, tra qualche giorno; a mio parere sarebbe cosa eccellente inserirla nel PlayGround, anche se personalmente non ho mai lavorato sulla piattaforma.
Riguardo il test che vuoi fare, gli LCD non gradiscono ricevere dati prima di essere pronti a trattarli, per cui se li spegni alla riaccensione facilmente vanno in blocco, diverso dovrebbe essere il discorso del pin ENABLE, che dovrebbe avere proprio la funzione di disabilitare la visualizzazione di dati comunque in arrivo. La cosa è interessante, appena riesci a provarla facci sapere.
:slight_smile:

Mi interessa molto la parte uscite digitali!
mi sa che in questi giorni ci dedicherò del tempo.

per sapere magari hai fatto già delle prove.. c'è un limite per la distanza tra un 74HC595 e l'alto? nel senso che se li collegassi con 1,5m di cavo schermato ci sono grossi problemi? magari di latenza?

Per me è un piacere condividere il lavoro che ho fatto con tutti voi, dopotutto le conoscenze di elettronica che ho vengono da chi ha condiviso i prorpi lavori in rete. Anche il tuo tutorial sui bootloader, Michele, è fra le cose che ho imparato grazie alla condivisione in rete. Se dopo i vostri scrupolosi test mi direte che ne vale la pena posso metterla volentieri nel playground, non ho idea di come si faccia ma ci penserò quando sarà ora.

Per quanto riguarda la domanda di "Leouz", non ho provato, ma anche se questi tipi di connessioni non sono certo pensate per collegamenti "a distanza", credo che fino a 1.5 metri si possa riuscire a far funzionare il tutto, con un buon cavo twisted schermato...se ho l'occasione di fare una prova simile ti faccio sapere, magari con l'oscilloscopio potrei vedere quanto rumore passa

Credo sia meglio prolungare i pin delle uscite piuttosto che i pin di gestione... eventuali interferenze potrebbero far commutare le uscite ad minchiam :sweat_smile:
Non ho mai fatto delle prove di lunghezza, li ho sempre messi vicini nella stessa scheda.

@smania2000: ho iniziato a vedere la libreria, la reputo molto utile.
Intanto ti ringrazio per averla condivisa, appena la testo per bene ti farò sapere come si comporta.
Sto preparando appositamente un pcb per testarla per quanto mi piace :wink:

bel lavoro.

Aggiungi nella libreria anche una cartella Examples, ci semplifichi ancora di piu' la vita

@Pelletta: wow, adirittura un pcb apposta :slight_smile: ... mi fa piacere ti piaccia, spero si comporti bene. Mi raccomando il condensatore di disaccopiamento sui 74HC595, non so se hai letto il mio articolo, ma senza metterlo a random dopo diverse migliaia di cicli di funzionamento, sui display avevo isolati errori di interpretazione che portavano a shiftare l'area del display e a far comparire caratteri indesiderati in giro per lo schermo (sapessi quanto tempo ho perso per capirlo!!!)

@brunello: ottimo suggerimento, nonostante la prima cosa che io faccia con le librerie degli altri è aprire gli esempi, non ho minimamente pensato di scrivere nulla per la mia, mi sono limitato a descrivere il funzionamento nell'articolo. Appena ho un attimo metto degli esempi e li allego alla libreria.

Grazie a tutti.

Tranquillo, ho messo un condensatore da 100nF sugli shift register con gli lcd.
Sto per saldare i pcb e iniziare i test; intanto mi sono permesso di aggiungere due funzioni alla libreria che mi fanno molto comodo.
Non interferiscono con il resto del codice. Una serve per gestire la retroilluminazione dei display:

void hc595::SetBacklight(unsigned char numeroDisplay,unsigned char pinRetro,bool statoRetro)
{
  bitWrite(Buffer[numeroDisplay],pinRetro,statoRetro);
  Send595();
}

Il primo parametro è relativo allo shift register dove è collegato il display, il secondo è l'uscita disponibile dello shift register dove è collegato il transistor (0 o 2) e il terzo è un valore booleano che rappresenta lo stato della retroilluminazione quindi LOW spenta e HIGH accesa.
Esempio:

My595.SetBacklight(0,2,HIGH);// accende la retroilluminazione del display collegato all'uscita 2 del primo shift register

Appena inizializzato il display però la retroilluminazione resterebbe spenta, quindi andrebbe accesa subito dopo l'inizializzazione del display.
Allo stesso modo con l'istruzione ResetDisplay della libreria la retroilluminazione si spegne involontariamente quindi ho aggiunto una seconda funzione per pulire il display senza perdere lo stato della retroilluminazione:

void hc595::clean(unsigned char lcd)
{
  SendLcdCommand(LCD595_DISPLAY_CLEAR,lcd);
}

L'unico parametro da passargli è lo shift register dov'è collegato il display.

Dato che sto ancora usando l'ide 0.022 ho anche fatto in modo di renderla compatibile con le vecchie versioni:

#if ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

Ovviamente sei libero di ignorare queste due funzioni, io le tengo per comodità.
Vado a saldare le schedine per i test, ho un display 16x4 e alcuni 16x2; di questi ultimi ne ho diversi modelli quindi avrò un bel da fare

GRANDIOSO!!!!
Non mi sarei mai sognato di trovare tanta disponibilità.

Mi sembra che le tue siano ottime proposte che andrò ad inserire nel codice finale. Se puoi solo farmi un favore: hai detto che la ResetDisplay spegne la retroilluminazione: la "colpa" dovrebbe essere la "Buffer[num]=0" che trovi dentro la funzione. Potresti provare a commentarla e vedere se fà il reset senza interferire con la retroilluminazione? Se così fosse possiamo cancellarla. Comunque la proposta di usare una funzione "clean" apposita mi sembra ragionevole visto che deve fare un sacco di operazioni in meno.

Grazie mille, aspetto con ansia i risultati.

NB: posso citarti sul mio blog quando farà gli aggiornamenti del caso?

Ho provato due lcd 16x2 e un display 7 segmenti, per adesso tutto bene.
Domani mattina provo i caratteri custom e le cose che mi hai suggerito per il reset.
I primi test li ha superati alla grande, hai fatto un ottimo lavoro!
Per la citazione sul tuo blog non c'è problema, se vuoi ti posso anche fornire qualche immagine e gli esempi che uso per i test

Aggiornamento:
funziona tutto senza sorprese, anche il display 16x4 s'è comportato bene. Al primo tentativo le scritte sulla terza e quarta riga erano spostate a dx di 3 spazi, è bastato impostare a 2 il terzo parametro della funzione "SetCursor" per allineare tutto.
Ho provato a cancellare i display con la funzione "ResetDisplay"; commentando "Buffer[num]=0" i display tornano vuoti e la retroilluminazione non viene alterata. Tuttavia la scritta scompare, riappare e scompare di nuovo, fa una specie di lampeggio prima di cancellare definitivamente i display.
I caratteri custom li visualizza in modo corretto.
Le funzioni che ho aggiunto non danno problemi.

Promossa a pieni voti!

Ottimo, mi fa piacere che sia funzionato tutto al primo colpo. Ora faccio qualche piccola modifica al software sulla base dei tuoi suggerimenti e aggiungo gli esempi. Se hai fatto delle foto mandamele pure che le pubblico volentieri. Sto preparando una pagina sul mio blog per tenere traccia dei vari aggiornamenti e della documentazione.

Grazie ancora.

Stefano

Eccomi, scusate l'assenza ma quando faccio le notti al lavoro faccio fatica a riprendermi. Come promesso ho preparato una paginetta per mantenere gli aggiornamenti della libreria, se vi interessa la trovate qui: http://www.mcmajan.com/mcmajanwpr/?page_id=1636

Nella paginetta ho riportato lo schema di collegamento e l'elenco delle funzioni principali. Le modifiche apportate rispetto alla versione che vi ho proposto alcuni giorni fà sono:

  1. Estesa la compatibilità alle vecchie IDE
  2. Ho aggiunto un esempio nella cartella della libreria così è richiamabile direttamente dall'IDE
  3. Aggiunta la funzione Lcd_SetFreePin(pin,valore,sr) per pilotare l'uscita dei pin 0 e 2 che restano liberi sullo shift register quando connettete un display. pin può valere 0 o 2, valore è HIGH o LOW ed sr è il numero di shift register a cui è connesso il display.
  4. Per giustizia a Pelletta ho messo anche la funzione SetBackLight (occhio che la disposizione dei parametri è diversa da quella da te proposta per mantenere come standard su tutti i comandi l'uso dell'ultimo parametro per il numero di shift register; poi ho messo la L maiuscola). In realtà NON è una funzione aggiuntiva, non ho fatto altro che mettere un #define che la rimanda alla Lcd_SetFreePin, in questo modo riduco il peso della sketch.
  5. Aggiunta la funzione DisplayClean(sr), l'unico parametro è lo shift register. Anche in questo caso ho sfruttato un #define per ridurre la lunghezza del codice finale.
  6. Per omogeneità dei nomi delle funzioni ho modificato ResetDisplay con DisplayReset
  7. Ora la DisplayReset non interferisce più con i pin 0 e 2 liberi.

Credo di aver raccolto tutti i suggerimenti, se manca qualcosa fatemi sapere. Ho già qualche idea nuova ma per qualche giorno sono impegnato....vi aggiornerò...

Stefano

Gran bel lavoro, complimenti, per fare una cosa per bene metti il link anche nel primo post del Topic. Ora propongo lo spostamento in MegaTopic :wink:
Ah, una cosa ancora, il mitico Pelletta (con 2 "l") è assolutamente un LUI, niente dubbi XD, quindi correggi appena puoi questi errori.

Complimenti per il lavoro, karma +1 :slight_smile:

Testato:
Complimenti per il lavoro, karma +1 :slight_smile:

E bravo Test, mi stai facendo prendere dalla gelosia, ed io che credevo di esserti stato utile :grin:

Scusa mike, sarò ancora assonnato, si sono a letto :slight_smile: ma non riesco ad interpretare la tua risposta :slight_smile:
A cosa ti riferisci ?

Spetta, è per il karma ?
Dei tuoi 390, 300 sono miei :slight_smile: