[RISOLTO] RTC con ds1307

Salve a tutti sto avendo diversi problemi con l’RTC, sto utilizzando questo schema per il ds1307:

e ho aggiunto un display per visualizzare l’ora senza collegare tutto a PC.
Sto usando la libreria di ladyada RTClib: http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit
Ora ho dei problemi con il seguente sketch:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
 
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

RTC_DS1307 RTC;
 
void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2); 
    lcd.clear();
    
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
}
 
void loop () {
    DateTime now = RTC.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    lcd.setCursor(0,0);
lcd.print(now.day(),DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.year(), DEC);
lcd.print(' ');
lcd.setCursor(0,1);
lcd.print(now.hour(),DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.print(' ');
        
 
    Serial.print(" since 1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
 
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
 
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
 
    Serial.println();
    delay(1000);
}

Cosa succede: l’ora è sfasata di circa 2 minuti rispetto all’ora vera, inoltre se modifico e carico lo sketch succede ogni volta che tolgo l’alimentazione perdo l’ora… ho controllato l’RTC ed è tutto collegato correttamente. Che può essere?
HO notato che ci sono diverse versioni della stessa libreria. Quale è meglio usare?

simo96:
Ho notato che ci sono diverse versioni della stessa libreria. Quale è meglio usare?

Sempre la più aggiornata.
Le pull'up mettile da 2.2K.
Non ricordo se il contenitore dell'oscillatore vada saldato a GND.

PaoloP:
Non ricordo se il contenitore dell'oscillatore vada saldato a GND.

Quanto meno poggiato sul piano di massa :wink:

Però ... detto tra noi ... a me funziona perfettamente anche infilato su una breadboard ... :grin: :grin: :grin:

Guglielmo

Quindi mi conviene saldare il contenitore del quarzo a massa? Ok.
Per ora pensavo di aver risolto, ma oggi ricollego l'alimentazione e mi ritrovo l'ora di ieri sera di quando ho caricato lo sketch.
Cosa sbaglio?

Il problema è chiaramente QUI :

if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
}

Per qualche motivo, alla partenza del tuo programma, la funzione RTC.isrunning() ritorna falso e quindi viene eseguito l’IF che … va a ricaricare nell’orologio la data e ora … DI COMPILAZIONE del programma !!!

Guglielmo

Saldare il quarzo?? :fearful:

Una cosa, sostituisco le resistenze di pullup con quelle da 2,2k e collego la carcassa del quarzo a massa.
Non ho idea di come scrivere il programma per settare l'ora dell'RTC visto che fino ad ora mi sono sempre basato sugli sketch di esempio e modificati per il mio uso.

Ma ... la batteria l'hai collegata bene ???

Guglielmo

Credo di si. Come verifico questa cosa?

pelletta:
Saldare il quarzo?? :fearful:

Immagino intendesse collegarne il contenitore a massa con un anello di filo saldato ... come, del resto, specificato nella Application Note n.58 di Maxim :

"If possible, place a guard ring (connected to ground) around the crystal. This helps isolate the crystal from noise coupled from adjacent signals."

Guglielmo

simo96:
Credo di si. Come verifico questa cosa?

Con un Voltmetro ... tra il pin 3 e massa devi avere i 3V della batteria ... anche ad alimentazione staccata ...

Guglielmo

Allora, ieri sera era collegata correttamente ma ora vado a misurare e trovo 0V. Il filo non faceva bene contatto..
Ora, che batteria mi consigliate per l'RTC? CR2032?

simo96:
Ora, che batteria mi consigliate per l’RTC? CR2032?

La CR2032 va benissimo … prendi un “holder” dove metterla e salda i fili ad esso … esempio, una cosa come questa :

Guglielmo

gpb01:

pelletta:
Saldare il quarzo?? :fearful:

Immagino intendesse collegarne il contenitore a massa con un anello di filo saldato ... come, del resto, specificato nella Application Note n.58 di Maxim :

"If possible, place a guard ring (connected to ground) around the crystal. This helps isolate the crystal from noise coupled from adjacent signals."

Guglielmo

Ecco... ricordavo una cosa del genere.
Quindi non si deve saldare il contenitore ma tenerlo fermo da un anello o cavetto collegato a GND.

Ho provato il seguente sketch aggiungendo al primo caricamento la stringa che poi rimane commentata

//RTC.adjust(DateTime(__DATE__, __TIME__));

Ecco il Programma:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
 
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

 
RTC_DS1307 RTC;
 
void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2); 
    lcd.clear();
     //RTC.adjust(DateTime(__DATE__, __TIME__));
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
}
 
void loop () {
    DateTime now = RTC.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    lcd.setCursor(0,0);
lcd.print(now.day(),DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.year(), DEC);
lcd.print(' ');
lcd.setCursor(0,1);
lcd.print(now.hour(),DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
lcd.print(' ');
        
 
    Serial.print(" since 1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
 
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
 
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
 
    Serial.println();
    delay(1000);
}

Ora una cosa che mi sembra strana, ho provato lo stesso sketch su due schede arduino:
la prima è Arduino uno e non funziona… non riesco a leggere la seriale e sul display leggo 165/165/2165 165:165:85
la seconda è Arduino mega 2560 e funziona correttamente, l’ora è molto vicina a quella reale (giusto quei secondi)

EDIT: la scheda Arduino uno utilizzava una shield fatta da me del RTC ds1307 mentre quella dell’Arduino Mega era fatta su breadboard, ora ricontrollando la shield mi sono accorto di un falso contatto. Ho sistemato il tutto e funziona. Grazie a tutti per i consigli.

Vedo che hai risolto ma tengo a dirlo lo stesso per futuri lettori che leggessero questo thread alla ricerca di una soluzione allo stesso problema.

Nel 99% dei casi gli errori di lettura del DS1307 sono da addebitare alla batteria: se è assente o se non è collegata bene o se è scarica, il chip ha problemi di stabilità. Quindi, collegare sempre la batt anche per prove su breadboard.

leo72:
Nel 99% dei casi gli errori di lettura del DS1307 sono da addebitare alla batteria: se è assente o se non è collegata bene o se è scarica, il chip ha problemi di stabilità. Quindi, collegare sempre la batt anche per prove su breadboard.

… aggiungo …

… o, se non avete la batteria perché state facendo semplici prove su breadboard, seguite quello che c’è scritto nel datasheet … collegate a massa il piedino 3 (quello della batteria), e non lasciatelo non collegato !!!

Guglielmo