Module RTC ds1307 : ne fonctionne pas (edit : DS3231 pas plus)

Bonsoir,

toujours pour mon projet de volets, j'ai essayé de câbler et d'utiliser un module RTC DS1307

J'ai suivi la page du randomnerdtuto :

J'ai adapté le câblage à ma carte ESP32-S3-wroom-1

DS1307          ESP32
SCL	     -->    GPIO 9
SDA	     -->    GPIO 8
VCC	     -->    3V3
GND	     -->    GND

Les ports semblent OK puisque le scanner I2C trouve deux adresses

Mais quand je charge le code proposé :

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp32-ds1307-real-time-clock-rtc-arduino/
  Based on the RTClib Library examples: github.com/adafruit/RTClib/blob/master/examples
*/

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  Serial.begin(115200);
  delay(2000);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    //Serial.flush();
    //while (1) delay(10);  //supprimé sinon ça démarre jamais
    delay(2000);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
  // Get the current time from the RTC
  DateTime now = rtc.now();
  
  // Getting each time field in individual variables
  // And adding a leading zero when needed;
  String yearStr = String(now.year(), DEC);
  String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
  String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
  String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC); 
  String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
  String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
  String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];

  // Complete time string
  String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;

  // Print the complete formatted time
  Serial.println(formattedTime);

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

La console me donne des erreurs et cela ne fonctionne pas :

00:28:29.801 -> Couldn't find RTC
00:28:29.801 -> 
00:28:30.397 -> E (4013) i2c.master: I2C transaction unexpected nack detected
00:28:30.397 -> E (4014) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
00:28:30.397 -> E (4015) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
00:28:30.397 -> E (4023) i2c.master: I2C transaction unexpected nack detected
00:28:30.429 -> E (4028) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
00:28:30.429 -> E (4035) i2c.master: i2c_master_receive(1240): I2C transaction failed
00:28:30.429 -> E (4041) i2c.master: I2C transaction unexpected nack detected
00:28:30.429 -> E (4046) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
00:28:30.429 -> E (4054) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
00:28:30.462 -> E (4061) i2c.master: I2C transaction unexpected nack detected
00:28:30.462 -> E (4066) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
00:28:30.462 -> E (4073) i2c.master: i2c_master_transmit_receive(1220): I2C transaction failed
00:28:30.462 -> Sunday, 2000-00-00 45:129:00
00:28:30.462 -> 
00:28:33.468 -> E (7081) i2c.master: I2C transaction unexpected nack detected
00:28:33.468 -> E (7081) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
00:28:33.468 -> E (7083) i2c.master: i2c_master_transmit_receive(1220): I2C transaction failed
00:28:33.468 -> Sunday, 2000-00-00 45:129:00

Ces 4 dernières lignes se répètent ensuite en boucle...

C'est mon module qui est HS ? mon code qui est pourri ?

merci d'avance

(pile changée, connexion testées)

Essayez avec la bibliothèque RTCLib, ils ont un exemple pour la DS1307

Il faut peut être aussi rajouter des pull-up sur SCL et SDA (je mets 4.7k)

Notez que la 1307 dérive extrêmement rapidement, je ne recommanderai pas son usage dans un projet qui doit tourner plus que quelques heures - prenez une DS3231 à la place et utilisez l’heure obtenue par NTP internet si votre ESP32 a accès au WiFI / Internet

La ds1307 utilise un quartz et sa dérive due a la temperature dépends de celle du quartz que le fabricant du module a choisi de monter.
Et dans un module a pas cher ...........

Le ds3231 utilise des mems. Les mems sont intrinsèquement moins précis qu’un quartz, mais ils sont gravés sur le silicium et Maxim, maintenant Analog devices, a intégré une compensation en température ce qui réduit considérablement la dérive par rapport a un quartz externe.

1 Like

MErci de cette réponse...

C'est bien cette bib que j'utilise GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library et le code de RNT semble largement inspiré de celui-ci

Je vais tenter les pull-up dès que possible, merci du tuyau

Le montage est prévu pour être connecté H24 mais je vais peut-être changer pour un DS3231

Oui ca vaudrait mieux ou vous allez vite perdre l’heure

La DS1307 dérive en théorie d’environ 52 secondes par mois avec un quartz à 20 ppm (de mémoire) mais en pratique elle dépasse souvent plusieurs minutes par mois à cause des variations de température et de la qualité du quartz. La DS3231 dérive de moins d’une minute par an.

Pour un système d'automatisation de volets, ce n'est pas critique, surtout si l'horloge RTC peut être recalée par NTP une ou deux fois par jour (ou plus)
Mais pour le principe et vu le prix, autant se faire plaisir...

Merci pour ces précisions

Dans ce cas, la RTC n'est même pas nécessaire.
Un comptage basé sur millis() recalé périodiquement est largement suffisant.

En cas de panne de courant, il est arrivé que la box ne reparte pas toute seule correctement et nécessite un deuxième reboot manuel :frowning:
D'où l'idée de l'horloge RTC en cas d'absence, même si ce n'est pas très courant.

Même si elle reboote correctement, elle le fera beaucoup plus lentement que l'ESP et il y aura donc une prériode sans horloge correcte jusqu'à la première synchro correcte

