Go Down

Topic: Orologio \ Sveglia DCF77 RTC 6 digit 7 segmenti (Read 19821 times) previous topic - next topic

ricki158

Buongiorno a tutti!
Spesso ho trovato orologi che mostrano soltanto le ore e i minuti, regolati a mano con un RTC. Io invece vorrei fare meglio, vorrei realizzare un orologio \ sveglia radiocontrollato.

Nello specifico, vorrei utilizzare:
- ATMega 328p in modalità "standalone", estraendo i due pin Tx e Rx per avere la possibilità di aggiornare il firmware direttamente sulla scheda con un semplice convertitore FTDI USB \ Seriale TTL;

Display:
- 6 Digit 7-segmenti blu da 0.56in di altezza;
- 4 led 3 mm blu;
- segmenti comandati da un HFE4543 BCD to 7 segmenti decoder, attraverso un ULN2803;
- cifre e led comandati da un HFE4028 BCD to decimal decoder, attraverso un TD62783AP;

Keyboard:
- 4 bottoni in serie con resistenza di pull-up;
- 1 switch;
- 1 led DCF77 Error;
- 1 led sveglia inserita;

Altro:
- LM7805 per alimentare la parte "logica";
- LM7809 per alimentare la parte di "potenza" dei led;
- Buzzer;
- Batteria tampone per RTC;
- Modulo DCF77 ancora da decidere;
- Alimentazione esterna con un semplice trasformatore a 12 volt;

Questo è lo schema elettrico dal quale ho preso spunto, naturalmente è diverso perché devo inserirci dentro il modulo RTC e sistemare i pin per l'ATMega328p. Sto rifacendo lo schema elettrico con KiCad ma non avendo già i componenti ci metto un po'.

http://www.turbokeu.com/myprojects/ledclock/led-clock%20dcf%20ca1.gif[/img]]

Siccome sono alle prime esperienze serie con Arduino, volevo condividere con voi questo progetto, anche per avere dritte per quanto riguarda il codice. Per il momento ho già chiesto informazioni per quanto riguarda la gestione BCD e della temporizzazione attraverso millis() qui.

Nel prossimo post scriverò il codice che fino ad ora ho scritto anche grazie al vostro aiuto.

Mi scuso fin da subito per il mio livello di programmazione, ma spero anche grazie al vostro aiuto di imparare tanto.

Vi ringrazio tutti fin da subito!

Riccardo

ricki158

Per il momento ho buttato giù questo codice:

Code: [Select]

/* ATMega 328P Standalone */
/* PORTD raggruppa in 1 byte di 8 bit i pin digitali da 0 a 7. Ricordiamo che i pin 0 e 1 sono rispettivamente Rx e Tx. L'ultimo bit corrisponde al pin digitale 0. */
/* PORTB raggruppa in 1 byte di 8 bit i pin digitali da 8 a 13. L'ultimo bit corrisponde al pin digitale 8. */
/* PORTC raggruppa in 1 byte di 8 bit i pin analogici da 0 a 5. L'ultimo bit corrisponde al pin analogico 0. */

#define LEDs 9                                    /* LED SEC 4 led blu che segnano i secondi. sono collegati al digit6 prima a sinistra delle ore. */
#define LEDd 10                                   /* LED DCF77 ERROR led rosso che si accende in caso di errore del DCF77 o dati incorretti. */
#define LEDa 11                                   /* LED ALARMled di inserimento dell'allarme. */
#define BUZ 12                                    /* BUZZER cicalina di allarme. */
#define LED_STATUS 13                             /* LED STATUS led di stato come su scheda ArduinoUNO. */
#define KEY A0                                    /* KEYBOARD pin analogico che legge i valori dei 4 bottoni */
#define SWa A1                                   /* SWITCH ALARM pin analogico che legge l'interruttore per la sveglia */


