Vous êtes sur la page 1sur 17

Module d'interface DS3231

Precision RTC avec Arduino

Nous savons tous que la plupart des microcontrôleurs que nous utilisons pour nos
projets sont indépendants du temps; en termes simples, ils ne sont pas conscients du
temps qui les entoure. C'est OK pour la plupart de nos projets, mais de temps en temps,
lorsque vous rencontrez une idée où le respect du temps est une préoccupation majeure,
le module DS3231 Precision RTC est un sauveur. Il est parfait pour les projets contenant
l'enregistrement de données, la création d'horloge, l'horodatage, les minuteries et les
alarmes.

Puce DS3231 RTC


Au cœur du module se trouve une puce RTC à faible coût et extrêmement précise de
Maxim - DS3231 . Il gère toutes les fonctions de chronométrage et dispose d'une
interface I2C simple à deux fils qui peut être facilement interfacée avec n'importe quel
microcontrôleur de votre choix.

La puce conserve les informations sur les secondes, les minutes, les heures, le jour, la
date, le mois et l'année. La date de fin de mois est automatiquement ajustée pour les
mois de moins de 31 jours, y compris les corrections pour l'année bissextile (valable
jusqu'à 2100).

L'horloge fonctionne au format 24 heures ou 12 heures avec un indicateur AM / PM. Il


fournit également deux alarmes horaires programmables.

L'autre fonctionnalité intéressante de cette carte est fournie avec la broche SQW, qui
produit une belle onde carrée à 1 Hz, 4 kHz, 8 kHz ou 32 kHz et peut être gérée par
programme. Cela peut en outre être utilisé comme une interruption en raison d'une
condition d'alarme dans de nombreuses applications basées sur le temps.

Oscillateur à cristal compensé en


température (TCXO)
La plupart des modules RTC sont livrés avec un cristal externe de 32 kHz pour le
chronométrage. Mais le problème avec ces cristaux est que la température extérieure
peut affecter leur fréquence d'oscillation. Ce changement de fréquence peut être
négligeable mais il s'additionne sûrement.

Pour éviter ces légères dérives dans le cristal, le DS3231 est entraîné par un oscillateur à
cristal compensé en température de 32 kHz (TCXO) . Il est hautement immunisé contre
les changements de température externes.
TCXO est emballé à l'intérieur de la puce RTC, ce qui rend l'ensemble du paquet
volumineux. Juste à côté du cristal intégré se trouve un capteur de température.

Ce capteur compense les changements de fréquence en ajoutant ou en supprimant des


tics d'horloge afin que l'indication de l'heure reste sur la bonne voie.

C'est la raison pour laquelle TCXO fournit une horloge de référence stable et précise et
maintient le RTC avec une précision de ± 2 minutes par an.

DS3231 contre DS1307

La principale différence entre le DS3231 et le DS1370 est la précision du chronométrage.

Le DS1307 est livré avec un cristal externe de 32 kHz pour le chronométrage dont la
fréquence d'oscillation est facilement affectée par la température externe. Cela se traduit
généralement par un décalage d'environ cinq minutes par mois.

Cependant, le DS3231 est beaucoup plus précis, car il est livré avec un oscillateur à
cristal compensé en température (TCXO) interne qui n'est pas affecté par la température,
ce qui le rend précis jusqu'à quelques minutes par an au maximum.

DS1307 est toujours un RTC de grande valeur et vous sert bien, mais pour les projets qui
nécessitent un chronométrage plus précis, DS3231 est recommandé.

Batterie de secours
Le DS3231 intègre une entrée de batterie et maintient un chronométrage précis lorsque
l'alimentation principale de l'appareil est interrompue.

Le circuit de détection de puissance intégré surveille en permanence l'état du VCC pour


détecter les pannes de courant et bascule automatiquement sur l'alimentation de
secours. Ainsi, vous n'avez pas à vous soucier des pannes de courant, votre MCU peut
toujours suivre le temps.

La face inférieure de la carte contient un support de batterie pour 20 mm de lithium 3V


coïncident. Toute batterie CR2032 peut bien s'adapter.

En supposant qu'une batterie CR2032 complètement chargée d'une capacité de 220 mAh
est utilisée et que la puce consomme au minimum 3µA, la batterie peut maintenir le RTC
en fonctionnement pendant au moins 8 ans sans alimentation externe 5V.

220mAh / 3µA = 73333,34 heures = 3055,56 jours = 8,37 ans

EEPROM 24C32 intégrée


Le module DS3231 RTC est également livré avec une puce EEPROM 24C32 de 32 octets
d'Atmel ayant des cycles de lecture-écriture illimités. Il peut être utilisé pour enregistrer
des paramètres ou vraiment n'importe quoi.
L'EEPROM 24C32 utilise l'interface I2C pour la communication et partage le même bus
I2C que le DS3231.

