Progetto orologio (Risolto)

Buonasera a tutti.

Sto cercando di costruirmi un orologio digitale ed il primo passo è di far scorrere le 4 cifre dell'ora/minuti.

Per complicarmi la vita voglio utilizzare solo 3 PIN per le 4 cifre utilizzando 4 integrati 74HC595N collegati a cascata e …. primo inghippo!

Nessun problema a visualizzare i numeri, ma se cerco di modificarli in automatico le cifre scorrono troppo velocemente e se aggiungo un "delay" vedo solo l'unità. Inoltre la cifra dell'unità risulta sempre più luminosa (v. foto).

Qualcuno può indicarmi dove sbaglio? Allego anche schema del circuito.

/*
 *  PROVA 4 numeri 3 PIN
*/

#define DATA_PIN 4
#define LATCH_PIN 3
#define CLOCK_PIN 2

unsigned long a;
unsigned long b;
unsigned long c;
unsigned long d;
int x = 2345;
int e;
int f;
int g;
int h;

unsigned long values[] = {
  //gfedcba
  0x7E, // 0
  0xC,  // 1
  0xB6, // 2
  0x9F, // 3
  0xCD, // 4
  0xDA, // 5
  0xFA, // 6
  0xE,  // 7
  0xFE, // 8
  0xDE, // 9
};

void setup() {
  pinMode(DATA_PIN, OUTPUT);
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  ora();
  Serial.println(x);
  Serial.println(g);
  animation1(1000);
}

void writeRegister(unsigned long value) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value >> 24);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value >> 16);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value >> 8);
  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);
  digitalWrite(LATCH_PIN, HIGH);
}

void animation1(unsigned long animationDelay) {
  a = values[h];
  b = values[g];
  d = values[f];
  c = values[e];

  writeRegister(d << 24);
  writeRegister(c << 16);
  writeRegister(b << 8);
  writeRegister(a << 0);
}

void ora() {
  e = (x / 1000);
  f = (x - (e * 1000)) / 100;
  g = (x - (e * 1000) - (f * 100)) / 10;
  h = (x - (e * 1000) - (f * 100) - (g * 10));
  //  delay (1000);
  //  x = x + 1;
}

Grazie e auguri di una serena Pasqua.

Enrico

4Integrati_schem.pdf (1.03 MB)

Usare gli shift register non è complicare, anzi, semplifica molto il software perché i singoli digit sono comandati in modo stabile in hardware e non sono multiplexati a software.

MA... stai usando gli shift register come un multiplex, infatti quelle quattro 'writeRegister' di fila sono senza senso. La 'writeRegister' butta già fuori 32 bit (che poi rimangono li belli stabili), quindi basta caricare i nostri bit (ottenuti da 'values') in una variabile unsigned long e passarla una sola volta a 'writeRegister'.

Poi c'è il secondo problema, mancano le resistenze sui LED, se proprio non si vogliono mettere su tutti (che sarebbe il modo corretto) almeno metterne una tra ogni catodo comune e massa.

Grazie, ma...

basta caricare i nostri bit (ottenuti da 'values') in una variabile unsigned long e passarla una sola volta a 'writeRegister

ecco il problema, non ho la più pallida idea di come fare e in internet non sono riuscito a trovare (in italiano) alcun esempio!

Per quanto riguarda le resistenze le ho messe (purtroppo avevo solo quella da 470 Ohm!) ma mi sono dimenticato d'inserirle nello schema.

Saluti

La forma aritmetica:

unsigned long dati = d;
dati = (dati * 256) + c;
dati = (dati * 256) + b;
dati = (dati * 256) + a;

Quella logica identica:

unsigned long dati = d;
dati = (dati << 8) | c;
dati = (dati << 8) | b;
dati = (dati << 8) | a;

Il risultato:

.--------.--------.--------.--------.
|   D    |   C    |   B    |   A    |
'--------'--------'--------'--------'
 ^                                 ^
 bit 31                            bit 0

Ho utilizzato il tuo aiuto in forma logica, e tutto funziona alla perfezione, GRAZIE!

Se ho ben capito: a) dopo ogni aggiunta ti sposti di 8 bit per inserire il numero successivo e b) la barra verticale equivale allo "&" logico.

Nella forma aritmetica non riesco a collocare il perché della moltiplicazione per "256".

Non è che questi miei quesiti richiedono necessariamente una risposta, ma mi piace capire quello che faccio anche in vista di future applicazioni.

Saluti ed ancora una serena Pasqua!

enrico24:
la barra verticale equivale allo "&" logico

Ennò :slight_smile: Se volevo fare l' & logico scrivevo &, io volevo fare l' | logico (operatori bitwise)

Nella forma aritmetica non riesco a collocare il perché della moltiplicazione per "256".

Un valore binario spostato a sinistra/destra di una posizione corrisponde a una moltiplicazione/divisione per due del valore.

Grazie ancora.

Ennò Se volevo fare l' & logico scrivevo &, io volevo fare l' | logico (operatori bitwise)

Scusa la mia poca padronanza dei termini tecnici, intendevo l'& normalmente usato in Excel, acces, ecc.