【得捷电子Follow me第1期】作品提交 - 温湿度计和网络时钟(开机播放生日快乐歌)
[复制链接]
本帖最后由 walker2048 于 2023-6-30 20:29 编辑
作品提交 - 温湿度计和网络时钟 展示视频
项目介绍
介绍: 本项目旨在利用 CircuitPython 进行开发,制作一个具有温湿度检测功能和网络时钟功能的设备,使用的硬件包括树莓派 Pico-W、SHT31 温湿度传感器和 SSD1306 OLED 显示屏。通过该设备,可以实时监测环境的温度和湿度,并从网络获取准确的时间信息,同时显示在 OLED 屏幕上。以下是我在项目中的经验总结。
-
硬件准备: 首先,要确保准备齐全所需的硬件设备。树莓派 Pico-W 是一款支持 CircuitPython 的微控制器,内置 CircuitPython环境,能够非常方便地运行 Python脚本。SHT31 温湿度传感器是一个高精度的传感器,能够准确测量环境的温度和湿度。SSD1306 OLED 显示屏是一款小尺寸的显示屏,适合在项目中显示温湿度数据和时间信息。
-
CircuitPython 开发环境: 在开始项目之前,需要正确安装 CircuitPython 的开发环境。可以通过 Adafruit CircuitPython 官方网站获得相关的文档和资源。树莓派 Pico-W 的支持可以通过 UF2 文件烧录到 Pico-W 上,这样就可以在 Pico-W 上运行 CircuitPython 环境。
-
连接硬件: 连接 SHT31 温湿度传感器和 SSD1306 OLED 显示屏到树莓派 Pico-W 上,并确保连接正确。
-
时间同步和网络连接: 为了获取网络时间,需要确保开发板可以连接到互联网。根据你使用的开发板和网络模块,设置和配置网络连接。通常,需要提供 Wi-Fi SSID 和密码来连接到你的本地网络。一旦连接成功,开发板可以通过网络获取准确的时间信息。
-
温湿度数据读取: 使用 CircuitPython 的相应库和模块,从温湿度传感器读取实时数据。根据你选择的传感器,可能需要导入相应的库并调用相应的函数来读取数据。获取到温湿度数据后,可以进一步处理和显示。
-
屏幕显示和用户界面: 将温湿度数据显示在屏幕上,可以使用相应的显示库和函数。根据你的屏幕类型和尺寸,选择合适的库和方法来显示文本和图形。你可以创建一个简单的用户界面,以便更好地呈现温湿度数据和时间信息。
-
时间同步和网络时钟显示: 通过网络同步时间,并将网络时间显示在屏幕上。使用 CircuitPython 的日期和时间库,可以从网络获取当前时间,并将其格式化为需要的显示形式。确保在需要时更新时间,并显示准确的本地时间。
-
音乐播放功能:通过PWM控制蜂鸣器扩展板,播放音乐。由于购买的蜂鸣器只能播放一些简单的音调,并不能实现非常复杂的多媒体功能,所以只是播放一些音调。
功能代码展示
导入需要用到的库
import board
import busio
import displayio
import os
import rtc
import socketpool
import terminalio
import time
import pwmio
import wifi
import array as arr
import adafruit_displayio_ssd1306
from adafruit_display_text import label
import adafruit_ntp
import adafruit_sht31d
Wifi联网和NTP校时功能
使用os.getenv()函数获取setting.toml文件里的wifi配置信息,并配置wifi网络
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
print("Connected to", ssid)
通过配置NTP服务器,实例化NTP(使用aliyun的ntp服务器网址),并将网络时间设置成本地时间。然后就可以通过time.localtime()来获取到当前的RTC时间,可以在最终的刷屏代码里调用此函数,并输出到屏幕。
pool = socketpool.SocketPool(wifi.radio)
ntp = adafruit_ntp.NTP(pool, tz_offset=8, server="ntp.aliyun.com")
# NOTE: This changes the system time so make sure you aren't assuming that time
# doesn't jump.
rtc.RTC().datetime = ntp.datetime
初始化屏幕
首先释放板子内置的displayio默认占用的引脚(不释放有可能会引起IO占用错误),然后指定I2C设备的引脚,最后初始化SSD1306屏幕。
displayio.release_displays()
# Create the I2C interface.
i2c = busio.I2C(scl=board.GP9, sda=board.GP8)
display_bus = displayio.I2CDisplay (i2c, device_address = 0x3C) # The address of my Board
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64, rotation=180)
clock = displayio.Group() # no max_size needed
temp_hi = displayio.Group() # no max_size needed
display.show(clock)
接下来编写屏幕绘制内容
分别绘制clock和temp_hi两个画面,用于显示时钟和温湿度传感器,并设定对应显示的内容:如字体,位置,大小
# Draw a label
text = "Music"
cloock_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=20, y=25, scale=2)
clock.append(cloock_area)
# Draw a smaller inner rectangle
inner_bitmap = displayio.Bitmap(126, 62, 1)
inner_palette = displayio.Palette(1)
inner_palette[0] = 0x000000 # Black
inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=1, y=1)
temp_hi.append(inner_sprite)
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
sensor = adafruit_sht31d.SHT31D(i2c)
# Draw a label
text = "temp 25"
temp = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=6, y=20)
temp_hi.append(temp)
text = "hi 75%"
hi = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=6, y=35)
temp_hi.append(hi)
初始化PWM音乐和对应音阶
piezo = pwmio.PWMOut(board.A0, duty_cycle=0, frequency=440, variable_frequency=True)
CD=arr.array('i',[0,131,147,165,175,196,211,248])
C=arr.array('i',[0,262,294,330,350,393,441,495])
CU=arr.array('i',[0,525,589,661,700,786,882,990])
播放生日快乐歌曲
for f in (CD[5],CD[5],CD[6],0,CD[5],0,C[1],0,CD[7],0,0,
CD[5],CD[5],CD[6],0,CD[5],0,C[2],0,C[1],0,0,
CD[5],CD[5],C[5],0,C[3],0,C[1],0,CD[7],CD[6],0,0,
C[4],C[4],C[3],0,C[1],0,C[3],0,CD[2],0,0,0,
CD[5],CD[5],CD[6],0,CD[5],0,C[1],0,CD[7],0,0,
CD[5],CD[5],CD[6],0,CD[5],0,C[2],0,C[1],0,0,
CD[5],CD[5],C[5],0,C[3],0,C[1],0,CD[7],CD[6],0,0,
C[4],C[4],CD[3],0,CD[1],0,CD[3],0,CD[2],0,0,0
):
if f == 0:
piezo.duty_cycle = 0 # Off
time.sleep(0.2) # Pause
else:
piezo.frequency = f
piezo.duty_cycle = 65535 // 2 # On 50%
time.sleep(0.15) # On for 1/4 second
piezo.duty_cycle = 0 # Off
time.sleep(0.05) # Pause between notes
切换屏幕显示内容并更新时钟或者温湿度信息
count = 0
interface = clock
while True:
if (count % 5 == 0):
if ( interface == clock):
interface = temp_hi
else:
interface = clock
if ( interface == clock):
t = time.localtime()
cloock_area.text = "%d:%d-%02d" % ( t.tm_hour, t.tm_min, t.tm_sec)
display.show(clock)
else:
temp.text = "Temp %0.1f" % sensor.temperature
hi.text = "hi %0.1f" % sensor.relative_humidity
display.show(temp_hi)
count += 1
time.sleep(1)
项目效果图片展示
项目总结:通过本次的作品,我学习到了CircuitPython的wifi联网、NTP校时、sht31温湿度数据读取、小型OLED屏幕数据显示、以及PWM蜂鸣器播放等知识,也学会了CircuitPython的基本使用方式,如环境搭建,库的调用,debug和调试运行等知识。也认识到了CircuitPython这个非常库的嵌入式开发框架,能参加这样的活动,我非常开心。
附件是所有库和配置文件,setting.toml里的wifi密码记得自己修改好
|