478|0

2

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【得捷电子Follow me第2期】任务提交 [复制链接]

 

感谢 EEWORLD 和 得捷电子,提供了这次让我能获得提升的机会

作为一名高中牲,对单片机有些许涉猎,这次有幸接触到了 ESP-S3 板子,不得不说 CircuitPython 确实比直接用 C 编写节省了不少时间。这次探索的过程也让我了解了不少 ESP32-S3 的知识,还有吃灰许久的电烙铁。


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

    视频地址:【得捷电子Follow me第2期】任务提交


内容二:任务/项目总结报告

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

    首先导入核心库,字体库以及文本显示库

import os
import board
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
font = bitmap_font.load_font(os.getenv('FONT_FILE_PATH')) # 加载字体

    使用核心库初始化显示屏

# 初始化显示屏
board.DISPLAY.brightness = 0.45
board.DISPLAY.rotation = 0

# 创建显示文本的组
text_group = displayio.Group()

    为了更简洁的设计界面UI,我编写了一个将 adafruit_display_text.label 添加到 text_group 的函数。关于 adafruit_display_text  的具体使用,可以参考 官方文档

def append_label_to_group(text_group, font, x, y, text = '', color = 0x00FFFF, line_spacing = 0.8, scale = 1):
    text_area = label.Label(font, text=text, color=color)
    text_area.x = x
    text_area.y = y
    text_area.line_spacing = line_spacing
    text_area.scale = scale
    text_group.append(text_area)

向 text_group 添加要显示的内容

append_label_to_group(text_group, font, 10, 20, "任务1: 实现屏幕控制与中文显示", color)
append_label_to_group(text_group, font, 10, 60, "1234567890.ABCDEFGHIJKLMN\nOPQRSTUVWXYZ", color)
append_label_to_group(text_group, font, 10, 100, "Follow Me 第二期      @YSChain", color)

刷新屏幕,无限等待

board.DISPLAY.show(text_group)
while True:
    pass

上电,看效果:


任务2:网络功能使用

    首先,你需要打开 CircuitPython 根目录下的 settings.toml 文件,向内加入这些设置。

    SSID 为 WiFi 和 热点 的名字

    AP_* 为热点的配置

WIFI_SSID = "ChinaNet-2.4G-****"
WIFI_PASSWORD = "********"
AP_SSID = "ESP32-S3-YS01"
AP_PASSWORD = "YSBot-TEST"

    导入 WIFI 和请求发送相关库,初始化

import wifi, ssl
import socketpool
import adafruit_requests
import os
TEST_URL = 'http://wifitest.adafruit.com/testwifi/index.html'
print("ESP32-S3 网络连接测试")
print(f"MAC 地址: {[hex(i) for i in wifi.radio.mac_address]}")

    连接 WIFI

print(f"正连接到 {os.getenv('WIFI_SSID')}")
wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print(f"已连接到 {os.getenv('WIFI_SSID')}")
print(f"内网 IP 地址: {wifi.radio.ipv4_address}")

    发送请求,输出结果

pool = socketpool.SocketPool(wifi.radio)
req = adafruit_requests.Session(pool, ssl.create_default_context())
res = req.get(TEST_URL)

print(f"测试请求返回内容: \n  \
{'-' * 40}              \n  \
{res.text}              \n  \
{'-' * 40}              \n  \
\
'完毕!")

    效果图(由于板子没有自带中文字库,REPL 输出会忽略中文,故采用 VSCode 展示)

 

热点创建:

我试图在板子上搭建一个小型的服务器,无奈实在找不到资料,或许它只能使用 MQTT 来实现互联?希望能有大佬解答这个疑惑。

wifi.radio.start_ap(os.getenv("AP_SSID"), os.getenv("AP_PASSWORD"))
wifi.radio.start_dhcp_ap()

    (显然它不可能可以上网


任务3:控制WS2812B

    由于按键数量的限制,此处使用一个按键来轮换各个颜色

    导入相关库,并初始化 D5 Pin,将其设置为上拉模式,将按键的两个引脚分别接到 3.3V 和 D5

import time
import board
import digitalio
import neopixel

button_pin = board.D5
button = digitalio.DigitalInOut(button_pin)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP

设置内置颜色,并启动板载 WS2812B

# 颜色数组
COLORS = [
    (255, 0, 0),     # 红
    (180, 120, 0),   # 橙
    (180, 180, 0),   # 黄
    (0, 255, 0),     # 绿
    (0, 0, 255),     # 蓝
    (75, 0, 130),    # 靛
    (215, 110, 215)  # 紫
]

# 默认显示蓝色
Color_Num = 4
Color = COLORS[4]
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
pixel.brightness = 0.2

随后是一个简单的按键判断和软件消抖

debounce_delay = 0.8  # 消抖延迟,单位s
while True:
    if not button.value:  # 按键被按下
        time.sleep(debounce_delay)  # 延迟一段时间进行消抖
        if not button.value:  # 确认按键仍然被按下
            Color = COLORS[Color_Num]  # 设置led颜色
            pixel.fill(Color)
            Color_Num = (Color_Num + 1) % 7

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

    1. 连接WiFi同上,此处省略

    2. 发送http请求,此处需要前往 这里 获取自己城市的天气代码,替换链接中的数据

import ssl
import socketpool
import adafruit_requests

# 请求获取JSON
## api文档  https://www.sojson.com/blog/305.html
TARGET_URL = "http://t.weather.itboy.net/api/weather/city/101210404"

# 发送请求并解析 JSON 数据
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
response = requests.get(TARGET_URL)
weather = response.json()

    3. 初始化屏幕,定义“任务一”中出现过的那个函数

import board
import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
from adafruit_display_shapes.rect import Rect

display = board.DISPLAY
board.DISPLAY.brightness = float(os.getenv('DISPLAY_BRIGHTNESS'))
board.DISPLAY.rotation = 0
font = bitmap_font.load_font(os.getenv('FONT_FILE_PATH')) # 加载字体
text_group = displayio.Group()

def append_label_to_group(text_group, font, x, y, text = '', color = 0xC8D2F8, line_spacing = 0.9, scale = 1):
    text_area = label.Label(font, text=text, color=color)
    text_area.x = x
    text_area.y = y
    text_area.line_spacing = line_spacing
    text_area.scale = scale
    text_group.append(text_area)

divider_color = 0x001FDD  # 分界线的颜色

    4. 检查天气数据是否获取成功

if weather['message'][0:7] != 'success':
    print('[FATAL] 日历数据获取失败!')
    text_area = label.Label(font, text='[FATAL] 日历数据获取失败!', color=0xff7e00)
    text_area.x = 30
    text_area.y = 50
    text_area.line_spacing = 0.9
    text_area.scale = 1
    text_group.append(text_area)

    display.show(text_group)
    while True:
        pass

    5. 解析天气数据并显示(明日的数据同理)

cityInfo  = weather['cityInfo']
city_weather = weather['data']
forecast = city_weather['forecast']


### 今日的数据
str1 = f' {forecast[0]["ymd"][5:]}  RH:{"0" if len(city_weather["shidu"])==2 else ""}{city_weather["shidu"]}  [{forecast[0]["sunrise"]}-{forecast[0]["sunset"]}]  {forecast[0]["type"]}'
aqi  = f" AQI: {'0' if forecast[0]['aqi'] < 100 else ''}{forecast[0]['aqi']}"
if forecast[0]['aqi'] <= 50:
    aqi_color = 0x00e400
elif forecast[0]['aqi'] <= 100:
    aqi_color = 0xf0f000
elif forecast[0]['aqi'] <= 150:
    aqi_color = 0xff7e00
elif forecast[0]['aqi'] <= 200:
    aqi_color = 0xf00000
elif forecast[0]['aqi'] <= 300:
    aqi_color = 0x99004c
else:
    aqi_color = 0x7e0023

wind_str = f"{'  ' if len(forecast[0]['fx']) == 2 else ''}{forecast[0]['fx']} {'0' if len(forecast[0]['fl']) == 2 else ''}{forecast[0]['fl']}"
tem_str = f"{forecast[0]['low'][3:]}~{forecast[0]['high'][3:]}"

append_label_to_group(text_group, font, 0, 10, str1)
append_label_to_group(text_group, font, 0, 30, aqi, aqi_color)
append_label_to_group(text_group, font, 70, 30, f"{wind_str}   {tem_str}")
text_group.append(Rect(0, 43, 240, 1, fill=divider_color))
### END 今日的数据

    6. 获取万年历数据并解析显示。这里使用到了 RoolToolsApi,请前往 这里 注册获取自己的 Key。随后将这段内容加入你的 settings.toml 文件中:

mxnzp_APP_ID = "n****b"
mxnzp_APP_SECRET = "3***d"

接下来和获取天气数据相似:发送请求,解析JSON,显示。不再赘述

TARGET_URL = f"https://www.mxnzp.com/api/holiday/single/{weather['date']}?ignoreHoliday=false&app_id={os.getenv('mxnzp_APP_ID')}&app_secret={os.getenv('mxnzp_APP_SECRET')}"

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

print(f"Fetching and parsing json from 'https://www.mxnzp.com/api/holiday/single/'")
response = requests.get(TARGET_URL)
calendar = response.json()

if calendar['code'] != 1:
    append_label_to_group(text_group, font, 30, 100, '日历数据获取失败', 0xff7e00)
else:
    append_label_to_group(text_group, font, 10, 100, f"{calendar['data']['yearTips']}年 [{calendar['data']['chineseZodiac']}]  {calendar['data']['lunarCalendar']}  -  {calendar['data']['typeDes']}")
    append_label_to_group(text_group, font, 0, 120, f"宜:{calendar['data']['suit'][0:8]} | 忌:{calendar['data']['avoid'][0:8]}")
    效果展示:AQI 指数的颜色会随着空气质量的情况而变化,天气预报中位于方括号内的内容是日出日落时间

心得体会:

    曾经试图用 Arduino UNO R3 制作一个桌面时钟,加入对电灯的自动控制等功能,最终因为 adafruit 的 GFX 库占用内存过多而放弃了那块TFT显示屏。这次一定程度上也是奔着这块不错的显示屏来的。利用 Python 开发确实有着非常大的优势,烧录代码更是方便迅速。

    未来计划利用它制作一个简易的热成像仪,这块屏幕刚好可以用来实时监视,同时用WiFi将图像传输到树莓派,省去了再拿个设备记录的痛。虽然分辨率很低,但是作为一个测量温度的小工具,想必还是很不错的。
    最后,再次感谢得捷电子,感谢 EEWORLD!


内容三:可编译下载的代码

【得捷电子第二期】任务代码.7z (440.34 KB, 下载次数: 2)
点赞 关注
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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