cd4511 e 74138

ciao a tutti, diciamo che avrei finito la meta' del programma, ho collegato un semplice schema con il cd4511 e il 74138 per il multiplex dei display, ma il risultato visivo e' alquanto scadente, mi spiego; ogni display visualizza in numero esatto, pero' i segmenti che dovrebbero essere spenti rimango leggermente accesi e il risultato visivo e' brutto,cosa potrebbe essere?

grazie.

// Arduino pins connected to the 74LS138
const uint8_t LedA1 = 6;
const uint8_t LedA2 = 7;
const uint8_t LedA3 = 8;

// Arduino pins connected to the 4511
const uint8_t LedA = 2;
const uint8_t LedB = 3;
const uint8_t LedC = 4;
const uint8_t LedD = 5;


void setup()
{
  // Let the Arduino know which pins go where
  pinMode(LedA, OUTPUT);
  pinMode(LedB, OUTPUT);
  pinMode(LedC, OUTPUT);
  pinMode(LedD, OUTPUT);
  
  pinMode(LedA1, OUTPUT);
  pinMode(LedA2, OUTPUT);
  pinMode(LedA3, OUTPUT);  
  
  digitalWrite(LedA1, LOW);
  digitalWrite(LedA2, LOW);
  digitalWrite(LedA3, LOW);

  //Serial.begin(9600);
}

void loop()
{
  print_number(724513);
}

void print_number(unsigned long int n) {
  static int d = 2;
  set_digit(d, n/100000);
  set_digit(d, n/10000);
  set_digit(d, n/1000);
  set_digit(d, n/100);
  set_digit(d, n/10);
  set_digit(d, n/1);
}

void set_digit(const unsigned d, const unsigned long value) {
  set_number_4511(value);
  delay(d);
  set_number_74138(value);
}


void set_number_4511(const unsigned long n) {
  static const struct number {
    uint8_t d;
    uint8_t c;
    uint8_t b;
    uint8_t a;
  } numbers[] = {
    { LOW,  LOW,  LOW,  LOW}, /* 0 */
    { LOW,  LOW,  LOW, HIGH}, /* 1 */
    { LOW,  LOW, HIGH,  LOW}, /* 2 */
    { LOW,  LOW, HIGH, HIGH}, /* 3 */
    { LOW, HIGH,  LOW,  LOW}, /* 4 */
    { LOW, HIGH,  LOW, HIGH}, /* 5 */
    { LOW, HIGH, HIGH,  LOW}, /* 6 */
    { LOW, HIGH, HIGH, HIGH}, /* 7 */
    {HIGH,  LOW,  LOW,  LOW}, /* 8 */
    {HIGH,  LOW,  LOW, HIGH}, /* 9 */
  };
  digitalWrite(LedA, numbers[n%10].a);
  digitalWrite(LedB, numbers[n%10].b); 
  digitalWrite(LedC, numbers[n%10].c);
  digitalWrite(LedD, numbers[n%10].d);
}

void set_number_74138(const unsigned long int nx) {
  static int tmp1,tmp2;  
  tmp1=tmp2;
  static const struct numberx {
    uint8_t cc;
    uint8_t bb;
    uint8_t aa;
  } numbers1[] = { /* Mappa 74138 */
    { LOW,  LOW,  LOW},  /* 0 */ 
    { LOW,  LOW,  HIGH}, /* 1 */
    { LOW,  HIGH, LOW},  /* 2 */
    { LOW,  HIGH, HIGH}, /* 3 */
    { HIGH, LOW,  LOW},  /* 4 */
    { HIGH, LOW,  HIGH}, /* 5 */
  };
  digitalWrite(LedA1, numbers1[tmp1%10].aa);
  digitalWrite(LedA2, numbers1[tmp1%10].bb);
  digitalWrite(LedA3, numbers1[tmp1%10].cc);

  tmp1++;
  tmp2=tmp1;

  if (tmp1>5)
  {
    tmp1=0;
    tmp2=0;
  }
}

vabbe' grazie ugualmente.