byte sLEDs = LOW;                                 /* variabile di stato LEDs */
#define intLEDshigh  250                          /* intervallo accensione 250 millisecondi LEDs */
#define intLEDslow 750                            /* intervallo spegnimento 750 millisecondi LEDs */
unsigned long pTempoLEDs = millis();              /* salva i millisecondi una volta all'accensione del processore per il loop dei LEDs, alla quale aggiungerò gli intervalli */
byte aBUZ = LOW;                                  /* variabile di stato buzzer attivata dall'allarme */
byte sBUZ = LOW;                                  /* variabile di stato buzzer */
#define intBUZhigh 750                            /* intervallo accensione 750 millisecondi Buzzer */
#define intBUZlow 250                             /* intervallo spegnimento 250 millisecondi Buzzer */
unsigned long pTempoBUZ = millis();               /* salva i millisecondi una volta all'accensione del processore per il loop del Buzzer, alla quale aggiungerò gli intervalli */


uint32_t pMultiplex = micros();                   /* salva i microsecondi una sola volta all'accensione del processore per il loop del multiplexing per il display 7 segmenti */

byte DATE[6] = {0, 0, 0, 0, 0, 0};                /* posizione 0 = decine giorno, posizione 5 = unità anno. */
byte TIME[6] = {0, 0, 0, 0, 0, 0};                /* posizione 0 = decine ore, posizione 5 = unità secondi. */
byte DIGIT = 0;                                   /* numero della cifra per il multiplexing, da 1 a 6, digit1 prima a destra dei secondi, digit6 prima a sinistra delle ore. */


void setup() {
  DDRD = DDRD | B11111100;                        /* richiamo il registro della porta D (pin digitali da 0 a 7) e setto i pin dal 2 al 7 in modalità output, senza cambiare i pin Tx e Rx per sicurezza. */
  DDRB = DDRB | B11111111;                        /* richiamo il registro della porta B (pin digitali da 8 a 13) e setto tutti i pin in modalità output. */
  DDRC = DDRC | B00000000;                        /* richiamo il registro della porta C (pin analogici da 0 a 5) e setto tutti i pin in modalità input. */
}

void multiplex() {
  if (++DIGIT > 6) DIGIT = 1;                     /* digit cicla da 1 a 6 */
  byte VALUE = TIME[6 - DIGIT];                   /* indice array cicla da 5 a 0 */
  PORTD = (PORTD & 3) | (DIGIT << 2) | (VALUE << 5);    /*  */
  PORTB = (PORTB & 0xFE) | (VALUE >> 3);          /*  */
}

void alarmBUZZER(){                               /* fa suonare il buzzer quando l'allarme è acceso */
  if(aBUZ=HIGH){                                  /* nel caso in cui la variabile aBUZ è alta, cioè se l'allarme è inserito */
    switch(sBUZ){                                 /* in base allo stado della variabile sBUZ ho i due casi */
      case HIGH:                                  /* caso in cui la variabile sBUZ è alta */
        if(millis() - pTempoBUZ >= intBUZhigh){   /* la variabile pTempoBUZ all'inizio è uguale a millis e la differenza è 0. Ciclando aumenta la differenza fino ad arrivare all'intervallo scelto */
          sBUZ = LOW;                             /* cambio lo stato della variabile */
          pTempoBUZ += intBUZhigh;                /* alla variabile pTempoBUZ aggiungo l'intervallo così da azzerare la differenza di prima */
          digitalWrite(BUZ, sBUZ);                /* porto bassa l'uscita */
        }
        break;                                    /* blocca qui l'if */
      case LOW:                                   /* caso in cui la variabile sBUZ è bassa */
        if(millis() - pTempoBUZ >= intBUZlow){    /* la variabile pTempoBUZ all'inizio è uguale a millis e la differenza è 0. Ciclando aumenta la differenza fino ad arrivare all'intervallo scelto */
          sBUZ = HIGH;                            /* cambio lo stato della variabile */
          pTempoBUZ += intBUZlow;                 /* alla variabile pTempoBUZ aggiungo l'intervallo così da azzerare la differenza di prima */
          digitalWrite(BUZ, sBUZ);                /* porto alta l'uscita */
        }
    }
  }
}

void blinkLEDs(){                                 /* lampeggia i 4 led 3 mm blu */
  switch(sLEDs){                                  /* in base allo stato della variabile sLEDs ho i due casi */
    case HIGH:                                    /* caso in cui la variabile sLEDs è alta */
      if(millis() - pTempoLEDs >= intLEDshigh){   /* la variabile pTempoLEDs all'inizio è uguale a millis e la differenza è 0. Ciclando aumenta la differenza fino ad arrivare all'intervallo scelto */
        sLEDs = LOW;                              /* cambio lo stato della variabile */
        pTempoLEDs += intLEDshigh;                /* alla variabile pTempoLEDs aggiungo l'intervallo così da azzerare la differenza di prima */
        digitalWrite(LEDs, sLEDs);                /* porto bassa l'uscita */
      }
      break;                                      /* blocca qui l'if */
    case LOW:                                     /* caso in cui la variabile sLEDs è bassa */
      if(millis() - pTempoLEDs >= intLEDslow){    /* la variabile pTempoLEDs all'inizio è uguale a millis e la differenza è 0. Ciclando aumenta la differenza fino ad arrivare all'intervallo scelto */
        sLEDs = HIGH;                             /* cambio lo stato della variabile */
        pTempoLEDs += intLEDslow;                 /* alla variabile pTempoLEDs aggiungo l'intervallo così da azzerare la differenza di prima */
        digitalWrite(LEDs, sLEDs);                /* porto alta l'uscita */
      }
  }
}

void loop() {

  if (micros() - pMultiplex > 3300) {             /* la variabile pMultiplex all'inizio è uguale a micro e la differenza è 0. Ciclando aumenta la differenza fino ad arrivare 33000 microsecondi */
    pMultiplex += 3300;                           /* alla variabile pMultiplex aggiungo 3300 microsecondi così da azzerare la differenza di prima */
    multiplex();                                  /* accende la prossima cifra */
  }
  alarmBUZZER();                                  /* fa suonare il buzzer quando l'allarme è acceso */
  blinkLEDs();                                    /* lampeggia i 4 led 3 mm blu */
}

ricki158

Per leggere i bottoni ho pensato a questo codice, siccome vorrei dividere tutto il programma in funzioni, senza caricare tutto nella funzione loop.

Code: [Select]

#define KEY A0                                    /* KEYBOARD pin analogico dei 4 pulsanti */
#define SWa A1                                    /* SWITCH Alarm pin analogico dell'interruttore della sveglia */

int KEYBOARD = 0;                                 /* salva i valori della tastiera per poi confrontarli */
byte SWalarm = 0;                                 /* salva i valori dell'interruttore per poi confrontarli */

void readKEYBOARD(){                              /* legge i valori dei 4 bottoni e dell'interruttore */
  KEYBOARD = analogRead(KEY);                     /* salvo nella variabile KEYBOARD il valore del pin analogico 0, cioè dei 4 bottoni */
  if (KEYBOARD < 60) {return 1;}                  /* se minore di 60 ritorna il valore 1 */
  /* Time \ Date */
  else if (KEYBOARD < 200) {return 2;}            /* se nessuno dei casi precedenti e minore di 200 ritorna il valore 2 */
  /* Alarm */
  else if (KEYBOARD < 400) {return 3;}            /* se nessuno dei casi precedenti e minore di 400 ritorna il valore 3 */
  /* Snooze */
  else if (KEYBOARD < 600) {return 4;}            /* se nessuno dei casi precedenti e minore di 600 ritorna il valore 4 */
  /* Time Zone */
  return 0;                                       /* in ogni altro caso ritorna il valore 0 */       
  SWalarm = analogRead(SWa);                      /* salvo nella variabile SWalarm il valore del pin analogico 1, cioè dell'interruttore */
  if(SWalarm > 511) {return 5;}                   /* se l'interruttore è acceso fai questo */
  else return 6;                                  /* se l'interruttore è spento fai questo */
}

