[作品提交] 【得捷电子Follow me第2期】+ 汇总提交帖:玩转Adafruit ESP32-S3 TFT Feather

MoJing   2023-10-5 22:56 楼主

第一部分

演示视频

视频链接:http://training.eeworld.com.cn/video/37925


第二部分

本项目包括以下内容:

任务1:控制屏幕显示中文
由于CircuitPython的字库中没有中文,因此需要自己加入中文的Bitmap字库。然后直接使用adafruit_display_text这个库来显示文字就可以了。

任务2:网络功能使用
ESP32本身内置Wifi模块,简单调试就可以连接网络。连接网络后获取一下当前时间来测试效果。

任务3:控制WS2812B
WS2812B市板载的一颗LED灯,可以使用CircuitPython来对该LED进行控制。我使用了板子上的几个可触控的触点来进行颜色的控制。

任务4-分任务1:日历&时钟
在连接网络后,通过调用接口来获取当前的时间和天气信息,并将处理好的数据显示在屏幕上,实时刷新。

任务5:通过网络控制WS2812B
这里我写了一个网页,可以通过网页来实时控制板载的WS2812B的开关和所显示的颜色。

 

本次项目采用的开发板型号为Adafruit ESP32-S3 TFT Feather,是由开源硬件行业知名公司Adafruit出品的一款富有特色的开源硬件,开发板使用乐鑫ESP32-S3芯片,支持WiFi和蓝牙功能,自带高清TFT彩色显示屏。非常适合物联网应用开发等开发环境。

其他传感器使用了来自Microchip的温度传感器MCP9808,可以实现最大精度±0.5℃的温度检测,且配备了可编程寄存器,为温度传感应用提供灵活性。环境光传感器为LITE-ON的LTR-329,该传感器将光强度转换为直接I2C接口可读取的数字输出信号。它在0.01 lux到64k lux 的广泛动态范围内提供线性响应,并非常适合高环境亮度下的应用。


任务1:控制屏幕显示中文

详细贴:【得捷电子Follow me第2期】 任务1:控制屏幕显示中文 http://bbs.eeworld.com.cn/thread-1253011-1-1.html

Bitmap字库
由于CircuitPython的字库中没有中文,因此需要自己加入中文的Bitmap字库。在网上找了文泉驿的字体【下载地址】,建议下载pcf格式的,文件小一点。

显示文字
接下来就很简单了,去文档翻翻找点样例跑一跑就行,这里主要是用到了adafruit_display_text这个库,照样找文档,官方文档里给了一个label可以用来显示文字,还有wrap_text_to_lines()和wrap_text_to_pixels()来进行字符串的分行。

直接简单写个显示的代码:

import board
import displayio
from adafruit_display_text import label, wrap_text_to_pixels
from adafruit_bitmap_font import bitmap_font
str2display="任务1:控制屏幕显示中文(必做任务)\n\n1.完成屏幕的控制,并且能显示中文 \n\n2.搭配器件:Adafruit ESP32-S3 TFT Feather"
display = board.DISPLAY
board.DISPLAY.brightness = 0.5
font = bitmap_font.load_font("wenquanyi_13px.pcf")
color = 0xFFFFFF
background_color = 0x555555
text_group = displayio.Group()
text_area = label.Label(font, text="\n".join(wrap_text_to_pixels(str2display,18)), color=color, background_color=background_color)
text_area.x = 2
text_area.y = 10
text_area.line_spacing = 0.7
text_area.scale = 1
text_group.append(text_area)
display.show(text_group)
while True:
pass

IMG_3631.JPG  


任务2:网络功能使用

详细贴:【得捷电子Follow me第2期】 任务2:网络功能使用 http://bbs.eeworld.com.cn/thread-1253014-1-1.html

wifi连接
首先连接wifi,按照官方的建议,把ssid和密码保存在secrets.py中,这样避免在分享代码的时候泄露隐私。

# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it
secrets = {
'ssid' : 'xxxx',
'password' : 'xxxxx',
'timezone' : "Asia/Shanghai"
}

然后在代码中连接该wifi就可以了:

import wifi
wifi.radio.connect(secrets["ssid"], secrets["password"])
print("Connected to {}!".format(secrets["ssid"]))
print("IP:", wifi.radio.ipv4_address)

网络测试
简单测试一下网络 

  1. 官方测试接口http://wifitest.adafruit.com/testwifi/index.html
    使用的是adafruit_requests这个库来进行网络请求

 

