1381|1

17

帖子

6

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第2期】玩转Adafruit ESP32-S3 TFT Feather (全流程综合贴) [复制链接]

  本帖最后由 QuaX_Chow 于 2023-10-14 16:18 编辑

2023.8.19(开始动工,存个草稿先)


2023.10.6

这次给大家带来的是Follow Me第二期任务的速通教学(鸽了很久

本次活动基本查阅查阅手册就可以通过

感谢主办方eeworld得捷电子的支持,感谢各位提前发帖的大神坛友

内容一:3-5分钟短视频

内容二:本篇

内容三:本人整理的资料包(包含示例代码、任务代码、官方资料、部分外部库,打不开就是还没审核,可以先用老的资料包)

 


1、Quick Start

首先我们快速搭建一下我们所需的开发环境,本次使用的是官方推荐的Mu Editor编写CircuitPython。

使用数据线将开发板与电脑相连,并连按两次reset键(如下所示)

当Neo灯绿灯常亮,红色LED呼吸灯闪烁时,电脑就会显示连接到了一个新磁盘。将资料包-other中的adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.3.uf2拖入新磁盘的根目录即可为开发板快速添加circuitpython支持包。
或者直接去官网下载,下载链接:circuitpy包
待文件移动完成后开发板屏幕上即会显示开发板信息和uid(如下图)同时出现一个新u盘

PS:circuitpython其实还有个中文包,但在屏幕上显示的是拼音。。(adafruit-circuitpython-adafruit_feather_esp32s3_tft-zh_Latn_pinyin-8.2.3.uf2如下所示)

再在电脑上安装好Mu Editor(下载地址),当然如thonny啥的也是可以的。
 
我们想要编辑代码的话,直接打开根目录(如下所示)下的code.py并编辑即可
 

首先我们先刷两个测试程序,程序都可以在手册或者对应库的示例代码里找到

第一个是可以直接使用的点灯程序,直接cv进code.py即可。
下载成功即可看见板载LED闪烁。
  • import board
  • import digitalio
  • import time
  • led = digitalio.DigitalInOut(board.LED)
  • led.direction = digitalio.Direction.OUTPUT
  • while True:
  • led.value = True
  • time.sleep(0.5)
  • led.value = False
  • time.sleep(0.5)

测试代码①

播放器加载失败: 未检测到Flash Player,请到安装

 

第二个是图片显示代码,添加资料包中other-lib中的imageload库即可实现。

  • import board
  • import displayio
  • import adafruit_imageload
  • 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.show(group)
  • #
  • while True:
  • pass

测试代码②

添加外部库的方法:打开外部库的压缩包,将对应文件夹复制进开发板u盘根目录下的lib文件夹即可(如imageload库)

 

 

本代码需在根目录下创建image文件夹,并在该文件夹下粘贴下面这张已转格式的图片↓

测试图片
播放器加载失败: 未检测到Flash Player,请到安装
ys

 
2、任务1:控制屏幕显示中文(必做任务)
我们想要控制屏幕显示中文的话,需要使用bitmap库将点阵字体加载到displayio中,可以使用bdf、pcf等格式,非常简单
 
  • import board
  • import displayio
  • from adafruit_display_text import label, wrap_text_to_lines
  • from adafruit_bitmap_font import bitmap_font
  • # 设置要显示的字符串
  • dis_str = "完成屏幕的控制并且能显示中文"
  • def screen_dispstr(str):
  • # 根据屏幕旋转角度确定每行显示的字符数
  • if board.DISPLAY.rotation % 180 == 0:
  • char_num = 23 # 横屏
  • else:
  • char_num = 13 # 竖屏
  • strbuf = ""
  • for i in range(len(str) / char_num):
  • # 将字符串按每行字符数拆分,并添加换行符
  • strbuf = strbuf + str[i * char_num:(i + 1) * char_num] + "\n"
  • return strbuf
  • # 初始化显示屏
  • display = board.DISPLAY
  • board.DISPLAY.brightness = 0.35
  • board.DISPLAY.rotation = 0
  • # 加载字体和设置颜色
  • font = bitmap_font.load_font("wenquanyi_10pt.pcf")
  • color = 0x00FFFF
  • # 创建显示文本的组和标签
  • text_group = displayio.Group()
  • text_area = label.Label(font, text=screen_dispstr(dis_str), color=color)
  • text_area.x = 2
  • text_area.y = 6
  • text_area.line_spacing = 0.8
  • text_area.scale = 1
  • text_group.append(text_area)
  • display.show(text_group)
  • # 持续显示
  • while True:
  • pass
 
 
  1. 初始化显示屏模块,并设置亮度和旋转角度
  2. 加载所需的字体文件
  3. 创建显示文本的组和标签对象,并设置文本内容、颜色、位置和缩放
  4. 将文本标签对象添加到显示文本的组中
  5. 使用display.show将显示文本的组添加到显示屏上进行显示
  6. 进入持续显示的循环,保持文本显示在屏幕上
 
 
播放器加载失败: 未检测到Flash Player,请到安装
xszw

 
 
 
3、任务2:网络功能使用(必做任务)
首先我们为开发板配置一下网络功能所需的信息。
在根目录下新建一个文本文档,命名为settings,保存后将后缀改为.toml(结果如下图)。
想要编辑的话以文本格式打开直接编辑或者有VS Code的话也可以直接编辑。

 

想实现Adafruit ESP32-S3 TFT Feather的网络功能也十分简单,参考手册P143(如下图所示)就行,但与手册方法不同的是,我们的配置信息存在了settings.toml文件中。
手册P143截图

我们先连接WiFi

settings.toml中,配置你想要连接的WiFi的ID和密码。

PS:只支持2.4G频段,手机开个热点就行

具体如下:

  • WIFI_SSID = "HOMO"
  • WIFI_PASSWORD = "1145141919810"

配置完成后,直接在code.py中使用示例代码即可

  • # SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries
  • #
  • # SPDX-License-Identifier: MIT
  • import os
  • import wifi
  • print("ESP32-S3 Station Test")
  • print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
  • print("Available WiFi networks:")
  • for network in wifi.radio.start_scanning_networks():
  • print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
  • network.rssi, network.channel))
  • wifi.radio.stop_scanning_networks()
  • print(f"Connecting to {os.getenv('WIFI_SSID')}")
  • wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
  • print(f"Connected to {os.getenv('WIFI_SSID')}")
  • print(f"My IP address: {wifi.radio.ipv4_address}")
