【得捷电子Follow me第2期】任务汇总提交帖子
[复制链接]
本帖最后由 walker2048 于 2023-10-20 15:29 编辑
经过一段时间的努力,总算完成了本次活动的内容。
一、演示视频
二、项目总结报告:各阶段作业
1、任务1:使用CircuitPython显示图片和中文(点击链接查看详细教程)
任务1其实就是通过调用CircuitPython的库,实现屏幕显示和字体显示,而固件并没有内置中文字体,需要用户自行把中文字体给处理好。
displayio简介
displayio 是 CircuitPython 中用于管理和控制显示设备(通常是液晶屏或 OLED 屏幕)的库。它提供了一种方式来创建和管理图形元素,以便在显示设备上绘制各种图形和文本。 简单来说,就是可以用display系列库来制作一些简单的界面。而最简单的莫过于使用背景图片加文字的形式。
首先,我们需要创建一个 displayio.Display 对象,该对象表示物理显示设备。这块板子的固件默认已经绑定好显示设备,我们只需要引入对应的库,并调用即可。 完全不需要去管显示屏驱动,分辨率,偏移量那些东西。
接下来,我们可以创建一个或多个 displayio.Group 对象,它们用于组织图形元素。每个对象可以包含多个图形元素,它们将按照添加的顺序绘制到显示设备上。 同一时间只显示一个对象,可以创建多个 displayio.Group 来实现屏幕切换。
我们可以使用label.Label函数来创建一个文字标签,这个函数需要三个参数。 第一个是字体,显示中文必须使用自定义字体,固件自带是没有中文的。 第二个参数是需要显示的文字内容,第三个参数是字体颜色。像刚刚说的,我们需要使用自定义字体,这就得使用bitmap_font.load_font方法来加载字体了。 如代码里显示的,只需要传递正确的字体路径参数即可。 然后字体颜色可以指定一下,代码里使用的是黑色。 由于我们做时钟,需要使用两种不同大小的字体,这里我使用了思源黑体的16号优化天气字体。 只包含了很少的字,体积比较小,加载时间比较快。 而时钟使用了60磅的字体,字体大一些,只包含数字。首先我们创建一个名称为date的标签(label),并设置这个标签的x轴和y轴起点偏移量,最后将这个标签加入图像组。 用同样的方式添加week,time,temp,tempzh几个标签,这几个标签的x,y轴起点都需要自己慢慢调整。标签都添加后,就可以使用display.show(group)把标签显示了。 最后定义一个死循环,屏幕的内容就会固定住了。 从视频可以看到背景、各个标签的加载过程,按加入的顺序一个个显示出来了。

2、任务2:wifi联网和wifi 热点(点击链接查看详细教程)
其实CircuitPython的联网非常简单,只要setting.toml配置里添加相关配置即可。
配置完,重启后,可以看到板子上已正常显示IP地址,如下图所示。

使用以下代码可以轻松创建一个名称为cpy_wifi,密码是temppasswd的热点,连接后可以获取到ip地址,但是无法连接互联网。
- import os
- import time
- import ssl
- import wifi
- import socketpool
- import microcontroller
- import adafruit_requests
-
- wifi.radio.start_ap("cpy_wifi", "temppasswd")
- print(f"SSID: cpy_wifi")
- print(f"PASSWORD: temppasswd")
-
- while True:
- pass