Serve lo schema elettrico.

Per primo non credo che hai un 74138 (famiglia TTL originaria) ma una altra famiglia caratterizzata da una o due lettere tra il 74 e il 138.

Se hai collagato gli anodi al 4511 e i catodo comune al 74138 il 74138 non reggará la somma della corrente dei segmenti.

Presumo che hai fatto una matrice con il 4511 e il 74xx138
Hai un errore di programma o di concetto.

la sequenza giusta per visualizzare un numero é
Devi selezionare la posizione giusta col 138
Devi accendere i segmenti di quella posizione
Aspettare un attimo per visualizzare il numero
Devi spegnere tutti i segmenti di quella posizione
Ripetere il tutto per le altre posizioni.

Comunque studiati

e gli array
perché cosí puoi semplificare molto lo SKetch

void set_number_4511(const unsigned long n) {
  static const struct number {
    uint8_t d;
    uint8_t c;
    uint8_t b;
    uint8_t a;
  } numbers[] = {
    { LOW,  LOW,  LOW,  LOW}, /* 0 */
    { LOW,  LOW,  LOW, HIGH}, /* 1 */
    { LOW,  LOW, HIGH,  LOW}, /* 2 */
    { LOW,  LOW, HIGH, HIGH}, /* 3 */
    { LOW, HIGH,  LOW,  LOW}, /* 4 */
    { LOW, HIGH,  LOW, HIGH}, /* 5 */
    { LOW, HIGH, HIGH,  LOW}, /* 6 */
    { LOW, HIGH, HIGH, HIGH}, /* 7 */
    {HIGH,  LOW,  LOW,  LOW}, /* 8 */
    {HIGH,  LOW,  LOW, HIGH}, /* 9 */
  };
  digitalWrite(LedA, numbers[n%10].a);
  digitalWrite(LedB, numbers[n%10].b);
  digitalWrite(LedC, numbers[n%10].c);
  digitalWrite(LedD, numbers[n%10].d);
}

si riduce a

const uint8_t Led[] = {2,3,4,5};
...
for (int i=0; I<4,I++)
{
  digitalWrite(Led[i], bitRead(numbers[n%10],i));
}

Consiglio:
Comprati una MAX7219 che fa tutta la gestione dei segmenti/posizioni autonomemente. Devi dargli solo i numeri da visualizzare.

Ciao Uwe

ciao, grazie per il consiglio,ma il max7219 non posso usarlo inquanto "vorrei" costruire un orologio a nixie
lo schema sperimentale provvisorio e' questo purtroppo al momento non riesco a fare un video.
studiero' la tua soluzione software alternativa.
grazie

Aspetta ... nixie ?

Se si, allora non puoi usare nessuno di quei chip per pilotarli ... il 4511 arriva al massimo a 20V, l'altro a 5.5V, e la maggior parte dei tubi nixie richiedono dai 150 ai 300 V per funzionare, dipende dai modelli e dalla grandezza (pare che qualche industria Giapponese abbia riprodotto delle nixie piu "moderne" che lavorano con soli 100V, ma sotto a quelli non credo ce ne siano) ... la tensione in se non e' problematica da ottenere, basta anche un banale 555, ma anche se le correnti in gioco sono bassissime e non pericolose, specie se ottenute con un'oscillatore dedicato, serve trovare dei chip drivers che reggano le tensioni in gioco, oppure costruire un banco di uscite usando transistor discreti, sempre che reggano minimo 300V ... ti servira' comunque un banco driver per gli anodi, verso il positivo, che reggano tali tensioni, e quelli li dovrai per forza realizzare con dei transistor, o almeno io non riesco a ricordarmi alcun tipo di driver integrato per anodi che reggesse quei valori ...

(Nota per Guglielmo: considerando le bassissime correnti in gioco, ho risposto anche se le tensioni da utilizzare sono piu alte dei 48V, ma lascio decidere a te se cancellare il mio post o meno, se ritieni che non sia opportuno menzionare certe tensioni anche a correnti minime cancella pure senza problemi)