L'adresse I2C de l'EEPROM peut être facilement modifiée grâce aux trois cavaliers à
souder A0, A1 et A2 à l'arrière. Chacun de ceux-ci est utilisé pour coder en dur
l'adresse. Si un cavalier est court-circuité avec de la soudure, cela définit l'adresse.

Selon la fiche technique du 24C32, ces 3 bits sont placés à la fin de l'adresse I2C 7 bits,
juste avant le bit de lecture / écriture.

Comme il y a 3 entrées d'adresse, qui peuvent prendre 2 états, soit HIGH / LOW, on peut
3
donc créer 8 (2   ) combinaisons (adresses) différentes.

ASTUCE

Par défaut, toutes les 3 entrées d'adresse sont tirées HAUT à l'aide de pullups intégrés,
donnant à 24C32 une adresse I2C par défaut de 1010111 binaire ou 0x57 hexadécimal .

En court-circuitant les cavaliers de soudure, les entrées d'adresse sont réduites à l'état
bas. Il vous permet de définir l'adresse I2C selon le tableau ci-dessous.
Le code de lecture / écriture à bord de l'EEPROM 24C32 est donné à la fin du tutoriel .

Brochage du module DS3231 RTC


Le module DS3231 RTC a un total de 6 broches qui l'interfacent avec le monde
extérieur. Les connexions sont les suivantes:

32 000 broche émet l'horloge de référence stable (compensée en température) et


précise.
SQWpin émet une belle onde carrée à 1 Hz, 4 kHz, 8 kHz ou 32 kHz et peut être gérée par
programme. Cela peut en outre être utilisé comme une interruption en raison d'une
condition d'alarme dans de nombreuses applications basées sur le temps.
SCL est une broche d'horloge série pour l'interface I2C.
SDA est une broche de données série pour l'interface I2C.
VCCbroche alimente le module. Il peut être n'importe où entre 3,3 V et 5,5 V.
GND est une broche de masse.

Câblage du module DS3231 RTC à Arduino


UNO
Accrochons le RTC à l'Arduino.

Les connexions sont assez simples. Commencez par connecter la broche VCC à la sortie
5V de l'Arduino et connectez GND à la terre.

Maintenant, nous restons avec les broches qui sont utilisées pour la communication
I2C. Notez que chaque carte Arduino a différentes broches I2C qui doivent être
connectées en conséquence. Sur les cartes Arduino avec la disposition R3, le SDA (ligne
de données) et SCL (ligne d'horloge) sont sur les en-têtes de broches proches de la
broche AREF. Ils sont également appelés A5 (SCL) et A4 (SDA).

Si vous avez un Mega, les broches sont différentes! Vous voudrez utiliser le numérique
21 (SCL) et 20 (SDA). Reportez-vous au tableau ci-dessous pour une compréhension
rapide.

SCL SDA

Arduino Uno A5 A4

Arduino Nano A5 A4

Arduino Mega 21 20

Léonard / Micro 3 2

Le diagramme suivant vous montre comment tout câbler.


Câbla

ge du module DS3231 RTC avec Arduino

Installation de la bibliothèque RTClib


La communication avec un module RTC est une tâche ardue. Heureusement,
la bibliothèque RTClib a été écrite pour cacher toutes les complexités afin que nous
puissions émettre des commandes simples pour lire les données RTC.

Pour installer la bibliothèque, accédez à Sketch> Inclure la bibliothèque> Gérer les


bibliothèques… Attendez que Library Manager télécharge l'index des bibliothèques et met
à jour la liste des bibliothèques installées.
Filtrez votre recherche en tapant « rtclib ». Il devrait y avoir quelques entrées. Recherchez
RTClib par Adafruit. Cliquez sur cette entrée, puis sélectionnez Installer.
Code Arduino - Date et heure de lecture
L'esquisse suivante vous donnera une compréhension complète de la façon de régler /
lire la date et l'heure sur le module DS3231 RTC et peut servir de base à des expériences
et des projets plus pratiques.

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

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday",


"Thursday", "Friday", "Saturday"};

void setup ()
{
Serial.begin(9600);
delay(3000); // wait for console opening

if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");

// Comment out below lines once you set the date & time.
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

// Following line sets the RTC with an explicit date & time
// for example to set January 27 2017 at 12:56 you would call:
// rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
}
}

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

Serial.println("Current Date & Time: ");


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.println("Unix Time: ");


