897|2

8

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第2期】+ 提交帖:基于ESP32-S3的万年历 [复制链接]

  本帖最后由 liuvx 于 2023-11-21 17:04 编辑

最近完成了本期活动的全部内容,本次活动中使用的Adafruit ESP32-S3 TFT Feather开发板,支持WiFi和蓝牙功,自带高清TFT彩色显示屏。完成了屏幕显示中文,连接WiFi,驱动RGB,制作万年历等任务。

内容一:演示视频

这次实现的是基于ESP32-S3的万年历,可以连接上网络,并在屏幕上显示现在的时间,日期,天气和温度。

得捷电子 Follow me 第2期任务-得捷电子 Follow me 第2期任务-EEWORLD大学堂
内容二:项目总结报告

任务1:控制屏幕显示中文

首先,将效果图呈现在这

图 1 效果图

 

 

 

前期准备工作

  1. 拿到Adafruit ESP32-S3 TFT Feather开发板上电,进入UF2模式,并安装CircuitPython环境。
    CircuitPython固件UF2下载页面:
    Feather ESP32-S3 TFT Download (circuitpython.org)
  2. 将下载好的UF2固件直接拖进Adafruit ESP32-S3 TFT Feather自带的盘中,等待自动重启即可。
  3. 当你的屏幕显示如图2一样时,CircuitPython即安装好

 

图 2

 

 

正式开始

 

图 3 CircuitPython

 

我是使用VScode进行配置,可以先安装这个插件后再进行后面的操作。

 

本次任务所需要3个库

我们可以在vscode里执行这一个命令

然后在输入

                          

 

之后就可以查找并安装自己所需要的库了。

可以在进入命令执行时,输入

可以查询到自己所下载的库

本节还需要额外添加字库

字库链接:

链接已隐藏,如需查看请登录或者注册

我所使用的是wenquanyi_13px.pcf,下载好之后直接拖进开发板所带的盘就行。

 

                    然后是代码部分

这一部分是导入所必要的库

import board

import displayio

from adafruit_display_text import label, wrap_text_to_lines

from adafruit_bitmap_font import bitmap_font

然后设定屏幕参数

display = board.DISPLAY
board.DISPLAY.brightness = 0.2  # 设置显示屏亮度为0.35
board.DISPLAY.rotation = 0  # 设置显示屏旋转为0度

然后设置需要在屏幕上显示的字

# 加载自定义字体文件
font = bitmap_font.load_font("wenquanyi_13px.pcf")

# 设置文本颜色
color = 0xFF0000  # 这里的颜色为红色

# 初始化文本变量
text_change = 0

# 创建显示组和文本标签
text_group = displayio.Group()
text_area = label.Label(font, text="test", color=color)  # 创建文本标签对象

text_area.x = 0  # 设置文本的X坐标
text_area.y = 55  # 设置文本的Y坐标
text_area.line_spacing = 0.5  # 设置文本行间距
text_area.scale = 2  # 设置文本放大倍数

# 设置文本内容
text_area.text = "WIFI:ESP\n密码:00000000"  # 这里设置文本内容
text_area.ass = "w"
text_group.append(text_area)  # 将文本标签添加到显示组中
display.show(text_group)  # 在显示设备上显示文本

任务2:连接WiFi和创建热点

这个任务的要求是完成网络功能的使用,能够创建热点和连接到WiFi。 

并且代码比较简单

先说下连接WIFI:

在我们刷入固件后,可以在盘中看到一个settings.toml的文件,我们只需要修改它即可实现WIFI的链接

 然后修改里面的代码

#配置WIFI的ID
CIRCUITPY_WIFI_SSID = "Liuv"
#配置WiFi密码
CIRCUITPY_WIFI_PASSWORD = "12345678"
#配置网页工作流密码
CIRCUITPY_WEB_API_PASSWORD = "123456"
#配置网页工作流端口
CIRCUITPY_WEB_API_PORT = 80

在我们连上WIFI后,屏幕会显示出ip地址

这样我们的WIFI就链接上了。

然后是开启热点

导入必须的库

