Horloge RTC ne compte pas le temps

Bonjour,

J'ai ressorti mes arduino méga avec leur Sheild SD.

J'ai changé la pile, réglé l'heure avec mon programme de l'époque:

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

void setup() {

  Serial.begin(57600);
  Wire.begin();
  rtc.begin();

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 //reglage de l'horloge
  //rtc.adjust(DateTime(DATE, TIME));
}

void loop() {

 DateTime now = rtc.now();
 //cherche l'heure actuelle

  Serial.print(now.year());
  Serial.print('/');
  Serial.print(now.month());
  Serial.print('/');
  Serial.print(now.day());
  Serial.print(' ');
  Serial.print(now.hour());
  Serial.print(':');
  Serial.print(now.minute());
  Serial.print(':');
  Serial.print(now.second());
  Serial.println();

  Serial.println();
  
  delay(3000);
}

Or sur les deux j'ai un problème, l'horloge ne compte plus le temps.

J'ai lancé un scanner i2C:

[quote="kamill, post:2, topic:874781"] https://playground.arduino.cc/Main/I2cScanner/ [/quote]

dont voici la réponse:

I2C device found at address 0x68  !

Merci par avance.

Bonjour,

Tu n'expliques pas comment tu te rend compte que ton RTC ne compte plus le temps.

Si tu utilises le programme dont tu mets le listing, après l'avoir lancé une fois, il faut lettre en commentaire la ligne "rtc.adjust(DateTime(F(_DATE_), F(_TIME_)));" sinon la date heure va être réinitiallisée à chaque lancement du programme.

Voici une copie du moniteur série:

2026/7/17 1:16:5

2026/7/17 1:16:5

2026/7/17 1:16:5

Je peut laisser tourner le programme pendant des heures, rien ne change.

De plus, concernant la ligne "rtc.adjust(DateTime(F(_DATE_), F(_TIME_)));" c'est dans le setup, donc je dois pouvoir la laisser. Mais je l'ai mise après également en commentaire.

Le arduino est constamment branché au PC.

Bonjour aurel0087

Non, cette ligne ne s'utilise qu'en cas de déconnexion de la batterie pour mettre une fois, l'horloge à l'heure.
A la compilation, avec cette ligne, la date et l'heure de cette dernière est "gravée" dans l'Arduino et est reprise à chaque démarrage. C'est pourquoi il faut télécharger et lancer le programme avec cette ligne pour la mise à l'heure, mettre cette ligne en remarque, puis retélécharger le programme.

Pour ton programme, modifies la façon de démarrer ta RTC, à la place de:
rtc.begin();
mets:

if (!rtc.begin()) {
  Serial.println("RTC non trouve !");
  while (1);
}

Tu verras si ta RTC est bien en route.

Cordialement
jpbbricole

D’accord.

J'ai remplacé la ligne.

Cela ne me met pas RTC non trouvé.

Mais toujours le temps qui ne s’écoule pas.

2026/8/21 9:16:5

2026/8/21 9:16:5

2026/8/21 9:16:5

J'ai essayé ton programme, il fonctionne:

2026/7/17 14:18:2
2026/7/17 14:18:5
2026/7/17 14:18:8
2026/7/17 14:18:11
2026/7/17 14:18:14
2026/7/17 14:18:17
2026/7/17 14:18:20
2026/7/17 14:18:23
2026/7/17 14:18:26
2026/7/17 14:18:29
2026/7/17 14:18:32

Bizarrement de mon coté, je n'ai pas la bonne heure:

2026/7/17 0:13:44
2026/7/17 0:13:44
2026/7/17 0:13:44

J'ai refait les branchement, j'ai changé de module SD et de arduino, rien a faire.

D'après la datasheet, après une perte d'alimentation de sauvegarde la RTC se réinitialise à OFF.

On peut vérifier si le DS1307 tourne avec la méthode isrunning().
Si la valeur retournée est false il faut mettre à 1 le poids fort du registre 0 de la RTC.
Je pense que le plus simple serait de faire la modification suivante dans la librairie

fichier RTC_DS1307.cpp

/**************************************************************************/
/*!
    @brief  Set the date and time in the DS1307
    @param dt DateTime object containing the desired date/time
*/
/**************************************************************************/
void RTC_DS1307::adjust(const DateTime &dt) {
  uint8_t buffer[8] = {0,
//                       bin2bcd(dt.second()),
                       0x7F & bin2bcd(dt.second()),  // active RTC
                       bin2bcd(dt.minute()),
                       bin2bcd(dt.hour()),
                       0,
                       bin2bcd(dt.day()),
                       bin2bcd(dt.month()),
                       bin2bcd(dt.year() - 2000U)};
  i2c_dev->write(buffer, 8);
}

On pourrait aussi faire une méthode pour activer/désactiver la RTC, mais il n'est pas illogique de forcer la démarrage lorsqu'on met la RTC à l'heure

EDIT: correction de la ligne contenant les secondes pour forcer le MSB à 0.

Merci, j'ai effectué la modification mais sans succès

