387浏览
查看: 387|回复: 0
打印 上一主题 下一主题

[讨论] Beetle 树莓派RP2350 - 桌面时钟摆件

[复制链接]
本帖最后由 无垠的广袤 于 2025-5-6 21:21 编辑

Beetle 树莓派RP2350 - 桌面时钟摆件
本文介绍了 DFRobot Beetle RP2350 开发板结合 DS1307 - RTC 时钟模块实现桌面时钟的项目设计。

项目介绍

包括 RTC 时钟模块(关键部件,用以存储时间数据)、DS1307 芯片介绍、工作原理、参数特点等信息,在此基础上实现工程代码编写、硬件测试等流程,最终实现桌面时钟显示摆件的项目设计。

方案设计

  • 调用 MicroPython 的 RTC 库,获取系统时间,并实现OLED显示;
  • 使用 IIC 通信连接 DS1307 模块,并实现时间的获取和校准;
  • 读取校准后的时钟数据,并完成 OLED 显示;
  • 断电测试,主控重新上电,观察 OLED 显示结果,和系统时间对比,确保 DS1307 模块有效记录时间。

DS1307

DS1307 是一款由美信 Maxim Integrated 公司生产的低功耗、带56字节非易失性 RAM 的实时时钟(RTC)芯片,广泛应用于需要精确时间管理的电子设备和嵌入式系统。

Beetle 树莓派RP2350 - 桌面时钟摆件图1

工作原理

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 、贴片


时序图

Beetle 树莓派RP2350 - 桌面时钟摆件图2

IIC 总线数据通信

Beetle 树莓派RP2350 - 桌面时钟摆件图3


注意事项
  • 使用时需要 初始化时间
  • 建议 使用备用电池 以保持断电时的计时
  • 时间数据以 BCD 格式存储,读取后需要转换
  • 新型 DS3231 芯片为更新替代型号,具有更高精度

详见:DS1307数据手册 .

原理图

Beetle 树莓派RP2350 - 桌面时钟摆件图5


引脚定义
DS1307 RTC 模块引脚输出定义
[td]
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


硬件连接

  • GP5 ---- SCL (DS1307)
  • GP4 ---- SDA (DS1307)
  • GP5 ---- SCL(OLED)
  • GP4 ---- SDA(OLED)

Beetle 树莓派RP2350 - 桌面时钟摆件图4

这里复用了硬件 IIC 引脚 GPIO5(IIC_SCL)和 GPIO4(IIC_SDA).

工程项目

介绍了系统时间显示测试、DS1307 模块的测试和校准、时钟显示、桌面摆件的项目设计。

系统时间显示

在使用 DS1307 模块获取和记录时间之前,通过系统时间的 OLED 显示项目对硬件连接进行测试。

代码

  1. '''
  2. Name: System time display on OLED screen
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: System time is displayed on OLED screen.
  7. Hardware connect:
  8. 5 ---- SCL(OLED)
  9. 4 ---- SDA(OLED)
  10. Shell print.
  11. '''
  12. from machine import Pin, I2C
  13. from ssd1306 import SSD1306_I2C
  14. import time
  15. i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
  16. days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
  17. devices = i2c.scan()
  18. # scan iic devices and print address name
  19. if len(devices) == 0:
  20.     print("No i2c device found.")
  21. else:
  22.     print("i2c devices found:", len(devices))
  23.    
  24.     for device in devices:
  25.         print("i2c scan:", hex(device))
  26. rtc_pico = machine.RTC() # datetime (2025, 5, 6, 1, 16, 30, 23, 0)
  27. print("System time: ", rtc_pico.datetime())
  28. oled_width = 128
  29. oled_height = 64
  30. oled = SSD1306_I2C(oled_width, oled_height, i2c, addr=devices[0])
  31. while True:
  32.     # Get current time from system
  33.     current_datetime = rtc_pico.datetime()
  34.     # Format the date and time as strings
  35.     formatted_date = '{:04d}-{:02d}-{:02d}'.format(current_datetime[0], current_datetime[1], current_datetime[2]) # year, month, day
  36.     formatted_time = '{:02d}:{:02d}:{:02d}:{:02d}'.format(current_datetime[4], current_datetime[5], current_datetime[6], current_datetime[7]) # hour, minute, second
  37.     formatted_day_week = days_of_week[current_datetime[3]] # week
  38.     try:
  39.         oled.fill(0)
  40.         oled.text('Date:' + formatted_date, 0, 0)
  41.         oled.text('Week:' + formatted_day_week, 0, 16)
  42.         oled.text('Time:' + formatted_time, 0, 32)
  43.         oled.show()
  44.         
  45.         # Print the formatted date and time to the shell
  46.         print(formatted_date + ' ' + formatted_day_week + ' ' + formatted_time)
  47.     except Exception as err:
  48.         print(f"Unable to initialize oled: {err}")
  49.    
  50.     # Wait for 1 second
  51.     time.sleep(1)
