【Funpack3-1】XG24-EK2703A板卡芯片温度变化曲线
该项目使用了CircuitPython,实现了显示XG24-EK2703A芯片温度变化曲线的设计,它的主要功能为:在XG24-EK2703A板卡运行CircuitPython环境,从EMU读取芯片内置温度传感器的数据,然后通过低功耗蓝牙(BLE)发送,在电脑上,通过Python扩展库ble-serial通过蓝牙获取发送的数据,并在H5页面上,使用echarts进行展示,显示温度变化曲线。
标签
Funpack活动
CircuitPython
温度传感器
低功耗蓝牙
XG24-EK2703A
ECharts
HonestQiao
更新2024-03-05
130

项目介绍:

XG24-EK2703A板卡的芯片自带了一个传感器,可以通过直接读取寄存器的方式获取其数据。

在本项目中,在XG24-EK2703A板卡上运行CircuitPython环境,通过从EMU(Energy Management Unit)寄存器获取数据,来还原为实际的温度值,然后通过低功耗蓝牙(BLE)发送。

在电脑上,通过Python的扩展库ble-serial,来连接对开发板的蓝牙,读取发送的数据,再转换到WebSocket服务,为网页提供数据。在网页上,通过ECharts,进行温度曲线图标的展示。

iShot_2024-02-29_12.13.26.png 


设计思路:

1. 功能设计:

要实现本项目所需要的功能,要完成以下:

  • 在开发板运行CircuitPython
  • 从XG24-EK2703A的EMU读取温度传感器数据
  • 通过蓝牙发送读取到的温度传感器数据
  • 在电脑上,连接到XG24-EK2703A的蓝牙服务
  • 将获取的数据,通过WebSocket服务提供服务
  • 在H5页面上,接收数据,并通过ECharts呈现曲线


2. 流程图:

具体的设计流程图如下:

XG24-EK2703A板卡芯片温度变化曲线.drawio.png 


硬件介绍:

要实现本项目的功能,除了要将XG24-EK2703A开发板通过Type-C连接到电脑,不需要其他额外的硬件设备。

image.png

 


实现步骤:

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固件烧录:

image.png

5). 测试CircuitPython环境

烧录完成后,就可以在电脑上,通过Thonny等工具进行连接测试了:

image.png

 image.png


以上部分,可以参考:1.CircuitPython固件烧录.md · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 - Gitee.com


2. 从EMU的寄存器中读取温度传感器的数据

1). 硬件寄存器了解

XG24-EK2703A开发板的核心是EFR32MG24系列,芯片自身带有一个温度传感器,用于测量芯片当前的运行温度。

image.png

在CircuitPython中,要读取这个芯片内温度传感器的数据,有两种方法:

  • 方法1:直接使用 microcontroller 模块提供的功能读取
    import microcontroller
    print("CPU温度:", microcontroller.cpu.temperature)
  • 方法2:通过内存映射,读取芯片内部的寄存器数据,也就是使用uctypes,通过内存映射,直接读取芯片内部的寄存器,从而获取该芯片内温度传感器的数据,并进行输出。


方法1 非常的简单,但只能读取最基础的数据。方法2 要复杂一些,但是可以读取到更多的数据,包括当前值和平均值。

在本项目中,采用了第2种方法进行读取。


从手册中可以得知,该温度传感器的数据规格,以及转换为实际温度的公式:

image.png

在硬件系统重,EMU提供低功耗周期性温度测量,每250毫秒进行一次温度测量。 测量后,测量结果将分为两部分存储在EMU_TEMP寄存器中:

  • 温度平均值:存储在EMU_TEMP寄存器的TEMPAVG位字段中,温度值以开尔文度表示,小数部分以1⁄4开尔文度为单位。
  • 温度值整数部分:存储在EMU_TEMP寄存器的TEMP位字段中,温度值以开尔文度表示
  • 温度值小数部分:存储在EMU_TEMP寄存器的TEMPLSB位字段中,以1⁄4开尔文度为单位。 具体的bit位分配信息如下:

image.png

从上述表中可以看到,要获取当前的温度数据,则:

  • 整数部分: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: 

image.png

从EMU的寄存器内存映射中,可以找到EMU_TEMP寄存器的偏移地址0x088:


image.png

在我们的代码中,通过上述基地址和寄存器的偏移地址,就能够通过内存映射地址获取其对应的数据。


默认情况下,可以读取温度传感器当前的数值,如果要读取温度平均值,则需要先发送 EMU_CMD_TEMPAVGREQ 命令,才能进行平均值的计算。 从手册可以得知,要发送该命令,可以修改如下寄存器中对应 TEMPAVGREQ 位的值: 

image.png

image.png

 当设置一次 TEMPAVGREQ 后,将会进行一次温度平均值的计算,以备读取。

2). 了解uctypes模块

在CircuitPython环境中,uctypes模块能够让我们以结构化的方式来访问内存,以及映射到内存地址的芯片内部寄存器。 uctypes需要明确指定每个字段的偏移量,从结构开始以字节为单位给出偏移量,然后给出各个字段对应的位域,以便与内存映射数据一一对应。

不过,需要特别注意的是,uctypes 模块允许访问机器的任意内存地址(包括 I/O 和控制寄存器),一旦不小心使用它可能会导致系统崩溃、数据丢失,甚至硬件故障。

如果使用uctypes的过程中,程序运行出现下面的错误,那就说明操作了不该操作的数据,系统崩溃了:

image.png

在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 命令,并读取温度平均值和当前值了,具体效果如下: 

image.png


注意,要显示上图右则的数据绘图,只需要打开 Thonny 的 Plotter(绘图器)即可: 

image.png


以上部分,可以参考:7.获取芯片自带温度传感器数据.md · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 - Gitee.com


3. 通过低功耗蓝牙(BLE)发送数据

1). 低功耗蓝牙启动

XG24-EK2703A开发板自带了低功耗蓝牙功能:

image.png

BLE UART是BLE常见的功能,用于基于BLE,来实现UART接口,从而进行数据的发送。 


在XG24-EK2703A的CircuitPython,已经自带了支持BLE功能的模块,可以用如下的命令检测是否加载: image.png


然后,可以编写如下的代码:

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中会显示:

image.png


在手机或者电脑上进行连接,就会输出连接成功的信息:

image.png


以上部分,可以参考: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)


运行上述代码后,首先串口会收到数据,并可使用绘图器绘图:

image.png


4. 电脑通过蓝牙接收温度数据并绘图

1). 连接到开发板的蓝牙

首先,需要安装必须的Python支持库:

    #ble-serial: 
pip install ble-serial

#tornado:
pip install tornado

然后,使用ble-scan命令,来查找设备:

image.png

其中CircuitPython就是开发板提供的蓝牙服务,需要将其对应这行最前面的UUID复制下来备用。


在使用下面的命令,连接到开发板:

ble-serial -d 设备对应的uuid --expose-tcp-host 127.0.0.1 --expose-tcp-port 9999

同时,还通过tcp端口9999,对外提供数据服务。

运行后,结果如下:

image.png


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。


在电脑运行上述代码后,结果如下:

image.png


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/

image.png


点击读取,就可以读取数据并呈现了:

iShot_2024-02-29_12.13.26.png

以上部分,可以参考:8.蓝牙发送芯片温度传感器数据上位机绘图 · HonestQiao/EFR32xG24 Explorer Kit CircuitPython学习仓库 (gitee.com)


总结:

这次的XG24-EK2703A板卡虽然很小,但是SiLabs不愧是在行业深耕多年的老牌企业,一块小小的板子,提供的功能却非常的不错。

这个项目,知只是应用到了其中的一部分功能,来完成芯片内置温度传感器数据的读取,以及通过低功耗蓝牙(BLE)进行数据的发送。

另外,我也探索了板子的其他功能,感兴趣的通讯,也可以进一步了解:EFR32xG24 Explorer Kit CircuitPython学习仓库: 提供EFR32xG24 Explorer Kit开发板上的CircuitPython学习研究资料 (gitee.com)

最后,感谢硬禾提供本次项目的机会,能够在XG24-EK2703A板卡上进行学习研究。

附件下载
XG24-EK2703A板卡芯片温度变化曲线.zip
XG24-EK2703A板卡芯片温度变化曲线项目源码
团队介绍
一个狂热的开源爱好者和传播者,同时也是一名极客爱好者,长期关注嵌入式发展和少儿创客教育,既擅长互联网系统架构设计与研发,又拥有丰富的嵌入式研发经验。为人精力充沛,古道热肠,圈内人称乔大妈、乔帮主。
团队成员
HonestQiao
狂热的开源爱好者和传播者
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号