import wifi

然后开启热点

wifi.radio.start_ap('ESP', '00000000')

名字和密码。

 

 

任务完成

任务3:RGB灯的使用

 

本次任务所要使用的是板上自带的RGB灯和按键

我打算先不用按键来切换颜色,先使用time库来使它达到每0.5秒切换一次颜色的效果。

板上所带的RGB灯型号为WS2812b,可使用Adafruit提供的neopixe库来使用它

 

import neopixel

 

导入time库

import time

修改brightn可改变RGB灯最大亮度。

然后进入循环

while True:
    
    pixel.brightness = 0.6
    pixel.fill((255, 0, 0))
    time.sleep(0.5)
    pixel.brightness = 0.5
    pixel.fill((0, 255, 0))
    time.sleep(0.5)
    pixel.brightness = 0.1
    pixel.fill((0, 0, 255))
    time.sleep(0.5)

中的

pixel.fill((255, 0, 0))

分别是Red,Green,Blue的颜色控制。

time.sleep(0.5)

表示延时0.5s

当你烧入代码后就能观察到rgb在红色,绿色,蓝色来回切换,且每个的亮度不同。

完整代码如下

import time
import board
import neopixel

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)#初始化rgb引脚

pixel.brightness = 0.6#更改亮度

while True:
    
    pixel.brightness = 0.6
    pixel.fill((255, 0, 0))
    time.sleep(0.5)
    pixel.brightness = 0.5
    pixel.fill((0, 255, 0))
    time.sleep(0.5)
    pixel.brightness = 0.1
    pixel.fill((0, 0, 255))
    time.sleep(0.5)

这样,你就掌握了最基本的RGB灯的控制,再让我们看看如何用按键操作它吧

当你使用按键时,就要调用基本数字库了

import digitalio

然后再初始化按键

button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)

表示上拉输入

然后进入循环

while True:
    if not button.value:
        if n % 3 == 1:
            pixel.brightness = 0.6
            pixel.fill((255, 0, 0))
        elif n % 3 == 2:
            pixel.brightness = 0.5
            pixel.fill((0, 255, 0))
        elif n % 3 == 0:
            pixel.brightness = 0.3
            pixel.fill((0, 0, 255))
        n = n+1

仅仅这样写,也是有效果的,但是可能无法达到我们想要的结果。

因为按键在按下的时候会产生抖动,会对我们造成影响.

因此我们要加入延时函数来进行消抖

while True:
    if not button.value:
         time.sleep(0.1)
         if not button.value:
            if n % 3 == 1:
                pixel.brightness = 0.6
                pixel.fill((255, 0, 0))
            elif n % 3 == 2:
                pixel.brightness = 0.5
                pixel.fill((0, 255, 0))
            elif n % 3 == 0:
                pixel.brightness = 0.3
                pixel.fill((0, 0, 255))
            n = n+1

这样,就能满足我们的一个想要的效果了。

完整代码如下

import time
import board
import neopixel
import digitalio
n = 0
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)#初始化rgb引脚
pixel.brightness = 0.6#更改亮度

while True:
    if not button.value:
         time.sleep(0.1)
         if not button.value:
            if n % 3 == 1:
                pixel.brightness = 0.6
                pixel.fill((255, 0, 0))
            elif n % 3 == 2:
                pixel.brightness = 0.5
                pixel.fill((0, 255, 0))
            elif n % 3 == 0:
                pixel.brightness = 0.3
                pixel.fill((0, 0, 255))
            n = n+1
    else:
        pass
    
        

 

任务4:日历和时钟

在本次任务中,我们需要完成在我们的屏幕上显示时间与天气等信息

先放张效果图

 

我们来分步进行

首先是先完成文字部分

 

 

屏幕显示部分

需要的库可以自行查看之前的任务一

先设置屏幕的一些基本参数

# 设置板子的亮度和是否翻转
board.DISPLAY.brightness = 0.5  #
board.DISPLAY.rotation = 0  #
word_font = bitmap_font.load_font("wenquanyi_13px.pcf")

