【得捷电子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支持包。
待文件移动完成后开发板屏幕上即会显示开发板信息和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
-
-
- 初始化显示屏模块,并设置亮度和旋转角度
- 加载所需的字体文件
- 创建显示文本的组和标签对象,并设置文本内容、颜色、位置和缩放
- 将文本标签对象添加到显示文本的组中
- 使用display.show将显示文本的组添加到显示屏上进行显示
- 进入持续显示的循环,保持文本显示在屏幕上
播放器加载失败: 未检测到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中使用示例代码即可
-
-
-
-
- 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]
-
- 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模块连接到无线网络,SocketPool和Requests库访问API,获取天气预报的JSON数据
- 然后,解析JSON数据并提取所需的天气信息
- 使用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
-
-
- NUM_LEDS = 64
- LED_PIN = board.D12
- Color_Num = 0
-
-
-
- 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
-
- 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
-
-
-
通过设置LED的数量和引脚,初始化Neopixel,定义彩虹颜色数组
-
DigitalInOut来控制LED和按钮的引脚。将LED引脚设置为输出模式,按钮引脚设置为输入模式,启用上拉电阻
-
使用time模块来进行延迟和消抖操作。在按键按下时延迟一段时间进行消抖,确保只有有效的按键触发
-
循环检测按钮状态。当按钮被按下时,切换LED的状态并设置Neopixel的像素颜色为彩虹颜色。每次按下按钮,彩虹颜色的索引加一,当达到最大索引时重新开始
播放器加载失败: 未检测到Flash Player,请到 安装
8864
7、任务5:通过网络控制WS2812B(可选任务,非必做)
翻手册翻手册翻手册
官方手册P148
说实话,我还是第一次接触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
-
-
- 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"))
-
- except Exception as e:
- print("Failed to connect to WiFi. Error:", e, "\nBoard will hard reset in 30 seconds.")
- time.sleep(30)
- microcontroller.reset()
-
-
- pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.3)
-
-
- 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)
-
-
- display.show(main_group)
-
-
- def connected(client):
- print("Connected to Adafruit IO! Listening for NeoPixel changes...")
-
- client.subscribe("neopixel")
-
-
- def message(client, feed_id, payload):
- print("Feed {0} received new value: {1}".format(feed_id, payload))
-
- if feed_id == "neopixel":
- pixel.fill(int(payload[1:], 16))
-
-
-
- pool = socketpool.SocketPool(wifi.radio)
-
-
- 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(),
- )
-
-
- io = IO_MQTT(mqtt_client)
-
-
- io.on_connect = connected
- io.on_message = message
-
- timestamp = 0
- while True:
- try:
-
- if not io.is_connected:
-
- print("Connecting to Adafruit IO...")
- io.connect()
-
-
-
- neopixel_area.text = "Color: #{:02X}{:02X}{:02X}".format(*pixel[0])
-
-
- display.refresh()
-
-
-
-
-
- io.loop()
-
-
- except Exception as e:
- print("Failed to get or send data, or connect. Error:", e,
- "\nBoard will hard reset in 30 seconds.")
- time.sleep(30)
- microcontroller.reset()
- 使用WiFi模块连接到无线网络,并在TFT显示屏上显示连接状态
- 使用MQTT协议连接到Adafruit IO,并订阅"neopixel"的feed
- 当接收到"neopixel" feed的新值时,更新NeoPixel的颜色,并在TFT显示屏上显示颜色信息
播放器加载失败: 未检测到Flash Player,请到 安装
wlanneo
对本活动的心得体会
我觉得本次活动对我来说十分有意义,因为开发板+1因为新接触了一种语法,并且增加了自己的ddl
任务总体难度适中,且可查的中文资料较少,可以培养rtfm的好习惯
建议下次活动直接来块小Linux开发板
(完)2023/10/14
|