Introduction
Vous avez toujours voulu ajouter une horloge temps réel (RTC) à votre projet sans avoir le matériel sous la main ? Avec Velxio, vous pouvez simuler une lecture complète d’une RTC I2C en utilisant un Raspberry Pi Pico et une DS1307 virtuelle — le tout dans votre navigateur. Dans ce tutoriel, nous allons parcourir le circuit, le code et les concepts clés pour que vous puissiez utiliser la communication I2C en toute confiance dans vos propres projets.
Présentation du circuit
Commençons par examiner le circuit. Ouvrez l’exemple dans Velxio et vous verrez les composants suivants :

Le circuit est simple : un Raspberry Pi Pico (nano-rp2040) est connecté à deux LED et à une RTC DS1307 virtuelle (non représentée comme un composant séparé — la RTC est intégrée à la simulation). Les LED servent d’indicateurs visuels pour l’activité I2C.
- LED (bleue) : Connectée à la broche D12 (ligne SDA) via un fil bleu. Son anode (A) est connectée à D12, et sa cathode (C) va à GND.1 via un fil noir.
- LED (jaune) : Connectée à la broche D10 (ligne SCL) via un fil orange. Son anode (A) est connectée à D10, et sa cathode (C) va à GND.1 via un fil noir.
Les deux LED partagent la même masse (GND.1). Le bus I2C est constitué des lignes SDA (données) et SCL (horloge). La RTC DS1307 est connectée en interne à ces lignes à l’adresse 0x68. Les LED ne sont pas strictement nécessaires pour la communication I2C, mais elles donnent un repère visuel indiquant que les lignes basculent.
Pour construire ce circuit vous-même, vous pouvez utiliser le sélecteur de composants Velxio :

Recherchez “Raspberry Pi Pico” et “LED”, puis câblez-les comme décrit. La barre d’outils du canevas vous permet de zoomer et de disposer les composants :