咱们可以在这个任务中增加一张图片来使其更加美观

需要这个库

import adafruit_imageload

然后引入图片,注意图片需要是bmp格式的

# 引入图片
image, palette = adafruit_imageload.load(
    '/images/ysqd.bmp', bitmap=displayio.Bitmap, palette=displayio.Palette)
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)

然后再显示其他文字,如时间,温度啥的

# 日期的设置
date = label.Label(word_font, text="test", color=0x000000)
date.x = 10  #
date.y = 20
date.scale = 2  #
group.append(date)

# 周几的设置
week = label.Label(word_font, text="周五", color=0x000000)
week.x = 120
week.y = 20
week.scale = 2
group.append(week)

# 时间的设置
timer = label.Label(word_font, text='10:17', color=0x779649)
timer.x = 15
timer.y = 65
timer.scale = 2  #
group.append(timer)

# 天气文字的设置
weather = label.Label(word_font, text='阴', color=0x3271ae)
weather.x = 10
weather.y = 110
weather.scale = 2  #
group.append(weather)

# 温度文字的设置
temperature = label.Label(word_font, text='10度-15度', color=0x3271ae)
temperature.x = 60
temperature.y = 110
temperature.scale = 2
group.append(temperature)

# 事实温度文字的设置
tem_now = label.Label(word_font, text='10度', color=0x3271ae)
tem_now.x = 150
tem_now.y = 65
tem_now.scale = 2
group.append(tem_now)

最后再显示即可

board.DISPLAY.show(group)

WIFI连接

和之前类似,在SETTING这个文件中配置ssid和password

# 连接WIFI,若连接失败会报错
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
time.sleep(1)
print("Connected to", ssid)

延时1s的目的为了使能够连接WiFi后再进行后面的操作

获取信息

相关库介绍

adafruit_ntp

adafruit_requests

rtc

 

获得天气这个需要从其他地方返回数据获得

我这里使用的是易客云API,比较方便和稳定

代码部分

# 周几文字的数据
def get_wday(week_today):
    if week_today == 0:
        return "周一"
    elif week_today == 1:
        return "周二"
    elif week_today == 2:
        return "周三"
    elif week_today == 3:
        return "周四"
    elif week_today == 4:
        return "周五"
    elif week_today == 5:
        return "周六"
    elif week_today == 6:
        return "周日"

再利用RTC来获得时间

# 使用rtc
rtc.RTC().datetime = adafruit_ntp.NTP(socketpool.SocketPool(
    wifi.radio), tz_offset=8, server='ntp.aliyun.com').datetime

从API获取天气情况

def get_weather():
    requests = adafruit_requests.Session(
        socketpool.SocketPool(wifi.radio), ssl.create_default_context())
    appid = os.getenv("appid")
    appsecret = os.getenv("appsecret")
    res = requests.get(
        'https://v0.yiketianqi.com/free/day?appid=%s&appsecret=%s&unescape=1&city=南阳' % (appid, appsecret)).json()
    return res['wea'], res['tem_night'], res['tem_day'], res['tem']

注意这里的appid和appsecret需要从易客云获取并写入settings这个文件中

否则会无法正常获得温度

再进行循环之前先获取一遍信息

# 获得时间
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%s℃-%s℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)

进入循环后需要对获取信息的速度加以限制

while True:
    time_now = time.localtime()
    timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
    if time_now.tm_min == 0:
        wea, tem_night, tem_day, tem = get_weather()
        weather.text = wea
        temperature.text = '%d℃-%d℃' % (tem_night, tem_day)
        tem_now.text = '%s度' % (tem)
    if time_now.tm_hour == 0:
        date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
        week.text = get_wday(time_now.tm_wday)

    pass

这样就OK了

完整代码如下

import board
import displayio
import os
import wifi
import ssl
import socketpool
import adafruit_ntp
import rtc
import time
import ipaddress
import adafruit_requests
import adafruit_imageload
from adafruit_display_text import label, wrap_text_to_lines
from adafruit_bitmap_font import bitmap_font
# 获得WIFI名字和密码
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")


