Visualizzare su display 7 segmenti 2-digit

Ciao a tutti,

ho vecchie reminiscenze di programmazione e di elettronica ma mi considero abbastanza scarso lo stesso, per cui vi ringrazio sin d'ora e spero di non tediarvi troppo.

Allora, la settimana scorsa in fiera ho comprato un Arduino Uno e due display a 7 segmenti, uno ad 1 digit a catodo comune e l'altro doppio, cioè a 2-digit con anodo comune in una unica schedina contenente anche due shift register 74hc595 connessi con il pin 9 di uno al pin 14 dell'altro.

Con il display ad 1 digit non ho avuto problemi a visualizzare le cifre da 0 a 9, invece sta andando male con quello doppio perchè non riesco proprio a visualizzare numeri a 2 cifre come il 36, che porto come esempio.

Qui come collego il doppio display ad Arduino

https://postlmg.cc/w1HFvvy6

Per visualizzare una cifra su ciascun digit, visto che i due display hanno i segmenti in comune e i due 595 hanno i pin corrispondenti connessi tra loro, la logica che applico nello sketch è questa

1)spengo entrambi i digit, il digit1 (quello a sinistra) e anche digit2 (quello a destra)
2)preparo lo shift register inserendo il 3
3)accendo digit1 e spengo digit2 + delay(5) ( dovrei vedere il 3 a sinistra )

4)spengo digit1 e digit2
5)preparo lo shift register inserendo il 6
6)spengo digit1 e accendo digit2 + delay(5) ( dovrei vedere il 6 a destra )
7) ricomincio da 1

Se qualcuno vuole dare un'occhiata allo sketch, provo ad inserire anche quello

int clockPin = 7;                                         //pin 11 del 595, filo marrone (SCLK)
int latchPin = 8;                                         //pin 12 del 595 , filo blu   (RCLK)
int dataPin = 10 ;                                      //pin 14 del 595 , filo yellow (DATA)

int digit1 = 11;                                          // anodo del digit di sinistra al pin digitale 11 di Arduino
int digit2 = 12;                                          // anodo del digit di destra al pin digitale 12 di Arduino

void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
}

void loop()
{
  visual();                                           // procedura che visualizza un numero a 2 cifre
}



void visual()

///////////////////////////////////////////////////// ESEMPIO per VISUALIZZARE il numero 36
                                                   
{                                                   // per visualizzare 3

  digitalWrite(digit1, 0);digitalWrite(digit2, 0);  //spengo entrambi i digit
 
  digitalWrite(latchPin, HIGH);                     //metto 3 nello shift register
  shiftOut(dataPin, clockPin, MSBFIRST, 48);         
  digitalWrite(latchPin, LOW);                     

  digitalWrite(digit1, 1);                               // accendo digit1 che dovrebbe visualizzare il 3
  digitalWrite(digit2, 0);                              // spengo digit2 
 
  delay(500);                                                // ritardo lungo per vedere cosa si visualizza
  

///////////////////////////////////////////

                                                      // per visualizzare 6

  digitalWrite(digit1, 0);digitalWrite(digit2, 0);    //spengo entrambi i digit
 
  digitalWrite(latchPin, HIGH);                             //metto 6 nello shift register
  shiftOut(dataPin, clockPin, MSBFIRST, 2);
  digitalWrite(latchPin, LOW);

  digitalWrite(digit1, 0);                                        // spengo digit1
  digitalWrite(digit2, 1);                                       // accendo digit1 che dovrebbe visualizzare il 6
   
  delay(500);                                                         // ritardo lungo per vedere cosa si visualizza

}

Quello che succede dopo l'avvio è che vedo inizialmente blinkare 33 ( quindi i due digit funzionano), e subito dopo rimane il blink del 3 sul digit2 di destra, mentre il digit1 di sinistra rimane spento e del 6 nessuna traccia. Se faccio girare solo la parte di codice che riguarda la cifra 6, allora succede che inizialmente vedo il numero 66 e poi sul digit di destra si fissa il 6 mentre il digit di sinistra rimane sempre spento, come nel caso precedente della cifra 3.

Non ho altri display doppi con cui provare e, tra l'altro, i due anodi connessi ai pin 11 e 12 di Arduino è come se non ci fossero, infatti se li stacco il comportamento dopo l'avvio rimane immutato.

Grazie per avere letto fin qui e per l'aiuto :wink:

Posso sapere perché non usi questa libreria e i relativi esempi?

Ciao,
P.

Cercando di scrivere da solo quelle quattro righe necessarie rischia di imparare troppo? :slight_smile:

L'ho provata l'ho provata e mi sarebbe piaciuto usare

sr.set(1, HIGH)