void loop()}{
  readKEYBOARD();                                 /* legge i valori dei 4 bottoni e dell'interruttore */
}


Naturalmente i valori per dividere i bottoni li deciderò quando proverò il circuito e al posto di ritornarmi i numeri vorrei dare delle istruzioni.

Volevo sapere se ci sono metodi migliori per questa gestione.

Inoltre volevo un parere su quale RTC utilizzare e su quale modulo DCF77 usare.
Siccome i PCB me li faccio io, per me non è un problema inserire il circuito elettronico dell'RTC direttamente sulla mia scheda, anche con il porta batteria. Mi basta avere uno schema elettrico e le sigle dei componenti per vedere i datasheet. Per quanto riguarda il modulo DCF77 invece credo che ci siano sei filtri dentro e preferirei prenderlo già fatto (e quindi funzionante) perché so che è delicato e il segnale poche volte si riceve. Magari una schedina che posso connettere con i connettori a strip.

Per quanto riguarda la gestione del DCF77 pensavo di usare l'apposita libreria DCF77 che però non ho capito se utilizza un pin specifico o meno, mentre per il modulo RTC lo vorrei usare via i2c. Non ho una libreria a portata di mano, ma ho visto già alcuni progetti con moduli RTC.

claudio_f

#3
Jan 19, 2017, 09:56 pm Last Edit: Jan 19, 2017, 10:06 pm by Claudio_F
Quote from: ricki158
Per il momento ho buttato giù questo codice:
Code: [Select]
void alarmBUZZER(){
  if(aBUZ=HIGH){

Doppio errore, una svista sintattica (l'assegnamento invece dell'uguaglianza), e una logica, portando a LOW aBUZ durante il suono del buzzer, il buzzer non smette più di suonare.

Quote
l'apposita libreria DCF77 che però non ho capito se utilizza un pin specifico o meno
Da quanto ho letto l'altra volta viene usato il pin digital 2 di Arduino, questo perché tale pin, e anche il 3, ha una gestione più completa degli interrupt. Quella libreria per non essere bloccante funziona ad interrupt attivati dai cambiamenti dello stato del pin, ma volendo si potrebbe anche non usarla, e scrivere un grosso switch (attivato alla frequenza di multiplex) che decodifica "a mano" la trama un bit per volta, in tal caso si potrebbe usare il pin di ingresso che si preferisce.

Per quanto riguarda l'RTC (consigliato un modulo con DS3231) basta la sola libreria Wire.h per dialogare con il 3231 tramite bus i2c.

ricki158

#4
Jan 23, 2017, 02:04 am Last Edit: Jan 23, 2017, 02:27 am by ricki158
Doppio errore, una svista sintattica (l'assegnamento invece dell'uguaglianza), e una logica, portando a LOW aBUZ durante il suono del buzzer, il buzzer non smette più di suonare.
Hai ragione! Io ho comunque collegato un led all'uscita e lampeggiava esattamente per i secondi che imponevo io. Ho inserito la variabile perché se SWalarm (cioè la variabile dell'interruttore per innescare l'allarme) è alto (o basso, dipende dal circuito) e l'orario coincide con quello impostato, la variabile passa su HIGH e parte il ciclo switch... case.

Quote
Da quanto ho letto l'altra volta viene usato il pin digital 2 di Arduino, questo perché tale pin, e anche il 3, ha una gestione più completa degli interrupt. Quella libreria per non essere bloccante funziona ad interrupt attivati dai cambiamenti dello stato del pin, ma volendo si potrebbe anche non usarla, e scrivere un grosso switch (attivato alla frequenza di multiplex) che decodifica "a mano" la trama un bit per volta, in tal caso si potrebbe usare il pin di ingresso che si preferisce.
Farlo "a mano" significa avere un buon numero di conoscenze che posso acquisire solo con il vostro e tuo aiuto. Ho letto un po' questo topic dove dovrebbe appunto farlo "a mano". Ma devo appunto finire di leggerlo.

Quote
Per quanto riguarda l'RTC (consigliato un modulo con DS3231) basta la sola libreria Wire.h per dialogare con il 3231 tramite bus i2c.
Si questo me lo avevi detto in un altro topic. Volevo chiedere poi quali altri componenti devo mettere vicino al DS3231. Il modulo non vorrei prenderlo e, siccome ho spazio nella scheda vicino al processore ATMega, vorrei utilizzare componenti Through Hole su un circuito che mi realizzo io, con tanto di porta batteria tampone.

Mentre invece quale modulo DCF77 posso utilizzare? Avresti qualche link? Su eBay trovo tante cose, con antenne di dimensione diversa e non so quale andrebbe bene. Nel mio negozio di elettronica i moduli DCF77 non li vendono più, non li trattano neanche su ordinazione.

elrospo

Per leggere i bottoni ho pensato a questo codice, siccome vorrei dividere tutto il programma in funzioni, senza caricare tutto nella funzione loop.

Code: [Select]

#define KEY A0                                    /* KEYBOARD pin analogico dei 4 pulsanti */

  readKEYBOARD();                                 /* legge i valori dei 4 bottoni e dell'interruttore */
}


Naturalmente i valori per dividere i bottoni li deciderò quando proverò il circuito e al posto di ritornarmi i numeri vorrei dare delle istruzioni.

Volevo sapere se ci sono metodi migliori per questa gestione.


fare sketch  senza qualche specie di hardware collegato (anche solo un accrocchio di breadboard)
è una gran perdita di tempo   perché non si sa mai quello che si è scritto veramente.

con un hardware collegato ci sono alte probabilità di  trovare subito le "sviste" o peggio, man mano che lo completi.

fare un circuito stampato funzionante con 4-5 integrati  per chi è all' inizio potrebbe essere uno scoglio insormontabile



ExperimentUno

Se hai un RTC, il DCF77 non lo vedo una comodità.

ricki158

Ho una shield con LCD + 6 pulsanti dove gira un codice che funziona. Questo codice deriva da quello, solo che ho voluto fare tutto in una funzione, per cui alla peggio utilizzo quel codice. Posso anche provare questo codice  su quella shield.

L'unica comodità del DCF77 è che non devo impostare l'ora.

ricki158

Come antenna + modulo DCF77 prenderò questo.
Alla fine mi sono deciso a prendere il modulo RTC DS3231 anziché farmelo da me, anche perché l'integrato non esiste in Through Hole.
C'è qualche modulo DCF77 migliore?

claudio_f

#9
Jan 24, 2017, 06:27 pm Last Edit: Jan 24, 2017, 07:23 pm by Claudio_F
Quote from: ricki158
Come antenna + modulo DCF77 prenderò questo
Sembra interessante, sul datasheet però non dice che tipo di uscita è quella dati (open collector, push-pull ecc) ne che tensione sopporta, sarà da fare qualche prova per vedere come collegarsi senza danni (il modulo funziona a 3.3V).

Migliori? Boh. Non è un genere molto trattato e sicuramente non si trova in negozio... Mi sembra solo un po'strana l'assenza del condensatore di sintonia a ridosso della bobina (serve per aumentare il Q) che si vede in altre foto.

Interessa anche a me come possibile sostituto/rifacimento del mio ricevitore realizzato interamente "a mano" nel 2003 a partire dall'antenna avvolta con il filo di una bobina di relé.


EDIT: anzi, su questo datasheet è specificato che si tratta di un'uscita push-pull, alta in presenza degli impulsi (corrispondenti alla riduzione dell'ampiezza della portante radio), in grado di erogare o assorbire circa 5µA... quindi bisogna interporre un buffer adattatore di livello (un paio di transistor, o un operazionale).

