Funpack3-1期XG24-EK2703A——温度数据读取蓝牙上传
XG24-EK2703A是一款基于EFR32MG24片上系统的开发套件,具备超低成本、低功耗和小巧的特点。该套件支持2.4GHz无线通信,兼容蓝牙LE、蓝牙mesh、Zigbee、Thread和Matter协议,该开发板最核心部分是EFR32MG24B210F1536IM48无线SoC芯片,使用蓝牙低功耗和蓝牙网状网络实现物联网无线连接,EFR32MG24无线SoC芯片以ARM Cortex-M3为核心、主频为78MHz且支持2.4GHz无线通信,带有1536KB闪存和256KBRAM。
任务介绍:
使用EFR32MG24芯片内部温度传感器读取芯片内部温度,将温度数据通过蓝牙功能上传至手机APP,APP将温度数据绘制成曲线展示
实现步骤一:搭建软件代码开发环境,代码编写,调试
本设计主要实现了基于Silicon Labs XG24-EK2703A开发板开发温度传感器,将温度数据通过蓝牙上传手机实现可视化。
本工程分为两个部分,开发板部分代码以及移动端部分开发:
软件代码编写主要有两个功能,温度读取以及蓝牙功能
开发环境搭建:
①CircuitPython固件下载地址为
EFR32xG24 Explorer Kit Download (circuitpython.org)
②固件下载完成后,使用Simplicity Commander软件进行烧录
下载地址为Production Programming Options - Silicon Labs (silabs.com)
(需要注意,软件下载注册并登录需要Silion账户)
③python环境搭建,本次开发使用的是Thonny软件,下载地址为
Thonny, Python IDE for beginners
因为使用的是python,相关资料可以查看python.org
以上三个步骤为板卡环境搭建步骤,搭建完成后就可以链接板卡开始代码调试开发了。
实现步骤二:
EFR32MG24芯片内部带有高精度温度传感器,通过设置和读取相关几个重要的温度数据传感器就可以获得实时的温度值,相关寄存器地址及功能介绍如下:
温度数据寄存器EMU_ADDR_TEMP_OFFSET ,该寄存器存储温度传感器转换好后的温度数据,单位字节
温度传感器状态寄存器EMU_ADDR_STATUS_OFFSET ,该寄存器存储温度传感器的数据状态
温度命令寄存器EMU_ADDR_CMD_OFFSET,通过设置该寄存器可以开关温度传感器
首先引入相关python固件,及定义相关数据结构体和变量:
import time
import board
import uctypes
from uctypes import BF_POS, BF_LEN
from uctypes import UINT32, BFUINT32, BFUINT16, BFUINT8, struct
# EMU 温度传感器数据和状态数据结构
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,
}),
}
以上定义到的EMU_LAYOUT结构体通过位操作对相关寄存器地址数据访问及处理, BF_LEN 对数据长度进行位,使用BFUINT32对齐数据格式,通过位移数据计算获得最后的温度数据。
定义相关寄存器和寄存器地址:
# EMU内存映射基础地址
EMU_ADDR_BASE =0x50004000
# EMU温度数据寄存器地址偏移量
EMU_ADDR_TEMP_OFFSET = 0x088
# EMU状态数据寄存器地址偏移量
EMU_ADDR_STATUS_OFFSET = 0x084
# EMU命令寄存器地址偏移量
EMU_ADDR_CMD_OFFSET = 0x070
使用板卡内部温度传感器读取温度实现代码:
# 输出 EMU_LAYOUT 的size
#print(uctypes.sizeof(EMU_LAYOUT))
def say(n):
print("[:.2f]".format(n))
# EMU_CMD 内存映射
emu_cmd = uctypes.bytearray_at(EMU_ADDR_BASE+EMU_ADDR_CMD_OFFSET, 1)
通过打印可以将实时温度和平均温度数据打印出来,
while True:
# 发送 EMU_CMD_TEMPAVGREQ 命令
emu_cmd[0] = emu_cmd[0] | 0x10
# emu数据读取结构
emu = struct(EMU_ADDR_BASE, EMU_LAYOUT)
# 当前温度值
T1 = emu.EMU_TEMP.TEMP
T2 = emu.EMU_TEMP.TEMPLSB
Tk = T1 + T2/4
Tc = Tk - 273.15
# 平均温度值
T1 = emu.EMU_TEMP.TEMPAVG
T2 = emu.EMU_TEMP.TEMPAVGLSB
Tavgk = T1 + T2/4
Tavgc = Tavgk - 273.15
#print([T1, T2, Tavgk, Tavgc])
print("温度平均值: %0.2f, 温度当前值: %0.2f" % (Tavgc, Tc))
time.sleep(1)
通过打印可以看到温度值,然后再调试蓝牙代码,将温度数据发送至手机APP
增加蓝牙功能,首先引入蓝牙头文件及定义相关变量
发送数据端口使用串口发送,蓝牙用户名定义为"xG24-yxy"
将可连接状态初始化为可以被连接状态,代码如下:
import time
import board
import uctypes
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
advertisement.short_name = "xG24-yxy"
advertisement.connectable = True
主循环中打开蓝牙连接功能,尝试连接,连接成功后增加Connected的打印表示连接成功
while True:
ble.start_advertising(advertisement)
print("Waiting to connect...")
while not ble.connected:
pass
print("Connected.")
while ble.connected:
Tavgc = 10
result = "%0.1f\n" % (Tavgc)
uart.write(result.encode("utf-8"))
time.sleep(1)
最终代码为:
import time
import board
import uctypes
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from uctypes import BF_POS, BF_LEN
from uctypes import UINT32, BFUINT32, BFUINT16, BFUINT8, struct
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
advertisement.short_name = "xG24-yxy"
advertisement.connectable = True
# EMU内存映射基础地址
EMU_ADDR_BASE =0x50004000
# EMU温度数据寄存器地址偏移量
EMU_ADDR_TEMP_OFFSET = 0x088
# EMU状态数据寄存器地址偏移量
EMU_ADDR_STATUS_OFFSET = 0x084
# EMU命令寄存器地址偏移量
EMU_ADDR_CMD_OFFSET = 0x070
# EMU 温度传感器数据和状态数据结构
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,
}),
}
# 输出 EMU_LAYOUT 的size
#print(uctypes.sizeof(EMU_LAYOUT))
def say(n):
print("[:.2f]".format(n))
# EMU_CMD 内存映射
emu_cmd = uctypes.bytearray_at(EMU_ADDR_BASE+EMU_ADDR_CMD_OFFSET, 1)
while True:
ble.start_advertising(advertisement)
print("Waiting to connect...")
while not ble.connected:
pass
print("Connected.")
while ble.connected:
# 发送 EMU_CMD_TEMPAVGREQ 命令
emu_cmd[0] = emu_cmd[0] | 0x10
# emu数据读取结构
emu = struct(EMU_ADDR_BASE, EMU_LAYOUT)
# 当前温度值
T1 = emu.EMU_TEMP.TEMP
T2 = emu.EMU_TEMP.TEMPLSB
Tk = T1 + T2/4
Tc = Tk - 273.15
# 平均温度值
T1 = emu.EMU_TEMP.TEMPAVG
T2 = emu.EMU_TEMP.TEMPAVGLSB
Tavgk = T1 + T2/4
Tavgc = Tavgk - 273.15
#print([T1, T2, Tavgk, Tavgc])
print("温度平均值: %0.2f, 温度当前值: %0.2f" % (Tavgc, Tc))
result = "%0.1f,%0.1f\n" % (Tc,Tavgc)
uart.write(result.encode("utf-8"))
time.sleep(1)
二、手机APP接收端曲线绘制部分
手机端使用BluefruitConnect软件,然后连接板卡蓝牙
连接成功后,常温下数据图,如图所示(蓝色为平均温度值,红色为当前温度值)
用手捏住板卡芯片,将人体温服传导给芯片,温度开始上升,温度曲线如图所示
将手拿开后,温度曲线下降,如图所示
参考资料链接:
总结:再次特意感谢funpack3-1期的小伙伴和大佬们对我的支持,从他们中学到很多东西!