In passato si usavano i 7441, oppure i 74141, riuscire a trovarne ancora da qualche parte, puoi pilotarci le nixie ... ricordo addirittura che esisteva un chip, 74142, che aveva all'interno contatore decimale, latch a 4 bit, decodifica decimale e drivers per tubi nixie, che si usava per costruire i primi frequenzimetri, ma credo non sia piu trovabile ormai, parlo di 35/40 anni fa ...

si certo, non sono cosi' sprovveduto, posto lo schema quello serio per capirci, le mie prove con il cd4511 era solo per "provare" pezzo per pezzo il codice e l'hardware.

C'e' anche un'altro thread che ho visto solo ora, sull'argomento, potreste unire le risorse intellettuali ... :wink:

Etemenanki:
C'e' anche un'altro thread che ho visto solo ora, sull'argomento, potreste unire le risorse intellettuali ... :wink:

ha ha ha ha ha......

Parlo del secondo schema. A me continua a non tornare quel 74138. Le sue uscite sono normalmente tutte alte, e bassa solo quella selezionata con A B C. Quindi tutte le cifre sono sono sempre accese contemporaneamente tranne una.

... quale secondo schema ? ...

EDIT: visto adesso ... si, forse voleva dire 238, il 138 ha le uscite attive basse, mentre il 238 attive alte ... i transistor in quella configurazione non effettuano un'inversione di logica, quindi se da alto sulle basi dei NPN, i PNP vanno in conduzione, per cui cosi non va ...

RIEDIT: > superciccio: guardando meglio lo schema, mi sono reso conto che non stai usando nessun blanking hardware per la commutazione ... cosa fai per evitare lo sfarfallio durante il cambio di cifra, selezioni via sketch una delle uscite inutilizzate del driver degli anodi mentre scambi i catodi ?

ciao a tutt!!!! per dissipare meglio ogni dubbio e/o inconprensione ho pubblicato 3 video, sempre lo stesso programma (ovviamente) con tre delay differenti 500ms,200ms e 50ms e infine una foto con un ritardo di 1ms per poter vedere meglio il risultato finale di come gli altri segmenti risultano semispenti???? o semispenti????
l'ic e' 74hc138 ho provato anche con 74hct138 (TTL compatibile....)

uwefed:
Presumo che hai fatto una matrice con il 4511 e il 74xx138
Hai un errore di programma o di concetto.

la sequenza giusta per visualizzare un numero é
Devi selezionare la posizione giusta col 138
Devi accendere i segmenti di quella posizione
Aspettare un attimo per visualizzare il numero
Devi spegnere tutti i segmenti di quella posizione
Ripetere il tutto per le altre posizioni.

Questo lo hai considerato?

Se guardi bene le cifre, l' immagine fantasma é sempre la cifra alla sua sinistra.
3 col 7 non si vede perché ha gli stessi segmenti accesi
7 col 5
5 col 4
4 col 2 e 2 con 8 sono accesi tutti i segmenti spenti

DEVI spegnere tutti i segmenti prima che cambi posizione !!! e non come fai cambi la posizione e poi cambi i segmenti.

Ciao Uwe

uwefed:
Questo lo hai considerato?

Se guardi bene le cifre, l' immagine fantasma é sempre la cifra alla sua sinistra.
3 col 7 non si vede perché ha gli stessi segmenti accesi
7 col 5
5 col 4
4 col 2 e 2 con 8 sono accesi tutti i segmenti spenti

DEVI spegnere tutti i segmenti prima che cambi posizione !!! e non come fai cambi la posizione e poi cambi i segmenti.

Ciao Uwe

...che occhio fine! si ho capito, adesso faccio qualche modifica vediamo cosa posso inventarmi.
grazie

Un problema fondamentale è sicuramente la mancanza del blanking già detta.

Ma in ogni caso continua a sembrarmi sbagliato l'hardware, anche nel primo schema con i 4511 (post #3) i transistor PNP non funzionano, le cifre si accendono solo per la corrente inversa che passa nella giunzione collettore->base :o

