Garder l'heure dans tous vos projets !

Introduction

L’un des aspects essentiels de nombreux projets sur Raspberry Pi est la gestion du temps. Que vous souhaitiez créer un réveil, un enregistreur de données ou tout autre dispositif nécessitant une synchronisation temporelle précise, l’utilisation d’un module RTC (Real Time Clock) est la solution idéale.

Le module RTC possède une pile bouton qui va permettre de continuer à calculer l’heure même lorsque la Raspberry Pi est hors tension et donc de garder la bonne l’heure lors du redémarrage de celle-ci.

Dans ce cours, nous explorerons le module RTC DS1307 pour Raspberry Pi. Ce module utilise l’I2C de la Raspberry pour transmettre ces valeurs. Voici le schéma du branchement du DS1307 sur la Raspberry Pi :

Programmation

L’un des aspects essentiels de nombreux projets sur Raspberry Pi est la gestion du temps. Que vous souhaitiez créer un réveil, un enregistreur de données ou tout autre dispositif nécessitant une synchronisation temporelle précise, l’utilisation d’un module RTC (Real Time Clock) est la solution idéale.

 Voici ce que l’on obtient en tapant cette commande. Notre module RTC à comme adresse i2c 0x068. On le voit apparaitre avec l’I2Cdetect, ce qui veut dire qu’il ait bien connecter à notre Raspberry Pi :

Si vous avez une erreur en tapant i2cdetect alors c’est que celui-ci n’est pas activé dans la configuration de la Raspberry pi. Dans notre cours sur l’i2c sur la Raspberry nous expliquons comment l’activer.

Une fois l’I2C activé et que votre module RTC est bien détecté par la carte, on va voir le programme pour lire l’heure. La première étape est d’installer la librairie nécessaire à la gestion de l’I2C :

sudo apt install -y python-smbus

On va ensuite créer un fichier en python afin d’y écrire notre progamme :

sudo nano module_rtc.py
Voici le programme pour lire l’heure venant du module :
import smbus
import time

# Adresse I2C du DS1307
rtc_address = 0x68

# Initialise le bus I2C
bus = smbus.SMBus(1)  # Utilisez 0 pour la version 1 de la Raspberry Pi

def bcd_to_decimal(bcd):
    return ((bcd // 16) * 10 + (bcd % 16))

def read_ds1307():
    # Lecture des données de l'horloge RTC
    second = bcd_to_decimal(bus.read_byte_data(rtc_address, 0x00) & 0x7F)  # Masquer le bit "halt" des secondes
    minute = bcd_to_decimal(bus.read_byte_data(rtc_address, 0x01))
    hour = bcd_to_decimal(bus.read_byte_data(rtc_address, 0x02) & 0x3F)  # Masquer les bits de mode 12/24 heures

    return hour, minute, second

def print_time(hour, minute, second):
    print(f"Heure actuelle : {hour:02d}:{minute:02d}:{second:02d}")

try:
    hour, minute, second = read_ds1307()
    print_time(hour, minute, second)

except IOError:
    print("Erreur de communication avec le module RTC. Assurez-vous qu'il est correctement connecté.")

Pour lancer le programme, voici la ligne de commande :
sudo python module_rtc.py

 

Une fois le programme lancé voici l’heure sur le terminal :

Comme vous pouvez le voir, l’heure n’est pas forcément correcte. On va donc devoir la configurer correctement. Voici le programme suivant qui permet de modifier l’heure :   
import smbus
import time

# Adresse I2C du DS1307
DS1307_ADDR = 0x68

# Numéro de bus I2C sur Raspberry Pi
I2C_BUS = 1

def bcd_to_decimal(bcd):
    return (bcd // 16) * 10 + (bcd % 16)

def decimal_to_bcd(decimal):
    return ((decimal // 10) << 4) + (decimal % 10)

def read_ds1307():
    bus = smbus.SMBus(I2C_BUS)
    data = bus.read_i2c_block_data(DS1307_ADDR, 0, 7)
    bus.close()
    
    second = bcd_to_decimal(data[0] & 0x7F)
    minute = bcd_to_decimal(data[1])
    hour = bcd_to_decimal(data[2] & 0x3F)
    day = bcd_to_decimal(data[4])
    month = bcd_to_decimal(data[5])
    year = bcd_to_decimal(data[6]) + 2000
    
    return (year, month, day, hour, minute, second)

def set_ds1307(year, month, day, hour, minute, second):
    bus = smbus.SMBus(I2C_BUS)
    
    data = [0, decimal_to_bcd(second), decimal_to_bcd(minute),
            decimal_to_bcd(hour), 0, decimal_to_bcd(day),
            decimal_to_bcd(month), decimal_to_bcd(year - 2000)]
    
    bus.write_i2c_block_data(DS1307_ADDR, 0, data)
    bus.close()

if __name__ == "__main__":
    # Lire l'heure actuelle du DS1307
    current_time = read_ds1307()
    print("Heure actuelle du DS1307:", current_time)

    # Définir une nouvelle heure (remplacez ces valeurs par celles souhaitées)
    new_time = (2024, 3, 5, 12, 30, 0)
    print("Réglage de la nouvelle heure du DS1307:", new_time)
    
    # Appliquer la nouvelle heure au DS1307
    set_ds1307(*new_time)
    
    # Lire et afficher la nouvelle heure du DS1307
    updated_time = read_ds1307()
    print("Nouvelle heure du DS1307:", updated_time)

Vous devez remplacer par votre heure dans “new time” afin que cela soit correcte. Relancez ensuite le premier programme afin de voir la bonne heure affichée.