【Digi-Key Follow me Issue 2】Project Summary
[Copy link]
A task summary video
Video link: https://training.eeworld.com.cn/video/38575
Second Development Board Introduction
This time, the Adafruit ESP32-S3 development board with TFT screen is used. The development board uses the ESP32-S3 chip from Shanghai Espressif. The chip supports Bluetooth (CircuitPython does not support) and wifi. It is understood that esp32-s3 and its derivatives are mainly used in IoT products.
Three Project Introduction
This follow 2 needs to complete 4 tasks. I chose to complete: 1. Control the screen to display Chinese 2. Network functions (including creating wifi hotspots and connecting to wifi) 3. Use buttons to control the display and color switching of the onboard LED 4. Calendar & clock display. After comparison, I chose CircuitPython for development. I watched the video of "Busy Dead Dragon" and combined it with my actual use. I found the following problems:
1. Choose to use the web method to connect the serial port for debugging. Sometimes the web page fails to connect to the serial port.
2. Select vscode to open the code.py file, but you cannot view the serial port REPL information.
Therefore, select the mu editor editor. You can edit the CircuitPython code file and open the serial port debugging window stably.
Task 1: Control the screen to display Chinese
This task is the first task. First, you need to be familiar with how to burn the firmware of CircuitPython. Visit https://circuitpython.org/board/adafruit_feather_esp32s3_tft/ and select uf2 firmware download. Then, press the RST key on the development board twice to enter the burning interface. Then copy the downloaded adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.6.uf2 firmware to the development board. The burning is successful.
Next, we need to complete the Chinese font display. First, we need to know that we need to call the corresponding library. The download address of the library is: https://circuitpython.org/libraries . Download the "Bundle for Version 8.x" version of the library according to the burned program. After decompressing it locally, go to the lib folder of the decompressed folder and copy the adafruit_bitmap_font folder, adafruit_imageload folder, and adafruit_display_text folder to the lib folder of the development board.
If you need to display the corresponding Chinese characters, you need to process the font library. First, you can choose to download the corresponding font library ttf file on the Internet. Then use the Fontmin software to open the corresponding font library file, select the corresponding characters and numbers you need to use, and save it as a new ttf file, which only contains the selected characters. Then use the FontForge software to generate a bdf file. However, this file will load slowly. Therefore, refer to the relevant content mentioned in https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display , and use the https://adafruit.github.io/web-bdftopcf/ website to convert the bdf file to a pcf file online. Please note that the bdf file is actually smaller than the pcf file, but it loads slowly. The pcf file is slightly larger, but loads quickly. Next, edit the code to display the relevant Chinese characters.
# 在这里写上你的代码 :-)
import board
import displayio
# 导入外部库adafruit_imageload
import adafruit_imageload
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
# 使用固件自带的屏幕设备
display = board.DISPLAY
# 创建本例程里像组
group = displayio.Group()
# 加载图片
image, palette = adafruit_imageload.load("/pic/bg2.png")
# 是否开启透明
palette.make_transparent(3)
# 创建图片布局
grid = displayio.TileGrid(image, pixel_shader=palette)
# 将图片布局添加到图像组,由于是第一个添加的,默认是最下层
group.append(grid)
# 显示当前图像组
display.show(group)
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/myfont2.pcf")
color = 0x000000
slog = label.Label(font, text="很高兴参加得捷电子", color=color)
slog.x = 30
slog.y = 38
group.append(slog)
slog2 = label.Label(font, text="Follow me 第二期", color=color)
slog2.x = 40
slog2.y = 70
group.append(slog2)
display.show(group)
while True:
pass
Task 2 Network functions (including creating wifi hotspots and connecting to wifi)
1. Connect to wifi
To connect to Wi-Fi, you only need to modify the corresponding configuration file. Modify the corresponding fields of the settings.toml file in the root directory of the development board folder.
CIRCUITPY_WIFI_SSID = "The name of the WIFI you are currently connecting to"
CIRCUITPY_WIFI_PASSWORD = "The WiFi password you are currently connecting to"
After saving, press the RST key on the board, the development board will automatically connect to WiFi and obtain the IP address.
2. Wi-Fi hotspot
import wifi
wifi.radio.start_ap("rz", "12345678")
The above two lines of code can let the mobile phone search for rz to connect. In the experiment, it was found that even if the wifi connection in settings.toml was set up and the hotspot was connected successfully, the connected mobile phone still could not access the Internet.
Task 3: Use buttons to control the display and color switching of the onboard LED
Download the library file in Task 1, copy the neopixel.mpy file and the adafruit_led_animation folder to the lib folder of the development board.
Import the corresponding library file, and selectively import the color of the light to be displayed. This uses the boot button to switch the color of the LED light, view the circuit schematic of the development board,
The boot button is low level effective. So in the code we set the boot pull-up and input.
Then use the number of key presses and the displayed color to find the modulus, and repeat this cycle every 3 times.
# 导入board内置库
import board
# 导入time内置库
import time
from digitalio import DigitalInOut, Direction, Pull
import neopixel
# 从adafruit_led_animation.animation.blink库导入Blink
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.color import BLUE, RED, JADE, BLACK, ORANGE, GOLD, OLD_LACE
# str1 = "Leo"
# print("Hello world!",str1)
# 初始化像素灯引脚
pixel_pin = board.NEOPIXEL
# 设置像素灯数量
num_pixels = 1
# 初始化像素灯
pixels = neopixel.NeoPixel(
pixel_pin, num_pixels, brightness=0.2, auto_write=False, pixel_order=neopixel.GRB
)
# 初始化blink动态效果,speed 闪烁频率0.5m
blink = Blink(pixels, speed=0.5, color=BLACK)
# 初始化btn按钮对象
btn = DigitalInOut(board.BOOT0)
# 设置btn引脚为输入
btn.direction = Direction.INPUT
# 设置btn引脚为上拉
btn.pull = Pull.UP
# 定义led_color变量,用于五种颜色切换
led_color = 0
# 进入while循环
while True:
# 判断按键是否按下
if not btn.value:
# 若按键按下,则对led_color求余数,根据余数指定led颜色
if led_color % 3 == 0:
blink = Blink(pixels, speed=0.5, color=RED)
print("LED is RED")
elif led_color % 3 == 1:
blink = Blink(pixels, speed=0.5, color=BLUE)
print("LED is BLUE")
elif led_color % 3 == 2:
blink = Blink(pixels, speed=0.5, color=GOLD)
print("LED is GOLD")
# led_color 增加1
led_color = led_color + 1
else:
# 按键未按下时啥也不干
pass
time.sleep(0.2)
blink.animate()
In the imported adafruit_led_animation library, we selected the blink animation effect because there is only one light on the board, so this is easy to display. The first parameter of the blink function is the initial function of the LED light.
neopixel.NeoPixel function is used to process LED lights. The default library has solidified the onboard pixel lights and screen instances in the firmware. You can use board.NEOPIXEL to assign values to pins. Since there is only one pixel light on the board, the number of lights is also set to 1.
Task 4 Calendar & Clock Display
First, get the current time through network access. Only with the current time can the date, temperature and weather be displayed. Get the real-time time by calling http://vv.video.qq.com/checktime?otype=json . Write a week conversion function to display the week in Chinese characters. Then, apply for a key in the Gaode API and get the corresponding city and weather conditions through the requests function. Then get the corresponding weather conditions every hour and display them. This function can obtain the local external network IP address through the external network, and then obtain the local city code through the IP address, and then call Gaode's weather display. In the experiment, it was found that the external network IP address obtained at home could not obtain the corresponding weather information through the Gaode API. Therefore, this code is not posted.
import board
# 导入displayio库(内置的)
import displayio
# 导入外部库adafruit_imageload,如果没有就在教程附件下载
import adafruit_imageload
# 导入外部库adafruit_display_text里的lable,用于显示标签
from adafruit_display_text import label
# 导入外部库adafruit_bitmap_font里的lable
from adafruit_bitmap_font import bitmap_font
# 导入os库,用来获取wifi信息
import os
# 导入rtc库,实现RTC时钟
import rtc
# 导入wifi、time库备用
import wifi
import time
# 导入网络库备用
import ssl
import socketpool
import adafruit_ntp
import adafruit_requests
import json
from adafruit_datetime import datetime, date,timezone,timedelta
# 使用固件自带的屏幕设备,不需要另行初始化屏幕参数
display = board.DISPLAY
# 创建本例程里的唯一图像组
group = displayio.Group()
# 加载图片
image, palette = adafruit_imageload.load("/pic/bg2.png")
# 是否开启透明
palette.make_transparent(0)
# 创建图片布局
grid = displayio.TileGrid(image, pixel_shader=palette)
# 将图片布局添加到图像组,由于是第一个添加的,默认是最下层
group.append(grid)
# 显示当前图像组
display.show(group)
# 加载字体并定义字体颜色为黑色
font = bitmap_font.load_font("/font/myfont1.pcf")
nun_font = bitmap_font.load_font("/font/myfont2.pcf")
color = 0x000000
# 初始化日期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
date = label.Label(font, text="00月00日", color=color)
date.x = 50
date.y = 20
group.append(date)
# 初始化星期标签并设置x,y轴绘图坐标,然后将标签添加到图像组
week = label.Label(font, text="周一", color=color)
week.x = 30
week.y = 120
group.append(week)
# 初始化时间标签并设置x,y轴绘图坐标,然后将标签添加到图像组
timeT = label.Label(nun_font, text="00:00", color=color)
timeT.x = 15
timeT.y = 60
group.append(timeT)
# 初始化温度标签并设置x,y轴绘图坐标,然后将标签添加到图像组
temp = label.Label(font, text="30°", color=color)
temp.x = 80
temp.y = 120
group.append(temp)
# 初始化天气标签并设置x,y轴绘图坐标,然后将标签添加到图像组
tempzh = label.Label(font, text="晴", color=color)
tempzh.x = 130
tempzh.y = 120
group.append(tempzh)
# 显示修改后的图像组
display.show(group)
# while True:
# pass
# 使用os.getenv函数,从setting.toml文件里获取wifi ssid和密码
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
# 连接到 wifi
print("Connecting to", ssid)
wifi.radio.connect(ssid, password)
print("Connected to", ssid)
TEXT_URL= "http://vv.video.qq.com/checktime?otype=json"
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
response = requests.get(TEXT_URL)
timestamp = time.time()
txt = response.text.split("QZOutputJson=")[1]
print(txt)
#print(txt)
data = json.loads(txt.replace(";",""))
local_time = datetime.fromtimestamp(data["t"])
rtc.RTC().datetime=time.localtime(data["t"] + 8*3600)
def get_wday(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 "周日"
# 初始化requests对象
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
def get_weather():
# 设置城市id
city = "450900"
# 这个函数使用的是高德API,使用该API需要先去注册相关账户,申请key。
key = ""
# 拼接天气链接url
getweather_url = "https://restapi.amap.com/v3/weather/weatherInfo?city=" + city + "&key=" + key
# 获取天气json数据
response = requests.get(getweather_url)
json_resp = response.json()
# 关闭连接
response.close()
# 解析json数据,并返回温度和天气信息
for da in json_resp["lives"]:
#print(da["temperature"])
return da["temperature"], da["weather"]
# 先创建一个status变量,用来在设备启动时获取天气信息
status = "boot"
# 主循环
while True:
# 每秒获取一次本地RTC时间
t = time.localtime()
# 首次启动或者本地RTC时间的分钟属性为0时,更新日期标签和天气标签
if (status == "boot" or t.tm_min == 0):
# 更新日期标签
date.text = "%d月%d日" % (t.tm_mon, t.tm_mday)
week.text = get_wday(t.tm_wday)
# 获取天气信息
str_t, str_tz = get_weather()
# 更新温度标签
temp.text = "%s°" % (str_t)
# 更新天气标签
tempzh.text = str_tz
status = "updated"
# 每隔1秒 更新一次时钟标签,用于动态显示
if (t.tm_sec % 2 == 0):
timeT.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
timeT.color = 0x000000
else:
timeT.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
timeT.color = 0xD9D7C9
# 刷新屏幕
display.show(group)
# 休眠1秒
time.sleep(1)
# while True:
# pass
My thoughts on this event:
This is my first time to participate in Digi-Key's follow-up project, and it is also my first time to program with CircuitPython. I originally planned to use Arduino to implement it, but due to work reasons, I did not have enough time. It is a pity that CircuitPython does not have a Bluetooth library. In the subsequent study, I plan to use Arduino to achieve the same function. I hope I can gain more knowledge about microcontrollers.
Code download link: https://download.eeworld.com.cn/detail/java620/629883
|