复制代码




效果

Beetle 树莓派RP2350 - 桌面时钟摆件图6



同时终端打印时间(间隔 1 秒)

Beetle 树莓派RP2350 - 桌面时钟摆件图7

DS1307 模块

测试 DS1307 模块,调用模块时间并实现终端打印。

代码

  1. '''
  2. Name: RTC DS1307 demo
  3. Author: ljl
  4. Date: 2025.05
  5. Other: Connect ds1307 module and print ds1307 time.
  6. Ref:https://randomnerdtutorials.com/ ... canner-micropython/
  7. '''
  8. from machine import Pin, I2C
  9. import ds1307
  10. rtc_pico = machine.RTC()
  11. print("System time: ", rtc_pico.datetime())
  12. # scan i2c devices
  13. i2c = machine.I2C(id=0, scl=Pin(5), sda=Pin(4), freq = 400000)
  14. devices = i2c.scan()
  15. # print i2c devices address
  16. if len(devices) == 0:
  17.     print("No i2c device found.")
  18. else:
  19.     print("i2c devices found:", len(devices))
  20.    
  21.     for device in devices:
  22.         print("i2c scan:", hex(device))
  23. # the adress of ds1307 is 0x68
  24. rtc_ds1307 = ds1307.DS1307(i2c)
  25. print("DS1307 time: ", rtc_ds1307.datetime())
复制代码



效果

Beetle 树莓派RP2350 - 桌面时钟摆件图8

初始时间为 2000 年 1 月 1 日, 0 时 0 分 0 秒

校准
DS1307 模块在首次上电、断电情况下时钟会初始化,因此 时钟校准 是该模块实现具体应用的重要环节。
代码

在上述代码后面添加 update_time() 函数并执行


  1. def update_time():
  2.     ''' --- custom time --- '''
  3.     #str_time = input("Please input [year month day week hour minute second]: ")
  4.     #if str_time == '': return
  5.     #str_time = rtc_pico.datetime()
  6.     #givenTime = tuple(map(int, tuple(str_time.split(' '))))
  7.     #print(givenTime)
  8.     #rtc_ds1307.datetime(givenTime)
  9.     ''' --- use system time --- '''
  10.     givenTime = rtc_pico.datetime()
  11.     rtc_ds1307.datetime(givenTime)
  12. update_time()
  13. print("DS1307 time corrected: ", rtc_ds1307.datetime())
复制代码



时钟校正后的结果为

Beetle 树莓派RP2350 - 桌面时钟摆件图9

此时,断电重新上电,读取 DS1307 时钟模块,可获得正确的时间。

时钟显示
在完成前面的 OLED 显示和 DS1307 时钟读取及校准流程的基础上,进一步将从模块读取的时间数据显示在 OLED 屏幕即可。

