第一次参加带此类活动中还是很兴奋的,过程也是一波三折,登陆两个多月板子才陆续到手里,马上就开始紧张的交作业环节了,首先我们先回顾一下本次的活动有那些作业需要交。
任务1:控制屏幕显示中文(必做任务)
完成屏幕的控制,并且能显示中文
搭配器件:Adafruit ESP32-S3 TFT Feather
任务2:网络功能使用(必做任务)
完成网络功能的使用,能够创建热点和连接到WiFi
搭配器件:Adafruit ESP32-S3 TFT Feather
任务3:控制WS2812B(必做任务)
使用按键控制板载Neopixel LED的显示和颜色切换
搭配器件:Adafruit ESP32-S3 TFT Feather
任务4:从下方5个分任务中选择1个感兴趣的完成即可(必做任务)
■ 分任务1:日历&时钟——完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息
建议搭配器件:Adafruit ESP32-S3 TFT Feather
■ 分任务2:WS2812B效果控制——完成一个Neopixel(12灯珠或以上)控制器,通过按键和屏幕切换展示效果
建议搭配器件:Adafruit ESP32-S3 TFT Feather、可寻址RGB LED
■ 分任务3:数据检测与记录——按一定时间间隔连续记录温度/亮度信息,保存到SD卡,并可以通过按键调用查看之前的信息,并在屏幕上绘图
建议搭配器件:Adafruit ESP32-S3 TFT Feather、光传感器、温度传感器、微型 SD卡模块
■ 分任务4:音乐播放功能——实现音乐播放器功能,可以在屏幕上显示列表信息和音乐信息,使用按键进行切换,使用扬声器进行播放
建议搭配器件:Adafruit ESP32-S3 TFT Feather、音频放大器、扬声器
■ 分任务5:AI功能应用——结合运动传感器,完成手势识别功能,至少要识别三种手势(如水平左右、前后、垂直上下、水平画圈、垂直画圈,或者更复杂手势
建议搭配器件:Adafruit ESP32-S3 TFT Feather、运动传感器
任务5:通过网络控制WS2812B(可选任务,非必做)
结合123,在手机上通过网络控制板载Neopixel LED的显示和颜色切换,屏幕同步显示状态
搭配器件:Adafruit ESP32-S3 TFT Feather
可以看到1,2,3,4任务都是必做的,5可以选择做或者不做。
那么就挨个来不着急。
接下来先给大家讲解一下各个任务的实现:
//内容一:3-5分钟短视频//
补充视频
//内容二: 任务/项目总结报告//
任务一:
第1步:安装otf2bdf工具,找了一圈发现win平台是没有的,这里就在linux上操作了,如下图所示就安装成功了。
第2步:我们执行转换命令: otf2bdf 一品创享体1.20.ttf -p 16 -o yipingchuangxiang_v1.2_16.bdf
-p的意思就是指定生成的字库文字大小 -o 指定生成的文件名
可以看到我这里箭头指的已经生成了,还有一个文字大小48的就不演示了。
第3步:现在已经得到了bdf格式的字库了,这个文件大小有1M多,如果还嫌大放不进去可以使用官方推荐的工具进一步转换为pcf格式。
https://adafruit.github.io/web-bdftopcf/
点击进去将刚才生成的bdf文件上传上去既可以自动转换为pcd文件,这个转换后文件只有500多k了。
第4步:在u盘里面新建文件夹font,images,将字库文件丢到font后面就可以调用了,同样,后面调用图片也是需要我们丢图片到images文件夹
第5步:在u盘里面新建文件settings.toml,填上如下内容,板子就可以自动连接到wifi了
# SPDX-FileCopyrightText: 2023 Adafruit Industries
#
# SPDX-License-Identifier: MIT
# This is where you store the credentials necessary for your code.
# The associated demo only requires WiFi, but you can include any
# credentials here, such as Adafruit IO username and key, etc.
CIRCUITPY_WIFI_SSID = "you ssid"
CIRCUITPY_WIFI_PASSWORD = "you password"
CIRCUITPY_WEB_API_PASSWORD = "you password"
CIRCUITPY_WEB_API_PORT = 80
第6步:在编写的时候需要用到一些库,可以从这个https://circuitpython.org/libraries网站上下载,需要用到那个直接在lib文件夹拷贝到u盘里面的lib文件夹即可,没有就创建一个。
第7步:在u盘里面新建文件code.py,在里面填上如下内容我们就可以完成任务1了。
import board # 导入board库,用于访问硬件板上的引脚和设备
import displayio # 导入displayio库,用于管理和控制显示器
from vectorio import Rectangle # 导入vectorio库,用于创建和管理矩形图形
import adafruit_imageload # 导入adafruit_imageload库,用于加载图像文件
# 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_display_text import label
# 导入外部库adafruit_bitmap_font里的lable,用于显示字体
from adafruit_bitmap_font import bitmap_font
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/yipingchuangxiang_v1.2_16.pcf")
color = 0x000000
# 获取内置显示器对象
display = board.DISPLAY
# 加载PNG图像
image, palette = adafruit_imageload.load("images/bg.png")
# 将透明色设置为隐藏
palette.make_transparent(0)
# 创建用于加载的图像瓦片网格
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
tile_grid.x = display.width // 2 - tile_grid.tile_width // 2
tile_grid.y = display.height // 2 - tile_grid.tile_height // 2
# 创建空白背景
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xFFFFFF
rect = Rectangle(
pixel_shader=bg_palette, width=display.width, height=display.height, x=0, y=0
)
# 创建显示器组对象
group = displayio.Group()
# 添加背景
group.append(rect)
# 添加加载的图像瓦片网格
group.append(tile_grid)
# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text=" 电子工程世界\n www.eeworld.com.cn\n 简称EEWORLD", color=color)
date.x = 0
date.y = 20
group.append(date)
# 在显示器上显示组
board.DISPLAY.show(group)
# 持续循环,使程序保持在显示器上显示
while True:
pass
最后我们来看一下,完成效果。
任务二:
这个作业非常简单,我们只需要在程序中导入wifi库即可,然后在程序中调用wifi.radio.start_ap就行了,直接上代码
import wifi #这个是内部库
import board # 导入board库,用于访问硬件板上的引脚和设备
import displayio # 导入displayio库,用于管理和控制显示器
import adafruit_imageload # 导入adafruit_imageload库,用于加载图像文件
from vectorio import Rectangle # 导入vectorio库,用于创建和管理矩形图形
from adafruit_display_text import label # 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_bitmap_font import bitmap_font # 导入外部库adafruit_bitmap_font里的lable,用于显示字体
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/yipingchuangxiang_v1.2_16.pcf")
color = 0x000000
# 获取内置显示器对象
display = board.DISPLAY
# 加载PNG图像
image, palette = adafruit_imageload.load("images/bg.png")
# 将透明色设置为隐藏
palette.make_transparent(0)
# 创建用于加载的图像瓦片网格
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
tile_grid.x = display.width // 2 - tile_grid.tile_width // 2
tile_grid.y = display.height // 2 - tile_grid.tile_height // 2
# 创建空白背景
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xFFFFFF
rect = Rectangle(
pixel_shader=bg_palette, width=display.width, height=display.height, x=0, y=0
)
# 创建显示器组对象
group = displayio.Group()
# 添加背景
group.append(rect)
# 添加加载的图像瓦片网格
group.append(tile_grid)
# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text=" 电子工程世界\n www.eeworld.com.cn\n 简称EEWORLD", color=color)
date.x = 0
date.y = 20
group.append(date)
wifi.radio.start_ap("eeworld", "www.eeworld.com.cn")
print(f"SSID: eeworld")
print(f"PASSWORD: www.eeworld.com.cn")
# 在显示器上显示组
board.DISPLAY.show(group)
# 持续循环,使程序保持在显示器上显示
while True:
pass
可以看到已经生成了一个名字叫eeworld的wifi,我们输入密码也是可以连接上去的。
连接wifi的话其实我们在settings.toml配置一下就可以连接到wifi了。
任务三:
这个作业需要我们控制ws2812,所以我们需要再导入一个库neopixel,这个库是外部库,需要我们拷贝到u盘lib目录里面去
然后我这边刚好有一个圆形灯板,有30灯,可以利用板子上的boot按钮切换灯的颜色,具体看代码。
import time # 这个是内部库
import wifi # 这个是内部库
import board # 导入board库,用于访问硬件板上的引脚和设备
import neopixel # 这个是驱动ws2812BRGB灯所需要的库
import digitalio # 这个是内部库,数字io需要的库
import displayio # 导入displayio库,用于管理和控制显示器
import adafruit_imageload # 导入adafruit_imageload库,用于加载图像文件
from vectorio import Rectangle # 导入vectorio库,用于创建和管理矩形图形
from adafruit_display_text import label # 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_bitmap_font import bitmap_font # 导入外部库adafruit_bitmap_font里的lable,用于显示字体
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/yipingchuangxiang_v1.2_16.pcf")
color = 0x000000
# 获取内置显示器对象
display = board.DISPLAY
# 加载PNG图像
image, palette = adafruit_imageload.load("images/bg.png")
# 将透明色设置为隐藏
palette.make_transparent(0)
# 创建用于加载的图像瓦片网格
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
tile_grid.x = display.width // 2 - tile_grid.tile_width // 2
tile_grid.y = display.height // 2 - tile_grid.tile_height // 2
# 创建空白背景
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xFFFFFF
rect = Rectangle(
pixel_shader=bg_palette, width=display.width, height=display.height, x=0, y=0
)
# 创建显示器组对象
group = displayio.Group()
# 添加背景
group.append(rect)
# 添加加载的图像瓦片网格
group.append(tile_grid)
# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text=" 电子工程世界\n www.eeworld.com.cn\n 简称EEWORLD", color=color)
date.x = 0
date.y = 20
group.append(date)
wifi.radio.start_ap("eeworld", "www.eeworld.com.cn")
print(f"SSID: eeworld")
print(f"PASSWORD: www.eeworld.com.cn")
pixel_pin = board.D13 #设置ws2812控制引脚
num_pixels = 30 # 设置灯珠数量
ORDER = neopixel.GRB #颜色排列顺序
pixels = neopixel.NeoPixel(
pixel_pin, num_pixels, brightness=0.05, auto_write=False, pixel_order=ORDER
)
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
# 在显示器上显示组
board.DISPLAY.show(group)
button_state = False
led_state = 1
# 持续循环,使程序保持在显示器上显示
while True:
if not button.value and button_state == False:
button_state = True
led_state = led_state + 1;
time.sleep(0.2)
if led_state == 3:
led_state = 0;
print("Hello World",led_state)
else:
time.sleep(0.2)
button_state = False
if led_state == 0:
pixels.fill((255, 0, 0))
pixels.show()
elif led_state == 1:
pixels.fill((0, 255, 0))
pixels.show()
elif led_state == 2:
pixels.fill((0, 0, 255))
pixels.show()
可以看下效果
控制板载的灯的画只需要将IO改为:
pixel_pin = board.NEOPIXEL #设置ws2812控制引脚
num_pixels = 1 # 设置灯珠数量
效果如下:
任务四:
这个作业我们需要完成一共网络时钟,我们的去一些第三方平台申请一共获取天气的接口,我这里用的是高德的api,然后调用接口去请求数据即可,然后直接套用前面显示的程序显示到屏幕即可,看代码
import board # 导入board库,用于访问硬件板上的引脚和设备
import os
import rtc
import ssl
import time as Time
import wifi # 这个是内部库
import neopixel # 这个是驱动ws2812BRGB灯所需要的库
import digitalio # 这个是内部库,数字io需要的库
import displayio # 导入displayio库,用于管理和控制显示器
import socketpool
import adafruit_ntp
# import adafruit_datetime 000
import adafruit_requests
import adafruit_imageload # 导入adafruit_imageload库,用于加载图像文件
from vectorio import Rectangle # 导入vectorio库,用于创建和管理矩形图形
from adafruit_display_text import label # 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_bitmap_font import bitmap_font # 导入外部库adafruit_bitmap_font里的lable,用于显示字体
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/yipingchuangxiang_v1.2_16.pcf")
time_font = bitmap_font.load_font("/font/DingTalk_ncn_60.pcf")
color = 0x000000
# 获取当前设备的rtc时钟
pool = socketpool.SocketPool(wifi.radio) #初始化
ntp = adafruit_ntp.NTP(pool, tz_offset=8, server="ntp.aliyun.com") #校正时间
rtc.RTC().datetime = ntp.datetime #校正时间
# 获取内置显示器对象
display = board.DISPLAY
# 加载PNG图像
image, palette = adafruit_imageload.load("images/bg.png")
# 将透明色设置为隐藏
palette.make_transparent(0)
# 创建用于加载的图像瓦片网格
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
tile_grid.x = display.width // 2 - tile_grid.tile_width // 2
tile_grid.y = display.height // 2 - tile_grid.tile_height // 2
# 创建空白背景
bg_palette = displayio.Palette(1)
bg_palette[0] = 0xFFFFFF
rect = Rectangle(
pixel_shader=bg_palette, width=display.width, height=display.height, x=0, y=0
)
# 创建显示器组对象
group = displayio.Group()
# 添加背景
group.append(rect)
# 添加加载的图像瓦片网格
group.append(tile_grid)
wifi.radio.start_ap("eeworld", "www.eeworld.com.cn")
print(f"SSID: eeworld")
print(f"PASSWORD: www.eeworld.com.cn")
# pixel_pin = board.D13 #设置ws2812控制引脚
# num_pixels = 30 # 设置灯珠数量
pixel_pin = board.NEOPIXEL #设置ws2812控制引脚
num_pixels = 1 # 设置灯珠数量
ORDER = neopixel.GRB #颜色排列顺序
pixels = neopixel.NeoPixel(
pixel_pin, num_pixels, brightness=0.05, auto_write=False, pixel_order=ORDER
)
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
label_city = label.Label(font, text="上海市", color=color)
label_city.x = 20
label_city.y = 20
group.append(label_city)
label_weather = label.Label(font, text="晴", color=color)
label_weather.x = 160
label_weather.y = 20
group.append(label_weather)
label_time = label.Label(time_font, text="00:00", color=color)
label_time.x = 20
label_time.y = 60
group.append(label_time)
label_temperature = label.Label(font, text="温度:", color=color)
label_temperature.x = 20
label_temperature.y = 120
group.append(label_temperature)
label_winddirection = label.Label(font, text="风向:", color=color)
label_winddirection.x = 120
label_winddirection.y = 120
group.append(label_winddirection)
# 在显示器上显示组
board.DISPLAY.show(group)
button_state = False
led_state = 0
weather_info = None
province = None
city = None
weather = None
temperature = None
wind_direction = None
wind_power = None
humidity = None
report_time = None
sys_init = 1
get_weather_flag = 0
former_time = 0
print("start")
def get_weather():
# 调用天气接口API
JSON_URL = "https://restapi.amap.com/v3/weather/weatherInfo?key="+os.getenv("CIRCUITPY_WEATHER_API_KEY")+"&city="+os.getenv("CIRCUITPY_WEATHER_API_CITY")
print(JSON_URL)
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
response = requests.get(JSON_URL)
# 解析JSON数据
JSON_DATA = response.json()
# 获取天气信息
weather_info = JSON_DATA["lives"][0]
province = weather_info["province"]
city = weather_info["city"]
weather = weather_info["weather"]
temperature = weather_info["temperature"]
wind_direction = weather_info["winddirection"]
wind_power = weather_info["windpower"]
humidity = weather_info["humidity"]
report_time = weather_info["reporttime"]
# 打印天气信息
print("Province: {}".format(province))
print("City: {}".format(city))
print("Weather: {}".format(weather))
print("Temperature: {}°C".format(temperature))
print("Wind Direction: {}".format(wind_direction))
print("Wind Power: {}".format(wind_power))
print("Humidity: {}%".format(humidity))
print("Report Time: {}".format(report_time))
now_time = Time.localtime()
label_time.text = "%d:%d" % (now_time.tm_hour, now_time.tm_min)
label_city.text = city
label_temperature.text = "温度:"+temperature
label_winddirection.text = "风向:"+wind_direction
# 持续循环,使程序保持在显示器上显示
while True:
if not button.value and button_state == False:
button_state = True
led_state = led_state + 1;
Time.sleep(0.2)
if led_state == 3:
led_state = 0;
print("Hello World",led_state)
else:
Time.sleep(0.2)
button_state = False
if led_state == 0:
pixels.fill((255, 0, 0))
pixels.show()
elif led_state == 1:
pixels.fill((0, 255, 0))
pixels.show()
elif led_state == 2:
pixels.fill((0, 0, 255))
pixels.show()
now_time = Time.localtime()
if (sys_init == 1): #第一次上电读取一下天气
sys_init = 0
print("sys_init",now_time)
try:
get_weather()
except:
print("get_weather An exception occurred")
if (get_weather_flag == 1 and now_time.tm_hour == 0): #一小时更新一次天气
try:
get_weather()
except:
print("get_weather An exception occurred")
get_weather_flag = 0
if (now_time.tm_sec == 10):
get_weather_flag = 1
if(former_time != now_time.tm_min): #一分钟刷新一下时间
label_time.text = "%d:%d" % (now_time.tm_hour, now_time.tm_min)
former_time = now_time.tm_min
看下最后效果:
最后上传一下可运行的u盘打包文件,里面配置文件需要自己新建一下。
//内容三:可编译下载的代码//
引用: 火辣西米秀 发表于 2023-10-19 07:29 eeworld的logo都整出来了 强
哈哈,整了个完整的中文字库,想显示什么就显示什么了
引用: 秦天qintian0303 发表于 2023-10-19 08:47 效果相当不错啊,这个背景图片很好看
女朋友给做的背景图