This post was last edited by zionlio on 2023-11-27 00:46
Project Introduction
Hello everyone. I am Liao, an ordinary worker from Guangdong. I have been working for so long and have also been exposed to the relevant knowledge of development boards. The rapid development of various smart products recently has aroused my strong interest in smart hardware. I happened to see this event on Bilibili, so I signed up for the second phase of the event. The first choice is hardware selection, an Adafruit ESP2-S3 with a screen, and a MPL3115A2 sensor for collecting air pressure/altitude temperature. After confirming the hardware, I placed an order and began a long wait. I finally received the goods one day in October. So I started the process of tossing. The functions realized in this project are mainly based on the four tasks of the forum. Task 1: Control the screen to display Chinese. Task 2: Use network functions. Task 3: Control WS2812B. Task 4 Calendar & Clock - Complete a perpetual calendar clock that can be updated through the Internet, and display local weather information and data detection and recording.
Demo Video
Demo Video
Task 1: Control the screen to display Chinese
Control the screen to display Chinese (mandatory task)
Complete the screen control and display Chinese
Matching device: Adafruit ESP32-S3 TFT Feather
- The first choice is to confirm that the font to be used is Tik Tok Beautiful Font.
- Use Fontmin software to create minimized fonts
- Use the otf2bdf tool to convert the minimized ttf font to a bdf font. I converted five sizes of fonts, which can be used and deleted later.
- Use the online conversion tool provided by Adafruit to convert the bdf format font file into pcf format
https://adafruit.github.io/web-bdftopcf/
- Create a new fonts folder under the device storage CIRCUITPY, and copy the final pcf file to this folder on the device for easy reference later.
- Download the library file of circuitpy, find the required library file and copy it to the lib folder of CIRCUITPY in the device storage.
Download address : https://circuitpython.org/libraries
- Use vs code to complete the coding
import board
import time
import displayio
import adafruit_imageload
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
#创建Disaplay对象用于控制和操作显示屏的显示内容。
display = board.DISPLAY
#字体颜色
color = 0x111000
#不同大小的字体文件
font30 = bitmap_font.load_font("/fonts/Douyin30.pcf")
font16 = bitmap_font.load_font("/fonts/Douyin16.pcf")
font20 = bitmap_font.load_font("/fonts/Douyin20.pcf")
fontchinese = bitmap_font.load_font("/fonts/DouyinChinese30.pcf")
#创建显示组
group =displayio.Group()
#创建文本显示对象
chinesetexttoshow = label.Label(fontchinese,text="你好世界!",x=5,y=80,scale=1,color=color)
#将文本显示对象chinesetexttoshow添加到group对象中
group.append(chinesetexttoshow)
#在屏幕上显示group对象
display.show(group)
print("done")
#创建循环
while True:
pass
Effect
Task 2: Network Function Usage
- Connect to Wi-Fi
Edit the CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD fields in settings.toml in the CIRCUITPY disk to the corresponding SSID name and password. After restarting the board, you can automatically connect to the network and obtain the IP.
- Turn on hotspot
Use the following code to directly turn on the hotspot, and then you can use your mobile phone to connect to this hotspot
wifi.radio.start_ap("ESP32-S3", "987654321")
Show results
Task 3: Control WS2812B (Required Task)
Use buttons to control the display and color switching of the onboard Neopixel LED
Matching device: Adafruit ESP32-S3 TFT Feather
Overall idea: as noted
import board
import time
import adafruit_led_animation
import neopixel
from digitalio import DigitalInOut, Direction, Pull
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.color import JADE, BLACK, ORANGE, GOLD, OLD_LACE
# 任务3:控制WS2812B 使用按键控制板载Neopixel LED的显示和颜色切换
# 将NEOPIXEL引脚分配给pixel_pin变量,这个引脚连接着NeoPixel LED
pixel_pin = board.NEOPIXEL
# 设置num_pixels变量为1,表示只控制一个LED灯珠
num_pixels = 1
# 初始化blink对象,并设置其关联的NeoPixel对象、闪烁速度和LED颜色。NeoPixel对象在创建时指定了LED灯珠的一些属性。
blink = Blink(neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.2, auto_write=False ),speed=1, color=0x000000)
# 初始化btn对象,它代表一个数字输入/输出引脚(BOOT0引脚)。BOOT0引脚通常用于在启动时选择微控制器的启动模式
btn = DigitalInOut(board.BOOT0)
# 配置btn引脚的方向为输入模式,即这个引脚用于接收外部信号(比如按钮的状态)
btn.direction = Direction.INPUT
# 设置btn引脚的上拉/下拉电阻为上拉模式。上拉模式意味着当没有外部信号输入时,引脚的电平被拉高(即电压接近电源电压)。
btn.pull = Pull.UP
# 定义led_color变量,并初始化为0。这个变量用于记录当前LED的颜色状态。
led_color = 0
# 进入一个无限循环,这个循环会一直运行,除非有外部因素中断它(比如按下Ctrl+C或者微控制器断电)。
while True:
# 检查btn引脚的电平状态。如果btn.value为False(即引脚电平为低),表示按钮被按下。
if not btn.value:
# 对led_color求余数,根据余数判断应该设置哪种LED颜色。这里使用了if-elif语句来实现这个逻辑。
if led_color % 5 == 0:
blink.color = 0x00FF00 # 设置LED颜色为绿色(Jade)
print("LED is JADE") # 在控制台打印当前LED颜色状态
elif led_color % 5 == 1:
blink.color = 0xFFA500 # 设置LED颜色为橙色(Orange)
print("LED is ORANGE") # 在控制台打印当前LED颜色状态
elif led_color % 5 == 2:
blink.color = 0xFFD700 # 设置LED颜色为金色(Gold)
print("LED is GOLD") # 在控制台打印当前LED颜色状态
elif led_color % 5 == 3:
blink.color = 0xFDF5E6 # 设置LED颜色为米色(Old Lace)
print("LED is OLD_LACE") # 在控制台打印当前LED颜色状态
elif led_color % 5 == 4:
blink.color = 0x000000 # 设置LED颜色为黑色(Black)
print("LED is BLACK") # 在控制台打印当前LED颜色状态
# 将led_color增加1,这样下次循环时可以切换到下一个颜色状态。
led_color += 1
else:
pass # 如果按钮没有被按下,什么也不做,直接跳过这个循环迭代。
# 让程序暂停1秒(1000毫秒)。
time.sleep(1)
# 调用blink对象的animate方法,开始闪烁效果。这个方法会根据blink对象的当前属性和状态来控制LED的闪烁效果。
blink.animate()
Show results
Task 4:
Subtask 1: Calendar & Clock - Complete a perpetual calendar clock that can be updated via the Internet and display local weather information
Subtask 3: Data detection and recording - continuously record temperature/brightness information at a certain time interval, save it to the SD card, and call up and view previous information through buttons and draw on the screen
Recommended devices: Adafruit ESP32-S3 TFT Feather, light sensor, temperature sensor, micro SD card module
the whole idea:
Connect to wifi, get ntp time, set local time, create various bitmap display objects, and finally display them in a loop.
import board
import time
import os
import wifi
import socketpool
import adafruit_ntp
import ssl
import rtc
import sys
import adafruit_requests
import displayio
import adafruit_imageload
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
import adafruit_datetime
import adafruit_mpl3115a2
#判断是星期几
def get_day(wday):
if (wday ==0):
return "一"
elif (wday ==1):
return "二"
elif (wday ==2):
return "三"
elif (wday ==3):
return "四"
elif (wday ==4):
return "五"
elif (wday ==5):
return "六"
elif (wday ==6):
return "日"
i2c = board.I2C()
sensor = adafruit_mpl3115a2.MPL3115A2(i2c)
url = "https://api.openweathermap.org/data/2.5/weather?q=Guangzhou,cn&APPID=6f603744d4bab2d5f92eba7b5ee49267&&lang=zh_cn"
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
print(ssid)
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
#连接wifi
try:
wifi.radio.connect(ssid,password)
print("Connecting to confiured Wifi")
except Exception as e:
print(f"连接到 Wifi 时发生错误: {e}")
time.sleep(5)
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()
#wifi.disconnect()
time.sleep(2)
wifi.radio.connect(ssid, password)
print("重新连接到配置的 Wifi")
pool=socketpool.SocketPool(wifi.radio)
sslCtx=ssl.create_default_context()
#获取ntp时间
retry_count = 0 # 计数器变量,记录重试次数
max_retries = 3 # 最大重试次数
while True:
try:
ntp = adafruit_ntp.NTP(pool, tz_offset=+8, server="ntp.aliyun.com")
rtc.RTC().datetime = ntp.datetime
# 其他代码逻辑
break # 如果成功执行,则跳出循环
except Exception as e:
print("发生异常:", e)
# 打印异常信息,并根据重试次数决定是否继续尝试
retry_count += 1
if retry_count <= max_retries:
continue # 继续尝试重新执行
else:
print("已达到最大重试次数,停止重试。")
break # 停止重试,退出循环
#change system time
rewneweddatetime=rtc.RTC().datetime
current_date = adafruit_datetime.datetime(rewneweddatetime[0], rewneweddatetime[1], rewneweddatetime[2], rewneweddatetime[3], rewneweddatetime[4], rewneweddatetime[5])
weekday = current_date.weekday()
monthandday = str(rewneweddatetime.tm_mon)+"月"+str(rewneweddatetime.tm_mday)+"日"
hourandmin = str(rewneweddatetime.tm_hour)+"时"+str(rewneweddatetime.tm_min)+"分"
print("Today is ", weekday)
font8 = bitmap_font.load_font("/fonts/Douyin8.pcf")
font10 = bitmap_font.load_font("/fonts/Douyin10.pcf")
font12 = bitmap_font.load_font("/fonts/Douyin12.pcf")
font14 = bitmap_font.load_font("/fonts/Douyin14.pcf")
font16 = bitmap_font.load_font("/fonts/Douyin16.pcf")
font18 = bitmap_font.load_font("/fonts/Douyin18.pcf")
font20 = bitmap_font.load_font("/fonts/Douyin20.pcf")
font24 = bitmap_font.load_font("/fonts/Douyin24.pcf")
font30 = bitmap_font.load_font("/fonts/Douyin30.pcf")
display = board.DISPLAY
#显示第一屏内容
group =displayio.Group()
image, palette = adafruit_imageload.load("/pic/bg.png")
palette.make_transparent(0)
grid = displayio.TileGrid(image, pixel_shader=palette)
group.append(grid)
color = 0xff0000
green = 0x008000
temperature = sensor.temperature
week =label.Label(font16,text="星期",color = color)
realtemp =label.Label(font16,text="室温",color = color)
whichday =label.Label(font20,text=get_day(weekday),color = color)
monthandday = label.Label(font12,text=monthandday,color = color)
hourandmin = label.Label(font12,text=hourandmin,color = color)
week.x = 22
week.y = 25
realtemp.x = 158
realtemp.y = 25
whichday.x = 32
whichday.y = 66
monthandday.x=14
monthandday.y=110
hourandmin.x=160
hourandmin.y=110
group.append(week)
group.append(realtemp)
group.append(whichday)
group.append(monthandday)
group.append(hourandmin)
TEMP= "{0:0.1f}°C".format(temperature)
temp = label.Label(font20,text=TEMP,color = green)
temp.x = 154
temp.y = 66
group.append(temp)
#显示第二屏内容
group2 = displayio.Group()
image2, palette2 = adafruit_imageload.load("/pic/bg2.png")
palette2.make_transparent(0)
grid2 = displayio.TileGrid(image2, pixel_shader=palette2)
group2.append(grid2)
color2 = 0x2e0000
#初始化海平面大气压
sensor.sealevel_pressure = 1022
requests=adafruit_requests.Session(
pool, sslCtx)
response=requests.get(url)
json=response.json()
main = json["main"]
sensor.sealevel_pressure = main["sea_level"]
forecastsl = main["sea_level"]
weather = json["weather"]
forecastwh = weather [0]
forecastdesc = forecastwh["description"]
pressure = sensor.pressure
altitude = sensor.altitude
temp = main["temp"]-273.15
temprange = "{0:0.1f}".format(main["temp_min"]-273.15) + "-"+ "{0:0.1f}".format(main["temp_max"]-273.15) +"°C"
print(main["temp_min"])
print(main["temp_max"])
humidity = str(main["humidity"])+"%"
#将元素放入Label
networksl = label.Label(font10,text="海平面气压",color = color2)
innerrealpressure = label.Label(font10,text="室内气压",color = green)
altitude1 = label.Label(font10,text="高度",color = green)
sp = label.Label(font16,text=str(sensor.sealevel_pressure)+"帕",color = color2)
ep = label.Label(font16,text="{0:0.1f}".format(pressure)+"帕",color = green)
al = label.Label(font16,text="{0:0.1f}".format(altitude)+"米",color = green)
sc = label.Label(font16,text=forecastdesc,color = color2)
#控制元素位置
networksl.x=10
networksl.y=12
sp.x = 10
sp.y = 32
innerrealpressure.x = 10
innerrealpressure.y = 50
ep.x = 10
ep.y = 72
altitude1.x= 10
altitude1.y = 92
al.x = 10
al.y = 112
#将元素放入group2
group2.append(networksl)
group2.append(sp)
group2.append(innerrealpressure)
group2.append(ep)
group2.append(altitude1)
group2.append(al)
yj = label.Label(font10,text="预计",color = color2)
gz = label.Label(font16,text="广州",color = color2)
jt = label.Label(font10,text="今天",color = color2)
wd = label.Label(font14,text="{0:0.1f}".format(temp)+"度",color = color2)
wdrange = label.Label(font14,text=temprange,color = color2)
sd =label.Label(font14,text=humidity,color = color2)
yj.x = 124
yj.y = 14
gz.x = 156
gz.y = 12
jt.x = 205
jt.y = 14
sc.x = 124
sc.y = 40
wd.x = 124
wd.y = 70
wdrange.x = 124
wdrange.y = 95
sd.x = 124
sd.y = 118
group2.append(yj)
group2.append(gz)
group2.append(jt)
group2.append(sc)
group2.append(wd)
group2.append(wdrange)
group2.append(sd)
display.auto_refresh = False
while True:
display.show(group)
display.refresh()
time.sleep(5)
display.show(group2)
display.refresh()
time.sleep(5)
Mission Effect
Source code
download
|