# 周几文字的数据
def get_wday(week_today):
    if week_today == 0:
        return "周一"
    elif week_today == 1:
        return "周二"
    elif week_today == 2:
        return "周三"
    elif week_today == 3:
        return "周四"
    elif week_today == 4:
        return "周五"
    elif week_today == 5:
        return "周六"
    elif week_today == 6:
        return "周日"


# 连接WIFI,若连接失败会报错
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
time.sleep(10)
print("Connected to", ssid)
# 获得天气情况


def get_weather():
    requests = adafruit_requests.Session(
        socketpool.SocketPool(wifi.radio), ssl.create_default_context())
    appid = os.getenv("appid")
    appsecret = os.getenv("appsecret")
    res = requests.get(
        'https://v0.yiketianqi.com/free/day?appid=%s&appsecret=%s&unescape=1&city=南阳' % (appid, appsecret)).json()
    return res['wea'], res['tem_night'], res['tem_day'], res['tem']


# 使用rtc
rtc.RTC().datetime = adafruit_ntp.NTP(socketpool.SocketPool(
    wifi.radio), tz_offset=8, server='ntp.aliyun.com').datetime
# 引入图片
image, palette = adafruit_imageload.load(
    '/images/ysqd.bmp', bitmap=displayio.Bitmap, palette=displayio.Palette)
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)
# 设置板子的亮度和是否翻转
board.DISPLAY.brightness = 0.5  #
board.DISPLAY.rotation = 0  #
word_font = bitmap_font.load_font("wenquanyi_13px.pcf")

# 日期的设置
date = label.Label(word_font, text="test", color=0x000000)
date.x = 10  #
date.y = 20
date.scale = 2  #
group.append(date)

# 周几的设置
week = label.Label(word_font, text="周五", color=0x000000)
week.x = 120
week.y = 20
week.scale = 2
group.append(week)

# 时间的设置
timer = label.Label(word_font, text='10:17', color=0x779649)
timer.x = 15
timer.y = 65
timer.scale = 2  #
group.append(timer)

# 天气文字的设置
weather = label.Label(word_font, text='阴', color=0x3271ae)
weather.x = 10
weather.y = 110
weather.scale = 2  #
group.append(weather)

# 温度文字的设置
temperature = label.Label(word_font, text='10度-15度', color=0x3271ae)
temperature.x = 60
temperature.y = 110
temperature.scale = 2
group.append(temperature)

# 事实温度文字的设置
tem_now = label.Label(word_font, text='10度', color=0x3271ae)
tem_now.x = 150
tem_now.y = 65
tem_now.scale = 2
group.append(tem_now)
# 获得时间
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%s℃-%s℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)
board.DISPLAY.show(group)


while True:
    time_now = time.localtime()
    timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
    if time_now.tm_min == 0:
        wea, tem_night, tem_day, tem = get_weather()
        weather.text = wea
        temperature.text = '%d℃-%d℃' % (tem_night, tem_day)
        tem_now.text = '%s度' % (tem)
    if time_now.tm_hour == 0:
        date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
        week.text = get_wday(time_now.tm_wday)

    pass

 

 

内容三:任务总结

本次活动是我真正意义上接触ESP32,之前只接触过STM32,51之类的单片机。通过本次活动,我学到了许多ESP32的使用方法以及CircuitPython的操作。明白了esp32在某些地方使用上确实比32简单些。这次任务带我进入了嵌入式的新领域,使我的技能得到了训练,也使得之前一知半解的知识得到了补充,收获满满,非常感谢得捷电子和ee对本次活动的支持。

代码资源链接

follow me 第二期全套代码-嵌入式开发相关资料下载-EEWORLD下载中心

最新回复

感谢楼主提供的技术分享,先收藏学习再发表个人意见,顶起来   详情 回复 发表于 2023-11-23 18:12
点赞 关注
 
 

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

测试和整理的很好,学习了

 
 
 

回复

755

帖子

5

TA的资源

纯净的硅(高级)

板凳
 

感谢楼主提供的技术分享,先收藏学习再发表个人意见,顶起来


 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表