[Digi-Key Follow me Issue 2] + Submit Post: Perpetual Calendar Based on ESP32-S3
[Copy link]
This post was last edited by liuvx on 2023-11-21 17:04
Recently, we have completed all the contents of this activity. The Adafruit ESP32-S3 TFT Feather development board used in this activity supports WiFi and Bluetooth functions and has a built-in high-definition TFT color display. We have completed tasks such as displaying Chinese on the screen, connecting to WiFi, driving RGB, and making a perpetual calendar.
Content 1: Demonstration Video
This time, we implemented a perpetual calendar based on ESP32-S3, which can connect to the Internet and display the current time, date, weather and temperature on the screen.
Digi-Key Electronics Follow me Second Phase Task - Digi-Key Electronics Follow me Second Phase Task - EEWORLD University
Content 2: Project Summary Report
Task 1: Control the screen to display Chinese
First, the effect diagram is presented here
Figure 1 Effect diagram
initial preparation work :
- Get the Adafruit ESP32-S3 TFT Feather development board, power it up, enter UF2 mode, and install the CircuitPython environment.
CircuitPython firmware U F2 download page:
Feather ESP32-S3 TFT Download (circuitpython.org)
- Drag the downloaded UF2 firmware directly into the disk that comes with the Adafruit ESP32-S3 TFT Feather and wait for it to restart automatically.
- When your screen looks like Figure 2, CircuitPython is installed .
figure 2
Officially begin :
Figure 3 CircuitPython
I use V Scode for configuration. You can install this plug-in first and then proceed with the following operations.
This task requires 3 libraries
We can execute this command in vscode
Then enter
After that, you can search and install the libraries you need.
When entering the command execution, enter
You can query the library you downloaded
This section also requires additional fonts
Font library link:
What I use is wenquanyi_13px.pcf. After downloading it, just drag it into the disk that comes with the development board.
Then the code part
This part is to import the necessary libraries
import board
import displayio
from adafruit_display_text import label, wrap_text_to_lines
from adafruit_bitmap_font import bitmap_font
Then set the screen parameters
display = board.DISPLAY
board.DISPLAY.brightness = 0.2 # 设置显示屏亮度为0.35
board.DISPLAY.rotation = 0 # 设置显示屏旋转为0度
Then set the characters to be displayed on the screen.
# 加载自定义字体文件
font = bitmap_font.load_font("wenquanyi_13px.pcf")
# 设置文本颜色
color = 0xFF0000 # 这里的颜色为红色
# 初始化文本变量
text_change = 0
# 创建显示组和文本标签
text_group = displayio.Group()
text_area = label.Label(font, text="test", color=color) # 创建文本标签对象
text_area.x = 0 # 设置文本的X坐标
text_area.y = 55 # 设置文本的Y坐标
text_area.line_spacing = 0.5 # 设置文本行间距
text_area.scale = 2 # 设置文本放大倍数
# 设置文本内容
text_area.text = "WIFI:ESP\n密码:00000000" # 这里设置文本内容
text_area.ass = "w"
text_group.append(text_area) # 将文本标签添加到显示组中
display.show(text_group) # 在显示设备上显示文本
Task 2: Connect to WiFi and create a hotspot
The requirement for this task is to complete the use of network functions, be able to create a hotspot and connect to WiFi.
And the code is relatively simple
Let's talk about connecting to WIFI first:
After we flash the firmware, we can see a settings.toml file in the disk. We only need to modify it to achieve WIFI connection
Then modify the code inside
#配置WIFI的ID
CIRCUITPY_WIFI_SSID = "Liuv"
#配置WiFi密码
CIRCUITPY_WIFI_PASSWORD = "12345678"
#配置网页工作流密码
CIRCUITPY_WEB_API_PASSWORD = "123456"
#配置网页工作流端口
CIRCUITPY_WEB_API_PORT = 80
After we connect to WIFI, the screen will display the IP address
Our WIFI is now connected.
Then turn on the hotspot
Import required libraries
import wifi
Then turn on the hotspot
wifi.radio.start_ap('ESP', '00000000')
Name and password.
mission completed
Task 3: Use of RGB lights
This task will use the RGB lights and buttons on the board.
I plan to use the time library to achieve the effect of switching colors every 0.5 seconds instead of using buttons to switch colors.
The RGB light model on the board is WS2812b, and you can use it using the neopixel library provided by Adafruit .
import neopixel
Import the time library
import time
Modify brightn to change the maximum brightness of the RGB light.
Then enter the loop
while True:
pixel.brightness = 0.6
pixel.fill((255, 0, 0))
time.sleep(0.5)
pixel.brightness = 0.5
pixel.fill((0, 255, 0))
time.sleep(0.5)
pixel.brightness = 0.1
pixel.fill((0, 0, 255))
time.sleep(0.5)
middle
pixel.fill((255, 0, 0))
They are Red, Green, and Blue color controls respectively.
time.sleep(0.5)
Indicates a delay of 0.5s
After you burn the code, you can observe that RGB switches back and forth between red, green, and blue, and the brightness of each is different.
The complete code is as follows
import time
import board
import neopixel
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)#初始化rgb引脚
pixel.brightness = 0.6#更改亮度
while True:
pixel.brightness = 0.6
pixel.fill((255, 0, 0))
time.sleep(0.5)
pixel.brightness = 0.5
pixel.fill((0, 255, 0))
time.sleep(0.5)
pixel.brightness = 0.1
pixel.fill((0, 0, 255))
time.sleep(0.5)
Now you have mastered the most basic control of RGB lights. Now let's see how to operate it with buttons.
When you use the buttons, you call the basic digital library
import digitalio
Then initialize the button
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
Indicates pull-up input
Then enter the loop
while True:
if not button.value:
if n % 3 == 1:
pixel.brightness = 0.6
pixel.fill((255, 0, 0))
elif n % 3 == 2:
pixel.brightness = 0.5
pixel.fill((0, 255, 0))
elif n % 3 == 0:
pixel.brightness = 0.3
pixel.fill((0, 0, 255))
n = n+1
Just writing it like this is effective, but it may not achieve the results we want.
Because the keys will vibrate when pressed, which will affect us.
Therefore, we need to add a delay function to eliminate jitter
while True:
if not button.value:
time.sleep(0.1)
if not button.value:
if n % 3 == 1:
pixel.brightness = 0.6
pixel.fill((255, 0, 0))
elif n % 3 == 2:
pixel.brightness = 0.5
pixel.fill((0, 255, 0))
elif n % 3 == 0:
pixel.brightness = 0.3
pixel.fill((0, 0, 255))
n = n+1
In this way, we can achieve the desired effect.
The complete code is as follows
import time
import board
import neopixel
import digitalio
n = 0
button = digitalio.DigitalInOut(board.BUTTON)
button.switch_to_input(pull=digitalio.Pull.UP)
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)#初始化rgb引脚
pixel.brightness = 0.6#更改亮度
while True:
if not button.value:
time.sleep(0.1)
if not button.value:
if n % 3 == 1:
pixel.brightness = 0.6
pixel.fill((255, 0, 0))
elif n % 3 == 2:
pixel.brightness = 0.5
pixel.fill((0, 255, 0))
elif n % 3 == 0:
pixel.brightness = 0.3
pixel.fill((0, 0, 255))
n = n+1
else:
pass
Task 4: Calendar and Clock
In this task, we need to display time and weather information on our screen.
First put a rendering
Let’s do it step by step
First, complete the text part
Screen display
You can check the previous task for the required library.
First set some basic parameters of the screen
# 设置板子的亮度和是否翻转
board.DISPLAY.brightness = 0.5 #
board.DISPLAY.rotation = 0 #
word_font = bitmap_font.load_font("wenquanyi_13px.pcf")
We can add a picture to this task to make it more beautiful
Need this library
import adafruit_imageload
Then import the picture, note that the picture needs to be in bmp format
# 引入图片
image, palette = adafruit_imageload.load(
'/images/ysqd.bmp', bitmap=displayio.Bitmap, palette=displayio.Palette)
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)
Then display other text, such as time, temperature, etc.
# 日期的设置
date = label.Label(word_font, text="test", color=0x000000)
date.x = 10 #
date.y = 20
date.scale = 2 #
group.append(date)
# 周几的设置
week = label.Label(word_font, text="周五", color=0x000000)
week.x = 120
week.y = 20
week.scale = 2
group.append(week)
# 时间的设置
timer = label.Label(word_font, text='10:17', color=0x779649)
timer.x = 15
timer.y = 65
timer.scale = 2 #
group.append(timer)
# 天气文字的设置
weather = label.Label(word_font, text='阴', color=0x3271ae)
weather.x = 10
weather.y = 110
weather.scale = 2 #
group.append(weather)
# 温度文字的设置
temperature = label.Label(word_font, text='10度-15度', color=0x3271ae)
temperature.x = 60
temperature.y = 110
temperature.scale = 2
group.append(temperature)
# 事实温度文字的设置
tem_now = label.Label(word_font, text='10度', color=0x3271ae)
tem_now.x = 150
tem_now.y = 65
tem_now.scale = 2
group.append(tem_now)
Finally, display it
board.DISPLAY.show(group)
WIFI CONNECTIVITY
Similar to before, configure ssid and password in the SETTING file
# 连接WIFI,若连接失败会报错
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
time.sleep(1)
print("Connected to", ssid)
The purpose of the 1s delay is to enable the subsequent operations to be performed after connecting to WiFi.
getting information
Related library introduction
adafruit_ntp
adafruit_requests
rtc
To get the weather, you need to return data from other places.
I use the Yike Cloud API here, which is more convenient and stable
Code section
# 周几文字的数据
def get_wday(week_today):
if week_today == 0:
return "周一"
elif week_today == 1:
return "周二"
elif week_today == 2:
return "周三"
elif week_today == 3:
return "周四"
elif week_today == 4:
return "周五"
elif week_today == 5:
return "周六"
elif week_today == 6:
return "周日"
Then use RTC to get the time
# 使用rtc
rtc.RTC().datetime = adafruit_ntp.NTP(socketpool.SocketPool(
wifi.radio), tz_offset=8, server='ntp.aliyun.com').datetime
Get weather conditions from API
def get_weather():
requests = adafruit_requests.Session(
socketpool.SocketPool(wifi.radio), ssl.create_default_context())
appid = os.getenv("appid")
appsecret = os.getenv("appsecret")
res = requests.get(
'https://v0.yiketianqi.com/free/day?appid=%s&appsecret=%s&unescape=1&city=南阳' % (appid, appsecret)).json()
return res['wea'], res['tem_night'], res['tem_day'], res['tem']
Note that the appid and appsecret here need to be obtained from Yike Cloud and written into the settings file
Otherwise, the temperature will not be obtained normally.
Get the information before looping again
# 获得时间
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%s℃-%s℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)
After entering the loop, the speed of obtaining information needs to be limited
while True:
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
if time_now.tm_min == 0:
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%d℃-%d℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)
if time_now.tm_hour == 0:
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
pass
That's it.
The complete code is as follows
import board
import displayio
import os
import wifi
import ssl
import socketpool
import adafruit_ntp
import rtc
import time
import ipaddress
import adafruit_requests
import adafruit_imageload
from adafruit_display_text import label, wrap_text_to_lines
from adafruit_bitmap_font import bitmap_font
# 获得WIFI名字和密码
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
# 周几文字的数据
def get_wday(week_today):
if week_today == 0:
return "周一"
elif week_today == 1:
return "周二"
elif week_today == 2:
return "周三"
elif week_today == 3:
return "周四"
elif week_today == 4:
return "周五"
elif week_today == 5:
return "周六"
elif week_today == 6:
return "周日"
# 连接WIFI,若连接失败会报错
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
time.sleep(10)
print("Connected to", ssid)
# 获得天气情况
def get_weather():
requests = adafruit_requests.Session(
socketpool.SocketPool(wifi.radio), ssl.create_default_context())
appid = os.getenv("appid")
appsecret = os.getenv("appsecret")
res = requests.get(
'https://v0.yiketianqi.com/free/day?appid=%s&appsecret=%s&unescape=1&city=南阳' % (appid, appsecret)).json()
return res['wea'], res['tem_night'], res['tem_day'], res['tem']
# 使用rtc
rtc.RTC().datetime = adafruit_ntp.NTP(socketpool.SocketPool(
wifi.radio), tz_offset=8, server='ntp.aliyun.com').datetime
# 引入图片
image, palette = adafruit_imageload.load(
'/images/ysqd.bmp', bitmap=displayio.Bitmap, palette=displayio.Palette)
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
group = displayio.Group()
group.append(tile_grid)
# 设置板子的亮度和是否翻转
board.DISPLAY.brightness = 0.5 #
board.DISPLAY.rotation = 0 #
word_font = bitmap_font.load_font("wenquanyi_13px.pcf")
# 日期的设置
date = label.Label(word_font, text="test", color=0x000000)
date.x = 10 #
date.y = 20
date.scale = 2 #
group.append(date)
# 周几的设置
week = label.Label(word_font, text="周五", color=0x000000)
week.x = 120
week.y = 20
week.scale = 2
group.append(week)
# 时间的设置
timer = label.Label(word_font, text='10:17', color=0x779649)
timer.x = 15
timer.y = 65
timer.scale = 2 #
group.append(timer)
# 天气文字的设置
weather = label.Label(word_font, text='阴', color=0x3271ae)
weather.x = 10
weather.y = 110
weather.scale = 2 #
group.append(weather)
# 温度文字的设置
temperature = label.Label(word_font, text='10度-15度', color=0x3271ae)
temperature.x = 60
temperature.y = 110
temperature.scale = 2
group.append(temperature)
# 事实温度文字的设置
tem_now = label.Label(word_font, text='10度', color=0x3271ae)
tem_now.x = 150
tem_now.y = 65
tem_now.scale = 2
group.append(tem_now)
# 获得时间
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%s℃-%s℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)
board.DISPLAY.show(group)
while True:
time_now = time.localtime()
timer.text = '%02d:%02d' % (time_now.tm_hour, time_now.tm_min)
if time_now.tm_min == 0:
wea, tem_night, tem_day, tem = get_weather()
weather.text = wea
temperature.text = '%d℃-%d℃' % (tem_night, tem_day)
tem_now.text = '%s度' % (tem)
if time_now.tm_hour == 0:
date.text = '%d月%d日' % (time_now.tm_mon, time_now.tm_mday)
week.text = get_wday(time_now.tm_wday)
pass
Content 3: Task Summary
This activity was my real contact with ESP32. Before that, I had only been exposed to MCUs such as STM32 and 51. Through this activity, I learned a lot about how to use ESP32 and how to operate CircuitPython. I realized that ESP32 is indeed simpler to use than 32 in some places. This mission brought me into a new field of embedded systems, trained my skills, and supplemented my previous half-knowledge. I gained a lot. I am very grateful to Digi-Key and EE for their support for this activity.
Code resource link
follow me The second full set of code - Embedded development related materials download - EEWORLD Download Center
|