Tu as vérifié l'état de la pile?
Que retourne la méthode isrunning(), avant et après avoir fait adjust()?

La pile est neuve.

Que je comprenne bien, j'ai copié le code que vous m'avez donné dans la bibliothèque:

void RTC_DS1307::adjust(const DateTime &dt) {
  uint8_t buffer[8] = {0,
//                       bin2bcd(dt.second()),
                       DS1307_ON | bin2bcd(dt.second()),  // active RTC
                       bin2bcd(dt.minute()),
                       bin2bcd(dt.hour()),
                       0,
                       bin2bcd(dt.day()),
                       bin2bcd(dt.month()),
                       bin2bcd(dt.year() - 2000U)};
  i2c_dev->write(buffer, 8);
}

Ensuite j'ai programmé avec sans adjust Et il ne sais rien passé de plus.
Mais peut être que je n'ai pas bien compris.

Merci d'avance

A la place de la méthode adjust() qui était déjà dans la librairie, on est bien d'accord?

Tu n'as pas répondu à la question

Que retourne la méthode isrunning(), avant et après avoir fait adjust()?

J'ai copié votre code exactement à cet endroit sur le fichier RTC_DS1307.cpp

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
/\*!
    @brief  Set the date and time in the DS1307
    @param dt DateTime object containing the desired date/time
\*/
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
`void RTC_DS1307::adjust(const DateTime &dt) {
  uint8_t buffer[8] = {0,
//                       bin2bcd(dt.second()),
                       DS1307_ON | bin2bcd(dt.second()),  // active RTC
                       bin2bcd(dt.minute()),
                       bin2bcd(dt.hour()),
                       0,
                       bin2bcd(dt.day()),
                       bin2bcd(dt.month()),
                       bin2bcd(dt.year() - 2000U)};
  i2c_dev->write(buffer, 8);
}

Je ne comprend pas votre notion de méthode.

Est ce ce code?

#include <Wire.h>
#include <RTClib.h>

RTC_DS1307 rtc;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  if (!rtc.begin()) {
    Serial.println("DS1307 non detecte");
    while (1);
  }

  if (!rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  DateTime now = rtc.now();

  Serial.print(now.timestamp(DateTime::TIMESTAMP_FULL));
  Serial.println();

  delay(1000);
}

Cordialement

Bonjour aurel0087

Il est possible que ton horloge soit arrêtée.
Pour voir si elle l'est, j'ai modifié ton programme et il affiche le registre concerné:

Registre secondes = 0x110001
2026/7/17 17:25:31

Il affiche le registre des secondes en binaire, dans ce cas en 6 bits.
Si tu as 8 bits, conc le bit 7 à 1, cela veut dire que ton horloge est arrêtée.

Le programme modifié:

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

void setup() {

	Serial.begin(57600);
	Wire.begin();
	rtc.begin();

	//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	//reglage de l'horloge
	//rtc.adjust(DateTime(DATE, TIME));
}

void loop() {

	DateTime now = rtc.now();
	//cherche l'heure actuelle

	Serial.print(now.year());
	Serial.print('/');
	Serial.print(now.month());
	Serial.print('/');
	Serial.print(now.day());
	Serial.print(' ');
	Serial.print(now.hour());
	Serial.print(':');
	Serial.print(now.minute());
	Serial.print(':');
	Serial.print(now.second());
	Serial.println();

	Serial.println();
	
	delay(3000);
	reg0check();
}

void reg0check()
{
Wire.beginTransmission(0x68);
Wire.write(0);
Wire.endTransmission();

Wire.requestFrom(0x68,1);

byte sec = Wire.read();

Serial.print("Registre secondes = 0x");
Serial.println(sec,BIN);	
}

A+
Cordialement
jpbbricole

Effectivement, voici la réponse:

Registre secondes = 0x100011

2026/7/17 9:1:23

Cordialement

Donc l'horloge n'est pas arrêtée, le mystère perdure :woozy_face:

Ajoute sous la ligne

reg0check();
Serial.println(rtc.now().unixtime());

le grand chiffre doit bouger:

Registre secondes = 0x1001000
1784310588
2026/7/17 17:49:48

Registre secondes = 0x1010001
1784310591
2026/7/17 17:49:51

Registre secondes = 0x1010100
1784310594
2026/7/17 17:49:54

Registre secondes = 0x1010111
1784310597
2026/7/17 17:49:57

Rien ne bouge:

Registre secondes = 0x10101001

1784257529

2026/7/17 3:5:29


Registre secondes = 0x10101001

1784257529

2026/7/17 3:5:29


Registre secondes = 0x10101001

1784257529

2026/7/17 3:5:29


Registre secondes = 0x10101001

1784257529

2026/7/17 3:5:29

 

Il faut regarder du côté du quartz, est il dessoudé ou, au pire, fichu?
C'est quoi comme module RTC?

J'ai essayé sur 3 shield SD différents.

Ils sont assez vieux, la pile était bien déchargée. Mais a l'époque ils ont fonctionnés plusieurs années.

J'ai une carte neuve qui est encore sous emballage. je la monte demain.

RTC_SD.pdf (3,4 Mo)