999 views|1 replies

15

Posts

5

Resources
The OP
 

[Digi-Key Follow me Issue 2] Play with Adafruit ESP32-S3 TFT Feather (Full Process Comprehensive Post) [Copy link]

 This post was last edited by QuaX_Chow on 2023-10-14 16:18

2023.8.19 (start construction, save a draft first)


2023.10.6

This time I bring you a quick tutorial for the second phase of Follow Me (I have been waiting for a long time

This activity can be basically checked by referring to the manual

Thanks to the organizers eeworld and Digi-Key Electronics for their support, and thanks to all the great forum friends who posted in advance.

Content 1: 3-5 minutes short video

Content 2: Main article

Content 3: The data package compiled by myself (including sample code, task code, official information, and some external libraries. If you can't open it, it means it has not been reviewed yet. You can use the old data package first)


1、Quick Start

First, let's quickly build the development environment we need. This time we use the officially recommended Mu Editor to write CircuitPython.

Connect the development board to the computer using a data cable and press the reset button twice (as shown below)

When the Neo light turns green and the red LED light flashes, the computer will show that a new disk is connected. Drag adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.3.uf2 from the data package-other into the root directory of the new disk to quickly add the circuitpython support package for the development board.
Or go to the official website to download directly, download link: circuitpy package
After the file is moved, the development board information and UID will be displayed on the development board screen (as shown below) and a new USB flash drive will appear.

PS: CircuitPython actually has a Chinese package, but what is displayed on the screen is pinyin. (Adafruit-circuitpython-adafruit_feather_esp32s3_tft-zh_Latn_pinyin-8.2.3.uf2 is shown below)

Then install Mu Editor ( download address ) on your computer . Of course, other programs like thonny are also acceptable.
If we want to edit the code, just open the code.py in the root directory (as shown below) and edit it.

First, we will run two test programs. The programs can be found in the manual or in the sample code of the corresponding library.

The first one is a lighting program that can be used directly. Just cv it into code.py.
If the download is successful, you can see the onboard LED flashing.
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)

Test code ①


The second is the image display code, which can be achieved by adding the imageload library in other-lib in the data package .

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

Test code ②

How to add an external library : open the compressed package of the external library and copy the corresponding folder into the lib folder in the root directory of the development board USB disk (such as the imageload library)

This code needs to create an image folder in the root directory and paste the following converted image in the folder↓

Test image
ys

2. Task 1: Control the screen to display Chinese (mandatory task)
If we want to control the screen to display Chinese, we need to use the bitmap library to load the dot matrix font into displayio. We can use bdf, pcf and other formats. It is very simple.
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. Initialize the display module and set the brightness and rotation angle
  2. Load the required font files
  3. Create group and label objects to display text, and set the text content, color, position, and scale
  4. Add a text label object to the group that displays the text
  5. Use display.show to add the group that displays the text to the display for display
  6. Enter a continuous display loop to keep the text displayed on the screen
xszw

3. Task 2: Use of network functions (mandatory task)
First, we configure the information required for the network function for the development board.
Create a new text document in the root directory, name it settings , save it and change the suffix to .toml (the result is as shown below).
If you want to edit it, open it in text format and edit it directly, or if you have VS Code, you can edit it directly.

It is also very simple to realize the network function of Adafruit ESP32-S3 TFT Feather . Just refer to P143 of the manual (as shown below). However, unlike the manual method, our configuration information is stored in the settings.toml file.
Screenshot from Manual P143

Let’s connect to WiFi first

In settings.toml , configure the ID and password of the WiFi you want to connect to.

PS: Only supports 2.4G frequency band, just open a hotspot on your phone

details as follows:

WIFI_SSID = "HOMO"
WIFI_PASSWORD = "1145141919810"

After the configuration is complete, just use the sample code in 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}")
Connect to WiFi
wifi

Recreate hotspot

In settings.toml , configure the ID and password of the development board AP.

details as follows:

AP_SSID = "HOMO"
AP_PASSWORD = "1145141919810"

The following code is based on the built-in library

#创建热点
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

Create Hotspot

ap

4. Task 3: Control WS2812B (required task)
To control WS2812B, just add the external library neopixel.py in lib (see other-lib for details )
Let’s refer to the sample code again (laughing)
Slightly change it to use an array to store color information
The button is directly replaced by Dupont wire, anyway, the principle is the same. At the same time, add software to eliminate jitter, the effect is good
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

neo(1)


Colorful cycle:
xunhuan

5. Task 4.1: Calendar & Clock (optional task)

Import the required libraries and modules, including wifi, os, ssl, socketpool, adafruit_requests.

Connect to wifi and send HTTP request to obtain JSON data of Wuxi's weather information.

Parse JSON data and extract weather information to be displayed, including city information, current time, air quality, temperature range, humidity, PM2.5, etc.

Display, end (


##连接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. Use the WiFi module to connect to the wireless network, the SocketPool and Requests libraries to access the API, and obtain the JSON data of the weather forecast
  2. Then, parse the JSON data and extract the required weather information
  3. Use the Displayio library to display weather information on the TFT display

rili

6. Task 4.2: WS2812B effect control (optional task)
Let’s take a look at the task requirements first:
Complete a Neopixel (12 or more LEDs) controller and display the effects by pressing buttons and switching the screen
By chance , I got a DFRobot 8*8 RGB light board at the end of last semester

If you have the hardware, you can start

For the control part, just refer to the neo program above.

Cycle through 7 colors

To display the color on the screen, just add a judgment in the loop

#以下是一起动捏
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. Initialize Neopixel by setting the number and pins of LEDs and define the rainbow color array

  2. DigitalInOut to control the LED and button pins. Set the LED pin to output mode, the button pin to input mode, and enable the pull-up resistor

  3. Use the time module to perform delay and debounce operations. Delay a period of time to debounce when a key is pressed to ensure that only valid keys are triggered

  4. Loop through the button states. When the button is pressed, toggle the LED state and set the Neopixel pixel color to a rainbow color. Each time the button is pressed, the rainbow color index increases by one, and starts over when the maximum index is reached.

8864

7. Task 5: Control WS2812B via the network (optional task, not required)
Flip the manual Flip the manual Flip the manual
Official Manual P148
Direct link to Adafruit IO: Link
To be honest, this is my first time to use MQTT, but it's no problem to follow the example
(The second half has been modified)
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. Use the WiFi module to connect to a wireless network and display the connection status on the TFT display
  2. Connect to Adafruit IO using MQTT protocol and subscribe to the "neopixel" feed
  3. When a new value from the "neopixel" feed is received, the color of the NeoPixel is updated and the color information is displayed on the TFT display.

wlanneo

My experience with this activity

I think this event is very meaningful to me, because the development board +1 because I have come into contact with a new syntax and added my own ddl

The overall difficulty of the task is moderate, and there is less Chinese information available, which can help cultivate good habits of rtfm

It is recommended that you get a small Linux development board for the next event.

(END)2023/10/14

This post is from DigiKey Technology Zone

Latest reply

Use the bitmap library to load the dot matrix font into displayio. You can use bdf, pcf and other formats, which is more convenient.   Details Published on 2023-10-15 08:04
 
 

6552

Posts

0

Resources
2
 

Use the bitmap library to load the dot matrix font into displayio. You can use bdf, pcf and other formats, which is more convenient.

This post is from DigiKey Technology Zone
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list