项目介绍:
XG24-EK2703A板卡的芯片自带了一个传感器,可以通过直接读取寄存器的方式获取其数据。
在本项目中,在XG24-EK2703A板卡上运行CircuitPython环境,通过从EMU(Energy Management Unit)寄存器获取数据,来还原为实际的温度值,然后通过低功耗蓝牙(BLE)发送。
在电脑上,通过Python的扩展库ble-serial,来连接对开发板的蓝牙,读取发送的数据,再转换到WebSocket服务,为网页提供数据。在网页上,通过ECharts,进行温度曲线图标的展示。
设计思路:
1. 功能设计:
要实现本项目所需要的功能,要完成以下:
- 在开发板运行CircuitPython
- 从XG24-EK2703A的EMU读取温度传感器数据
- 通过蓝牙发送读取到的温度传感器数据
- 在电脑上,连接到XG24-EK2703A的蓝牙服务
- 将获取的数据,通过WebSocket服务提供服务
- 在H5页面上,接收数据,并通过ECharts呈现曲线
2. 流程图:
具体的设计流程图如下:
硬件介绍:
要实现本项目的功能,除了要将XG24-EK2703A开发板通过Type-C连接到电脑,不需要其他额外的硬件设备。
实现步骤:
1. 安装CircuitPython环境
SiLabs已经和CircuitPython合作,提供了官方的CircuitPython固件,可以通过 EFR32xG24 Explorer Kit Download (circuitpython.org) 直接下载最新版本即可。当前最新版本为 CircuitPython 9.0.0-beta.2。
我的 XG24-EK2703A开发板,在macOS电脑上面,连接上开发板以后,就自动识别到了J-Link,可能是因为我之前安装过J-Link相关的软件。
如果是在Windows系统上,连接开发板后,打开设备管理器,检查是否正确识别。如果有感叹号之类的,说明没有正常识别。 可以按照下面的方式,安装驱动:
1). 安装J-Link软件
从 J-Link Software and Documentation Pack 下载适合自己电脑系统的版本,安装后重启电脑,重新连接开发板,看看是否正常识别
2). 安装Simplicity Studio
如果上面的方法不行的话,那就老老实实安装Simplicity Studio。 从 Development Tools // Wireless // EFR32xG24 Explorer Kit 下载对应系统的版本进行安装。 安装过程中,如果提示安装驱动,则Yes到底。
或者安装Simplicity Studio后,参考 https://www.sekorm.com/news/44749565.html 中的步骤安装驱动即可。
3). 安装Simplicity Commander
Simplicity Commander是臃肿庞大的Simplicity Studio的一部分,还好可以独立使用。 如果已经安装了Simplicity Studio,那么从 Tools 中选择 Simplicity Commander打开使用即可。
如果还没有安装,那么其单独的下载地址为: Production Programming Options for Silicon Labs Devices
4). 烧录固件
下载安装完成后,打开Simplicity Commander,按照下图的步骤,进行CircuitPython固件烧录:
5). 测试CircuitPython环境
烧录完成后,就可以在电脑上,通过Thonny等工具进行连接测试了:
以上部分,可以参考:1.CircuitPython固件烧录.md · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 - Gitee.com
2. 从EMU的寄存器中读取温度传感器的数据
1). 硬件寄存器了解
XG24-EK2703A开发板的核心是EFR32MG24系列,芯片自身带有一个温度传感器,用于测量芯片当前的运行温度。
在CircuitPython中,要读取这个芯片内温度传感器的数据,有两种方法:
- 方法1:直接使用 microcontroller 模块提供的功能读取
import microcontroller
print("CPU温度:", microcontroller.cpu.temperature) - 方法2:通过内存映射,读取芯片内部的寄存器数据,也就是使用uctypes,通过内存映射,直接读取芯片内部的寄存器,从而获取该芯片内温度传感器的数据,并进行输出。
方法1 非常的简单,但只能读取最基础的数据。方法2 要复杂一些,但是可以读取到更多的数据,包括当前值和平均值。
在本项目中,采用了第2种方法进行读取。
从手册中可以得知,该温度传感器的数据规格,以及转换为实际温度的公式:
在硬件系统重,EMU提供低功耗周期性温度测量,每250毫秒进行一次温度测量。 测量后,测量结果将分为两部分存储在EMU_TEMP寄存器中:
- 温度平均值:存储在EMU_TEMP寄存器的TEMPAVG位字段中,温度值以开尔文度表示,小数部分以1⁄4开尔文度为单位。
- 温度值整数部分:存储在EMU_TEMP寄存器的TEMP位字段中,温度值以开尔文度表示
- 温度值小数部分:存储在EMU_TEMP寄存器的TEMPLSB位字段中,以1⁄4开尔文度为单位。 具体的bit位分配信息如下:
从上述表中可以看到,要获取当前的温度数据,则:
- 整数部分:T1 = EMU_TEMP[2:10]
- 小数部分:T2 = EMU_TEMP[0:1]
- 测量温度:Tk = T1 + T2/4
- 测量温度摄氏度结果:Tc = Tk - 273.15 ,因为:K=℃+273.15
要获取当前的平均温度数据,则:
- 整数部分:T1 = EMU_TEMP[18:26]
- 小数部分:T2 = EMU_TEMP[16:17]
- 测量温度:Tk = T1 + T2/4
- 测量温度摄氏度结果:Tc = Tk - 273.15 ,因为:K=℃+273.15
在EFR32MG24的内存映射中,EMU的起始地址位 0x50004000:
从EMU的寄存器内存映射中,可以找到EMU_TEMP寄存器的偏移地址0x088:
在我们的代码中,通过上述基地址和寄存器的偏移地址,就能够通过内存映射地址获取其对应的数据。
默认情况下,可以读取温度传感器当前的数值,如果要读取温度平均值,则需要先发送 EMU_CMD_TEMPAVGREQ 命令,才能进行平均值的计算。 从手册可以得知,要发送该命令,可以修改如下寄存器中对应 TEMPAVGREQ 位的值:
当设置一次 TEMPAVGREQ 后,将会进行一次温度平均值的计算,以备读取。
2). 了解uctypes模块
在CircuitPython环境中,uctypes模块能够让我们以结构化的方式来访问内存,以及映射到内存地址的芯片内部寄存器。 uctypes需要明确指定每个字段的偏移量,从结构开始以字节为单位给出偏移量,然后给出各个字段对应的位域,以便与内存映射数据一一对应。
不过,需要特别注意的是,uctypes 模块允许访问机器的任意内存地址(包括 I/O 和控制寄存器),一旦不小心使用它可能会导致系统崩溃、数据丢失,甚至硬件故障。
如果使用uctypes的过程中,程序运行出现下面的错误,那就说明操作了不该操作的数据,系统崩溃了:
在XG24-EK2703A开发板的CircuitPython环境中,需要先定义从寄存器中读取数据的具体结构,包括温度值和状态值:
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,
}),
}
在详细了解 EFR32MG24 内部寄存器的细节后,你还可以定义读取更多寄存器的数据。
3). 读取温度传感器的数据
设置好数据结构后,就使用 uctypes.bytearray_at() 来做内存地址的直接映射,以便修改 TEMPAVGREQ 的值,从而实现发送 EMU_CMD_TEMPAVGREQ 命令:
# EMU_CMD 内存映射
emu_cmd = uctypes.bytearray_at(EMU_ADDR_BASE+EMU_ADDR_CMD_OFFSET, 1)
最终,具体代码如下:
import time
import uctypes
from uctypes import BF_POS, BF_LEN
from uctypes import UINT32, BFUINT32, BFUINT16, BFUINT8, struct
# 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:
# 发送 EMU_CMD_TEMPAVGREQ 命令
emu_cmd[0] = emu_cmd[0] | 0x10
# emu数据读取结构
emu = struct(EMU_ADDR_BASE, EMU_LAYOUT)
# 输出 EMU 温度传感器测量状态值
#print(emu.EMU_STATUS.TEMPACTIVE, emu.EMU_STATUS.TEMPAVGACTIVE)
# 当前温度值
T1 = emu.EMU_TEMP.TEMP
T2 = emu.EMU_TEMP.TEMPLSB
Tk = T1 + T2/4
Tc = Tk - 273.15
#print([T1, T2, Tk, Tc])
# 平均温度值
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)
保存上述代码,然后运行,就能够发送 EMU_CMD_TEMPAVGREQ 命令,并读取温度平均值和当前值了,具体效果如下:
注意,要显示上图右则的数据绘图,只需要打开 Thonny 的 Plotter(绘图器)即可:
以上部分,可以参考:7.获取芯片自带温度传感器数据.md · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 - Gitee.com
3. 通过低功耗蓝牙(BLE)发送数据
1). 低功耗蓝牙启动
XG24-EK2703A开发板自带了低功耗蓝牙功能:
BLE UART是BLE常见的功能,用于基于BLE,来实现UART接口,从而进行数据的发送。
在XG24-EK2703A的CircuitPython,已经自带了支持BLE功能的模块,可以用如下的命令检测是否加载:
然后,可以编写如下的代码:
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 = "CPY_HID"
advertisement.connectable = True
while True:
ble.start_advertising(advertisement)
print("Waiting to connect")
while not ble.connected:
pass
print("Connected")
while ble.connected:
s = uart.readline()
if s:
try:
s_str = s.decode("utf-8").replace("\r","").replace("\n","")
result = str(eval(s_str))
print(s_str, "=", result)
result = "%s=%s\n\r" % (s_str, result)
uart.write(result.encode("utf-8"))
except Exception as e:
s_str = s.decode("utf-8").replace("\r","").replace("\n","")
print("receive: ", s_str)
result = "receive: %s\n\r" % s_str
uart.write(result.encode("utf-8"))
在该代码中,执行后,将会启动蓝牙广播,提供BLE UART服务,等待其他设备连接。 连接成功后,如果收到了信息,则会先进行计算处理,如果计算成功,则返回计算结果;如果失败,则直接显示接受到的信息。
运行上述代码后,在CircuitPython中会显示:
在手机或者电脑上进行连接,就会输出连接成功的信息:
以上部分,可以参考:6.使用自带的低功耗蓝牙进行BLE_UART通讯.md · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 - Gitee.com
2). 通过低功耗蓝牙发送温度传感器数据
然后,结合上面从EMU读取温度传感器数据和蓝牙的代码,编写通过低功耗蓝牙发送温度数据的代码,具体如下:
import time
import board
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.complete_name = "CPY_TEMP"
advertisement.short_name = "CPY_TEMP"
advertisement.connectable = True
import uctypes
from uctypes import BF_POS, BF_LEN
from uctypes import UINT32, BFUINT32, BFUINT16, BFUINT8, struct
#import time
# 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 True:
while ble.connected:
# 发送 EMU_CMD_TEMPAVGREQ 命令
emu_cmd[0] = emu_cmd[0] | 0x10
# emu数据读取结构
emu = struct(EMU_ADDR_BASE, EMU_LAYOUT)
# 输出 EMU 温度传感器测量状态值
#print(emu.EMU_STATUS.TEMPACTIVE, emu.EMU_STATUS.TEMPAVGACTIVE)
# 当前温度值
T1 = emu.EMU_TEMP.TEMP
T2 = emu.EMU_TEMP.TEMPLSB
Tk = T1 + T2/4
Tc = Tk - 273.15
#print([T1, T2, Tk, Tc])
# 平均温度值
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.2f,%0.2f\n" % (Tavgc, Tc)
uart.write(result.encode("utf-8"))
time.sleep(0.5)
运行上述代码后,首先串口会收到数据,并可使用绘图器绘图:
4. 电脑通过蓝牙接收温度数据并绘图
1). 连接到开发板的蓝牙
首先,需要安装必须的Python支持库:
#ble-serial:
pip install ble-serial
#tornado:
pip install tornado
然后,使用ble-scan命令,来查找设备:
其中CircuitPython就是开发板提供的蓝牙服务,需要将其对应这行最前面的UUID复制下来备用。
在使用下面的命令,连接到开发板:
ble-serial -d 设备对应的uuid --expose-tcp-host 127.0.0.1 --expose-tcp-port 9999
同时,还通过tcp端口9999,对外提供数据服务。
运行后,结果如下:
2). 通过WebSocket提供服务
因为H5页面需要从WebSocket获取数据,所以还需要编写一个TCP转WebSocket的服务,具体代码如下:
#coding:utf-8
# 将tcp读取到的温度数据,使用websocket服务提供给网页读取
from tornado import web, websocket
from tornado import ioloop, gen, iostream
from tornado.tcpclient import TCPClient
import time
HOST = '127.0.0.1' # 温度服务ip地址
PORT = 9999 # 温度服务通信端口号
LISTEN_PORT = 9099 # 数据提供服务监听端口
data = b""
# TCP 数据读取
@gen.coroutine
def Trans():
global data
stream = yield TCPClient().connect(HOST, PORT)
try:
while True:
data = yield stream.read_bytes(20, partial=True)
print("data: ", data.decode("utf-8"))
except iostream.StreamClosedError:
data = b""
# WebSocket服务提供
class WebSocketHandler(websocket.WebSocketHandler):
def check_origin(self, origin: str) -> bool:
return True
def open(self):
print("open success")
# 定时器,每秒向前端发送一次数据
self.timer = ioloop.PeriodicCallback(self.send_data, 1000)
self.timer.start()
def on_close(self):
self.timer.stop()
def on_error(self, error):
print("error: ", error)
self.timer.stop()
def send_data(self):
# 向前端发送当前时间
if len(data)>0:
try:
self.write_message(data)
except Exception:
pass
# WebSocket服务定义
application = web.Application([
(r'/', WebSocketHandler),
])
if __name__ == '__main__':
print("WebSocket服务监听端口:", LISTEN_PORT)
application.listen(LISTEN_PORT)
print("启动数据读取服务")
ioloop.IOLoop.current().run_sync( Trans )
print("启动WebSocket数据提供服务")
ioloop.IOLoop.current().start()
以上代码,具体见源码包中的 tcp_ws.py。
在电脑运行上述代码后,结果如下:
3). H5页面读取数据,并通过ECharts呈现
完成前面的工作,数据提供服务就准备好了,最终的工作就是获取这些数据,并进行呈现了。
呈现数据,我使用ECharts来实现,具体的代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>XG24-EK2703A板卡芯片温度变化曲线</title>
<script type="text/javascript" src="jquery-3.2.0.min.js"></script>
<script src="echarts.min.js"></script>
<style>
.button_group {
position: fixed;
top: 400px;
left: 6%;
}
.button {
width: 90px;
height: 35px;
border-width: 0px;
border-radius: 3px;
background: #1e90ff;
cursor: pointer;
outline: none;
font-family: Microsoft YaHei;
color: white;
font-size: 15px;
}
</style>
</head>
<body>
<div
id="current_A"
style="width: 600px; height: 400px; margin-bottom: 100px"
></div>
<div class="button_group">
<input
class="button"
type="button"
value="读取"
id="start"
style="margin: 0 50px 0"
/>
<input
class="button"
type="button"
value="停止"
id="stop"
style="margin: 0 50px 0"
/>
</div>
<div>
<pre>
使用方法:
1. 参考案例7+6,使用BLE UART发送温度数据,格式为:平均值,当前值\\n
2. 安装 ble-serial: pip install ble-serial
3. 安装 tornado: pip install tornado
4. 执行 ble-scan,找到CIRCUITPY开头的设备对应的uuid
5. 执行 ble-serial -d 设备对应的uuid --expose-tcp-host 127.0.0.1 --expose-tcp-port 9999
6. 执行 python tcp_ws.py
7. 执行 python -m http.server 9080
8. 网页访问:http://127.0.0.1:9080/,点击读取
</pre>
</div>
<script type="text/javascript">
$(function () {
var temp_real = 0;
var temp_avg = 0;
//判断浏览器是否支持WebSocket
var supportsWebSockets =
"WebSocket" in window || "MozWebSocket" in window;
if (supportsWebSockets) {
//建立WebSocket连接(ip地址换成自己主机ip)
var ws = new WebSocket("ws://"+window.location.hostname+":9099/");
ws.onopen = function () {
//当WebSocket创建成功时,触发onopen事件
console.log("websocket连接成功");
// ws.send("hello"); //将消息发送到服务端
};
ws.onmessage = function (e) {
//当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
console.log("收到数据");
console.log(e.data);
var tmp = String(e.data).replace(/[\s]/g, "").split(",");
temp_avg = tmp[0];
temp_real = tmp[1];
};
ws.onclose = function (e) {
//当客户端收到服务端发送的关闭连接请求时,触发onclose事件
console.log("websocket已断开");
};
ws.onerror = function (e) {
//如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
console.log("websocket发生错误" + e);
};
} else {
layer.alert("您的浏览器不支持 WebSocket!");
}
// 初始化图表的数据输入数组
var data_real = [];
var data_avg = [];
var data_length = 30;
for (i = 0; i < data_length; i++) {
data_avg.push(25);
data_real.push(25);
}
//初始化全局变量
var global_status = 0; //加载页面时默认为0
//每个div分别创建一个form对象
var CurrentA = new My_form("current_A");
//页面加载时初始化静态图表
CurrentA.init_static();
//定义form类
function My_form(element_id) {
//form类所创建在指定的div的id
this.element_id = element_id;
//初始化图表,在具体指定元素位置创建图表,并传入数据列表
this.init_static = function () {
this.mychart = echarts.init(
document.getElementById(this.element_id)
);
// 初始化x轴数据
var _x_axis = [];
for (var i = 0; i < data_length; i++) {
_x_axis.push(i);
}
// 初始化y轴数据
var real_arr = [];
var avg_arr = [];
for (var i = 0; i < data_length; i++) {
real_arr.push(25);
avg_arr.push(25);
}
//设置图标配置项
this.mychart.setOption({
title: {
text: "XG24-EK2703A板卡芯片温度变化曲线",
x: "left",
textStyle: {
fontSize: 16,
},
},
tooltip: {
trigger: "axis",
},
// 调整图表在div中的大小
grid: {
top: "35px",
left: "50px",
right: "10px",
bottom: "50px",
},
legend: {
data: ["real", "avg"],
textStyle: {
fontSize: getDpr(),
},
x: "center",
},
toolbox: {
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ["line"] },
saveAsImage: { show: true },
},
},
calculable: true,
xAxis: {
type: "category",
boundaryGap: false,
data: _x_axis,
},
yAxis: {
type: "value",
min: 20,
max: 30,
splitNumber: 3,
},
series: [
{
name: "当前值",
type: "line",
color: "red",
data: real_arr,
},
{
name: "平均值",
type: "line",
color: "green",
data: avg_arr,
},
],
});
};
// 更新数据函数
this.update_data = function (real_data, model_data) {
this.mychart.setOption({
title: {
text: "XG24-EK2703A板卡芯片温度变化曲线",
x: "left",
textStyle: {
fontSize: 16,
},
},
series: [
{
name: "当前值",
data: real_data,
},
{
name: "平均值",
data: model_data,
},
],
});
};
}
//“开始实验”按钮点击事件
$("input[id='start']").click(function () {
global_status = 1;
});
//“终止实验”按钮点击事件
$("input[id='stop']").click(function () {
global_status = 0;
data_real.fill(25);
data_avg.fill(25);
CurrentA.init_static();
});
//legend字体大小
function getDpr() {
var windowWidth = $(window).width();
if (windowWidth < 1920) {
return 12;
}
if (windowWidth >= 1920 && windowWidth <= 3840) {
return 18;
}
if (windowWidth > 3840 && windowWidth <= 5760) {
return 30;
}
}
// 更新真实值
function update_data() {
data_real.push(temp_real);
data_avg.push(temp_avg);
if (data_real.length > data_length) {
data_real.shift();
}
if (data_avg.length > data_length) {
data_avg.shift();
}
}
//设置监听函数每一秒一次
setInterval(function () {
if (global_status === 0) {
return;
}
update_data();
CurrentA.update_data(data_real, data_avg);
}, 1000);
});
</script>
</body>
</html>
上述代码的逻辑并不复杂,如果对ECharts有过基础的了解,就可以看的很明白。
其通过WebSocket获取数据,然后通过折线图进行数据的呈现。
要使用上面的代码查看实际效果,需要将其保存为index.html,然后使用python提供一个简单的网页服务即可:
python -m http.server 9080
然后使用浏览器打开:http://127.0.0.1:9080/
点击读取,就可以读取数据并呈现了:
以上部分,可以参考:8.蓝牙发送芯片温度传感器数据上位机绘图 · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 (gitee.com)
总结:
这次的XG24-EK2703A板卡虽然很小,但是SiLabs不愧是在行业深耕多年的老牌企业,一块小小的板子,提供的功能却非常的不错。
这个项目,知只是应用到了其中的一部分功能,来完成芯片内置温度传感器数据的读取,以及通过低功耗蓝牙(BLE)进行数据的发送。
另外,我也探索了板子的其他功能,感兴趣的通讯,也可以进一步了解:EFR32xG24 Explorer Kit CircuitPython学习仓库: 提供EFR32xG24 Explorer Kit开发板上的CircuitPython学习研究资料 (gitee.com)
最后,感谢硬禾提供本次项目的机会,能够在XG24-EK2703A板卡上进行学习研究。