[经验分享] 【得捷电子Follow me第2期】任务4:日历&时钟

walker2048   2023-9-20 11:54 楼主

上上一期视频,我们实现了基本的天气时钟界面,界面的代码还是可以复用的。

由于导入了time库,原有的time标签需要更名成timeL。

import board
# 导入displayio库(内置的)
import displayio

# 导入外部库adafruit_imageload,如果没有就在教程附件下载
import adafruit_imageload
# 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_display_text import label
# 导入外部库adafruit_bitmap_font里的lable
from adafruit_bitmap_font import bitmap_font,用于显示字体

# 使用固件自带的屏幕设备,不需要另行初始化屏幕参数
display = board.DISPLAY

# 创建本例程里的唯一图像组
group = displayio.Group()

# 加载图片
image, palette = adafruit_imageload.load("/pic/tqbg.png")
# 是否开启透明
palette.make_transparent(0)

# 创建图片布局
grid = displayio.TileGrid(image, pixel_shader=palette)

# 将图片布局添加到图像组,由于是第一个添加的,默认是最下层
group.append(grid)

# 显示当前图像组
display.show(group)

# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/sytq_16.pcf")
nun_font = bitmap_font.load_font("/font/DingTalk_ncn_60.pcf")
color = 0x000000

# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text="10月3日", color=color)
date.x = 50
date.y = 30
group.append(date)

# 初始化星期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
week = label.Label(font, text="周二", color=color)
week.x = 150
week.y = 30
group.append(week)

# 初始化时间标签并设置x,y轴绘图坐标,然后将标签添加到图像组
time = label.Label(nun_font, text="18:20", color=color)
time.x = 20
time.y = 80
group.append(time)

# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/sytq_16.pcf")
nun_font = bitmap_font.load_font("/font/DingTalk_ncn_60.pcf")
color = 0x000000

# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text="10月3日", color=color)
date.x = 50
date.y = 30
group.append(date)

# 初始化星期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
week = label.Label(font, text="周二", color=color)
week.x = 150
week.y = 30
group.append(week)

# 初始化时间标签并设置x,y轴绘图坐标,然后将标签添加到图像组
time = label.Label(nun_font, text="18:20", color=color)
time.x = 20
time.y = 80
group.append(time)

# 初始化温度标签并设置x,y轴绘图坐标,然后将标签添加到图像组
temp = label.Label(font, text="30°", color=color)
temp.x = 70
temp.y = 140
group.append(temp)

# 初始化天气标签并设置x,y轴绘图坐标,然后将标签添加到图像组
tempzh = label.Label(font, text="晴", color=color)
tempzh.x = 110
tempzh.y = 140
group.append(tempzh)

# 显示修改后的图像组
display.show(group)

while True:
    pass

在实现了界面的基础上,只需要添加ntp网络校时、天气信息获取和更新的功能,就可以把这个天气时钟做好了。

 

第一步、导入需要用到的库

# 导入os库,用来获取wifi信息
import os
# 导入rtc库,实现RTC时钟
import rtc
# 导入wifi、time库备用
import wifi
import time

# 导入网络库备用
import ssl
import socketpool
import adafruit_ntp
import adafruit_requests

 

第二步、连接wifi

使用os.getenv函数,从setting.toml文件里获取wifi ssid和密码,然后连接到wifi即可

# 使用os.getenv函数,从setting.toml文件里获取wifi ssid和密码
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")

# 连接到 wifi
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
print("Connected to", ssid)

 

第三步、初始化ntp服务

使用adafruit_ntp.NTP函数初始化ntp服务,第一个函数是确定网络连接端口,

第二个函数设置时区,中国是+8时区,第三个函数用来指定ntp服务器地址。

然后使用ntp时间更新系统时间。

# 使用adafruit_ntp.NTP函数初始化ntp服务,第一个函数是确定网络连接端口,
# 第二个函数设置时区,中国是+8时区,第三个函数用来指定ntp服务器地址
pool = socketpool.SocketPool(wifi.radio)
ntp = adafruit_ntp.NTP(pool, tz_offset=8, server="ntp.aliyun.com")

# 使用ntp时间更新系统时间
rtc.RTC().datetime = ntp.datetime

第四步、编写星期数据转换函数

这个函数没啥复杂的,根据时间结构体获取到的tm_wday属性,判断是星期几

