[作品提交] 【得捷电子Follow me第2期】项目汇总

java620   2023-11-15 11:53 楼主

一 任务汇总视频

视频链接:https://training.eeworld.com.cn/video/38575

 

 

二 开发板介绍

      本次采用的是 Adafruit ESP32-S3 开发板带TFT屏幕,开发板采用的是上海乐鑫的ESP32-S3芯片。芯片是支持蓝牙(CircuitPython 不支持),wifi。据了解esp32-s3 及其衍生产品主要用于物联网产品中。

 

三 项目介绍

      本次follow 2 是需要完成4个任务。我选择的是完成:1.控制屏幕显示中文 2.网络功能(包括创建wifi热点与连接wifi)3. 利用按键控制板载led的显示与颜色切换 4. 日历&时钟的显示。经过对比选择CircuitPython 来进行开发。看过“忙碌的死龙”的视频,结合自己实际使用的情况。发现如下问题:

           1.选择采用web 的方式连接串口进行调试,时常会出现web页面连接串口不成功的情况。

           2.选择vscode 打开code.py 文件,但是却无法查看到串口 REPL 的信息。

           因而,选择mu editor 编辑器。 可以编辑CircuitPython 代码文件,同时可以稳定的打开串口调试窗口。

       任务一 控制屏幕显示中文

image.png  

image.png  

        本任务是首个任务,首先要熟悉怎么烧录 CircuitPython 的固件。访问https://circuitpython.org/board/adafruit_feather_esp32s3_tft/ 选择uf2 固件下载。然后,连接按开发板上的rst键2次,进入烧录界面。然后把下载的adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.6.uf2 固件复制到开发板中。即烧录成功。

        接下来,是要完成中文字体显示。首先需要知道,要调用相应的库。库的下载地址为:https://circuitpython.org/libraries。  根据烧录的程序下载“Bundle for Version 8.x”版本的库。解压到本地后,进入解压文件夹的lib文件夹下     复制adafruit_bitmap_font文件夹,adafruit_imageload文件夹,adafruit_display_text文件夹,到开发板的lib的文件夹下。

        需要显示相应的汉字则需要处理字库。首先可以选择在网上下载相应的字库ttf文件。然后利用Fontmin 软件打开相应的字库文件,选取相应的需要用到的字符及数字,保存为一个新的ttf文件,该文件仅仅包含了所选的字符。然后利用FontForge软件生成bdf文件。但是此文件加载会慢。于是,参考https://learn.adafruit.com/custom-fonts-for-pyportal-circuitpython-display中提到的相关内容,利用https://adafruit.github.io/web-bdftopcf/ 网址,在线把bdf文件转成pcf文件。请注意,bdf文件其实比pcf文件要小,只是加载的慢。pcf 文件稍大,但是加载的快。接下来编辑代码显示相关的汉字。

# 在这里写上你的代码 :-)
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

任务二 网络功能(包括创建wifi热点与连接wifi)

      1. 连接wifi

          wifi连接只需要修改相应的配置文件即可。修改开发板文件夹根目录下的 settings.toml文件相应字段。

           CIRCUITPY_WIFI_SSID = "当前要连接的WIFI名"

           CIRCUITPY_WIFI_PASSWORD = "当前要连接的WiFi密码"

            保存后按板上的rst键,开发板会自动连接wifi,并获取ip地址。

image.png  

2. wifi热点

     

import wifi

wifi.radio.start_ap("rz", "12345678")

  以上2行代码可以让手机搜索rz 进行连接。在实验中发现,尽量设置了settings.toml中wifi连接,且热点连接成功,但是所连接的手机仍然不能上网。

 

任务三 利用按键控制板载led的显示与颜色切换

image.png  

   任务一中下载的库文件,复制neopixel.mpy 文件, adafruit_led_animation文件夹到 开发板的lib 文件夹下。

  导入相应的库文件,并有选择的导入需要显示的灯的颜色。本利用boot按键来切换led灯的颜色,查看开发板电路原理图,

image.png   boot按键是低电平有效。则在代码中我们设置boot 上拉,输入。

 

然后利用按键次数,与所显示的颜色求余, 每3次循环一次。

# 导入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()

其中所导入的adafruit_led_animation 库,我们选择了blink(闪烁)动态效果,因为板子上面只有1个灯,所以这个想过容易显示出来。Blink函数第一个参数是led灯的初始函数。利用

neopixel.NeoPixel 函数进行处理化led灯。默认库在固件里就固化了板载像素灯和屏幕实例, 可以使用board.NEOPIXEL来给引脚赋值,由于板载只有1个像素灯,所以灯的数量也只设置成1。

 

任务四 日历&时钟的显示

 

image.png  

首先通过网络访问获取当前的时间,有了当前的时间,才能显示日期,及温度,天气。通过调用 http://vv.video.qq.com/checktime?otype=json 获取实时时间。编写星期转换函数,把星期用汉字显示出来。然后,在高德api申请一个key,通过requests函数获取相应的城市及天气情况。然后通过每一个小时获取相应的天气情况,并显示出来。本功能可以通过外网获得本地的外网的ip地址,然后通过ip地址获取本地的城市代码,进而调用高德的天气显示。 在实验中发现,在家里获取的外网ip地址,无法通过高德api获取相应的天气信息。因而,此段代码未贴出。

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

 

对本次活动的心得:

       本次是我第一次参加得捷的follow 项目,也是我第一次用CircuitPython进行编程,原本计划用arduino进行实现,但是因为工作的原因,时间不够了。CircuitPython无蓝牙库是一个遗憾。在后续的学习中,我计划用arduino  来实现同样的功能。希望我能获取更多的单片机的知识。

 

代码下载链接:https://download.eeworld.com.cn/detail/java620/629883

 

 

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复