Horloge intelligente LCD 128x64 : heure analogique/numérique & température – Arduino Nano + DS3231 RTC
Composants et fournitures
| Arduino Nano R3 | × | 1 |
| Module RTC DS3231M (±5ppm, I2C) | × | 1 |
| Potentiomètre 10 kΩ (simple tour) | × | 1 |
| Bouton poussoir momentané | × | 1 |
| Écran LCD graphique 128x64 | × | 1 |
Outils nécessaires
- Fer à souder (générique)
À propos de ce projet
Ce projet, présenté sur le site Arduino e Cia, réalise une horloge avec afficheur LCD graphique 128x64, potentiomètre de contraste, module RTC DS3231 et bouton poussoir. Le module RTC se connecte aux broches A4 (SDA) et A5 (SCL). Le bouton est sur la broche numérique 3 avec résistance de tirage interne activée par logiciel.
Le programme utilise plusieurs bibliothèques à installer avant compilation : décompressez-les dans le dossier LIBRARIES de l'IDE Arduino.
Deux écrans d'affichage
- Écran 1 : Horloge analogique, horloge numérique, date courante et température.
- Écran 2 : Horloge numérique, jour de la semaine, date, température courante, température minimale et maximale.
Le bouton sur la broche 3 permet de basculer entre les deux écrans.