ricki158

Intanto ho fatto lo schema elettrico per l'ATMega 328 P che allego qui di seguito.

Ho preso quel modulo allora, ma ti chiederò uno schema elettrico per il buffer adattatore di livello.

ExperimentUno

Ma tal modulo DCF77, in certe regioni italiane è facile che fallisce più delle volte che funziona. Diciamo dagli Appennini in giù.

claudio_f

#12
Jan 25, 2017, 06:50 pm Last Edit: Jan 25, 2017, 11:05 pm by Claudio_F
E beh, vediamo quando gli arriva se riusciamo a tirare fuori un LED pulsante in modo corretto  ;)

Intanto sullo schema vedo già un problema di alimentazione, quel modulo dcf funziona a 3.3V, e temo che anche la sua uscita non si possa collegare direttamente ad un pin di Arduino.

Per l'alimentazione potrebbe bastare resistenza da 330 Ω e zener da 3.3V

Non ho capito la funzione di tutti quei pulsanti.

Il LED dcf error (che lampeggerebbe quasi sempre) mi sembra meno utile di un LED sync ok (che invece indicherebbe ora sincronizzata e ricezione perfetta)... o meglio, per completezza, cioè capire sia quando le cose non vanno bene, sia quando vanno, servirebbero tutti e due. Più uno per gli impulsi grezzi emessi dal modulo... così si vede visivamente lo stato della ricezione e dell'orientamento dell'antenna.



