项目介绍
本项目使用了XG24-EK2703A套件的EFR32MG24芯片、Circuitpython语言,实现了温度检测与动态可视化系统的设计,主要功能为板卡芯片的温度检测、蓝牙传输上位机,以及上位机的数据接收与保存,基于保存的数据动态绘图时间--温度数据。
本项目完全实现了Circuitpython语言下的EFR32MG24芯片温度底层信息读取,借助于蓝牙通信,实时无线传输数据到上位机,同时基于Python语言,设计了完善的上位机数据接收与绘图代码,通过纯代码方案构建了一个蓝牙上位机可视化系统。
本项目证明了XG24-EK2703A套件使用Circuitpython语言的开发潜力,同时认为蓝牙通讯形式的上位机接收,在当前的平台技术支持下,能够取得满足工程实际需求的效果。
另外,本项目为Funpack第三季第一期活动作业的任务一。
设计思路
本项目首先基于adafruit给出的Circuitpython语言指南,论证了基于Circuitpython语言发送蓝牙数据的可行性。同时通过阅读EFR32MG24芯片手册,明确了读取芯片温度信息的可行性。
然后形成了Circuitpython代码,并借助于Simplicity Studio开发平台,对板卡烧录了已经编译好的具备Uctypes库的Circuitpython固件。
借助于Thonny这一开源的Python IDE,实现了该板卡的Circuitpython代码调试。
然后对上位机开发,基于 Python 语言的ble-serial库,实现了与板卡的蓝牙无线通信,并构建通信端口。
然后构建一段Python程序,可以接收该端口的信息,并基于接收到蓝牙信息,实时保存到表格文件。
在最后构建了一个用于绘图Python程序,对实时更新的表格文件动态读取,同时基于matplotlib库动态更新图像。
硬件介绍
XG24-EK2703A是基于EFR32MG24的低功耗无线开发平台,支持含有2.4 GHz无线协议的IoT应用程序,例如蓝牙LE、蓝牙Mesh等,芯片频率最高78MHz。
EFR32MG24 无线SoC可以使用 Matter、OpenThread 和 Zigbee 协议构建网状物联网无线连接。
该芯片具有 DSP 指令和浮点单元以实现高效信号处理的高性能 32 位 78.0 MHz ARM Cortex®-M33。Cortex-M33是ARM公司推出的一款高效能、高安全性的微控制器处理器。这款处理器是基于ARMv8-M架构,其主要特点是集成了硬件安全特性以及可选的浮点运算。支持ARM的TrustZone技术,能够为嵌入式设备提供更好的安全性,采用四级流水线架构,每个时钟周期只能执行一条指令,性能仅略微逊色于Cortex-M7处理器,但低功耗特性更好,且支持协处理器。
芯片还具备以下特性:高达 1536 kB 的闪存程序内存,RAM 数据内存高达 256 kB,2.4 GHz 收音机操作,无线电性能,广泛的MCU外围设备选择,具有全面可配置成型功能 的2(G)FSK、OQPSK DSSS、(G)MSK,MG24安全功能
XG24-EK2703A板卡硬件布局:
套件电路图见附件。
本项目开发软件介绍
软件流程图
芯片内主要代码片段及说明
temperature_blue1.py 程序代码说明。
首先,创建一个低功耗蓝牙地址,定义蓝牙名称。
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
advertisement.short_name = "CPY_MYG"
接下来的代码,读取芯片温度数据结构,以准备解析温度数据。EFR32MG24的EMU里面的温度传感器,TEMP代表温度整数,TEMPLSB代表温度小数(单位是1开尔文的四分之一)
EMU_LAYOUT = {
"EMU_TEMP": (
EMU_ADDR_TEMP_OFFSET,
{
"TEMP": 2 << BF_POS | 9 << BF_LEN | BFUINT32,
"TEMPLSB": 0 << BF_POS | 2 << BF_LEN | BFUINT32,
"TEMPAVG": 18 << BF_POS | 9 << BF_LEN | BFUINT32,
"TEMPAVGLSB": 16 << BF_POS | 2 << BF_LEN | BFUINT32,
}),
"EMU_STATUS": (
EMU_ADDR_STATUS_OFFSET,
{
"TEMPACTIVE": 2 << BF_POS | 1 << BF_LEN | BFUINT8,
"TEMPAVGACTIVE": 3 << BF_POS | 1 << BF_LEN | BFUINT8,
}),
}
接下来该文件的重要代码片段,为温度计算与蓝牙发送信息。
while ble.connected:
emu_cmd[0] = emu_cmd[0] | 0x10
emu = struct(EMU_ADDR_BASE, EMU_LAYOUT)
# 芯片读取的温度现值
T0 = emu.EMU_TEMP.TEMP
T1 = emu.EMU_TEMP.TEMPLSB
Tk = T0 + T1/4
Tc = Tk - 273.15
# 芯片读取的温度均值
T0 = emu.EMU_TEMP.TEMPAVG
T1 = emu.EMU_TEMP.TEMPAVGLSB
Tkmean = T0 + T1/4
Tcmean = Tkmean - 273.15
print("Temperature mean value: %0.2f; Temperature current value: %0.2f" % (Tcmean, Tc))
result = "%0.1f,%0.2f\n" % (Tcmean, Tc)
uart.write(result.encode("utf-8"))
time.sleep(1)
上位机蓝牙接收程序主要代码片段及说明
接下来对“temperature_new_PC_去除时间v1.1.py”文件中的代码进行解读。
本项目借助了TCP端口,传入蓝牙数据,然后借助于表格,作为信息中转途径,借助time库,计算不同接收数据的时间,精确到小数点后6位,以尽可能精确的表现时间与温度的关系。
def Trans():
global data, start_time
stream = yield TCPClient().connect(HOST, PORT)
try:
while True:
data = yield stream.read_bytes(20, partial=True)
print("data: ", data.decode("utf-8"))
save_to_csv(data) # 将数据保存到CSV文件
if start_time is None:
start_time = time.time() # 记录程序开始运行的时间
except iostream.StreamClosedError:
data = b""
# 保存数据到CSV文件
def save_to_csv(data):
with open('data.csv', 'a', newline='') as file:
writer = csv.writer(file)
writer.writerow([get_elapsed_time(), data.decode("utf-8")])
# 获取程序运行时间
def get_elapsed_time():
global start_time
if start_time is not None:
elapsed_time = time.time() - start_time # 计算程序运行的时间差
return str(elapsed_time)
else:
return ""
上位机数据动态绘图程序主要代码片段及说明
改程序借助于matplotlib.pyplot实现,难度较低。采用了坐标轴动态刷新的代码,因为运行时间过长后,横轴时间拉长,表现为横轴标签过密,以下代码很好地解决了这个问题。
# 根据数据量判断横坐标轴间距
num_data_points = len(time_data)
if num_data_points <= 10:
plt.xticks(rotation=45)
plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(base=1)) # 设置横坐标轴间距为1
elif num_data_points <= 20:
plt.xticks(rotation=45)
plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(base=2)) # 设置横坐标轴间距为2
else:
plt.xticks(rotation=45)
plt.gca().xaxis.set_major_locator(ticker.AutoLocator()) # 自动调整横坐标轴间距
开发流程
由于活动开发板支持Circuitpython,且本项目上位机前端使用python开发,因此直接使用该语言开发。借助 CircuitPython,使用 Python 语法控制板卡外设并与之交互,从而缩短开发时间并降低复杂性。
本项目开发,参考如下文档,Introducing CircuitPython Support for Silabs' xG24 Boards
Welcome To CircuitPython | Welcome to CircuitPython! | Adafruit Learning System
官方学习资料,Circuitpython
SiliconLabs/circuitpython_applications: Application Examples for CircuitPython (github.com) 官方例程
导入固件
首先下载导入开发板的 bin 文件,CircuitPython 8.2.9,下载文件名 adafruit-circuitpython-explorerkit_xg24_brd2703a-en_US-8.2.9.bin
。下载后可以关闭,后面不用看不下载 CircuitPython 9.0.0-alpha.6,这是开发测试版本,显示模块大幅度更新EFR32xG24 Explorer Kit Download (circuitpython.org)选中 ENGLISH ( US )
内置如下模块,
Built-in modules available: _asyncio, _bleio, _pixelmap, adafruit_bus_device, adafruit_pixelbuf, aesio, analogio, array, atexit, binascii, bitmaptools, board, builtins, builtins.pow3, busio, busio.SPI, busio.UART, collections, digitalio, displayio, errno, fontio, framebufferio, getpass, gifio, io, json, math, microcontroller, msgpack, nvm, onewireio, os, os.getenv, pwmio, rainbowio, random, re, rtc, sdcardio, select, sharpdisplay, storage, struct, supervisor, sys, terminalio, time, traceback, ulab, vectorio, watchdog, zlib
每次向 CircuitPython 提交新代码时,都会自动为每块电路板和每种语言构建二进制文件。二进制文件存储在 Amazon S3 上,按电路板和语言分类。
本文使用了一种单独编译的含有uctypes库的CircuitPython固件,因为uctypes库是调用读取芯片温度编码的必备的库,所以必须包含该库。下载链接如下:
「CircuitPython固件」: 链接:https://pan.quark.cn/s/7d42429eccab;提取码:TmkT
当然,也可以从如下链接,搜索历史上的官方发行版。Releases · adafruit/circuitpython (github.com)
安装SDK和刷写固件
首先下载完整最新版安装包并安装,Simplicity Studio - 芯科科技 (silabs.com)
具体细节可以看操作指南 Overview - latest - Simplicity Studio 5 Users Guide Silicon Labs (silabs.com)
接入板卡,安装即可,需要较好的网络环境,若安装失败就是网络原因,不再赘述。
使用 Simplicity Commander,打开方式如下
Simplicity Commander (silabs.com) 该网站有旧版本的独立下载网址
烧录完成后,重新接入一次单片机,否则黄灯会快速闪。
点灯测试
接下来测试点灯,若点灯实现,说明硬件开发环节没有任何问题。
在SDK端固件烧录好后,本文依靠于thonny IDE,这是芯科官方推荐的用于CircuitPython 的IDE,是一款开源简洁且便携的Python IDE,且具备强大的包管理功能。
首先,右下角设置解释器,使用CircuitPython 。
另外,视图中,打开如下内容
如果设置后解释器可以正常工作,出现如下代码,证明IDE配置完成。
Adafruit CircuitPython 9.0.0-alpha.6-11-g1d13364511-dirty on 2024-01-01; SiLabs xG24 Explorer Kit with EFR32MG24B210F1536IM48
Adafruit CircuitPython 9.0.0-alpha.6-11-g1d13364511-dirty on 2024-01-01; SiLabs xG24 Explorer Kit with EFR32MG24B210F1536IM48
此时,只需要创建代码,写入,保存到CircuitPython设备,代码即可运行。运行效果如下,此代码在开发板上,会让两个LED黄灯轮流亮起关闭。
主程序开发与测试
此处见上一节,“本项目开发软件介绍”。与硬件层面,下一节“功能展示及说明”,以及结合上传到bilibili的视频观看。
功能展示及说明
首先将temperature_blue1.py刷入板卡,并开始执行。
上位机连接蓝牙,运行如下命令:
ble-serial -d 04:87:27:E9:B4:A9 --expose-tcp-host 127.0.0.1 --expose-tcp-port 9999
连接后,由于IDE也开启了串口输出展示与绘图,从uart串口输出的内容如下(一条线是温度均值,一条线是现值):
接下来实现串口传图,然后在python,IDLE运行,temperature_new_PC_去除时间v1.1.py
开始运行后,shell输出温度均值和现值。同时在与“temperature_new_PC_去除时间v1.1.py”同目录下生成“data.csv”。
此时“data.csv”内容如下(表格在附件给出)。
27.9,28.10 | |
0.983337 | 27.4,27.85 |
1.986649 | 27.4,28.10 |
2.977292 | 27.4,27.10 |
4.01782 | 27.9,27.35 |
然后,在终端(Powershell或者命令提示符)新打开运行,
python plot_testv1.1.py
程序实现自动绘图,并实时更新。更新动态图效果见视频。
至此,任务完成。
心得体会
本项目的开发过程中,尝试过官方SDK给出的蓝牙方案,也考虑过借助于VFOA程序的蓝牙上位机绘图实现。
但对比起来,Python及其衍生语言以其强大的社区支持与易开发特性,极大程度简化了本项目实现流程,相关资料开源、易用,学习难度低,特别是上位机二次开发可以借此实现低成本的复杂应用。
本项目证明了XG24-EK2703A平台具备完备的CircuitPython适配能力,基于该语言开发基本可以满足原生蓝牙应用的各种要求,以及复现SDK中的若干Example。
最后,感谢电子森林与得捷电子等各方提供的支持。