Serial.print("elapsed ");
Serial.print(now.unixtime());
Serial.print(" seconds/");
Serial.print(now.unixtime() / 86400L);
Serial.println(" days since 1/1/1970");
// calculate a date which is 7 days & 30 seconds into the future
DateTime future (now + TimeSpan(7,0,0,30));

Serial.println("Future Date & Time (Now + 7days & 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);
}

Voici à quoi ressemble la sortie sur le moniteur série.

Explication du code:
L'esquisse commence par inclure les bibliothèques wire.h et RTClib.h pour communiquer
avec le module. Nous créons ensuite un objet de la bibliothèque RTClib et
définissons daysOfTheWeekun tableau de caractères 2D pour stocker les informations sur
les jours.

Dans les sections setup et loop du code, nous utilisons les fonctions suivantes pour
interagir avec le module RTC.

La fonction begin () garantit que le module RTC est connecté.

La fonction lostPower () lit les registres I2C internes du DS3231 pour vérifier si la puce a
perdu la notion du temps. Si la fonction renvoie true, nous pouvons alors définir la date et
l'heure.

La fonction Adjust () règle la date et l'heure. Ceci est une fonction surchargée.

 Une méthode surchargée DateTime(F(__DATE__), F(__TIME__)) définit la date et


l'heure auxquelles l'esquisse a été compilée.

 La deuxième méthode surchargée DateTime(YYYY, M, D, H, M, s)définit le RTC


avec une date et une heure explicites. Par exemple, pour définir le 27 janvier 2017 à 12 h
56, vous appelleriez:rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));

La fonction now () renvoie la date et l'heure actuelles. Sa valeur de retour est


généralement stockée dans la variable de type de données DateTime.

La fonction year () renvoie l'année en cours.

La fonction month () renvoie le mois en cours.

La fonction day () renvoie le jour actuel.

La fonction dayOfTheWeek () renvoie le jour actuel de la semaine. Cette fonction est


généralement utilisée comme index d'un tableau de caractères 2D qui stocke des
informations sur les jours comme celle définie dans le programme ci-
dessusdaysOfTheWeek

La fonction hour () renvoie l'heure actuelle.

La fonction minute () renvoie la minute actuelle.


La fonction second () renvoie les secondes actuelles.

La fonction unixtime () renvoie l'heure unix en secondes. L'heure Unix est un système


pour décrire un point dans le temps. C'est le nombre de secondes qui se sont écoulées
depuis 00:00:00 (connu sous le nom de temps universel coordonné - jeudi 1er janvier
1970).

La fonction TimeSpan () est utilisée pour ajouter / soustraire du temps à / de l'heure


actuelle. Vous pouvez ajouter / soustraire des jours, des heures, des minutes et des
secondes. C'est aussi une fonction surchargée.

 now() + TimeSpan(seconds) renvoie l'heure future avec des secondes ajoutées à


l'heure actuelle.

 now() - TimeSpan(days,hours, minutes, seconds)  renvoie le temps passé.

Code Arduino - Lecture / écriture en EEPROM


24C32
Avec le module DS3231 RTC, en prime, vous obtenez 32 octets de ROM effaçable
électriquement. Son contenu ne sera pas effacé même si l'alimentation principale de
l'appareil est interrompue.

Le programme suivant écrit puis lit un message à partir de l'EEPROM 24C32. Vous


pouvez utiliser ce programme pour enregistrer des paramètres ou des mots de passe ou
vraiment n'importe quoi.

#include <Wire.h>

void setup()
{
char somedata[] = "lastminuteengineers.com"; // data to write
Wire.begin(); // initialise the connection
Serial.begin(9600);
Serial.println("Writing into memory...");

// write to EEPROM
i2c_eeprom_write_page(0x57, 0, (byte *)somedata, sizeof(somedata));
delay(100); //add a small delay
Serial.println("Memory written");
}

void loop()
{
Serial.print("Reading memory: ");
int addr=0; //first address

// access the first address from the memory


byte b = i2c_eeprom_read_byte(0x57, 0);

while (b!=0)
{
Serial.print((char)b); //print content to serial port
addr++; //increase address
b = i2c_eeprom_read_byte(0x57, addr); //access an address from the
memory
}
Serial.println(" ");
delay(2000);
}

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte


data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}

// WARNING: address is a page address, 6-bit end will wrap around


// also, data can be maximum of about 30 bytes, because the Wire library has a
buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage,
byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {


byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}

// maybe let's not read more than 30 or 32 bytes at a time!


void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte
*buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}

Voici à quoi ressemble la sortie sur le moniteur série.


 Avertissement
 Politique de confidentialité

Copyright © 2021 LastMinuteEngineers.com

Vous aimerez peut-être aussi