Code Repository
1. Gitee: https://gitee.com/yangkun_monster/clock.git
2. Github: https://github.com/pifan-open-source-community/clock.git
Video Tutorial Address: Bilibili: Raspberry Pi Enthusiasts Base, Play Pi VLOG
Video VLOG Record: Bilibili: Play Pi VLOG
1. Overview
Create a desktop clock using Raspberry Pi PICO that can display the year, month, day, hour, minute, second, week, temperature, and humidity. The clock can be divided into two types: one uses the built-in RTC function, and the other uses the DS1302 clock module. You can choose according to your situation (the clock module has a backup battery to ensure it continues to run during power outages).
Programming Language: MicroPython.
2. Materials Preparation
1. Raspberry Pi PICO
PICO Interface Diagram
2. DHT11 Temperature and Humidity Sensor
DHT11 is a temperature and humidity sensor with calibrated digital signal output. Its precision is ±5%RH for humidity and ±2℃ for temperature, with a range of 5~95%RH for humidity and -20 to +60℃ for temperature.
3. DS1302 Clock Module (Optional)
The DS1302 clock chip is a low-power real-time clock chip with trickle-charge capability, introduced by DALLAS in the USA. It can time the year, month, day, week, hour, minute, and second, and has various functions such as leap year compensation. The DS1302 chip includes a 31-byte static RAM for storing real-time clock/calendar data and communicates with the microprocessor via a simple serial interface, storing the current time in RAM. The DS1302 chip automatically adjusts for the end of months with less than 31 days and corrects for leap years.
Pin Description
Registers (Optional)
Read addresses are 0x81 (seconds), 0x83 (minutes), 0x85 (hours), 0x87 (days), 0x89 (months), 0x8b (weeks), 0x8d (years)
Write addresses are 0x80 (seconds), 0x82 (minutes), 0x84 (hours), 0x86 (days), 0x88 (months), 0x8a (weeks), 0x8c (years)
4. SSD1306 Screen
The communication method is IIC
5. Other Materials
Breadboard
Male to female DuPont wire
3. Getting Started
1. Wiring
DTH11 | |
VCC | |
GND | |
DATA | GP0 |
SSD1306 | |
VCC | |
GND | |
SCL | GP3 |
SDA |
GP2 |
DS1302 | |
VCC | |
GND | |
CLK | GP12 |
DAT | GP13 |
RST | GP14 |
![Insert image description here](https://img-blog.csdnimg.cn/a80d7b6bde37487c9c86e0948b376a56.png#pic_center)
2. Writing the Program
(1)Clock Implemented Using Built-in RTC Function
This clock can automatically read the time from the computer when the PICO is connected to the computer. When power is lost, the clock will stop and cannot continue to run.
from machine import RTC
from machine import Pin
from machine import I2C
from ssd1306 import SSD1306_I2C
from machine import Timer
import dht
def clock_time(tim):
timee=clockk.datetime()
oled.fill(0)
oled.text("Date:",0,0)
oled.text(str(timee[0])+'-'+str(timee[1])+'-'+str(timee[2])+'-'+week[timee[3]],0,10)
oled.text(str(timee[4])+'-'+str(timee[5])+'-'+str(timee[6]),0,20)
d.measure()
oled.text("Temperature:"+str(d.temperature())+'C',0,40)
oled.text("Humidity:"+str(d.humidity())+'%',0,50)
oled.show()
i2c=I2C(1,sda=Pin(2),scl=Pin(3))
oled=SSD1306_I2C(128,64,i2c,addr=0X3c)
week=['Mon','Tues','Wed','Thur','Fri','Sat','Sun']
clockk=RTC()
#clockk.datetime((2022,10,30,6,17,25,0,0))#Set initial time, year, month, day, week, hour, minute, second
d=dht.DHT11(Pin(0))
tim=Timer(-1)
tim.init(period=300,mode=Timer.PERIODIC,callback=clock_time
(2)Clock Implemented Using DS1302 Clock Module
The clock module has a backup battery to ensure it continues to run during power outages.
Main Program
from machine import Pin
from machine import I2C
from ssd1306 import SSD1306_I2C
from machine import Timer
import dht
from DS1302 import DS1302
def clock_time(tim):
timee=ds.DateTime()
oled.fill(0)
oled.text("Date:",0,0)
oled.text(str(timee[0])+'-'+str(timee[1])+'-'+str(timee[2])+'-'+week[timee[3]],0,10)
oled.text(str(timee[4])+'-'+str(timee[5])+'-'+str(timee[6]),0,20)
d.measure()
oled.text("Temperature:"+str(d.temperature())+'C',0,40)
oled.text("Humidity:"+str(d.humidity())+'%',0,50)
oled.show()
i2c=I2C(1,sda=Pin(2),scl=Pin(3))
oled=SSD1306_I2C(128,64,i2c,addr=0X3c)
week=['Mon','Tues','Wed','Thur','Fri','Sat','Sun']
d=dht.DHT11(Pin(0))
ds = DS1302(Pin(12),Pin(13),Pin(14))
#ds.SetTime(2022,11,12,5,20,03,30)#Set initial time, year, month, day, week, hour, minute, second
tim=Timer(-1)
tim.init(period=300,mode=Timer.PERIODIC,callback=clock_time
DS1302 Library
''' DS1302 RTC drive
Author: shaoziyang Date: 2018.3
http://www.micropython.org.cn'''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)
def SetTime(self,YEAR,MONTH,DAY,WEEK,HOUR,MINUTE,SECOND,):
self.Year(YEAR)
self.Month(MONTH)
self.Day(DAY)
self.Weekday(WEEK)
self.Hour(HOUR)
self.Minute(MINUTE)
self.Second(SECOND)