第一部分
演示视频
视频链接: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
任务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)
网络测试
简单测试一下网络
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)
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设置成了紫色
控制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灯的颜色了。
任务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
最后显示的效果就是一个可以实时更新的万年历时钟+天气预报啦。
任务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)
总结
通过本次的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 编辑