Réglage de la date et l'heure
Utilisez le moniteur série en envoyant : année, mois, jour, heure, minute, seconde. Si correct, un message de confirmation s'affiche.
Code
Code principal (Arduino)
// Programme : LCD 128x64 et RTC DS3231
// Auteur : Arduino e Cia
#include <U8glib.h>
#include <DS3232RTC.h>
#include <Streaming.h>
#include <Time.h>
#include <Wire.h>
// Configuration afficheur (ajuster selon modèle)
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4, 7); // Enable, RW, RS, RESET
int X2 = 0, Y2 = 0, X3 = 0, Y3 = 0;
float angulo = 0;
int posicao = 0, posicaoh = 0;
int temperatura = 0;
int min_temp = 500, max_temp = -500;
int ScreenWith = 128, ScreenWithC = 96;
int ScreenHeight = 64, ScreenHeightC = 32;
#define botao 3
int estado_botao = 0;
char* dia_da_semana[] = {"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"};
void tela_1() {
u8g.drawRFrame(0, 0, 128, 64, 3);
// Température
u8g.setPrintPos(20, 30);
u8g.print(temperatura);
u8g.drawStr(42, 30, "C");
u8g.drawCircle(37, 34, 2);
mostra_relogio_digital();
// Horloge analogique
fundo_relogio();
desenha_ponteiro(hour()-1, 12.0, 10); // Heures
desenha_ponteiro(minute()-5, 60.0, 19); // Minutes
desenha_ponteiro(second()-5, 60, 21); // Secondes
}
void tela_2() {
u8g.drawRFrame(0, 0, 128, 64, 3);
u8g.drawRFrame(68, 4, 55, 56, 2);
mostra_relogio_digital();
u8g.setFont(u8g_font_5x8);
u8g.drawStr(78, 35, "MIN");
u8g.drawStr(78, 53, "MAX");
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(25, 41);
u8g.print(dia_da_semana[weekday()-1]);
// Temp actuelle
u8g.setPrintPos(83, 19);
u8g.print(temperatura);
u8g.drawStr(105, 19, "C");
u8g.drawCircle(100, 12, 2);
// Temp min
u8g.setPrintPos(98, 36);
u8g.print(min_temp);
u8g.drawCircle(113, 29, 2);
// Temp max
u8g.setPrintPos(98, 54);
u8g.print(max_temp);
u8g.drawCircle(113, 47, 2);
}
void desenha_ponteiro(float valor, float rotacao, int Radius) {
angulo = valor * 2.0 * 3.1415 / rotacao - 1.5707;
X2 = ScreenWithC + Radius * cos(angulo);
Y2 = ScreenHeightC + Radius * sin(angulo);
u8g.drawLine(ScreenWithC, ScreenHeightC, X2, Y2);
}
void fundo_relogio() {
u8g.drawCircle(ScreenWithC, ScreenHeightC, 27);
u8g.drawCircle(ScreenWithC, ScreenHeightC, 1);
u8g.setFont(u8g_font_6x13);
u8g.setFontPosTop();
u8g.drawStr(90, 9, "12");
u8g.drawStr(114, 25, "3");
u8g.drawStr(94, 44, "6");
u8g.drawStr(74, 25, "9");
for(int traco_minuto = 0; traco_minuto < 12; traco_minuto++) {
angulo = traco_minuto / 12.0 * 2 * 3.1415;
X2 = ScreenWithC + 25 * cos(angulo);
Y2 = ScreenHeightC + 25 * sin(angulo);
X3 = ScreenWithC + 25 * cos(angulo);
Y3 = ScreenHeightC + 25 * sin(angulo);
u8g.drawLine(X2, Y2, X3, Y3);
}
}
void mostra_relogio_digital() {
// Date
u8g.setFont(u8g_font_5x8);
u8g.setPrintPos(8, 55);
u8g.print(day());
u8g.drawStr(19, 55, "/");
u8g.setPrintPos(24, 55);
u8g.print(month());
u8g.drawStr(35, 55, "/");
u8g.setPrintPos(41, 55);
u8g.print(year());
// Heure:minutes
u8g.drawRBox(3, 4, 62, 21, 2);
u8g.setColorIndex(0);
u8g.setFont(u8g_font_fub17);
u8g.drawStr(29, 21, ":");
if (hour() < 10) {
u8g.drawStr(3, 23, "0");
posicaoh = 16;
} else posicaoh = 3;
u8g.setPrintPos(posicaoh, 23);
u8g.print(hour());
if (minute() < 10) {
u8g.drawStr(38, 23, "0");
posicao = 51;
} else posicao = 38;
u8g.setPrintPos(posicao, 23);
u8g.print(minute());
u8g.setColorIndex(1);
}
void setup() {
pinMode(3, INPUT_PULLUP);
Serial.begin(9600);
if (u8g.getMode() == U8G_MODE_R3G3B2) u8g.setColorIndex(255);
else if (u8g.getMode() == U8G_MODE_GRAY2BIT) u8g.setColorIndex(3);
else if (u8g.getMode() == U8G_MODE_BW) u8g.setColorIndex(1);
setSyncProvider(RTC.get);
Serial << F("Sync RTC");
if (timeStatus() != timeSet) Serial << F(" ÉCHEC!");
Serial << endl;
}
void loop() {
temperatura = RTC.temperature() / 4.0;
if (temperatura >= max_temp) max_temp = temperatura;
if (temperatura <= min_temp) min_temp = temperatura;
static time_t tLast;
time_t t;
tmElements_t tm;
// Réglage heure via série (format: année,mois,jour,heure,min,sec)
if (Serial.available() >= 12) {
int y = Serial.parseInt();
if (y >= 100 && y < 1000) Serial << F("Erreur: Année 2 ou 4 chiffres!") << endl;
else {
if (y >= 1000) tm.Year = CalendarYrToTm(y);
else tm.Year = y2kYearToTm(y);
tm.Month = Serial.parseInt();
tm.Day = Serial.parseInt();
tm.Hour = Serial.parseInt();
tm.Minute = Serial.parseInt();
tm.Second = Serial.parseInt();
t = makeTime(tm);
RTC.set(t);
setTime(t);
Serial << F("Heure modifiée: ");
printDateTime(t);
Serial << endl;
while (Serial.available() > 0) Serial.read();
}
}
t = now();
if (t != tLast) {
tLast = t;
printDateTime(t);
Serial << endl;
}
// Détection appui bouton (anti-rebond)
boolean valor_botao = digitalRead(3);
if (valor_botao != 1) {
while(digitalRead(3) != 1) delay(100);
estado_botao = !estado_botao;
}
// Boucle d'affichage
u8g.firstPage();
do {
if (estado_botao == 0) tela_1();
if (estado_botao == 1) tela_2();
} while(u8g.nextPage());
delay(10);
}
void printDateTime(time_t t) {
printI00(day(t), 0);
Serial << monthShortStr(month(t)) << _DEC(year(t));
Serial << ' ';
printI00(hour(t), ':');
printI00(minute(t), ':');
printI00(second(t), ' ');
}
void printI00(int val, char delim) {
if (val < 10) Serial << '0';
Serial << _DEC(val);
if (delim > 0) Serial << delim;
}
Bibliothèques
Téléchargement uniquement (pas d'aperçu).
Schémas

Processus de fabrication
- Signaux analogiques et numériques : fondements de l'instrumentation industrielle
- Capteurs analogiques vs numériques : types, applications et exemples pratiques
- Horloge POV Arduino : Construire un affichage LED à persistance rétinienne
- Construire une horloge maître LED personnalisée avec alarme – Visible à 12 mètres
- Créer des animations et jeux sur LCD avec Arduino UNO
- Moniteur de Température et Horloge Temps Réel Arduino avec Écran TFT 3.2"
- Horloge numérique TM1637 avec réglage heure/alarme – Prototype Arduino Nano
- Construire un voltmètre DIY avec Arduino et écran Nokia 5110
- Construire un Réveil Fiable avec RTC DS1302 et Arduino UNO