per costruire le cifre con i singoli segmenti, troppo bello per essere vero ma non ci crederai però purtroppo non funza

Leggendo tutto avevo anche provato questo, che dovrebbe visualizzare indipendentemente i due digit, qui per scrivere il numero 61 (ho cambiato numero magari è un numero più fortunato)

       #include <ShiftRegister74HC595.h>

    ShiftRegister74HC595<2> sr (10, 7, 8);  // (number of shift registers, data pin, clock pin, latch pin)

    int digit1,digit2;

    int cifra[] = {  B11000000, //0
                         B11111001, //1
                         B10100100, //2
                         B10110000, //3
                         B10011001, //4
                         B10010010, //5
                         B10000011, //6
                         B11111000, //7
                         B10000000, //8
                         B10011000  //9
                  };

                           
    void setup()

    {

        Serial.begin(9600);
     
        digit2=61 % 10 ;              // unità
        digit1=(61 / 10) % 10 ;       // decine
       
        Serial.print(digit1); Serial.print(" ");Serial.println(digit2);   // visualizza  esattamente 6 1
       
        uint8_t numberToPrint[]= {cifra[digit2],cifra[digit1]};
        sr.setAll(numberToPrint);     
       
    }

    void loop()
    {

    }

Sul monitor seriale il numero 61 viene visualizzato esattamente mentre su ciascun digit si vede solo il numero 1, ovvero la cifra delle unità su entrambi, praticamente si visualizza 11 e del 6 nessuna traccia. Non so, probabilmente quella libreria non la so usare io, però più che includerla e usare qualche suo comando non saprei che fare, o il display che ho in mano è fallato però anche qui, usando il tester ciascun segmento si accende toccando con il puntale rosso quello che dovrebbe essere l'anodo e con il nero il pin del segmento.

Ho anche provato con la libreria SevSeg ma buco nell'acqua anche con quella :woozy_face:

Mi sembra che sfuggano due cose: la prima è che quel display non si pilota in multiplex (non ci sono cifre da accendere una alla volta, sono semplicemente due shift register in serie da caricare), la seconda è che due shift register in serie si caricano semplicemente con due shiftOut una dopo l'altra, non serve nessuna libreria, come dice Datman sono quattro istruzioni in tutto: giù latch, shiftout, shiftout, su latch.

ShiftOut l'ho provata all'inizio ma senza successo ( v. primo post). Non ho capito però come usarne due, una dopo l'altra...non è che scrive la stessa cifra su entrambi i digit ? Cioè, se volessi scrivere 36 e scrivo

shiftOut(dataPin, clockPin, MSBFIRST,48)
shiftOut(dataPin, clockPin, MSBFIRST,2)

alla velocità a cui viene eseguito il loop, non è che mi scrive 33 la prima volta e 66 la seconda e vedo sempre 66 ?

Da quello che si capisce da foto e codici dei segmenti, quel display è fatto in questo modo:

5646325645

Gli shift register vanno caricati con 16 bit (otto ciascuno), quindi servono due shiftOut per creare la necessaria trasmissione seriale sincrona in questo formato:

Al sedicesimo fronte di salita del clock il primo bit trasmesso sarà arrivato all'uscita Q7 del registro "più lontano". Con il fronte di salita del latch tutti i bit vengono portati sulle uscite verso i sedici segmenti. E rimangono li fisse e stabili fino a nuova trasmissione.

sì, sono proprio collegati cosi quindi ok, il multiplexing non ha senso farlo. Immagino che per caricare il numero( cifra) su uno shift register dovrei prima selezionarlo, giusto ? Collegando i due anodi a due pin digitali e mettendoli HIGH alternativamente, non funziona però ho trovato che se faccio cosi, funziona

  shiftOut(dataPin, clockPin, MSBFIRST,  B00000001);       
  shiftOut(dataPin, clockPin, MSBFIRST, 48);                           //carica la cifra 3
 
  shiftOut(dataPin, clockPin, MSBFIRST,  B00000010);
  shiftOut(dataPin, clockPin, MSBFIRST, 2);                               //carica la cifra 6

per caso, il primo shiftOut, quello con B00000001, serve a selezionare il primo display e B00000010 il secondo display ? Lo chiedo perchè non ho trovato niente sia sul reference che sul web.

Vedi se questo progetto al simulatore wokwi ti può essere di aiuto.

Ciao.

Se fai quattro shiftOut trasmetti 32 bit, i primi 16 si perdono e restano gli ultimi 16 sulle uscite. Non c'è niente da selezionare.

Un simulatore ? Wow, grazie !

Grazie anche a te, però a cosa servono gli shiftOut con gli 8 bit, perchè se li tolgo non funza più.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.