Bonjour à tous,
J'ai eu des soucis avec une DS1307 raccordée à un ESP en 3.3V...
Par contre pas de souci avec une DS3231 qui est aussi beaucoup plus précise.
Bonne bidouille
MicroQuettas.

Bonjour,
le Ds1307 n'est pas compatible 3.3V. sa tolérance: 4.5V -- 5.5V.

sauf à utiliser un convertisseur de niveau.

+1

Concrètement si la tension d'alimentation Vcc est inférieure à 1,25 fois (valeur typique) la tension VBAT (donc < 3.75V pour une pile de 3V) le DS1307 passe en mode 'Power fail', son bus I2C cesse de fonctionner, l'horloge , elle , fonctionne sur la pile/batterie
A Vcc= 3.3V on est hors spécification, juste en dehors du fonctionnement garanti pour VBAT=3V
avec une pile faible , VBAT=2.5V , ça peut passer !!

image

la plage d'alimentation VCC recommandée est celle donnée par Leptro

c'est un circuit intégré RTC qui , en son temps , à rendu bien des services faute de mieux
En 2025 à moins d'avoir un projet pur 'Vintage' on gagne à l'oublier , surtout si on utilise un µC fonctionnant sous 3.3V

Convaincu... (en un seul mot, je vous vois venir)

Un DS3231 est commandé... À suivre

Bon, bin la suite n'est pas glorieuse... Je décoche le "résolu" pour le moment :frowning:

J'ai acheté ça : https://www.amazon.fr/dp/B0DBV777YT
annoncé pour fonctionner en 3,3 et 5V

Même branchement que précédemment :

DS1307          ESP32
SCL	     -->    GPIO 9
SDA	     -->    GPIO 8
VCC	     -->    3V3
GND	     -->    GND

J'ai mis le code de l'exemple de la bib RTClib de l'IDE adapté au DS3231 :

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  Serial.begin(57600);

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

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(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");

    // calculate a date which is 7 days, 12 hours, 30 minutes, 6 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 12h + 30m + 6s: ");
    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.print("Temperature: ");
    Serial.print(rtc.getTemperature());
    Serial.println(" C");

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

Ce sketch s'arrête à

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");

J'ai testé :

  • avec et sans résistance de pull-up : pareil
  • en alimentant par le pin 5V carte et DS3231 : pareil
  • avec et sans pile : pareil

Plus surprenant, j'ai aussi chargé le sketch du scanner d'I2C ( ESP32: I2C Scanner (Arduino) | Random Nerd Tutorials )
Avec la carte DS3231 : aucun port I2C n'est détecté
Alors qu'avec l'autre carte '1307' les ports étaient bien identifiés.

J'en perds mon latin (nan en vrai j'ai jamais fait de latin)

À toute fin utile : la carte ESP32 utilisée est celle-ci :
https://fr.aliexpress.com/item/1005006109469779.html
en version ESP32-S3 N16R8

Bonsoir @ProfesseurMephisto

si tu es en version 3.20 du core ESP32 d'Espressif fais un essai en rétrogradant vers la version précédente
(La version 3.20 utilise un nouveau driver i2C pour lequel des remontées de bugs ont apparues sur le dépôt Github) : https://github.com/espressif/arduino-esp32/issues/11228

J'ai la version 3.2.0 C'est bien de celle-là dont tu parles ? (avec un point entre 2 et 0)

J'essaye de suite...

J'ai dégradé en version 3.1.3 et 3.1.2 : ça ne change rien...

J'ai changé de modèle de carte pour un ESP32 wroom de base et ça fonctionne.

Reste à savoir si c'est le type de carte qui est buggée ou si c'est juste un mauvais échantillon. J'en ai une deuxième mais il faut que je soude les pattes pour la tester. Ce sera pour demain !

Même si je ferais surement comme toi, cela est-il vraiment nécessaire que l'ESP connaisse son heure à la seconde ou son programme se lance ?

Franchement si tu as un DS1307 fonctionnel, je ne vois pas "l'intérêt" de s'acharner à faire fonctionner un DS3231.

On peut se poser la question de la précision nécessaire pour ce genre d'équipement.
Tes volets, doivent absolument s'ouvrir à :

  • seconde près (MAJ nécessaire toutes les 4h).
  • minutes près (MAJ nécessaire toutes les 11j).
  • quart d'heure près (MAJ nécessaire toutes les 180j).
  • l'heure près.
  • la demi-journée près(je rigole)

Donc en imaginant que tu t'absente 6 mois et que pas de bol à peine partis, la box vrac, la dérive est-elle si gênante ?

:upside_down_face:

Non mais il ne peut pas se croire le premier janvier 1970 0h (ou je ne sais quoi). Ou alors il faut bloquer toute action avant la mise à l'heure par NTP. Cette dernière option est envisageable.

Très modeste... Le 1307 suffirait. Mais la contrainte du 5v complique les choses et de toute façon, il n'est pas plus fonctionnel (pour le moment) sur la carte que le 3231. Match nul, balle au centre.

Hé ho ! les profs ont des vacances mais pas 6 mois quand même :wink: