【得捷电子Follow me第2期】网络天气时钟入门开发与ws2812
[复制链接]
本帖最后由 Aegiss 于 2023-10-15 01:03 编辑
大家好,这次有幸参加得捷电子Follow me第2期活动,是件非常开心的事情。我平时主要从事MCU开发,基本使用C语言,偶有用到python。这次可以通过活动更深入了解micro python/circuit python,是个非常好的机会。
前瞻
本次使用的开发板基于ESP32-S3,有较强的性能。具备LCD彩色显示屏,板载ws2812,还有锂电池接口和电池管理芯片。不使用外扩模块就可以实现很多功能。本着入门circuit python的目的。本次先完成必做任务+ 网络天气时钟。开发板详情链接:https://learn.adafruit.com/adafruit-esp32-s3-tft-feather 后续还会经常用到这个网站的各种资源。
收到开发板初次上电测试后,先来刷个最新固件。
- 首先找到最新固件,链接 https://circuitpython.org/board/adafruit_feather_esp32s3_tft/
- 找到下载bin文件,保存到本地电脑,然后在页面右下角找到 ESP Web Flasher,按如下步骤操作:按住boot ,然后reset,便可使用网页刷写方式刷入最新固件
我理解的python使用主要依赖各种库,通过调用各种已经制作好的python库,可以非常轻松的实现我需要的功能,这一点比C语言更方便快捷。 通过一两天的摸索,基本搞清楚了介绍的文档,库的获取方式等等需要的信息。 基本的参考文档在此网址: https://docs.circuitpython.org/en/8.2.x/README.html
其他一些需要自己加入的库和示例代码放在GitHub:
- 在参考文档—— Core Modules下可以查看各个模块的功能和使用方式,基本按照此文档就可以把所有基础模块玩儿起来。
- 在库文件内可以找到中文显示需要的bitmap库、WS2812需要的neopixel.py,以及网络请求需要用到的 adafruit_requests.mpy
任务一:显示中文
首先准备一个中文字库(从论坛获得)放进lib文件夹,直接从库文件内参考一个使用bitmap的example,基本只需要修改字库名称, 代码如下:
# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import board
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import label
display = board.DISPLAY
font = bitmap_font.load_font("lib/sanjiruosixingkai_m_16.pcf")#根据自己的字库名称和路径修改
color = 0x11FFFF
# Set text, font, and color
text = "\
得捷电子follow me\n\
EEWorld\n\
电子工程师社区\n"
# Create the tet label
text_area = label.Label(font, text=text, color=color)
# Set the location
text_area.x = 20
text_area.y = 20
text_area.scale =2
# Show it
display.show(text_area)
# Loop forever so you can enjoy your text
while True:
pass
显示效果:
任务二:WIFI联网与AP开启
其实联网功能已经在固件的boot loader阶段 配置,只需要在根目录下的settings.toml文件内添加联网信息,reset后就可自动联网。 格式如下:
AP模式,那就设定在联网失败的情况下自动开启AP模式。最终代码如下:
# Initialize Wi-Fi connection
try:
wifi.radio.connect(
os.getenv("CIRCUITPY_WIFI_SSID"), os.getenv("CIRCUITPY_WIFI_PASSWORD")
)
print("Connected to %s!" % os.getenv("CIRCUITPY_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."
)
# WiFi状态查询,未连接WIFI则不联网更新数据,开启AP模式
wificonnect_State = wifi.radio.connected
print("wificonnect_State",wificonnect_State)
if(wificonnect_State == False):
wifi.radio.start_ap(ssid = 'Esp32', password = '')
if(wificonnect_State == True):
Wifi_Mode = 'STA'
else :
Wifi_Mode = 'AP'
if(wificonnect_State == True):
Wifi_ip = wifi.radio.ipv4_address
else :
Wifi_ip = wifi.radio.ipv4_address_ap
可以通过关闭路由器此SSID的网络来测试AP是否启动成功
任务二:WS2812控制
本次我连带购买了一个WS2812的灯环;参考官网一个把环形灯板跑成彩虹色的example,实测确实非常炫酷,可惜手里的环形灯只有一个,不能更绚烂。具体的演示效果见视频。
代码如下:
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import neopixel
# On CircuitPlayground Express, and boards with built in status NeoPixel -> board.NEOPIXEL
# Otherwise choose an open pin connected to the Data In of the NeoPixel strip, i.e. board.D1
# pixel_pin = board.D5 #此处根据自身需要,选择板载🐣灯珠或者外置的灯板,外置灯板则选择自己匹配的PIN脚
pixel_pin = board.NEOPIXEL
# On a Raspberry pi, use this instead, not all pins are supported
# pixel_pin = board.D18
# The number of NeoPixels
num_pixels = 16
# The order of the pixel colors - RGB or GRB. Some NeoPixels have red and green reversed!
# For RGBW NeoPixels, simply change the ORDER to RGBW or GRBW.
ORDER = neopixel.GRB
pixels = neopixel.NeoPixel(
pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=ORDER
)
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if pos < 0 or pos > 255:
r = g = b = 0
elif pos < 85:
r = int(pos * 3)
g = int(255 - pos * 3)
b = 0
elif pos < 170:
pos -= 85
r = int(255 - pos * 3)
g = 0
b = int(pos * 3)
else:
pos -= 170
r = 0
g = int(pos * 3)
b = int(255 - pos * 3)
return (r, g, b) if ORDER in (neopixel.RGB, neopixel.GRB) else (r, g, b, 0)
def rainbow_cycle(wait):
for j in range(255):
for i in range(num_pixels):
pixel_index = (i * 256 // num_pixels) + j
pixels[i] = wheel(pixel_index & 255)
pixels.show()
time.sleep(wait)
while True:
# Comment this line out if you have RGBW/GRBW NeoPixels
pixels.fill((255, 0, 0))
# Uncomment this line if you have RGBW/GRBW NeoPixels
# pixels.fill((255, 0, 0, 0))
pixels.show()
time.sleep(1)
# Comment this line out if you have RGBW/GRBW NeoPixels
pixels.fill((0, 255, 0))
# Uncomment this line if you have RGBW/GRBW NeoPixels
# pixels.fill((0, 255, 0, 0))
pixels.show()
time.sleep(1)
# Comment this line out if you have RGBW/GRBW NeoPixels
pixels.fill((0, 0, 255))
# Uncomment this line if you have RGBW/GRBW NeoPixels
# pixels.fill((0, 0, 255, 0))
pixels.show()
time.sleep(1)
rainbow_cycle(0.001) # rainbow cycle with 1ms delay per step
任务四:网络天气时钟
此项目可以说是非常适合本次的开发板,无需任何外置器件即可实现,有屏幕有WiFi,跑个天气时钟,再合适不过了。
此项目基本可以参考开发板页面推送的方案,按照自己的需要修改,主要有以下几点:
- 可以自己根据喜好选择几种天气背景图,使用PS等软件裁剪成屏幕像素尺寸大小的BMP格式。
- 需要一个天气API获取接口,我在这里使用了知心天气,去他网站注册一个账号,然后根据API调用方法描述,添加进代码里即可实现。
- 需要稍微了解下json数据解析,根据自己的API接口调整一下。
- 时钟与天气类似,也是找一个可以提供API的网站,获取值之后解析到数据组。
- 由于使用了时钟,需要每秒更新显示,而这些网站又基本都有访问频率限制,所以需要降低从服务器获取数据的频率,引入了RTC,将从服务器获取到的时间信息写入RTC,再从RTC获取当前时间用于显示。
最终显示效果如下:
图片和字体都没有选得很合适,显示效果有所欠缺
总结
- 收到板子后总共花了不到一周时间,基本把这几个任务跑完,算是入门了circuit python,目前来说,这个库确实还存在一些bug,恐无法商用。但对于个人用于快速验证想法点子,确实是非常方便快捷高效的选择。后续应该也会越来越多的使用python作相关应用开发。
- 本次其实很早就做完了这几个任务,但视频没时间剪辑出来,一直拖到国庆之后才完成,当然也确实比较忙。
- 本次没有完成拓展任务五,算是一大遗憾。之前只是匆匆瞥了一眼如何搭建服务器,然后在网页端控制,由于确实不懂网页相关代码编写,又没有较充裕得时间去学习,一拖再拖,未能在此节点完成。后续如果有机会,争取补上。
- 此次用到的开发板挺优秀的,小巧,但功能丰富合理,非常适合做ESP32相关的一些小点子验证。
|