def get_wday(wday):
    if (wday == 0):
        return "周一"
    elif (wday == 1):
        return "周二"
    elif (wday == 2):
        return "周三"
    elif (wday == 3):
        return "周四"
    elif (wday == 4):
        return "周五"
    elif (wday == 5):
        return "周六"
    elif (wday == 6):
        return "周日"

第五步、编写天气获取函数

这个函数使用的是高德API,使用该API需要先去注册相关账户,申请key。

获取到相关json数据后,就从json数据里解析温度和天气信息,并返回

# 初始化requests对象
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

def get_weather():
    # 设置城市id
    city = "450900"
    # 这个函数使用的是高德API,使用该API需要先去注册相关账户,申请key。
    key = "1xxx"
    # 拼接天气链接url
    getweather_url = "https://restapi.amap.com/v3/weather/weatherInfo?city=" + city + "&key=" + key
    # 获取天气json数据
    response = requests.get(getweather_url)
    json_resp = response.json()
    # 关闭连接
    response.close()
    # 解析json数据,并返回温度和天气信息
    for da in json_resp["lives"]:
        #print(da["temperature"])
        return da["temperature"], da["weather"]

最后、编写主循环代码

先创建一个status变量,用来在设备启动时获取天气信息。

然后在主循环里不断更新timeL的时间属性,每秒更换一下颜色,用来指示程序还在运行。

也提供一些动态效果,免得大家觉得过于单调。

然后每小时更新一下天气信息。详细的大家可以看注释,代码没啥难度的。等过段时间学习了gifio库,再考虑增加一些动画效果,例如任务眨眼睛什么的。

# 先创建一个status变量,用来在设备启动时获取天气信息
status = "boot"

# 主循环
while True:
    # 每秒获取一次本地RTC时间
    t = time.localtime()
    # 首次启动或者本地RTC时间的分钟属性为0时,更新日期标签和天气标签
    if (status == "boot" or t.tm_min == 0):
        # 更新日期标签
        date.text = "%d月%d日" % (t.tm_mon, t.tm_mday)
        week.text = get_wday(t.tm_wday)
        # 获取天气信息
        str_t, str_tz =  get_weather()
        # 更新温度标签
        temp.text = "%s°" % (str_t)
        # 更新天气标签
        tempzh.text = str_tz
        status = "updated"
    # 每隔1秒 更新一次时钟标签,用于动态显示
    if (t.tm_sec % 2 == 0):
        timeL.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
        timeL.color = 0x000000
    else:
        timeL.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
        timeL.color = 0xD9D7C9
    # 刷新屏幕
    display.show(group)
    # 休眠1秒
    time.sleep(1)

 

本帖最后由 walker2048 于 2023-10-5 21:38 编辑

回复评论 (7)

补充附件资料

点赞  2023-10-5 21:48

用os.getenv函数,从setting.toml文件里获取wifi ssid和密码,然后连接到wifi即可,,

这个密码还能修改么

点赞  2023-10-6 08:23
火辣西米秀 发表于 2023-10-6 08:23 用os.getenv函数,从setting.toml文件里获取wifi ssid和密码,然后连接到wifi即可,, 这个密码还能修改 ...

只需要修改setting.toml文件就行了,代码里不需要改。个人觉得这种方式更舒服,也不需要在代码里输入自家的wifi ssid和密码。分享代码也简单一些。

本帖最后由 walker2048 于 2023-10-6 11:30 编辑
点赞  2023-10-6 11:29

想问一下,为啥我文字每次刷新,上次显示的文字不会消失呀

点赞  2023-10-25 22:29
引用: eew_ZT4tFQ 发表于 2023-10-25 22:29 想问一下,为啥我文字每次刷新,上次显示的文字不会消失呀

不要新建label,然后add到group去。每个group都是一组内容,你添加的越多,叠加的层就越多。还搞不明白的可以发帖问,或者把详细步骤和代码贴出来。

点赞  2023-10-26 10:01
引用: walker2048 发表于 2023-10-26 10:01 不要新建label,然后add到group去。每个group都是一组内容,你添加的越多,叠加的层就越多。还搞不明白的 ...

好的,谢谢了,搞定了

点赞  2023-10-26 10:54

期待后续深度评测!

默认摸鱼,再摸鱼。2022、9、28
点赞  2023-10-26 17:47
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复