import ssl
import socketpool
import adafruit_requests
import time
# 请求URLs
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
print("ESP32-S2 WebClient Test")
print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
print(f"Fetching text from {TEXT_URL}")
response = requests.get(TEXT_URL)
print("-" * 40)
print(response.text)
print("-" * 40)

8c143a8147b21058b6016f47bfae3409.png  

  1. 联网获取当前时间
    请求http://quan.suning.com/getSysTime.do 这个API

 

import ssl
import socketpool
import adafruit_requests
import time
# 请求URLs
JSON_TIME_URL = "http://quan.suning.com/getSysTime.do"
print("ESP32-S2 WebClient Test")
print(f"My MAC address: {[hex(i) for i in wifi.radio.mac_address]}")
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
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)


任务3:控制WS2812B

详细贴:【得捷电子Follow me第2期】 任务3:控制WS2812B http://bbs.eeworld.com.cn/thread-1253016-1-1.html

Adafruit ESP32-S3 TFT Feather 板载了一颗 NeoPixel LED - 这种可寻址 RGB NeoPixel LED 在板上标记为 Neo,既可用作状态 LED(在 CircuitPython 和引导加载程序中),也可通过代码进行控制。它在 CircuitPython 中为board.NEOPIXEL ,在 Arduino 中为 PIN_NEOPIXEL。

设置LED颜色
下面我们使用CircuitPython来对该LED进行控制:

import board
import neopixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.3
grape = (190, 75, 219)
teal = (56, 217, 169)
while True:
    pixel.fill(grape)

在上面的代码中,我们将板载的LED设置成了紫色

2d87380458a6c18246126a2acb832fde.png  

控制LED颜色变化
Adafruit ESP32-S3 TFT Feather 提供了几个可触控的触点,在文档里都有列出来,因此我们可以很方便的通过这些触电来进行触摸操作,再由此控制LED色彩的变化,代码如下:

import time
import board
import neopixel
import touchio

pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)

pixel.brightness = 0.3

touch_A1 = touchio.TouchIn(board.D5)  
touch_A2 = touchio.TouchIn(board.D10) 

grape = (190, 75, 219) 
teal = (56, 217, 169)


while True:
    if touch_A1.value:
        pixel.fill(grape)  
    if touch_A2.value:
        pixel.fill(teal)
    time.sleep(0.05)

这时,我们就可以通过触摸板子上面的一排触点来改变LED灯的颜色了。

0389e16388db1d3d2b73f35de242c7e9.gif 点击上图查看Gif动图  


任务4-分任务1:日历&时钟

详细贴:【得捷电子Follow me第2期】 任务4-分任务1:日历&时钟 http://bbs.eeworld.com.cn/thread-1253089-1-1.html

1. 通过wifi联网
这个在任务2中就以及实现了,这里简单修改一下,如果连接失败就三秒后重试:

# 连接wifi
while not wifi.radio.ipv4_address:
    try:
        wifi.radio.connect(secrets["ssid"], secrets["password"])
    except ConnectionError as e:
        print("Connection Error:", e)
        print("Retrying in 3 seconds")
    time.sleep(3)
    gc.collect()
print("Connected!\n")

2. 调用API获取时间、天气等信息
获取当前时间是调用的苏宁的免费API,获取天气的API是阿里云市场找的免费试用,配置好appcode直接调用即可(调用的是24小时天气预报接口,想要设置预报几小时后的天气只要取对应数据就行):

# 获取数据
def get_data():
    try:
        response = requests.get(TIME_URL)
    except ConnectionError as e:
        print("Connection Error:", e)
        print("Retrying in 60 seconds")
    #text = response.json()['sysTime2'][:10] + "\n" + response.json()['sysTime2'][11:]
    time_text = response.json()['sysTime2'][:-3]
    try:
        response = requests.get(url=WEATHER_URL+"?areaCode="+params["areaCode"], headers=headers)
    except ConnectionError as e:
        print("Connection Error:", e)
        print("Retrying in 60 seconds")
    print(response.json()['showapi_res_body']['hourList'][0]['weather'])
    weather_text = (response.json()['showapi_res_body']['hourList'][0]['weather'] + " "
                    + response.json()['showapi_res_body']['hourList'][0]['temperature'] + " °C"
                    + "\n风: " + response.json()['showapi_res_body']['hourList'][0]['wind_direction']
                    + " " + response.json()['showapi_res_body']['hourList'][0]['wind_power'].split(" ")[0])

    print_text = time_text + "\n" + weather_text

    return print_text

