A Raspberry Pi Pico RTC Module

In this article we look at a Raspberry Pi Pico RTC Module based on the DS1302 chip

The Raspberry Pi Pico out of the box does not have RTC capabilities so with the addition of this

Here is a picture of the purchased module

Lets look at the DS1302 chip

The DS1302 chip contains a real-time clock/calendar and 31 bytes of static RAM. It communicates with a microprocessor via a simple serial interface.

The real-time clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The end of the month date is automatically adjusted for months with fewer than 31 days, including corrections for leap year.

The clock operates in either the 24-hour or 12-hour format with an AM/PM indicator.Interfacing the DS1302 with a microprocessor is simplified by using synchronous serial communication. Only three wires are required to communicate with the clock/RAM: CE, I/O (data line), and SCLK (serial clock).

Data can be transferred to and from the clock/RAM 1 byte at a time or in a burst of up to 31 bytes. The DS1302 is designed to operate on very low power and retain data and clock information on less than 1μW.

Specifications

Operating voltage 3.3V
Backup battery voltage 2.3V ~ 5.5V
Operating temperature -40°C ~ +85°C
Power consumption 100nA (keeping Clock and data)

Product page

There are 2 products on the page, the DS1302 board costs about $6

product page

Code

This is the test example

This can be found in the link below in  the github repo

from machine import Pin
import framebuf
import time
from machine import *
DS1302_REG_SECOND = (0x80)
DS1302_REG_MINUTE = (0x82)
DS1302_REG_HOUR   = (0x84)
DS1302_REG_DAY    = (0x86)
DS1302_REG_MONTH  = (0x88)
DS1302_REG_WEEKDAY= (0x8A)
DS1302_REG_YEAR   = (0x8C)
DS1302_REG_WP     = (0x8E)
DS1302_REG_CTRL   = (0x90)
DS1302_REG_RAM    = (0xC0)
class DS1302:

    def __init__(self, clk, dio, cs):
        self.clk = clk
        self.dio = dio
        self.cs  = cs
        self.clk.init(Pin.OUT)
        self.cs.init(Pin.OUT)
        
    def DecToHex(self, dat):
        return (dat//10) * 16 + (dat%10)

    def HexToDec(self, dat):
        return (dat//16) * 10 + (dat%16)

    def write_byte(self, dat):
        self.dio.init(Pin.OUT)
        for i in range(8):
            self.dio.value((dat >> i) & 1)
            self.clk.value(1)
            self.clk.value(0)

    def read_byte(self):
        d = 0
        self.dio.init(Pin.IN)
        for i in range(8):
            d = d | (self.dio.value()<<i)
            self.clk.value(1)
            self.clk.value(0)
        return d

    def getReg(self, reg):
        self.cs.value(1)
        self.write_byte(reg)
        t = self.read_byte()
        self.cs.value(0)
        return t

    def setReg(self, reg, dat):
        self.cs.value(1)
        self.write_byte(reg)
        self.write_byte(dat)
        self.cs.value(0)

    def wr(self, reg, dat):
        self.setReg(DS1302_REG_WP, 0)
        self.setReg(reg, dat)
        self.setReg(DS1302_REG_WP, 0x80)
                
    def start(self):
        t = self.getReg(DS1302_REG_SECOND + 1)
        self.wr(DS1302_REG_SECOND, t & 0x7f)

    def stop(self):
        t = self.getReg(DS1302_REG_SECOND + 1)
        self.wr(DS1302_REG_SECOND, t | 0x80)
        
    def Second(self, second = None):
        if second == None:
            return self.HexToDec(self.getReg(DS1302_REG_SECOND+1))%60
        else:
            self.wr(DS1302_REG_SECOND, self.DecToHex(second%60))

    def Minute(self, minute = None):
        if minute == None:
            return self.HexToDec(self.getReg(DS1302_REG_MINUTE+1))
        else:
            self.wr(DS1302_REG_MINUTE, self.DecToHex(minute%60))

    def Hour(self, hour = None):
        if hour == None:
            return self.HexToDec(self.getReg(DS1302_REG_HOUR+1))
        else:
            self.wr(DS1302_REG_HOUR, self.DecToHex(hour%24))

    def Weekday(self, weekday = None):
        if weekday == None:
            return self.HexToDec(self.getReg(DS1302_REG_WEEKDAY+1))
        else:
            self.wr(DS1302_REG_WEEKDAY, self.DecToHex(weekday%8))

    def Day(self, day = None):
        if day == None:
            return self.HexToDec(self.getReg(DS1302_REG_DAY+1))
        else:
            self.wr(DS1302_REG_DAY, self.DecToHex(day%32))

    def Month(self, month = None):
        if month == None:
            return self.HexToDec(self.getReg(DS1302_REG_MONTH+1))
        else:
            self.wr(DS1302_REG_MONTH, self.DecToHex(month%13))

    def Year(self, year = None):
        if year == None:
            return self.HexToDec(self.getReg(DS1302_REG_YEAR+1)) + 2000
        else:
            self.wr(DS1302_REG_YEAR, self.DecToHex(year%100))

    def DateTime(self, dat = None):
        if dat == None:
            return [self.Year(), self.Month(), self.Day(), self.Weekday(), self.Hour(), self.Minute(), self.Second()]
        else:
            self.Year(dat[0])
            self.Month(dat[1])
            self.Day(dat[2])
            self.Weekday(dat[3])
            self.Hour(dat[4])
            self.Minute(dat[5])
            self.Second(dat[6])

    def ram(self, reg, dat = None):
        if dat == None:
            return self.getReg(DS1302_REG_RAM + 1 + (reg%31)*2)
        else:
            self.wr(DS1302_REG_RAM + (reg%31)*2, dat)


ds = DS1302(Pin(2),Pin(3),Pin(4))

# CLK GPIO2
# DAT GPIO3
# RST GPIO4
ds.DateTime()
# Return: [2021, 1, 31, 7, 11, 10, 56]

#ds.Year() #Get today's year
#ds.Month() #Get today's month
#ds.Day() #Get today's date
#ds.Weekday() #Get the current day of the week
#ds.Hour() #Get the current hour
#ds.Minute() #Get the current minute
#ds.Second() #Get the current second

# You can add a number to the above function to set the time
# E.g
#ds.Year(2021) #Set this year to 2021
#ds.Day(2)#Set today as the 2nd

   
    
ds.Year(2021)
ds.Month(3)
ds.Day(21)
ds.Weekday(3)
ds.Hour(11)
ds.Minute(23)
ds.Second(45)
 
while 1:
    
    print(ds.Year(),ds.Month(),ds.Day(),ds.Weekday(),ds.Hour(),ds.Minute(),ds.Second()) 
    time.sleep(1)

 

Link

github link

Related posts

An RP2040 board in a Microbit form factor

A board that turns a RP2040 into a Raspberry Pi Zero

StackyPi – Raspberry Pi RP2040 based Board in a Pi Zero format

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Read More