手下败酱

  • 2023-12-12
  • 发表了主题帖: 【得捷电子Follow me第2期】+基于CircuitPython的任务总结 【修改调整版】

    本帖最后由 手下败酱 于 2023-12-13 11:20 编辑 //内容一:3-5分钟短视频// 上传视频:【得捷电子Follow me第2期】任务项目简-【得捷电子Follow me第2期】任务项目简介-EEWORLD大学堂 //内容二: 任务/项目总结报告// 项目介绍  使用 Adafruit ESP32-S3 TFT Feather 这块MINI的开发板上的资源和一些模块在基于CircuitPython来实现以下几个项目任务的功能:     1、任务1:控制屏幕显示中文(必做任务) 完成屏幕的控制,并且能显示中文     2、任务2:网络功能使用(必做任务) 完成网络功能的使用,能够创建热点和连接到WiFi     3、任务3:控制WS2812B(必做任务) 使用按键控制板载Neopixel LED的显示和颜色切换     4、任务4:日历&时钟 完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息 各任务功能对应的主要代码片段及说明&&各任务功能展示及说明   任务1:控制屏幕显示中文  效果图 任务功能对应的主要代码片段及说明 准备工作:  Adafruit ESP32-S3 TFT Feather  板子  拿到板子之后把下载到的包(adafruit-circuitpython-adafruit_feather_esp32s3_tft-en_US-8.2.6.uf2)拖到电脑显示的U盘里面   还需要有几个工具,因为要显示的中文字,在库里面没有哦,所以需要自己生成或者使用别人整理好的字库文件,当然使用自己喜欢的字体是多么美好的一件事情啦。  FontSmaller_2.0  FontSmaller 字体文件子集化工具     u8g2_fontmaker   breakstring/u8g2_fontmaker: U8G2字体生成懒人工具 (github.com) 这两个就是我生成bdf的字库的工具了,使用方法也非常简单 在自己电脑路径找一下自己喜欢的字体 C:\Windows\Fonts  打开FontSmaller_2.0  直接选中喜欢的字体,再出入自己需要显示的 字   点击  OK 选择生成路径,这样字库就好了   再用u8g2_fontmaker转bdf一下就好了  具体用法去看一下reade me  就知道了 其实就是修改这个文件就行了,对了别忘记把刚刚转的字体文件放进 font 文件        最后把生成的bdf文件拖进自己放字体的文件夹  听说把bdf转成pdf 加载速度会更快些 网站我也丢这里了 BDFtopCF字体转换器 (adafruit.github.io)    以下为code.py 中的源代码说明 这段主要是导入相关的模块有板子自带的,也有存放在板子U盘中 #导入自带模块 import board import displayio #导入显示图片、显示位图字体模块等其他的 import adafruit_imageload from adafruit_bitmap_font import bitmap_font from adafruit_display_text.scrolling_label import ScrollingLabel from adafruit_display_text import label from adafruit_st7789 import ST7789 一些TFT屏幕的初始化,还有一些定义 # 使用固件自带的屏幕设备,不需要另行初始化屏幕参数 display = board.DISPLAY # 创建本例程里的唯一图像组 group = displayio.Group() # 加载字体并定义字体颜色为黑色 font = bitmap_font.load_font("/font/Jay_Chou-16.bdf") nun_font = bitmap_font.load_font("/font/UPO-48.bdf") color = 0xFFFFFF     这段主要是对label的处理,先把显示的内容存放,再调用label函数  第一个函数是字体  第二个是显示的文本  第三个是显示的颜色  第四个是显示的背景颜色,最后一个是最大宽度,在设置一下ScrollingLabel函数实现滚动   最后显示图像数组,最后在主循环中循环滚动 ############################显示########################################## date = label.Label(font, text=" 晴天 \n – 周杰伦 (Jay Chou)", color=color) date.x = 10 date.y = 10 group.append(date) text1 = "\n 故事的小黄花\n 从出生那年就飘着\n 童年的荡秋千\n 随记忆一直晃到现在\n Re So So Si Do Si La\n So La Si Si Si Si La Si La So\n 吹着前奏望着天空\n 我想起花瓣试着掉落\n " text_area = label.Label(font, text=text1, color=0x0000FF, background_color=0xFFAA00,max_characters=20) #max_characters 显示的长度 animate_time 滚动的速度 text_area =ScrollingLabel(font,text=text1, max_characters=80, animate_time=0.26) text_area.x = 10 text_area.y = 68 group.append(text_area) ############################################################################### # 显示修改后的图像组 display.show(group) #循环 while True: text_area.update() 这里是整个工程的文件  任务1_中文显示.rar  这是效果是视频 [localvideo]614b73388c1d2c22b381e17dc8b962ee[/localvideo]   任务2:网络功能使用(必做任务)    效果图 注:上图最上面显示的IP地址是已连接到WIFI,给分配的IP   最下面打印的那两行是创建的热点,WIFI名称以及WIFI密码 手机可以搜索到     任务功能对应的主要代码片段及说明 首先是创建热点,这也非常简单,导入 import wifi 这个库 然后再调用 start_ap 这个函数,填入你的热点名称和密码 即可 也可以把创建的name 、password以及IP add 打印到屏幕上去,这里我只把  name 、password显示出来了,以下是全部代码 import os import time import ssl import wifi import socketpool import microcontroller import adafruit_requests wifi.radio.start_ap("adafruit_wifi", "12345678") print(f"NtworkName: adafruit_wifi") print(f"Password: 12345678") while True: pass 连接WIFI  配置下面这个文件就可以了   这是源码   任务3:控制WS2812B(必做任务) 大概思路:     先处理LED引脚的定义和LED 驱动      再去处理按键的一些定义和按键处理逻辑,还有屏幕的初始化     最后在主循环中一直循环判断哪一个按键按下     再去执行LED和TFT的效果   任务功能对应的主要代码片段及说明     关于导入的相关库 # 导入board内置库 import board # 导入neopixel内置库 import neopixel import digitalio,terminalio,displayio # 导入time内置库 import time import key from adafruit_display_text import label # 从digitalio内置库导入DigitalInOut, Direction, Pull from digitalio import DigitalInOut, Direction, Pull # 从adafruit_led_animation.color库导入五种颜色定义 from adafruit_led_animation.color import JADE,BLACK, ORANGE, GOLD, OLD_LACE 先去处理关于LED相关的引脚以及LED的驱动,这里我使用了两个引脚来驱动 WS2812  #关于LED的定义************************************************************************** led_io = digitalio.DigitalInOut(board.NEOPIXEL_POWER) led_io.direction = digitalio.Direction.OUTPUT led_io.value = True pixel = neopixel.NeoPixel(board.NEOPIXEL, 1) # 亮度 pixel.brightness = 0.1 pixe2 = neopixel.NeoPixel(board.A0, 16) # 亮度 pixe2.brightness = 0.1 这里就是我单独写的一个按键处理的文件。定义了5个按键都是独立按键 # 初始化btn按钮对象 btn = DigitalInOut(board.BOOT0) # 设置btn引脚为输入 btn.direction = Direction.INPUT # 设置btn引脚为上拉 btn.pull = Pull.UP ...... ...... btn4 = DigitalInOut(board.A4) # 设置btn1引脚为输入 btn4.direction = Direction.INPUT # 设置btn引脚为上拉 btn4.pull = Pull.UP def key(): time.sleep(0.1) # sleep for debounce if btn.value==0: time.sleep(0.1) # sleep for debounce if btn.value==0: return 1 elif btn1.value==0: return 2 elif btn2.value==0: return 3 elif btn3.value==0: return 4 elif btn4.value==0: return 5 else : return 0 配置屏幕的参数,这里直接调用封装号的配置处理 #屏幕的基础配置 display= board.DISPLAY 下面就是主循环了: # 进入while循环 while True: #进入循环先一直判断按键按下 key_value=key.key() # 判断按键是否按下 if key_value!=0: # 若按键按下,则根据余数指定led颜色 time.sleep(0.1) #这里就是按键消抖 print(key_value) #打印哪一个按键按下 if key_value == 1: #按键1按下了,执行里面的程序 pixel.fill((JADE))# 玉色 pixe2.fill((JADE))# 玉色 text ="JADE" text_area =label.Label(terminalio.FONT,text=text, color=JADE,x=10,y=30) text_group=displayio.Group(scale=2 ,x=0,y=0) text_group.append(text_area) display.show(text_group) elif key_value == 2: pixel.fill((ORANGE))# 橙色 pixe2.fill((ORANGE))# 橙色 text ="ORANGE" text_area =label.Label(terminalio.FONT,text=text, color=ORANGE,x=10,y=30) text_group=displayio.Group(scale=2 ,x=0,y=0) text_group.append(text_area) display.show(text_group) elif key_value == 3: pixel.fill((GOLD))# 金色 pixe2.fill((GOLD))# 金色 text ="GOLD" text_area =label.Label(terminalio.FONT,text=text, color=GOLD,x=10,y=30) text_group=displayio.Group(scale=2 ,x=0,y=0) text_group.append(text_area) display.show(text_group) elif key_value == 4: pixel.fill((OLD_LACE))# pixe2.fill((OLD_LACE))# text ="OLD_LACE" text_area =label.Label(terminalio.FONT,text=text, color=OLD_LACE,x=10,y=30) text_group=displayio.Group(scale=2 ,x=0,y=0) text_group.append(text_area) display.show(text_group) elif key_value == 5: pixel.fill((BLACK))# 黑色 pixe2.fill((BLACK))# 黑色 text ="BLACK" text_area =label.Label(terminalio.FONT,text=text, color=BLACK,x=10,y=30) text_group=displayio.Group(scale=2 ,x=0,y=0) text_group.append(text_area) display.show(text_group) else: # 空 pass [localvideo]0eb742c4355cd9425c216e8849a376e3[/localvideo] 这是源代码文件: 任务4:日历&时钟——完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息 完成一个可通过互联网更新的万年历时钟,并显示当地的天气信息      效果图 首先把界面给弄好,文字显示位置,以及图片大小,文字大小都需要考虑,这些我都在 Pixso 上处理的 主要思路:            先是处理界面根据在Pixso 上处理的图片,显示在TFT屏幕上面 # 使用固件自带的屏幕设备,不需要另行初始化屏幕参数 display = board.DISPLAY ############################图片显示########################################## # 创建本例程里的唯一图像组 group = displayio.Group() # 加载图片 image, palette = adafruit_imageload.load("/PIC/beijing.png") # 是否开启透明 palette.make_transparent(1) # 创建图片布局 grid = displayio.TileGrid(image, pixel_shader=palette) # 将图片布局添加到图像组,由于是第一个添加的,默认是最下层 group.append(grid) # 显示当前图像组 display.show(group) ############################################################################### # 加载字体并定义字体颜色为黑色 font = bitmap_font.load_font("/font/MYout-24.bdf") nun_font = bitmap_font.load_font("/font/UPO-48.bdf") color = 0x000000 date = label.Label(font, text="10月 31日", color=color) date.x = 25 date.y = 18 group.append(date) # 初始化星期标签并设置x,y轴绘图坐标,然后将标签添加到图像组 week = label.Label(font, text="周六", color=color) week.x = 179 week.y = 8 group.append(week) # 初始化时间标签并设置x,y轴绘图坐标,然后将标签添加到图像组 time = label.Label(nun_font, text="22:59", color=0xF2C3BD) # time.x = 20 # time.y = 60 time.x = 29 time.y = 65 group.append(time) # 初始化天气标签并设置x,y轴绘图坐标,然后将标签添加到图像组 tempzh = label.Label(font, text="23°~34° 晴", color=color) tempzh.x = 25 tempzh.y = 101 group.append(tempzh)    再处理网络时间更新,调用RTC函数来更新时间 , 再去处理高德API接收的值,这里分别接收了 温度和天气信息 pool = socketpool.SocketPool(wifi.radio) ntp = adafruit_ntp.NTP(pool, tz_offset=8, server="ntp.aliyun.com") # 使用ntp时间更新系统时间 rtc.RTC().datetime = ntp.datetime # 初始化requests对象 pool = socketpool.SocketPool(wifi.radio) requests = adafruit_requests.Session(pool, ssl.create_default_context()) def get_weather(): # 设置城市id city = "410702" # 这个函数使用的是高德API,使用该API需要先去注册相关账户,申请key。 key = "7121e4b427fa6f27704655b62db83d61" # 拼接天气链接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_sec == 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" print(ssid) print(str(wifi.radio.ipv4_address) ) # 每隔1秒 更新一次时钟标签,用于动态显示 if (t.tm_sec % 2 == 0): timel_s.text = ":%02d" % ( t.tm_sec) else: timel.text = "%02d:%02d" % ( t.tm_hour, t.tm_min) timel_s.text = ":%02d" % ( t.tm_sec) key_value=key.key() # 判断按键是否按下 if key_value!=0: # 若按键按下,则对led_color求余数,根据余数指定led颜色 time.sleep(0.1) print(key_value) if key_value == 1: pixel.fill((JADE))# 玉色 pixe2.fill((JADE))# 玉色 timel_s.color = JADE timel.color = JADE elif key_value == 2: pixel.fill((ORANGE))# 橙色 pixe2.fill((ORANGE))# 橙色 timel_s.color = ORANGE timel.color = ORANGE elif key_value == 3: pixel.fill((GOLD))# 金色 pixe2.fill((GOLD))# 金色 timel_s.color = GOLD timel.color = GOLD elif key_value == 4: pixel.fill((PINK))# pixe2.fill((PINK))# timel_s.color = PINK timel.color = PINK elif key_value == 5: pixel.fill((BLACK))# 黑色 pixe2.fill((BLACK))# 黑色 timel_s.color = BLACK timel.color = BLACK else: pass# 空 # 刷新屏幕 display.show(group) 下面是效果视频:[localvideo]825099034d59ec9447f4c40d6c7bd86b[/localvideo] 该工程文件: 其他:LTR—329光传感器模块&MCP9808温度传感器 温度传感器(MCP9808)         这款 I2C 数字温度传感器是我们见过的准确度更高的传感器之一,在传感器的 -40°C 至 +125°C 范围内的典型精度为 ±0.25°C,精度为 +0.0625°C。 它们适用于任何使用标准 i2c 的微控制器。有 3 个地址引脚,因此您最多可以将 8 个地址引脚连接到单个 I2C 总线,而不会发生地址冲突。最重要的是,宽电压范围使2.7V至5.5V电压可用! 引脚说明: VIN (仅接头版本的 VDD) - 这是正电源和逻辑电平引脚。它可以是2.7-5.5VDC,因此适合与3或5V逻辑一起使用。电源 VIN (VDD),具有您计划在 i2c 线路上使用的任何逻辑电平。 GND - 这是接地电源和逻辑参考引脚。 SCL - 这是 I2C 时钟引脚。板上已经有一个 10K 上拉,因此请将其直接连接到微控制器上的 i2c 主时钟引脚 SDA - 这是 I2C 数据引脚。板上已经有一个 10K 上拉,因此请将其直接连接到微控制器上的 i2c 主数据引脚 Alert - 这是来自MCP9808的中断/警报引脚。芯片具有一定的功能,可以在芯片温度高于或低于设定量时“提醒”您。可以触发此输出以告知你。它是集电极开路,因此如果要从该引脚读取信号,则需要使用上拉电阻。 A0(以及 A1 和 A2)- 这些是地址选择引脚。由于在 i2c 总线上只能有一个具有给定地址的设备,因此如果要在共享 i2c 总线上放置多个MCP9808,则必须有一种方法来调整地址。A0/A1/A2引脚设置i2c地址的底部三位。电路板上有下拉电阻,因此将它们连接到VDD以将位设置为“1”。它们在通电时读取,因此解除电源并重新通电以重置地址            默认地址0x18,地址可以通过将 A0/A1/A2 “添加”到0x18           A0 设置值为 1 的最低位,A1 设置值为 2 的中间位,A2 设置值为 4 的高位。最终地址是 0x18 + A2 + A1 + A0。           因此,例如,如果 A2 与 VDD 绑定,A0 与 VDD 绑定,则地址为 0x18 + 4 + 1 = 0x1D。           如果只有 A0 绑定到 VDD,则地址为 0x18 + 1 = 0x19           如果只有 A1 绑定到 VDD,则地址为 0x18 + 2 = 0x1A           如果只有 A2 绑定到 VDD,则地址为 0x18 + 4 = 0x1C 接线方式: 那接下来就是代码了 import time #导入延时库 import board #导入板子的资源库 import adafruit_mcp9808 #导入模块的库 i2c = board.I2C() # 使用板载的SDA和SCL mcp = adafruit_mcp9808.MCP9808(i2c) # 使用默认地址进行初始化: while True: tempC = mcp.temperature tempF = tempC * 9 / 5 + 32 #转换成 F print("Temperature: {} C {} F ".format(tempC, tempF)) time.sleep(4) 那如果把它添加到我的天气时钟上面呢:由于我往上面哈气,温度飙到了30多° 光传感器(LTR-329) LTR-329 光传感器是一款简单且流行的低成本 I2C 数字光传感器,易于集成到您的项目中,以实现可靠和广泛的光测量。     LTR-329ALS-01 规格: I2C 接口,最高快速模式 @ 400kbit/s,地址0x29(无法更改) 超小型芯片LED封装 内置温度补偿电路 待机模式下的低有功功耗 工作温度范围为 -30 C 至 +70 C 符合 RoHS 和无卤素标准 接近人眼光谱响应的光传感器 对红外/紫外线光源的抗扰度 自动抑制 50 / 60 Hz 灯光闪烁 6 种动态范围,从 0.01 勒克斯到 64k 勒克斯 16 位有效分辨率      尺寸:25.4 毫米 x 17.7 毫米 x 4.6 毫米 / 1.0“ x 0.7” x 0.2” 引脚说明 VIN - 这是电源引脚。要为电路板供电,请为其提供与微控制器逻辑电平相同的功率 - 使用5V。 3V - 这是稳压器的 3.3V 输出,如果您愿意,您可以从中获取高达 100mA 的电流。 GND - GND SCL - I2C 时钟引脚,连接到微控制器 I2C 时钟线。该引脚经过电平转换,因此可以使用 3-5V 逻辑,并且该引脚上有一个 10K 上拉。 SDA - I2C 数据引脚,连接到您的微控制器 I2C 数据线。该引脚经过电平转换,因此可以使用 3-5V 逻辑,并且该引脚上有一个 10K 上拉。 它的使用方法也非常简单 调用LTR329的库,再显示到TFT屏上 import time import board from adafruit_ltr329_ltr303 import LTR329 #导入外部库 import displayio # 导入外部库adafruit_display_text里的lable,用于显示标签 from adafruit_display_text import label # 导入外部库adafruit_bitmap_font里的lable from adafruit_bitmap_font import bitmap_font i2c = board.I2C() # 使用板载的SDA和SCL time.sleep(0.1) # 传感器需要100毫秒才能“启动”上电 ltr329 = LTR329(i2c) #使用封装好的TFT驱动 display = board.DISPLAY #创建显示组 group = displayio.Group() #加载字体 font = bitmap_font.load_font("/font/MYout-24.bdf") #用于显示 光强度的参数 Visible_ = label.Label(font, text="00", color=0xFF0707) Visible_.x = 5 Visible_.y = 18 group.append(Visible_) #用于显示 红外线的参数 Infrared_ = label.Label(font, text="00", color=0xFF07C5) Infrared_.x = 5 Infrared_.y = 68 group.append(Infrared_) while True: Visible= ltr329.visible_plus_ir_light Infrared=ltr329.ir_light Visible_.text="Visible: %d" %(Visible) Infrared_.text="Infrared: %d" %(Infrared) print("Visible + IR:", ltr329.visible_plus_ir_light) print("Infrared :", ltr329.ir_light) print() display.show(group) time.sleep(0.5) # sleep0.5 S 对本活动的心得体会                 非常荣幸参见本次活动,也非常感谢得捷对这次活动的支持,通过这次任务的学习,也让我从一个Python小白,成功了入了门,通过实践的效果,也有了更加深刻的印象,我非常认为这样的活动非常不错,最起码,自己也是亲手操作了,期间我自己也遇到 了不少问题,通过观看,直播教学,还有大佬们的相关教程,也解决了不少问题,也可以说顺利结束了本次活动,这次是第二期活动,现在我已经期待着第三期活动了,最后还是要感谢得捷平台,还有一些大佬的教程   //内容三:可编译下载的代码// 任务源文件:https://download.eeworld.com.cn/detail/%E6%89%8B%E4%B8%8B%E8%B4%A5%E9%85%B1/629595#related  

  • 加入了学习《【得捷电子Follow me第2期】任务项目简介》,观看 【得捷电子Follow me第2期】任务项目简

最近访客

< 1/1 >

统计信息

已有6人来访过

  • 芯积分:98
  • 好友:1
  • 主题:7
  • 回复:3

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言