Explication du code
Plongeons maintenant dans le code. Le sketch utilise la bibliothèque Wire (intégrée) pour communiquer avec la DS1307 via I2C. Voici le code complet :
// Raspberry Pi Pico — I2C DS1307 RTC Read
// Reads time from virtual RTC at address 0x68
#include <Wire.h>
byte bcdToDec(byte val) {
return ((val >> 4) * 10) + (val & 0x0F);
}
void setup() {
Serial.begin(115200);
delay(500);
Wire.begin();
Serial.println("=== Pico I2C RTC Read ===");
Serial.println("Reading DS1307 at 0x68 (system time)");
Serial.println();
}
void loop() {
// Set register pointer to 0
Wire.beginTransmission(0x68);
Wire.write(0x00);
Wire.endTransmission();
// Read 7 bytes: sec, min, hr, dow, date, month, year
Wire.requestFrom(0x68, 7);
if (Wire.available() >= 7) {
byte sec = bcdToDec(Wire.read() & 0x7F);
byte min = bcdToDec(Wire.read());
byte hr = bcdToDec(Wire.read() & 0x3F);
byte dow = bcdToDec(Wire.read());
byte date = bcdToDec(Wire.read());
byte month = bcdToDec(Wire.read());
byte year = bcdToDec(Wire.read());
const char* days[] = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
Serial.print("Time: ");
if (hr < 10) Serial.print('0'); Serial.print(hr); Serial.print(':');
if (min < 10) Serial.print('0'); Serial.print(min); Serial.print(':');
if (sec < 10) Serial.print('0'); Serial.print(sec);
Serial.print(" Date: ");
Serial.print(days[dow]); Serial.print(' ');
if (date < 10) Serial.print('0'); Serial.print(date); Serial.print('/');
if (month < 10) Serial.print('0'); Serial.print(month); Serial.print('/');
Serial.print("20"); if (year < 10) Serial.print('0'); Serial.println(year);
} else {
Serial.println("RTC not responding!");
}
delay(1000);
}
Comment ça fonctionne
-
Configuration : Nous démarrons la communication série à 115200 bauds et initialisons le bus I2C avec
Wire.begin(). La DS1307 se trouve à l’adresse 0x68. -
Boucle : Chaque seconde, nous :
- Envoyons un
beginTransmissionà l’adresse 0x68, écrivons 0x00 (le pointeur de registre vers le registre des secondes), puisendTransmission. - Demandons 7 octets à la RTC avec
Wire.requestFrom(0x68, 7). - Lisons chaque octet et convertissons du BCD (décimal codé en binaire) en décimal à l’aide de la fonction auxiliaire
bcdToDec. - Formatons et affichons l’heure et la date dans le moniteur série.
- Envoyons un
-
Conversion BCD : La DS1307 stocke les valeurs de temps au format BCD. Par exemple, l’octet
0x45représente 45 en BCD (4*10 + 5 = 45). La fonctionbcdToDecextrait le chiffre des dizaines (nibble haut) et le chiffre des unités (nibble bas) et les combine. -
Masquage : Nous appliquons des masques à certains registres :
- Secondes :
& 0x7Fefface le bit CH (arrêt de l’horloge). - Heures :
& 0x3Fefface le bit de mode 12/24 heures (en supposant le mode 24 heures).
- Secondes :
Concepts clés
- Protocole I2C : Un bus série à deux fils (SDA, SCL) pour la communication entre microcontrôleurs et périphériques. Chaque périphérique a une adresse unique.
- Bibliothèque Wire : La bibliothèque I2C intégrée d’Arduino. Utilisez
Wire.begin()pour rejoindre le bus,Wire.beginTransmission(addr)pour commencer à parler à un périphérique,Wire.write()pour envoyer des données,Wire.endTransmission()pour terminer, etWire.requestFrom(addr, count)pour lire des octets. - Format BCD : De nombreuses RTC utilisent le BCD pour simplifier l’affichage. Vous devez convertir en décimal pour une sortie lisible par l’humain.
- Correspondance des registres : La DS1307 a une carte de registres spécifique : secondes (0x00), minutes (0x01), heures (0x02), jour de la semaine (0x03), date (0x04), mois (0x05), année (0x06).
Pièges courants et conseils de débogage
- Mauvaise adresse I2C : Vérifiez l’adresse du périphérique. La DS1307 est généralement 0x68 (7 bits). Si vous obtenez “RTC not responding!”, vérifiez l’adresse.
- Résistances de tirage manquantes : Sur du matériel réel, les lignes I2C nécessitent des résistances de tirage. Dans Velxio, elles sont simulées en interne, vous n’avez donc pas besoin de les ajouter.
- Décalage de débit en bauds : Assurez-vous que le débit en bauds du moniteur série correspond à 115200.
- Pointeur de registre non défini : Définissez toujours le pointeur de registre avant de lire. Le code écrit 0x00 pour pointer vers le registre des secondes.
- Erreurs de masquage : Oublier de masquer le bit CH (secondes) ou le bit de mode 12/24 heures (heures) peut donner des valeurs incorrectes.
Extensions suggérées
- Régler l’heure : Ajoutez du code pour écrire l’heure actuelle dans la RTC. Utilisez
Wire.write()pour définir chaque registre. - Fonction d’alarme : Implémentez une alarme qui déclenche une LED à une heure donnée.
- Affichage sur écran LCD : Utilisez un écran LCD I2C pour afficher l’heure au lieu du moniteur série.
- Plusieurs RTC : Essayez de lire deux périphériques I2C différents sur le même bus.
Essayez par vous-même !
Prêt à expérimenter ? Ouvrez l’exemple en direct dans Velxio et lancez la simulation. Vous verrez l’heure s’afficher dans le moniteur série chaque seconde. Modifiez le code pour changer l’intervalle de mise à jour ou ajouter de nouvelles fonctionnalités.
Lancer l’exemple de lecture RTC I2C sur Pico
Bonne simulation !