Introduction

In this course we’ll look at how to use an RTC or clock module with the Beaglebone Black.

An RTC module keeps the time when your Beaglebone Black is switched off. It is an essential electronic component in many applications where precise time management is crucial. This small, self-contained device features an internal clock powered by a button cell, enabling it to continue operating even in the absence of a main power supply.

 

The RTC module chosen for this course is the DS1307. It uses I2C to communicate with the Beaglebone Black.

Here’s the circuit to connect the RTC module to the Beaglebone Black:

How do I check that the real time clock module is properly connected?

To verify that our RTC module, we will check if it is recognized by I2C. To do this, type the command i2cdetect -y -r 2.

In the picture to see 68 appear, which is the address of our RTC module.

RTC module time reading

Once the RTC module is properly connected, we will see the program in order to retrieve and modify the time coming from the RTC module. The first step is to install the smbus library which manages I2C communication:

sudo apt-get install python3-smbus

Here is the program to read the time and date coming from the RTC module:

import smbus
import datetime
import time

# I2C address of the RTC module on the BeagleBone Black
rtc_address = 0x68

# I2C bus selection (0 on the BeagleBone Black)
i2c_bus = smbus.SMBus(2)

def read_rtc():
    # Reading current time from RTC module
    rtc_data = i2c_bus.read_i2c_block_data(rtc_address, 0, 7)

    # Converting read data to datetime object
    year = rtc_data[6] + 2000
    month, day, hour, minute, second = rtc_data[5], rtc_data[4], rtc_data[2]& 0x3F, rtc_data[1] & 0x3F, rtc_data[0]& 0x3F

    current_time = datetime.datetime(year, month, day, hour, minute, second)
    return current_time

try:
    while True:
        # Reading and displaying the current time
        current_time = read_rtc()
        print(f"Current time: {current_time}")

        # Wait 1 second before next reading
        time.sleep(1)

except KeyboardInterrupt:
    # Closing the program when interrupted
    pass

finally:
    # Closing the I2C bus at the end of the program
    i2c_bus.close()

RTC module time reading

You probably realized in the previous program that the time was not accurate. This is why we are going to see a program to modify it.

import smbus
import time

# I2C address of the RTC module
rtc_address = 0x68

# I2C bus number on the BeagleBone Black
i2c_bus = 2

# Creation of the SMBus object
bus = smbus.SMBus(i2c_bus)

def set_rtc_time():
    try:
        # Reading the current time from the RTC
        current_time = bus.read_i2c_block_data(rtc_address, 0x00, 7)
        # Current time display
        print(f"Current time: {current_time[2]}:{current_time[1]}:{current_time[0]}")

        # Obtaining the new time from the user
        new_hour = int(input("New time (24 hour format): "))
        new_minute = int(input("New minute: "))
        new_second = int(input("New second:"))

        # Converting the new time to BCD (Binary-Coded Decimal) format
        new_hour_bcd = ((new_hour // 10) << 4) | (new_hour % 10)
        new_minute_bcd = ((new_minute // 10) << 4) | (new_minute % 10)
        new_second_bcd = ((new_second // 10) << 4) | (new_second % 10)

        # Writing the new time in the RTC
        bus.write_i2c_block_data(rtc_address, 0x00, [new_second_bcd, new_minute_bcd, new_hour_bcd] + current_time[3:])
        print("Time updated successfully!")

    except Exception as e:
        print(f"An error has occurred: {e}")

if __name__ == "__main__":
    set_rtc_time()