3. 在屏幕上显示信息
这里要注意天气信息中有中文的显示,因此还是用任务1的方法去实现一下,将所有信息显示在屏幕上,每分钟刷新一次就可以了:

# 查询数据并刷新屏幕
def refresh_screen(print_text):
    text_area = label.Label(font, text=print_text, scale=2)
    text_area.x = 10
    text_area.y = 10
    board.DISPLAY.show(text_area)

while True:
    info = get_data()
    refresh_screen(info)
    time.sleep(60)
    pass

最后显示的效果就是一个可以实时更新的万年历时钟+天气预报啦。

6c46cee75948a9f1f2ed787011918bbc.png  


任务5:通过网络控制WS2812B

详细贴:【得捷电子Follow me第2期】 任务5:通过网络控制WS2812B http://bbs.eeworld.com.cn/thread-1253218-1-1.html

控制平台设计
这部分和硬件关系不大就不详细介绍了,主要就是用SpringBoot写个简单的Redis服务然后前端调用就行,每个板子的LED可以对应一个token,这样也可以实现分别控制不同的板子

远程控制WS2812B
使用上面写好的控制平台直接将LED的状态同步过来就可以了。
配置信息
将需要用到的配置信息存放在secrets.py中。

# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it

secrets = {
    'ssid' : 'xxxx',
    'password' : 'xxxxxxxx',
    'timezone' : "Asia/Shanghai",
    'led_url' : "http://xxxxxxxxxxxxxxxxxxxxxxxxxx"
    }

连接wifi

# 连接wifi
while not wifi.radio.ipv4_address:
    try:
        wifi.radio.connect(secrets["ssid"], secrets["password"])
    except ConnectionError as e:
        print("Connection Error:", e)
        print("Retrying in 3 seconds")
    time.sleep(3)
    gc.collect()
print("Connected!\n")

同步LED状态
通过写好的接口获取LED状态并同步,获取到的状态信息有status表示LED的开关状态,r、g、b分别代表RGB的色值。

# 请求URLs
RGB_URL = secrets['led_url']

pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())

current_rgb = [0,0,0]
# 获取数据
def get_data():
    try:
        response = requests.get(RGB_URL)
    except ConnectionError as e:
        print("Connection Error:", e)
        print("Retrying in 60 seconds")

    global current_rgb
    if(response.json()['status']):
        current_rgb[0] = response.json()['r']
        current_rgb[1] = response.json()['g']
        current_rgb[2] = response.json()['b']
    else:
        current_rgb = [0, 0, 0]
    print(current_rgb)
    return current_rgb

屏幕显示数据
将获取到的LED状态同步显示在屏幕上。

display = board.DISPLAY
board.DISPLAY.brightness = 0.5

# 刷新屏幕
def refresh_screen():
    print_text = "RGB("+str(current_rgb[0])+" ,"+str(current_rgb[1])+" ,"+str(current_rgb[2])+")"
    text_area = label.Label(font, text=print_text, scale=2)
    text_area.x = 10
    text_area.y = 10
    board.DISPLAY.show(text_area)

a75e1a545b7c6c33202d854076b5422e.gif 点击上图查看Gif动图  


总结

通过本次的Follow me活动,我对于物联网设备的设计有了更深入的了解,在过程中我也对Adafruit ESP32-S3 TFT Feather这款板子的使用更加熟悉,在DigiKey购买过元器件的体验非常棒,使用CircuitPython来进行开发也非常好上手。最后非常感谢得捷电子和EEWORLD给我这次学习的机会!

任务贴汇总:

【得捷电子Follow me第2期】 任务1:控制屏幕显示中文 http://bbs.eeworld.com.cn/thread-1253011-1-1.html

【得捷电子Follow me第2期】 任务2:网络功能使用 http://bbs.eeworld.com.cn/thread-1253014-1-1.html

【得捷电子Follow me第2期】 任务3:控制WS2812B http://bbs.eeworld.com.cn/thread-1253016-1-1.html

【得捷电子Follow me第2期】 任务4-分任务1:日历&时钟 http://bbs.eeworld.com.cn/thread-1253089-1-1.html

【得捷电子Follow me第2期】 任务5:通过网络控制WS2812B http://bbs.eeworld.com.cn/thread-1253218-1-1.html

 


第三部分

可编译下载的代码:http://download.eeworld.com.cn/detail/eew_eFqDEj/629355

本帖最后由 MoJing 于 2023-10-7 10:28 编辑

回复评论 (1)

点赞,看着效果非常好  

在爱好的道路上不断前进,在生活的迷雾中播撒光引
点赞  2023-10-7 17:31
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复