Per quanto riguarda leggere la trama DCF77 a mano mi sono divertito a riscrivere in C più o meno il procedimento di quello che quattordici anni fa ho scritto in assembly per PIC16F628 (Arduino ancora non esisteva :'(). Non c'è niente di testato... meglio non quotare il codice visto che sicuramente sarà da correggere.

La trama di 59 bit (ricevuta domenica 7 settembre 2003 alle 12:37) è fatta così :



I dati sono inviati in formato BCD compatto, i bit meno significativi vengono trasmessi per primi. I bit rossi sono il controllo di parità pari (in pratica facendo lo xor dei bit ricevuti, compresa la parità, il risultato deve sempre essere zero). Il primo bit è sempre 0 (forse), il ventunesimo sempre 1 (sicuro).

Code: [Select]
void dcf()
{
    byte pulse = digitalRead(dcfPin);
    switch (dcfStat)
    {
        case 0: // restart processo
            dcfCnt = 0;
            dcfStat = 1;
            nBit = 1;
            bitXor = 0;
            break;

        case 1: // attesa secondo di sync
            if (pulse) { dcfStat = 0; break; }
            if (++dcfCnt == 400) dcfStat = 2;
            break;

        case 2: // attesa impulso
            if (pulse) { dcfCnt = 0; dcfStat = 3; }
            break;

        case 3: // misura impulso
            ++dcfCnt;
            if (!pulse)
            {
                if (dcfCnt < 16)     { dcfStat = 8; break; } // errore corto
                if (dcfCnt < 60)     bitRx = 0;
                else if (dcfCnt<104) bitRx = 1;
                else                 { dcfStat = 8; break; } // errore lungo
                dcfStat = 4;
            }
            break;

        case 4: // elabora bit
            if (nBit == 1 && bitRx)   { dcfStat = 8; break; } // errore start0
            if (nBit == 21 && !bitRx) { dcfStat = 8; break; } // errore start1
            bitXor ^= bitRx;
            if (nBit == 29 && bitXor) { dcfStat = 8; break; } // errore parita`
            if (nBit == 36 && bitXor) { dcfStat = 8; break; } // errore parita`
            rxData = (rxData >> 1) | (unsigned int)(bitRx << 15);
            dcfCnt = 0;
            if (nBit == 36)  // fine sezione ore minuti
            {
                rxData >>= 1;
                rxMinute = rxData & 0x0F;
                rxData >>= 4;
                rxMinute = 10*(rxData & 7) + rxMinute;
                rxData >>= 4;
                rxHour = rxData & 0x0F;
                rxData >>= 4;
                rxHour = 10*(rxData & 3) + rxHour;
                if (rxMinute > 59
                    || rxHour > 23) { dcfStat = 8; break; } // errore valori
                dcfStat = 6 ;
                break;
            }
            dcfStat = 5;
            break;

        case 5: // attesa 600 ms
            if (++dcfCnt == 240) { ++nBit; dcfStat = 2; }
            break;

        case 6: // attesa 24 sec
            if (++dcfCnt == 9600)
            {
                if (rxMinute == (priorRxMinute + 1) % 60
                    && rxHour == priorRxHour) rxOK = true;
                priorRxMinute = rxMinute;
                priorRxHour = rxHour;
                dcfCnt = 0;
                nBit = 1;
                bitXor = 0;
                dcfStat = 2;
            }
            break;

        case 8: // errore generale di ricezione
            rxError = true;
            dcfStat = 0;
    }

}

La funzione dcf va chiamata alla frequenza di multiplex (2.5ms in base a quanto scritto in questo post), legge il pin dcfPin (può essere un pin qualsiasi) e imposta a true due flag rxOK o rxError. Scrive l'ora ricevuta nelle variabili rxMinute (da 0 a 59) e rxHour (da 0 a 23). Effettua controlli su:
- durata singoli impulsi
- valore corretto dei bit di start e parità
- valore orario sensato
- da per buona l'ora (rxOK=true) quando si ricevono due trame consecutive OK con differenza di un solo minuto

Nota: ricava solo l'orario, fino al 36esimo bit, e ignora i successivi 23.

Per funzionare usa il seguente gruppo di definizioni/variabili globali:
Code: [Select]
#define       dcfPin A2          // pin Arduino input impulsi dcf
byte          nBit;              // numero del bit letto 1..60
byte          dcfStat = 0;       // stato processo dcf
unsigned int  dcfCnt;            // contatore 16 bit processo dcf
byte          bitRx;             // valore bit appena ricevuto
byte          bitXor;            // xor di tutti i bit ricevuti
unsigned int  rxData;            // scorrimento bit ricevuti in campo 16 bit
byte          rxMinute;          // minuto appena ricevuto
byte          rxHour;            // ora appena ricevuta
byte          priorRxMinute = 0; // minuto ricevuto precedente
byte          priorRxHour = 0;   // ora ricevuta precedente
bool          rxOK = false;      // true quando ricevuti dati OK
bool          rxError = false;   // true quando errore qualsiasi

ricki158

Intanto ti ringrazio, dedichi tempo ad una tecnologia ormai praticamente obsoleta!

Per quanto riguarda le funzioni dei tasti e dei LED dico subito che il progetto è riciclato dallo schema elettrico che ho messo nei primi post, ma nulla mi vieta di cambiarlo un attimo. La cosa che mi interessava imparare di più è la gestione del display in quella maniera, tramite BCD.

Per l'alimentazione posso fare grezzamente un partitore di tensione ed ho risolto.

Per quanto riguarda il tuo codice devo analizzarlo un po' e capirlo.

Grazie intanto per il tuo prezioso contributo!

ricki158

Ho dato un occhio al tuo codice. Dovrei tutto commentarlo bene per capire esattamente. Certe cose le capisco anche io che sono nuovo, però dovrei scrivere i commenti dettagliati per capire perfettamente e usare queste nozioni in futuro.

Penso che si possa fare la stessa cosa fatta in case 4 anche per la data senza problemi.

Per quanto riguarda i bit nominati come GS? Che cosa sarebbero?

Quindi se non so i secondi, dovrei aggiungere 1 fino a 60 nei secondi dell'RTC e azzerare i secondi e segnarmi le ore e i minuti quando cambiano i minuti rxMinute e rxOK è true.

Effettivamente con quelle due flag sarebbe bello avere i due led, magari uno verde e uno rosso. Oppure magari tenerlo acceso fisso se rxOK = true e rxErr = false e farlo blinkare se rf = false e rxErr = true.

p.s.: ma è vero che dovrebbero esserci dei bit codificati che danno informazioni sul meteo? E come potrebbero essere decifrati? Solo per sapere come funziona, non tanto per inserirlo in questo progetto.

Go Up