【得捷电子Follow me第2期】任务4:日历和时钟
[复制链接]
本帖最后由 ltand 于 2023-11-14 21:24 编辑
【得捷电子Follow me第2期】任务4:日历和时钟
基于ESP32-S3用于屏幕上显示现在的日期、时间和天气信息状况
效果图
下边是实现步骤说明
1.导入库和模块:
导入了一些内置库,显示库(`adafruit_imageload`,`adafruit_display_text`,`adafruit_bitmap_font`),以及网络相关库(ssl,socketpool,adafruit_ntp,adafruit_requests)
2.初始化图像组:
创建了一个显示图像组(`displayio.Group()`)。
加载背景图
初始化字体对象,设置字体大小和颜色。
创建日期、星期、温度、天气、时分的标签对象,并设置x轴y轴位置,然后将它们添加到图像组中。
3.连接到WiFi:
从环境变量中获取WiFi的SSID和密码。
使用`wifi.radio.connect()`连接到WiFi。
4.初始化NTP和RTC:
使用`socketpool`和`adafruit_ntp`初始化NTP(Network Time Protocol)对象,从阿里云NTP服务器获取时间。
设置设备的RTC时间为阿里云NTP服务器提供的时间
也可以选择其他可靠的NTP服务器:
ntp.aliyun.com (阿里云)
ntp1.aliyun.com (阿里云)
ntp2.aliyun.com (阿里云)
time.cloud.tencent.com (腾讯云)
time1.cloud.tencent.com (腾讯云)
time2.cloud.tencent.com (腾讯云)
ntp.sjtu.edu.cn (上海交通大学)
ntp.tuna.tsinghua.edu.cn (清华大学)
5.获取天气信息API:
从环境变量中得到设置好的高德地图密钥和自己所在城市代码
使用`socketpool`和`adafruit_requests`初始化HTTP请求
请求高德地图天气信息的API,处理JSON响应数据获取温度、天气和城市信息,不过请求参数问题可以用postman去测试一下接口
6.最后:
更新时间标签和天气信息,并且在每秒钟的循环中,使用本地RTC时间更新日期、星期、温度和天气信息标签
下边是实现代码
# 导入内置库
import board
import displayio
import os
import rtc
import wifi
import time
# 导入显示库
import adafruit_imageload
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
# 导入网络相关库
import ssl
import socketpool
import adafruit_ntp
import adafruit_requests
def run():
# 图像组实例对象
display = board.DISPLAY
group = displayio.Group()
# 加载背景图
image, palette = adafruit_imageload.load("/image/bg.png")
palette.make_transparent(0)
grid = displayio.TileGrid(image, pixel_shader=palette)
group.append(grid)
display.show(group)
# 设置字体大小和颜色
font = bitmap_font.load_font("/font/simhei_16.pcf")
nun_font = bitmap_font.load_font("/font/hei_60.pcf")
color = 0xFFFFFF
# 日期标签
date = label.Label(font, text="", color=color)
date.x = 0
date.y = 30
group.append(date)
# 星期标签
week = label.Label(font, text="", color=color)
week.x = 100
week.y = 30
group.append(week)
# 温度标签
temp = label.Label(font, text="", color=color)
temp.x = 150
temp.y = 30
group.append(temp)
# 天气标签
weatherLabel = label.Label(font, text="", color=color)
weatherLabel.x = 190
weatherLabel.y = 30
group.append(weatherLabel)
# 时分标签
timeLabel = label.Label(nun_font, text="", color=color)
timeLabel.x = 20
timeLabel.y = 80
group.append(timeLabel)
# 显示修改后的图像组
display.show(group)
# 连接到wifi
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
wifi.radio.connect(ssid, password)
print("wifi success", ssid)
# adafruit_ntp库初始化网络, 时区, ntp地址
pool = socketpool.SocketPool(wifi.radio)
ntp = adafruit_ntp.NTP(pool, tz_offset=8, server="ntp.aliyun.com")
# 设置连接阿里云的ntp服务器时间
rtc.RTC().datetime = ntp.datetime
# 初始化requests对象,用来请求http的接口
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
# 格式化星期
def get_weekday(index):
arr = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
return arr[index]
# 获取参数配置
CITY_CODE = os.getenv("CIRCUITPY_CITY_CODE")
GAODE_KEY = os.getenv("CIRCUITPY_GAODE_KEY")
def get_weather_info():
# 拼接接口参数
weather_url_api = f"https://restapi.amap.com/v3/weather/weatherInfo?city={CITY_CODE}&key={GAODE_KEY}"
# 请求数据
response = requests.get(weather_url_api)
json_resp = response.json()
response.close() # 关闭连接
# 解析json数据
for key in json_resp["lives"]:
return key["temperature"], key["weather"], key["city"]
# 创建开始状态
status = "start"
while True:
# 每秒获取一次本地RTC时间
t = time.localtime()
# 首次启动或者本地RTC时间的分钟属性为0时,更新日期标签和天气标签
if (status == "start" or t.tm_min == 0):
# 更新日期
date.text = "%d月%d日" % (t.tm_mon, t.tm_mday)
week.text = get_weekday(t.tm_wday)
# 更新天气信息接口
temp_text, weather_text, city = get_weather_info()
temp.text = "%s°" % (temp_text)
weatherLabel.text = weather_text
print("date: ", date.text, week.text)
print("city temp weather: ", city, "%s°" % (temp_text), weather_text)
status = "end"
# 每隔1秒 更新一次时钟标签
if (t.tm_sec % 2 == 0):
timeLabel.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
else:
timeLabel.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
display.show(group)
time.sleep(1)
|