代码


  1. '''
  2. Name: Time display on OLED screen by DS1307 RTC module
  3. Version: v1.0
  4. Date: 2025.05
  5. Author: ljl
  6. Other: DS1307 RTC module is used to obtain time and display it on OLED screen.
  7. Hardware connect:
  8. 5 ---- SCL (DS1307)
  9. 4 ---- SDA (DS1307)
  10. 5 ---- SCL(OLED)
  11. 4 ---- SDA(OLED)
  12. Shell print.
  13. '''
  14. from machine import Pin, I2C
  15. import ds1307
  16. from ssd1306 import SSD1306_I2C
  17. import utime
  18. i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
  19. days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
  20. devices = i2c.scan()
  21. # scan iic devices and print address name
  22. if len(devices) == 0:
  23.     print("No i2c device found.")
  24. else:
  25.     print("i2c devices found:", len(devices))
  26.    
  27.     for device in devices:
  28.         print("i2c scan:", hex(device))
  29. # define OLED module
  30. oled = SSD1306_I2C(128, 64, i2c,addr=devices[0])
  31. # define RTC DS1307 module
  32. rtc_pico = machine.RTC() # datetime (2025, 5, 6, 1, 16, 30, 23, 0)
  33. print("System time: ", rtc_pico.datetime())
  34. rtc_ds1307 = ds1307.DS1307(i2c)
  35. #print(dir(rtc_ds1307)) # dir --- print objects class values ...
  36. print("DS1307 time: ", rtc_ds1307.datetime())
  37. def update_time():
  38.     ''' --- custom time --- '''
  39.     #str_time = input("Please input [year month day week hour minute second]: ")
  40.     #if str_time == '': return
  41.     #str_time = rtc_pico.datetime()
  42.     #givenTime = tuple(map(int, tuple(str_time.split(' '))))
  43.     #print(givenTime)
  44.     #rtc_ds1307.datetime(givenTime)
  45.     ''' --- use system auto time --- '''
  46.     givenTime = rtc_pico.datetime()
  47.     rtc_ds1307.datetime(givenTime)
  48. #update_time() # run this code when DS1307 module need time correction
  49. while True:
  50.     # Get current time from the RTC module
  51.     current_datetime = rtc_ds1307.datetime()
  52.     # Format the date and time as strings
  53.     formatted_date = '{:04d}-{:02d}-{:02d}'.format(current_datetime[0], current_datetime[1], current_datetime[2]) # year, month, day
  54.     formatted_time = '{:02d}:{:02d}:{:02d}:{:02d}'.format(current_datetime[4], current_datetime[5], current_datetime[6], current_datetime[7]) # hour, minute, second
  55.     formatted_day_week = days_of_week[current_datetime[3]] # week
  56.     try:
  57.         oled.fill(0)
  58.         oled.text('Date:' + formatted_date, 0, 0)
  59.         oled.text('Week:' + formatted_day_week, 0, 16)
  60.         oled.text('Time:' + formatted_time, 0, 32)
  61.         oled.show()
  62.         
  63.         # Print the formatted date and time to the shell
  64.         print(formatted_date + ' ' + formatted_day_week + ' ' + formatted_time)
  65.     except Exception as err:
  66.         print(f"Unable to initialize oled: {err}")
  67.    
  68.     # Wait for 1 second
  69.     utime.sleep(1)
复制代码



效果

Beetle 树莓派RP2350 - 桌面时钟摆件图10


将 Type-C 数据线拔掉,维持系统断电一段时间,重新上电并执行程序,可见此时时钟读数依然准确,并与系统时间保持一致

增加外置电池,通过快接插头连接至 BAT 接口,即可制成桌面时钟摆件。

总结

本文介绍了 DFRobot Beetle RP2350 开发板结合 DS1307 时钟模块实现时间记忆,扩展板配合 3D 外壳实现桌面时钟摆件的项目设计,为 Beetle RP2350 开发板的开发设计和产品应用提供了参考。



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail