非常高兴能参加这次的Follow me 第2期开发板挑战活动,本次项目使用Adafruit ESP32-S3 TFT Feather开发板完成。该开发板采用乐鑫的ESP32-S3芯片,同时内置了一块IPS TFT显示屏,以及炫彩LED灯。内置的模块非常便于像我这样的新手学习和调试。结合Circuit Python的易用性,让开发变得非常好上手。
代码上传
视频上传
任务选择
本次项目选择了以下任务:
任务1:控制屏幕显示中文
任务2:网络功能使用
任务3:控制WS2812B
任务4分任务1:日历&时钟
任务开始前的准备工作:
只需要一块Adafruit ESP32-S3 TFT Feather,一根Type C数据线和一台电脑即可。
进入DFU模式:
将开发板与电脑通过Type C数
据线连接,待屏幕显示信息后,连按两下Rst按键,即可进入DFU模式。
烧录Circuit Python:
将Circuit Python的固
件直接拷贝到DFU模式下的U盘内,待进度走完即可完成烧录。
拷贝作业所需的库:
将作业所需的库拷贝到
DFU模式的U盘根目录下的lib文件夹即可。
完成wifi配置:
在settings.toml中将必要信息填入即可(此处截图时将ssid及密码做了掩码处理)。
至此已完成作业前的准备,下面是每一个任务的具体介绍和关键代码:
任务1:控制屏幕显示中文
任务要求:完成
屏幕的控制,并且能显示中文设计思路:对于显示中文,最大的难题在于解决字体问题。选择合适的字体导入后,创建图像组,将所需显示的文字添加到图像组后,使用板载屏幕进行显示,并创建死循环维持显示。
设计过程及代码:
这里使用Font Forge软件,加载所选择的TTF格式字体后,点击Element菜单下的Bitmap Strikes Available,选择所需的格式和参数。
此处设定字体大小为25,其他参数自动生成。
点击OK后,再点击Element菜单中的Regenerate Bitmap Glyphs,点击OK。
最后点击File菜单中的Generate Fonts后,如图设置格式,即可生成BDF字库
最后打开https://adafruit.github.io/web-bdftopcf/通过网页生成PCF格式字体。
改名后,置于开发板的font文件夹内,即可完成字体的设置。
直接对开发版内的code.py进行编辑,导入所需的模块:
import board
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
使用设备自带的屏幕设备
screen = board.DISPLAY
创建显示的图像组
contents = displayio.Group()
设置字体
font = bitmap_font.load_font("/font/font.pcf")
将每一行文字逐行设置,并设定字体,颜色为白色,放大倍率1,并添加到图像组中
text_1 = "人是万物的尺度,"
content_1 = label.Label(font, text=text_1, color=0xffffff, scale=1)
content_1.x = 10
content_1.y = 15
contents.append(content_1)
text_2 = "是存在的事物存在"
content_2 = label.Label(font, text=text_2, color=0xffffff, scale=1)
content_2.x = 10
content_2.y = 40
contents.append(content_2)
text_3 = "的尺度,也是不存"
content_3 = label.Label(font, text=text_3, color=0xffffff, scale=1)
content_3.x = 10
content_3.y = 65
contents.append(content_3)
text_4 = "在的事物不存在的"
content_4 = label.Label(font, text=text_4, color=0xffffff, scale=1)
content_4.x = 10
content_4.y = 90
contents.append(content_4)
text_5 = "尺度。"
content_5 = label.Label(font, text=text_5, color=0xffffff, scale=1)
content_5.x = 10
content_5.y = 115
contents.append(content_5)
将内容显示
screen.show(contents)
创建死循环维持内容持续显示
while True:
pass
至此完成作业1,效果如图:
任务2:网络功能使用
任务要求:完成网络功能的使用,能够创建热点和连接到WiFi
设计思路-创建热点:
利用wifi模块完成热点的创建,并利用任务1中的文字显示功能,将热点的ssid和密码显示在屏幕上。
设计思路-连接wifi:
利用wifi模块完成wifi连接,通过分支结构判断是否成功连接,若成功连接,则将所连接的wifi的ssid和所获取的ip地址显示在屏幕上。
创建热点:
导入所需的模块
import board
import displayio
import wifi
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
直接通过wifi模块完成热点的创建
wifi.radio.start_ap("Rica's wifi", "12345678")
以文字形式,将热点的ssid和密码显示在屏幕上:
screen = board.DISPLAY
contents = displayio.Group()
font = bitmap_font.load_font("/font/font.pcf")
text_1 = "wifi信息:"
content_1 = label.Label(font, text=text_1, color=0xffffff, scale=1)
content_1.x = 10
content_1.y = 40
contents.append(content_1)
text_2 = "SSID:Rica's wifi"
content_2 = label.Label(font, text=text_2, color=0xffffff, scale=1)
content_2.x = 10
content_2.y = 65
contents.append(content_2)
text_3 = "密码:12345678"
content_3 = label.Label(font, text=text_3, color=0xffffff, scale=1)
content_3.x = 10
content_3.y = 90
contents.append(content_3)
screen.show(contents)
while True:
pass
效果如图:
连接wifi:
导入所需的模块:
import os
import board
import displayio
import wifi
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
通过wifi模块完成网络的连接,此处获取了配置文件中设置的SSID和密码
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))
设置显示
screen = board.DISPLAY
contents = displayio.Group()
font = bitmap_font.load_font("/font/font.pcf")
判断是否成功连接,并设置不同的文字输出内容,若成功连接,可显示wifi的SSID以及IP地址
if wifi.radio.connected:
text_1 = f"wifi:{os.getenv('CIRCUITPY_WIFI_SSID')}"
text_2 = "您的IP地址为:"
text_3 = str(wifi.radio.ipv4_address)
else:
text_2 = "wifi连接失败!"
text_3 = "请检查设置!"
将结果进行输出
content_1 = label.Label(font, text=text_1, color=0xffffff, scale=1)
content_1.x = 10
content_1.y = 40
contents.append(content_1)
content_2 = label.Label(font, text=text_2, color=0xffffff, scale=1)
content_2.x = 10
content_2.y = 65
contents.append(content_2)
content_3 = label.Label(font, text=text_3, color=0xffffff, scale=1)
content_3.x = 10
content_3.y = 90
contents.append(content_3)
screen.show(contents)
while True:
pass
效果如图:
任务3:控制WS2812B
任务要求:使用按键控制板载Neopixel LED的显示和颜色切换
设计思路:设置灯珠的数量亮度,初始化灯珠及按键后,通过设置按键功能获取随机的数值作为RGB值,并以此RGB值作为灯珠的颜色显示。
导入所需的库
import board
import time
import neopixel
import digitalio
import random
from adafruit_led_animation.animation.blink import Blink
设置WS2812B,灯珠数量,亮度
led = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.1, auto_write=False, pixel_order=neopixel.GRB)
初始化显示模式
display = Blink(led, speed=0.5, color=(0, 0, 0))
初始化按键功能
button = digitalio.DigitalInOut(board.BOOT0)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
初始化RGB随机数
g_num = r_num = b_num = 0
当按下按键后,随机选择颜色并闪烁
while True:
if not button.value:
g_num = random.randrange(0, 256)
r_num = random.randrange(0, 256)
b_num = random.randrange(0, 256)
display = Blink(led, speed=0.5, color=(g_num, r_num, b_num))
else:
pass
time.sleep(0.2)
display.animate()
效果如图:
任务4分任务1:日历&时钟
任务要求:完成个可通过互联网更新的万年历时钟,并显示当地的天气信息 一
设计思路:通过互联网获取json格式的时间和天气信息,解析后做格式化输出,并显示在屏幕上
导入所需的模块
import os
import board
import displayio
import wifi
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
import socketpool
import adafruit_requests
import ssl
初始化屏幕,图像组,设置字体
screen = board.DISPLAY
contents = displayio.Group()
font = bitmap_font.load_font("/font/font.pcf")
设置获取时间和天气的url
time_url = "http://quan.suning.com/getSysTime.do"
weather_url = http://t.weather.sojson.com/api/weather/city/101010100
使用requests获取json格式的时间、天气信息,并解析
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
time_data = requests.get(time_url).json()['sysTime2'][:-3]
weather_data = requests.get(weather_url).json()
将天气、时间、温度、湿度等信息做格式化输出
text_1 = weather_data['cityInfo']['city'] + '天气'
text_2 = time_data
text_3 = weather_data['data']['forecast'][0]['week']
text_4 = '温度:' + weather_data['data']['wendu'] + '摄氏度'
text_5 = '湿度:' + weather_data['data']['shidu']
将各信息添加到图像组,并完成图像组的显示
content_1 = label.Label(font, text=text_1, color=0xffffff, scale=1)
content_1.x = 10
content_1.y = 15
contents.append(content_1)
content_2 = label.Label(font, text=text_2, color=0xffffff, scale=1)
content_2.x = 10
content_2.y = 40
contents.append(content_2)
content_3 = label.Label(font, text=text_3, color=0xffffff, scale=1)
content_3.x = 10
content_3.y = 65
contents.append(content_3)
content_4 = label.Label(font, text=text_4, color=0xffffff, scale=1)
content_4.x = 10
content_4.y = 90
contents.append(content_4)
content_5 = label.Label(font, text=text_5, color=0xffffff, scale=1)
content_5.x = 10
content_5.y = 115
contents.append(content_5)
screen.show(contents)
while True:
pass
效果如图:
项目总结:
项目介绍:
该项目基于Adafruit ESP32-S3 TFT Feather开发板实现,主要功能利用板载TFT显示屏、WIKFI模块以及炫彩LED灯实现。
项目预期目标:
完成对TFT显示屏的控制,并输出多行中文显示;
完成网络功能的使用,并成功创建热点,连接到wifi,同时屏幕可显示热点/wifi信息;
完成炫彩灯珠的控制,并通过按键控制随机的颜色变化;
完成上述功能的综合运用,通过wifi获取时间及当地天气信息,并通过屏幕显示。
项目实施过程中的挑战
开发板本身已具有丰富的板载模块,同时固件的烧录非常简单,结合CPY多样的库,项目整体难度不高,但还是遇到了如下2方面的挑战:
1,项目前期的准备工作
对于项目前期的准备主要是固件烧录,库的导入,wifi配置文件的设置,这些部分已经有了充分的教程,在认真学习后,比较顺利,只是库的导入由于经验不足,没有在前期计划好所需要用到的库,频繁的做了很多次“写代码-发现缺少必须的库-找到相应的库-导入“的重复操作。
2,中文字库的解决
由于字库文件本身的大小问题,板载存储没有足够的空间,所以需要对字体文件进行压缩。这个过程花了非常多的时间,也走了不少弯路。项目开始时找到的办法是在字库中只保留必要的字符来减小体积,但是这种做法针对成熟的项目开发是可行的,对于边调试边思考下一步该怎么做的新手,可能会造成重复调整字库的麻烦。在请教了群友之后找到了一个替代解决方案:将字库尽可能的压缩,在保证完整性的情况下塞进内部存储中。虽然体积依然较大,但是对于调试项目是足够的。
总结:
该项目很适合像我这样的新手作为上手的第一个项目,通过这个项目学到了以下内容:
DFU模式下CPY固件的烧录
DFU模式下库的导入
中文字库的修改及导入
settings.toml配置文件的编辑
板载模块(屏幕、wifi模块、LED)的调用
创建图像组显示文字
wifi的连接
热点的创建
通过requests模块获取信息
json信息的解析
心得体会:
本人作为一个小白,一直以来对单片机都有兴趣,但是毫无头绪,也找不到合适的空间和渠道,本次活动很好的给了一个入门单片机开发的抓手:
项目难度合理,教程很多,适合上手;
cpy易用,减少了写代码的难度,可以将更多精力用在对硬件的学习上;
论坛、微信群交流频繁,新手有问题能找到参考和问询的渠道;
有报销作为激励,新手容易坚持下去。
虽然这次活动出现了物流的小插曲,但是瑕不掩瑜,完成这个项目给了我很大的信心去更深入的了解单片机这个领域,感谢DigiKey和EEWORLD带来这么好的活动,下次有机会我还会参加更多项目,学习更多技能。