连接WiFi
 
播放器加载失败: 未检测到Flash Player,请到安装
wifi

 
 

再创建热点

settings.toml中,配置开发板AP的ID和密码。

具体如下:

  • AP_SSID = "HOMO"
  • AP_PASSWORD = "1145141919810"

以下代码基于自带的库

 
  • #创建热点
  • import os
  • import wifi
  • import adafruit_requests
  • print("ESP32-S3 Access Point Test")
  • print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
  • wifi.radio.start_ap(os.getenv("AP_SSID"), os.getenv("AP_PASSWORD"))
  • #显示网络信息
  • print(f"My SSID: {"HOMO"}")
  • print(f"My PASSWORD: {"1145141919810"}")
  • while True:
  • pass

创建热点

 

播放器加载失败: 未检测到Flash Player,请到安装
ap

 

 

 

 
4、任务3:控制WS2812B(必做任务)
要控制WS2812B,只需在lib中添加外部库neopixel.py(详见other-lib
再再参考一下示例代码(笑
稍微改一下,用数组存储颜色信息
按钮直接用杜邦线代替,反正原理是一样的。同时添加软件消抖,效果不错
  • import time
  • import board
  • import digitalio
  • import neopixel
  • button_pin = board.D5
  • Color_Num = 0
  • # 彩虹数组
  • RAINBOW_COLORS = [
  • (255, 0, 0), # 红
  • (255, 165, 0), # 橙
  • (255, 255, 0), # 黄
  • (0, 255, 0), # 绿
  • (0, 0, 255), # 蓝
  • (75, 0, 130), # 靛蓝
  • (238, 130, 238) # 紫
  • ]
  • #初始为红
  • Color = RAINBOW_COLORS[0]
  • button = digitalio.DigitalInOut(button_pin)
  • button.direction = digitalio.Direction.INPUT
  • button.pull = digitalio.Pull.UP
  • debounce_delay = 0.1 # 消抖延迟,单位为秒
  • button_pressed = False
  • pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
  • pixel.brightness = 0.3
  • while True:
  • if not button.value and not button_pressed: # 按键被按下且之前未被按下
  • button_pressed = True
  • time.sleep(debounce_delay) # 延迟一段时间进行消抖
  • if not button.value: # 确认按键仍然被按下
  • Color = RAINBOW_COLORS[Color_Num]
  • # 设置led颜色
  • pixel.fill(Color)
  • Color_Num += 1
  • if Color_Num == 7:
  • Color_Num -= 7
  • elif button.value: # 按键未被按下
  • button_pressed = False

 

播放器加载失败: 未检测到Flash Player,请到安装
neo(1)

 

七彩循环:
播放器加载失败: 未检测到Flash Player,请到安装
xunhuan

 
 
 
5、任务4.1:日历&时钟(选做任务)

 

导入所需的库和模块,包括wifi、os、ssl、socketpool、adafruit_requests。

连接wifi,发送HTTP请求获取无锡的天气信息的JSON数据。

解析JSON数据,提取需要显示的天气信息,包括城市信息、当前时间、空气质量、温度范围、湿度、PM2.5等。

显示,结束(

 
  • ##连接wifi --------------------------------------------------------------------------------------
  • # SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries
  • #
  • # SPDX-License-Identifier: MIT
  • import os
  • import wifi
  • print("ESP32-S3 Station Test")
  • print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
  • print("Available WiFi networks:")
  • for network in wifi.radio.start_scanning_networks():
  • print("\t%s\t\tRSSI: %d\tChannel: %d" % (str(network.ssid, "utf-8"),
  • network.rssi, network.channel))
  • wifi.radio.stop_scanning_networks()
  • print(f"Connecting to {os.getenv('WIFI_SSID')}")
  • wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
  • print(f"Connected to {os.getenv('WIFI_SSID')}")
  • print(f"My IP address: {wifi.radio.ipv4_address}")
  • ## END连接wifi --------------------------------------------------------------------------------------
  • ## 访问网络 --------------------------------------------------------------------------------------
  • import ssl
  • import socketpool
  • import adafruit_requests
  • # 请求获取JSON
  • ## api http://t.weather.sojson.com/api/weather/city/101280601
  • JSON_TIME_URL = "http://t.weather.itboy.net/api/weather/city/101190201"
  • pool = socketpool.SocketPool(wifi.radio)
  • requests = adafruit_requests.Session(pool, ssl.create_default_context())
  • ## END访问网络 --------------------------------------------------------------------------------------
  • ## 读取解析Json ---------------------------------------------------------------------------------------
  • print(f"Fetching and parsing json from {JSON_TIME_URL}")
  • response = requests.get(JSON_TIME_URL)
  • print("-" * 40)
  • ## print(f"Time: {response.json()['sysTime2']}")
  • print("-" * 40)
  • print(response.json())
  • weather = response.json()
  • cityInfo = weather['cityInfo']
  • city_weather = weather['data']
  • forecast = city_weather['forecast']
  • dis_str = ""+cityInfo['parent']+' '+cityInfo['city'] +' '+weather['time'][:11] + forecast[0]['week']
  • dis_str += '\n 空气质量:'+city_weather['quality'] +" " +forecast[0]['type']
  • dis_str += "\n 最"+forecast[0]['high']+' 最'+forecast[0]['low']
  • dis_str += "\n 湿度: "+city_weather['shidu']
  • dis_str += "\n PM2.5:"+str(city_weather['pm25']) +' PM10:'+str(city_weather['pm10'])
  • dis_str += "\n 注意!! "+forecast[0]['notice']
  • ## END读取解析Json ---------------------------------------------------------------------------------------
  • ## 显示天气信息 ---------------------------------------------------
  • 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.9
  • board.DISPLAY.rotation = 0
  • font = bitmap_font.load_font("wenquanyi_10pt.pcf")
  • ## 字体颜色
  • color = 0x9499CA
  • text_group = displayio.Group()
  • text_area = label.Label(font, text=dis_str, color=color)
  • text_area.x = 0
  • text_area.y = 10
  • text_area.line_spacing = 0.8
  • text_area.scale = 1
  • text_group.append(text_area)
  • display.show(text_group)
  • while True:
  • pass
  • ## END显示天气信息 ---------------------------------------------------
 
 
  1. 使用WiFi模块连接到无线网络,SocketPool和Requests库访问API,获取天气预报的JSON数据
  2. 然后,解析JSON数据并提取所需的天气信息
  3. 使用Displayio库在TFT显示屏上显示天气信息

 

播放器加载失败: 未检测到Flash Player,请到安装
rili

 

 

 
6、任务4.2:WS2812B效果控制(选做任务)
先瞅一眼任务要求:
完成一个Neopixel(12灯珠或以上)控制器,通过按键和屏幕切换展示效果
凑巧上学期末整了块DFRobot 8*8的RGB灯板👇

硬件有了那直接开整

控制部分直接参考上面neo的程序就行

循环切换7个颜色

屏幕显示颜色只要在循环加个判断就行

 
  • #以下是一起动捏
  • import board
  • import digitalio
  • import time
  • import neopixel
  • led_pin = board.D13
  • button_pin = board.D5
  • # 设置LED数量和引脚
  • NUM_LEDS = 64
  • LED_PIN = board.D12
  • Color_Num = 0
  • # 初始化Neopixel对象
  • pixels = neopixel.NeoPixel(LED_PIN, NUM_LEDS, brightness=0.2, auto_write=False)
  • # 彩虹数组
  • RAINBOW_COLORS = [
  • (255, 0, 0), # 红
  • (255, 165, 0), # 橙
  • (255, 255, 0), # 黄
  • (0, 255, 0), # 绿
  • (0, 0, 255), # 蓝
  • (75, 0, 130), # 靛蓝
  • (238, 130, 238) # 紫
  • ]
  • #初始为红
  • Color = RAINBOW_COLORS[0]
  • led = digitalio.DigitalInOut(led_pin)
  • led.direction = digitalio.Direction.OUTPUT
  • button = digitalio.DigitalInOut(button_pin)
  • button.direction = digitalio.Direction.INPUT
  • button.pull = digitalio.Pull.UP
  • debounce_delay = 0.1 # 消抖延迟,单位为秒
  • button_pressed = False
  • while True:
  • if not button.value and not button_pressed: # 按键被按下且之前未被按下
  • button_pressed = True
  • time.sleep(debounce_delay) # 延迟一段时间进行消抖
  • if not button.value: # 确认按键仍然被按下
  • led.value = not led.value
  • # 在每个LED上设置彩虹颜色
  • for i in range(NUM_LEDS):
  • Color = RAINBOW_COLORS[Color_Num]
  • pixels[i] = Color
  • pixels.show()
  • time.sleep(0.001)
  • Color_Num += 1
  • if Color_Num == 7:
  • Color_Num -= 7
  • elif button.value: # 按键未被按下
  • button_pressed = False

 

  1. 通过设置LED的数量和引脚,初始化Neopixel,定义彩虹颜色数组

  2. DigitalInOut来控制LED和按钮的引脚。将LED引脚设置为输出模式,按钮引脚设置为输入模式,启用上拉电阻

  3. 使用time模块来进行延迟和消抖操作。在按键按下时延迟一段时间进行消抖,确保只有有效的按键触发

  4. 循环检测按钮状态。当按钮被按下时,切换LED的状态并设置Neopixel的像素颜色为彩虹颜色。每次按下按钮,彩虹颜色的索引加一,当达到最大索引时重新开始

 

播放器加载失败: 未检测到Flash Player,请到安装
8864

 

 

 
7、任务5:通过网络控制WS2812B(可选任务,非必做)
翻手册翻手册翻手册
官方手册P148
链接直达Adafruit IO:链接
说实话,我还是第一次接触mqtt,但跟着例程走一遍也是没啥问题的
(后半段有所修改)
 
  • import time
  • import ssl
  • import os
  • from random import randint
  • import microcontroller
  • import socketpool
  • import wifi
  • import board
  • import neopixel
  • import displayio
  • import terminalio
  • import adafruit_minimqtt.adafruit_minimqtt as MQTT
  • from adafruit_io.adafruit_io import IO_MQTT
  • from adafruit_display_text import bitmap_label, label
  • # WiFi
  • try:
  • print("Connecting to %s" % os.getenv("WIFI_SSID"))
  • wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
  • print("Connected to %s!" % os.getenv("WIFI_SSID"))
  • # Wi-Fi connectivity fails with error messages, not specific errors, so this except is broad.
  • except Exception as e: # pylint: disable=broad-except
  • print("Failed to connect to WiFi. Error:", e, "\nBoard will hard reset in 30 seconds.")
  • time.sleep(30)
  • microcontroller.reset()
  • # Initialise NeoPixel
  • pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)
  • # Set up TFT display
  • display = board.DISPLAY
  • board.DISPLAY.brightness = 0.35
  • board.DISPLAY.rotation = 0
  • group = displayio.Group()
  • weather_color=0x00FF00
  • neopixel_area = label.Label(terminalio.FONT, text="NeoPixel", color=weather_color)
  • neopixel_area.x = 2
  • neopixel_area.y = 30
  • neopixel_area.line_spacing = 0.8
  • neopixel_area.scale = 1
  • main_group = displayio.Group()
  • main_group.append(group)
  • main_group.append(neopixel_area)
  • # Show the main group on the display
  • display.show(main_group)
  • # Define callback functions which will be called when certain events happen.
  • def connected(client):
  • print("Connected to Adafruit IO! Listening for NeoPixel changes...")
  • # Subscribe to Adafruit IO feed called "neopixel"
  • client.subscribe("neopixel")
  • def message(client, feed_id, payload): # pylint: disable=unused-argument
  • print("Feed {0} received new value: {1}".format(feed_id, payload))
  • #neopixel_area.text = "Feed {0} received new value: {1}".format(feed_id, payload)
  • if feed_id == "neopixel":
  • pixel.fill(int(payload[1:], 16))
  • # Create a socket pool
  • pool = socketpool.SocketPool(wifi.radio)
  • # Initialize a new MQTT Client object
  • mqtt_client = MQTT.MQTT(
  • broker="io.adafruit.com",
  • username=os.getenv("AIO_USERNAME"),
  • password=os.getenv("AIO_KEY"),
  • socket_pool=pool,
  • ssl_context=ssl.create_default_context(),
  • )
  • # Initialize Adafruit IO MQTT "helper"
  • io = IO_MQTT(mqtt_client)
  • # Set up the callback methods above
  • io.on_connect = connected
  • io.on_message = message
  • timestamp = 0
  • while True:
  • try:
  • # 如果Adafruit IO未连接...
  • if not io.is_connected:
  • # 连接到MQTT代理
  • print("Connecting to Adafruit IO...")
  • io.connect()
  • # 显示颜色信息
  • neopixel_area.text = "Color: #{:02X}{:02X}{:02X}".format(*pixel[0]) # 更新文本显示
  • # 显示更新后的屏幕
  • display.refresh()
  • # 显示延迟
  • # time.sleep(0.5)
  • # 显式处理消息循环
  • io.loop()
  • # 处理可能的失败
  • except Exception as e: # pylint: disable=broad-except
  • print("Failed to get or send data, or connect. Error:", e,
  • "\nBoard will hard reset in 30 seconds.")
  • time.sleep(30)
  • microcontroller.reset()

 

  1. 使用WiFi模块连接到无线网络,并在TFT显示屏上显示连接状态
  2. 使用MQTT协议连接到Adafruit IO,并订阅"neopixel"的feed
  3. 当接收到"neopixel" feed的新值时,更新NeoPixel的颜色,并在TFT显示屏上显示颜色信息

 

播放器加载失败: 未检测到Flash Player,请到安装
wlanneo

 

 

 

对本活动的心得体会

 

我觉得本次活动对我来说十分有意义,因为开发板+1因为新接触了一种语法,并且增加了自己的ddl

 

任务总体难度适中,且可查的中文资料较少,可以培养rtfm的好习惯

 

建议下次活动直接来块小Linux开发板

 

(完)2023/10/14

 

 

最新回复

用bitmap库将点阵字体加载到displayio中,可以使用bdf、pcf等格式,是比较方便   详情 回复 发表于 2023-10-15 08:04
点赞 关注
 
 

回复
举报

7069

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

用bitmap库将点阵字体加载到displayio中,可以使用bdf、pcf等格式,是比较方便

 
 
 

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

猜你喜欢
随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
报名赢【小米双肩包、contigo水杯】 | TI MSPM0 系列 MCU 再添新成员
了解TI 前沿新品——高性能与高性价比的优秀组合 MSPM0G351x / MSPM0L111x,4月24日(周四)上午10:00直播~

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表