3、任务3:控制WS2812B(点击链接查看详细教程)
CircuitPython点灯非常简单
由于本次活动的开发板子上只有一个ws2812灯,作为入门学习,也没必要了解这么多的动效。所以本次也只学习如何使用blink库。 要使用库,就得先导入库。
这里有两种不同的导入方式,第一种就是import board, 意思是导入board模块,完整调用board这个模块,然后可以使用这个模块提供的所有功能。需要使用对应实例或者函数的时候,就得这样用,例如board.NEOPIXEL。 第二种from adafruit_led_animation.color import JADE, BLACK, ORANGE, GOLD, OLD_LACE,意思是从adafruit_led_animation.color模块里导入JADE, BLACK, ORANGE, GOLD, OLD_LACE这几个符号,其他的不导入,不导入的自然就不能使用了。 通过阅读adafruit_led_animation.color的源码,可以了解到,这几个符号都是不同颜色元组,也可以理解成led灯的颜色。 只导入部分内容,并不会节省内存或者提高执行效率,只是可以少打点字,让代码更清晰罢了。例如现在使用JADE颜色只需要打JADE就可以了。
库导入了,就接下来就应该初始化引脚和像素灯实例了
由于这个板子是CircuitPython官方支持的板子,在固件里就固化了板载像素灯和屏幕实例。 我们的代码可以使用board.NEOPIXEL来给引脚赋值,由于板载只有1个像素灯,所以灯的数量也只设置成1。 初始化pixels,是使用了neopixel库的NeoPixel函数来初始化,亮度设置为20%。 NeoPixel函数的第一个参数pixel_pin是像素灯的数据引脚,第二个参数num_pixels是像素灯的数量,第三个参数brightness是像素灯的亮度,第四个参数auto_write是配置是否直接刷新数据,第五个 pixel_order是指定像素灯的RGB数据排列模式(目前是使用GRB模式)。 前面两个参数是必须的,位置也是固定的,后面三个参数使用了指定名称来传递,可以不用管(demo里抄过来的) 然后再给像素灯默认配置成黑色(不点亮)的状态。
成品图片展示
4、任务4:日历&时钟(点击链接查看详细教程)
在实现了界面的基础上,只需要添加ntp网络校时、天气信息获取和更新的功能,就可以把这个天气时钟做好了。
使用adafruit_ntp.NTP函数初始化ntp服务,第一个函数是确定网络连接端口,
第二个函数设置时区,中国是+8时区,第三个函数用来指定ntp服务器地址。
然后使用ntp时间更新系统时间。
编写星期数据转换函数和编写天气获取函数
- 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 "周日"
-
-
- pool = socketpool.SocketPool(wifi.radio)
- requests = adafruit_requests.Session(pool, ssl.create_default_context())
-
- def get_weather():
-
- city = "450900"
-
- key = "1xxx"
-
- getweather_url = "https://restapi.amap.com/v3/weather/weatherInfo?city=" + city + "&key=" + key
-
- response = requests.get(getweather_url)
- json_resp = response.json()
-
- response.close()
-
- for da in json_resp["lives"]:
-
- return da["temperature"], da["weather"]
最后写好主循环代码
-
- status = "boot"
-
-
- while True:
-
- t = time.localtime()
-
- 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"
-
- if (t.tm_sec % 2 == 0):
- timeL.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
- timeL.color = 0x000000
- else:
- timeL.text = "%02d:%02d" % ( t.tm_hour, t.tm_min)
- timeL.color = 0xD9D7C9
-
- display.show(group)
-
- time.sleep(1)
成品展示
5、光传感器和ADC的使用
LTR329是一款数字环境光和近红外传感器,用于测量光线强度和光谱特性。它能够检测可见光和红外光,适用于多种应用,如调光系统、亮度调节、环境亮度检测和接近检测。LTR329具有高分辨率、低功耗和广泛的动态范围,可在不同照明条件下提供准确的光度测量。此传感器通常集成在微小封装中,易于嵌入各种设备和系统,为智能手机、便携式设备和自动化系统等提供了环境感知功能。
CircuitPython也有库可以直接调用,简单设计了下界面,代码如下
- import board
-
- import displayio
-
-
- 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/tqbg.png")
-
- palette.make_transparent(1)
-
-
- grid = displayio.TileGrid(image, pixel_shader=palette)
-
-
- group.append(grid)
-
-
- display.show(group)
- color = 0x000000
-
- import terminalio
-
-
- date = label.Label(terminalio.FONT, text="10月3日", color=color, scale=3)
- date.x = 10
- date.y = 30
- group.append(date)
-
- import time
- from adafruit_ltr329_ltr303 import LTR329
- i2c = board.I2C()
-
-
- time.sleep(0.1)
- ltr329 = LTR329(i2c)
-
-
- while True:
- date.text="IR: %s \nInfra: %s" % (ltr329.visible_plus_ir_light, ltr329.ir_light)
- display.show(group)
- time.sleep(0.5)

ADC模块的使用
NAU7802是一款高精度的24位ADC传感器,专用于测量质量、力量和压力。其卓越的精度和低噪声性能使其成为精密测量应用的理想选择,如压力传感、称重传感和精密仪器。NAU7802采用了ΔΣ调制技术,具有高速采样率和可编程增益,可满足各种应用的要求。此外,它还集成了温度传感器、内部放大器和接口电路,使其易于集成到各种嵌入式系统中。这一功能齐全的传感器广泛用于医疗设备、工业自动化和科学仪器等领域。
同样用CircuitPython也可以很好的完成,代码如下。
- import board
-
- import displayio
-
-
- 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/tqbg.png")
-
- palette.make_transparent(1)
-
-
- grid = displayio.TileGrid(image, pixel_shader=palette)
-
-
- group.append(grid)
-
-
- display.show(group)
- color = 0x000000
-
- import terminalio
-
-
- date = label.Label(terminalio.FONT, text="10月3日", color=color, scale=2)
- date.x = 10
- date.y = 30
- group.append(date)
-
- import time
- from cedargrove_nau7802 import NAU7802
-
-
- nau7802 = NAU7802(board.I2C(), address=0x2A, active_channels=2)
-
- def zero_channel():
- """Initiate internal calibration for current channel.Use when scale is started,
- a new channel is selected, or to adjust for measurement drift. Remove weight
- and tare from load cell before executing."""
- print(
- "channel %1d calibrate.INTERNAL: %5s"
- % (nau7802.channel, nau7802.calibrate("INTERNAL"))
- )
- print(
- "channel %1d calibrate.OFFSET: %5s"
- % (nau7802.channel, nau7802.calibrate("OFFSET"))
- )
- print("...channel %1d zeroed" % nau7802.channel)
-
-
- def read_raw_value(samples=2):
- """Read and average consecutive raw sample values. Return average raw value."""
- sample_sum = 0
- sample_count = samples
- while sample_count > 0:
- while not nau7802.available():
- pass
- sample_sum = sample_sum + nau7802.read()
- sample_count -= 1
- return int(sample_sum / samples)
-
-
-
- print("*** Instantiate and calibrate load cells")
-
- enabled = nau7802.enable(True)
- print("Digital and analog power enabled:", enabled)
-
- print("REMOVE WEIGHTS FROM LOAD CELLS")
- time.sleep(3)
-
- nau7802.channel = 1
- zero_channel()
-
- print("READY")
-
-
- while True:
- nau7802.channel = 1
- value = read_raw_value()
- date.text="channel: 1 \nraw value: %7.0f" % (value)
- display.show(group)
- time.sleep(0.5)

三、源码链接
四、活动感言
感谢EEWORLD社区让我参加这个活动。这是一个极好的机会,让我能够学习、成长,结识志同道合的朋友。活动中的各种讨论和直播都启发了我,激发了我的创造力。我将在以后的工作和生活中充分运用这次活动中所学到的知识和见解。再次感谢,我期待未来更多这样的机会,为我的个人和职业发展贡献更多的力量。
|