Claudio_FF:
Un problema fondamentale è sicuramente la mancanza del blanking già detta.

Ma in ogni caso continua a sembrarmi sbagliato l'hardware, anche nel primo schema con i 4511 (post #3) i transistor PNP non funzionano, le cifre si accendono solo per la corrente inversa che passa nella giunzione collettore->base :o

ciao, quindi dovrei invertirli? o usare dei NPN????

grazie.

stavo provando con questo metodo un po' cosi' giusto per capire....

  digitalWrite(LedA1, numbers1[tmp1%10].aa);
  digitalWrite(LedA2, numbers1[tmp1%10].bb);
  digitalWrite(LedA3, numbers1[tmp1%10].cc);
  delay(1);
  digitalWrite(LedA1, HIGH);
  digitalWrite(LedA2, HIGH);
  digitalWrite(LedA3, HIGH);

ok adesso i numeri sono appena appena piu' constrastati ma ovviamente mi sballa tutto il "ciclo"
dal numero 123456 mi visualizza 612345

Mah, io non capisco
a parte gli errori che ogni tanto ti vengono segnalati, per i quali non entro più nel merito
ma se vuoi fare un orologio a tubi nixie, perchè ti ostini con dei sette segmenti a catodo comune?
i tubi nixie sono decadici (non 7 segmenti) ad ANODO comune, cambia un botto dell'elettronica di comando
o magari chiami nixie i display VFD? quelli si che sono 7 segmenti a catodo comune
anche ad anodo se è per questo, sono comandati di griglia.

Standardoil:
Mah, io non capisco
a parte gli errori che ogni tanto ti vengono segnalati, per i quali non entro più nel merito
ma se vuoi fare un orologio a tubi nixie, perchè ti ostini con dei sette segmenti a catodo comune?
i tubi nixie sono decadici (non 7 segmenti) ad ANODO comune, cambia un botto dell'elettronica di comando
o magari chiami nixie i display VFD? quelli si che sono 7 segmenti a catodo comune
anche ad anodo se è per questo, sono comandati di griglia.

ciao, no, io non mi ostino ad usare il cd4511 per pilotare le nixie, se guardi qualche post indietro potrai vedere il progetto principale che usa i 74141 per pilotare le nixie appunto,
questo schema con il cd4511 e 74138 mi serviva solo per testare una parte di software.
e infatti sto avendo problemi con queste "immagini fantasma", anche se mi e' stato spiegato il motivo (e sto cercando una soluzione) non capisco perche' utilizzando un delay alto tipo 500ms i numeri risultano ben contrastati. analizzo male io il problema?

grazie

Bah, guarda, dato che il problema te lo hanno detto altri non volevo tornarci.
Per fortuna, o sfortuna, i miei ingannieri ne hanno combinata un'altra, intanto che aspetto di poter prendere il barile per spalare via i tiristori bruciati ho tempo per dirtelo:
Quando cambi cifra tieni accesi i segmenti. E quindi per un attimo alla cifra nuova sono accesi i segmenti vecchi.
Maggiore è il tempo di accensione, minore il rapporto di tempi tra cambio e accensione. Maggiore quindi il contrasto
Il tuo errore non è sbagliare l'analisi, è non badare a quello che ti scrivono.

Standardoil:
Bah, guarda, dato che il problema te lo hanno detto altri non volevo tornarci.
Per fortuna, o sfortuna, i miei ingannieri ne hanno combinata un'altra, intanto che aspetto di poter prendere il barile per spalare via i tiristori bruciati ho tempo per dirtelo:
Quando cambi cifra tieni accesi i segmenti. E quindi per un attimo alla cifra nuova sono accesi i segmenti vecchi.
Maggiore è il tempo di accensione, minore il rapporto di tempi tra cambio e accensione. Maggiore quindi il contrasto
Il tuo errore non è sbagliare l'analisi, è non badare a quello che ti scrivono.

ok, grazie be' a questo punto e' un limite mio nel programmare..... perche' non riesco a trovare una soluzione software per ovviare a questo problema.
grazie.