Beetle 树莓派RP2350 - 桌面时钟摆件
Beetle 树莓派RP2350 - 桌面时钟摆件
🧭 本文介绍了 DFRobot Beetle RP2350 开发板结合 DS1307 - RTC 时钟模块实现桌面时钟的项目设计。
项目介绍
🌊 包括 RTC 时钟模块(关键部件,用以存储时间数据)、DS1307 芯片介绍、工作原理、参数特点等信息,在此基础上实现工程代码编写、硬件测试等流程,最终实现桌面时钟显示摆件的项目设计。
方案设计
- 调用 MicroPython 的 RTC 库,获取系统时间,并实现OLED显示;
- 使用 IIC 通信连接 DS1307 模块,并实现时间的获取和校准;
- 读取校准后的时钟数据,并完成 OLED 显示;
- 断电测试,主控重新上电,观察 OLED 显示结果,和系统时间对比,确保 DS1307 模块有效记录时间。
DS1307
🔥 DS1307 是一款由美信 Maxim Integrated 公司生产的低功耗、带56字节非易失性 RAM 的实时时钟(RTC)芯片,广泛应用于需要精确时间管理的电子设备和嵌入式系统。
工作原理
🕓 DS1307 通过 32.768 kHz
晶振产生时钟脉冲,追踪时间信息。通过 IIC 总线与主控设备通信,支持读写操作,用户可以通过配置寄存器来设置和调整时间。
参数特点
- 时钟/日历功能:提供秒、分、时、日、月、年、星期信息,自动闰年补偿,有效期至2100年
- 时间格式:支持 12 小时制和 24 小时制,在 12 小时制下具有 AM/PM 指示
- IIC接口:通过两线制 IIC 总线与 MCU 通信
- 56字节、电池备份、通用 RAM,写次数不受限制
- 可编程方波输出
- 低功耗:工作电流小于 500nA (电池备份模式),适合电池供电的便携设备
- 电源感应电路:具有内置的电源感应电路,能够检测主电源的断电情况,并自动切换到备用电池供电
- 宽工作电压:4.5V 至 5.5V
- 工作温度:-40°C 至 +85°C
- 封装: 8 引脚 DIP 、贴片
时序图 📉
IIC 总线数据通信
注意事项 📣
- 使用时需要 初始化时间
- 建议 使用备用电池 以保持断电时的计时
- 时间数据以 BCD 格式存储,读取后需要转换
- 新型 DS3231 芯片为更新替代型号,具有更高精度
⏲️ 详见:DS1307数据手册 .
原理图
🌲 详见:Tiny RTC Charging Circuit Schematic . RTC-DS1307-AT24C32-Real-Time-Clock-Module .
引脚定义
🌎 DS1307 RTC 模块引脚输出定义
Pin | Name | Describe |
---|---|---|
SQ | Square Wave | Optional square wave or logic level output |
DS | DS18B20 | Output for temperature readings if DS18B20 is connected (we won’t use) |
SCL | I2C Clock | I2C clock for DS1307 and EEPROM |
SDA | I2C Data | I2C data for DS1307 and EEPROM |
VCC | Input Supply | 3.3V or 5V power for module and to charge coin cell battery |
GND | Ground | Ground |
BAT | Battery Voltage | For monitoring battery voltage |
⚗️详见:DS1307 RTC Module - MicroPython , MicroPython driver for TinyRTC I2C modules .
硬件连接
GP5 ---- SCL (DS1307)
GP4 ---- SDA (DS1307)
GP5 ---- SCL(OLED)
GP4 ---- SDA(OLED)
💡 这里复用了硬件 IIC 引脚 GPIO5(IIC_SCL)和 GPIO4(IIC_SDA).
工程项目
☘ 介绍了系统时间显示测试、DS1307 模块的测试和校准、时钟显示、桌面摆件的项目设计。
系统时间显示
🌈 在使用 DS1307 模块获取和记录时间之前,通过系统时间的 OLED 显示项目对硬件连接进行测试。
代码
'''
Name: System time display on OLED screen
Version: v1.0
Date: 2025.05
Author: ljl
Other: System time is displayed on OLED screen.
Hardware connect:
5 ---- SCL(OLED)
4 ---- SDA(OLED)
Shell print.
'''from machine import Pin, I2C
from ssd1306 import SSD1306_I2C
import timei2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']devices = i2c.scan()
# scan iic devices and print address name
if len(devices) == 0:print("No i2c device found.")
else:print("i2c devices found:", len(devices))for device in devices:print("i2c scan:", hex(device))rtc_pico = machine.RTC() # datetime (2025, 5, 6, 1, 16, 30, 23, 0)
print("System time: ", rtc_pico.datetime())
oled_width = 128
oled_height = 64
oled = SSD1306_I2C(oled_width, oled_height, i2c, addr=devices[0])while True:# Get current time from systemcurrent_datetime = rtc_pico.datetime()# Format the date and time as stringsformatted_date = '{:04d}-{:02d}-{:02d}'.format(current_datetime[0], current_datetime[1], current_datetime[2]) # year, month, dayformatted_time = '{:02d}:{:02d}:{:02d}:{:02d}'.format(current_datetime[4], current_datetime[5], current_datetime[6], current_datetime[7]) # hour, minute, secondformatted_day_week = days_of_week[current_datetime[3]] # weektry:oled.fill(0)oled.text('Date:' + formatted_date, 0, 0)oled.text('Week:' + formatted_day_week, 0, 16)oled.text('Time:' + formatted_time, 0, 32)oled.show()# Print the formatted date and time to the shellprint(formatted_date + ' ' + formatted_day_week + ' ' + formatted_time)except Exception as err:print(f"Unable to initialize oled: {err}")# Wait for 1 secondtime.sleep(1)
🥁 参考:RTC - MicroPython . Random Nerd Tutorials .
效果
🎛️ 同时终端打印时间(间隔 1 秒)
DS1307 模块
⌚️ 测试 DS1307 模块,调用模块时间并实现终端打印。
代码
'''
Name: RTC DS1307 demo
Author: ljl
Date: 2025.05
Other: Connect ds1307 module and print ds1307 time.
Ref:https://randomnerdtutorials.com/raspberry-pi-pico-i2c-scanner-micropython/
'''from machine import Pin, I2C
import ds1307rtc_pico = machine.RTC()
print("System time: ", rtc_pico.datetime())# scan i2c devices
i2c = machine.I2C(id=0, scl=Pin(5), sda=Pin(4), freq = 400000)
devices = i2c.scan()# print i2c devices address
if len(devices) == 0:print("No i2c device found.")
else:print("i2c devices found:", len(devices))for device in devices:print("i2c scan:", hex(device))# the adress of ds1307 is 0x68
rtc_ds1307 = ds1307.DS1307(i2c)
print("DS1307 time: ", rtc_ds1307.datetime())
效果
🔔 初始时间为 2000 年 1 月 1 日, 0 时 0 分 0 秒
校准
🧩 DS1307 模块在首次上电、断电情况下时钟会初始化,因此 时钟校准 是该模块实现具体应用的重要环节。
代码
🎨 在上述代码后面添加 update_time()
函数并执行
def update_time():''' --- custom time --- '''#str_time = input("Please input [year month day week hour minute second]: ")#if str_time == '': return#str_time = rtc_pico.datetime()#givenTime = tuple(map(int, tuple(str_time.split(' '))))#print(givenTime)#rtc_ds1307.datetime(givenTime)''' --- use system time --- '''givenTime = rtc_pico.datetime()rtc_ds1307.datetime(givenTime)update_time()
print("DS1307 time corrected: ", rtc_ds1307.datetime())
🧵 时钟校正后的结果为
🎯 此时,断电重新上电,读取 DS1307 时钟模块,可获得正确的时间。
时钟显示
⏰ 在完成前面的 OLED 显示和 DS1307 时钟读取及校准流程的基础上,进一步将从模块读取的时间数据显示在 OLED 屏幕即可。
代码
'''
Name: Time display on OLED screen by DS1307 RTC module
Version: v1.0
Date: 2025.05
Author: ljl
Other: DS1307 RTC module is used to obtain time and display it on OLED screen.
Hardware connect:
5 ---- SCL (DS1307)
4 ---- SDA (DS1307)
5 ---- SCL(OLED)
4 ---- SDA(OLED)
Shell print.
'''from machine import Pin, I2C
import ds1307
from ssd1306 import SSD1306_I2C
import utimei2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']devices = i2c.scan()
# scan iic devices and print address name
if len(devices) == 0:print("No i2c device found.")
else:print("i2c devices found:", len(devices))for device in devices:print("i2c scan:", hex(device))# define OLED module
oled = SSD1306_I2C(128, 64, i2c,addr=devices[0])# define RTC DS1307 module
rtc_pico = machine.RTC() # datetime (2025, 5, 6, 1, 16, 30, 23, 0)
print("System time: ", rtc_pico.datetime())rtc_ds1307 = ds1307.DS1307(i2c)
#print(dir(rtc_ds1307)) # dir --- print objects class values ...
print("DS1307 time: ", rtc_ds1307.datetime())def update_time():''' --- custom time --- '''#str_time = input("Please input [year month day week hour minute second]: ")#if str_time == '': return#str_time = rtc_pico.datetime()#givenTime = tuple(map(int, tuple(str_time.split(' '))))#print(givenTime)#rtc_ds1307.datetime(givenTime)''' --- use system auto time --- '''givenTime = rtc_pico.datetime()rtc_ds1307.datetime(givenTime)#update_time() # run this code when DS1307 module need time correctionwhile True:# Get current time from the RTC modulecurrent_datetime = rtc_ds1307.datetime()# Format the date and time as stringsformatted_date = '{:04d}-{:02d}-{:02d}'.format(current_datetime[0], current_datetime[1], current_datetime[2]) # year, month, dayformatted_time = '{:02d}:{:02d}:{:02d}:{:02d}'.format(current_datetime[4], current_datetime[5], current_datetime[6], current_datetime[7]) # hour, minute, secondformatted_day_week = days_of_week[current_datetime[3]] # weektry:oled.fill(0)oled.text('Date:' + formatted_date, 0, 0)oled.text('Week:' + formatted_day_week, 0, 16)oled.text('Time:' + formatted_time, 0, 32)oled.show()# Print the formatted date and time to the shellprint(formatted_date + ' ' + formatted_day_week + ' ' + formatted_time)except Exception as err:print(f"Unable to initialize oled: {err}")# Wait for 1 secondutime.sleep(1)
效果
🎉 将 Type-C 数据线拔掉,维持系统断电一段时间,重新上电并执行程序,可见此时时钟读数依然准确,并与系统时间保持一致
🌻 增加外置电池,通过快接插头连接至 BAT 接口,即可制成桌面时钟摆件。
总结
🎁 本文介绍了 DFRobot Beetle RP2350 开发板结合 DS1307 时钟模块实现时间记忆,扩展板配合 3D 外壳实现桌面时钟摆件的项目设计,为 Beetle RP2350 开发板的开发设计和产品应用提供了参考。