FastBond4挑战部分-基于Cardputer的智能网络健康监测节点设计
该项目使用了M5Stack Cardputer开发板和M5Unit-Miniscale称重传感器,实现了基于ESP32-S3的智能网络健康监测节点的设计,它的主要功能为:多传感器支持(自动扫描I2C总线)、重量稳定性检测(滑动窗口算法)、数据上传(MQTT协议)、状态显示(TFT屏幕)、LED指示。。
标签
物联网
ESP32-S3
MQTT
健康监测
FastBond4
搜主意
更新2026-05-06
13

一、所选主题和项目介绍

1.1 项目背景

在物联网应用场景中,多设备协同工作是一个常见需求。传统的物联网设备需要预先配置网络参数和设备地址,部署过程繁琐且容易出错。本项目使用M5Stack Cardputer开发板,实现一款支持智能网络发现的健康监测节点,实现设备的即插即用和自动组网,大幅简化物联网系统的部署和维护。

1.2 项目目标

本项目使用M5Stack Cardputer V1.1 (K132)开发板,实现一款智能健康监测节点,主要功能如下:

  1. 多传感器支持:自动扫描I2C总线,支持多个称重传感器
  2. 重量稳定性检测:采用滑动窗口算法检测重量稳定性
  3. 数据上传:通过MQTT协议将重量数据上传至服务器
  4. 状态显示:内置TFT显示屏实时显示设备状态
  5. LED指示:通过RGB LED指示传感器状态

1.3 创新点

  1. 自动传感器发现:自动扫描I2C总线,无需手动配置传感器地址
  2. 稳定性检测算法:采用滑动窗口算法,三次采样波动小于2g认为稳定
  3. 多传感器管理:支持多个称重传感器同时工作,自动分配ID
  4. 实时状态显示:TFT屏幕实时显示各传感器重量和状态
  5. 远程数据上报:通过MQTT协议实现数据远程上报

二、硬件介绍

2.1 主控设备

M5Stack Cardputer (SKU: K132) — 基于ESP32-S3的卡片电脑,配备56键键盘、1.14英寸TFT屏幕、Grove扩展接口,支持WiFi和I2C通信。

参数

规格

主控芯片

ESP32-S3FN8,双核240MHz

Flash

8MB

显示屏

1.14英寸 ST7789V2,240×135

扩展接口

Grove HY2.0-4P (I2C)、SD卡槽

电池

内置120mAh + 底座1400mAh

2.2 传感器模块

M5Unit-Miniscale 称重传感器 — 基于HX711的I2C称重模块,量程0-500g,精度0.1g,板载RGB LED指示,默认地址0x26(可配置0x26-0x2D)。

2.3 硬件连接

Cardputer引脚

Miniscale引脚

功能

PORTA_SDA

SDA

I2C数据线

PORTA_SCL

SCL

I2C时钟线

3.3V

VCC

电源正极

GND

GND

电源地

📷 实物照片(Cardputer与Miniscale传感器连接)

┌─────────────────────────────────────────────────────────────────────────┐
│ Cardputer 主控板 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ESP32-S3 │ │ST7789 │ │QWERTY │ │USB-C │ │PORTA │ │
│ │主控芯片 │ │显示屏 │ │键盘 │ │接口 │ │I2C接口 │ │
│ └────┬────┘ └─────────┘ └─────────┘ └─────────┘ └────┬────┘ │
│ │ │ │
│ │ WiFi │ I2C
│ │ │ │
└───────┼────────────────────────────────────────────────────────┼──────────┘
│ │
MQTT
│ │
▼ ▼
┌───────────────────┐ ┌─────────────────────┐
MQTT Broker │ │ Miniscale传感器 │
(云端服务器) (多个级联)
│ │ │ │
│ ┌─────────────┐ │ │ ┌───────────────┐ │
│ │数据接收 │ │ │ │ 0x26 - 物品1 │ │
│ │数据存储 │ │ │ │ 0x27 - 物品2 │ │
│ └─────────────┘ │ │ │ 0x28 - 物品3 │ │
└───────────────────┘ │ └───────────────┘ │
└─────────────────────┘

三、方案框图和项目设计思路

3.1 系统架构

                           ┌─────────────────┐
MQTT Broker │
(云端服务器)
└────────┬────────┘

MQTT


┌─────────────────┐
│ Cardputer │
(监测节点)
└────────┬────────┘

I2C

┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Miniscale│ │Miniscale│ │Miniscale│
0x26 │ │ 0x27 │ │ 0x28
│ 物品1 │ │ 物品2 │ │ 物品3
└─────────┘ └─────────┘ └─────────┘

3.2 设备启动流程

                    ┌─────────────┐
│ 设备启动 │
└──────┬──────┘


┌─────────────┐
│ 加载配置 │
│ settings.toml│
└──────┬──────┘


┌─────────────┐
│ 连接WiFi │
└──────┬──────┘


┌─────────────┐
│ 扫描I2C总线 │
│ 发现传感器 │
└──────┬──────┘


┌─────────────┐
│ 连接MQTT
│ 订阅配置主题│
└──────┬──────┘


┌─────────────┐
│ 主循环运行 │
│ 读取重量 │
│ 检测稳定性 │
│ 上报数据 │
└─────────────┘

3.3 重量稳定性检测算法

采用滑动窗口算法检测重量稳定性:

  1. 采样窗口:连续采样3次
  2. 稳定判定:窗口内最大值与最小值差值 ≤ 2g
  3. 变化检测:稳定值与上次稳定值差值 ≥ 阈值时认为有变化

四、原理图和PCB展示及介绍

4.1 硬件连接原理图

本项目使用M5Stack官方硬件,硬件连接采用I2C总线方式。为支持多个Miniscale传感器级联,设计了I2C级联扩展板。


                    Cardputer
┌───────────┐
│ │
3.3V ──────────┤ 3V3 │
│ │
GND ──────────┤ GND
│ │
SCL ──────────┤ PORTA_SCL
│ │
SDA ──────────┤ PORTA_SDA
│ │
└───────────┘


┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Miniscale│ │Miniscale│ │Miniscale│
0x26 │ │ 0x27 │ │ 0x28
│ 牙刷 │ │ 水杯 │ │ 其他 │
└─────────┘ └─────────┘ └─────────┘

4.2 I2C级联扩展板PCB

为方便多个Miniscale传感器级联连接,设计了I2C级联扩展板(基于KiCad设计)。

📷 I2C级联扩展板PCB原理图:见附件
📷 I2C级联扩展板PCB布局图:见附件

>
4.3 I2C总线扫描

Cardputer支持多种I2C接口:

def init_i2c():
"""
初始化I2C总线

Cardputer有两个I2C接口:
- board.I2C(): 内置I2C
- board.PORTA_I2C(): PORTA接口的I2C
"""
i2c_list = []

# 尝试PORTA_I2C
if hasattr(board, 'PORTA_I2C'):
i2c = board.PORTA_I2C()
i2c_list.append(('PORTA_I2C', i2c))

# 尝试内置I2C
if hasattr(board, 'I2C'):
i2c = board.I2C()
i2c_list.append(('I2C', i2c))

# 尝试busio
i2c = busio.I2C(scl=board.G2, sda=board.G1)
i2c_list.append(('busio', i2c))

# 探测传感器
for name, i2c in i2c_list:
found = probe_sensors_quick(i2c)
if found:
return i2c

return None

五、软件流程图和关键代码介绍

5.1 主程序结构

"""
M5Stack Cardputer V1.1 - 智能重量监测终端

功能特性:
1. 自动扫描I2C称重设备
2. 重量稳定性检测
3. MQTT数据上报
4. TFT状态显示
"""

5.2 配置加载

def load_config():
"""
加载配置文件

优先级:
1. supervisor.runtime.config (如果可用)
2. settings.toml 文件
3. os.getenv (环境变量)
4. 默认值
"""
# 尝试从supervisor加载
if SUPERVISOR_AVAILABLE:
settings = supervisor.runtime.config
WIFI_SSID = settings.get("CIRCUITPY_WIFI_SSID")
MQTT_BROKER = settings.get("MQTT_BROKER")
# ...

# 尝试从settings.toml加载
if not config_loaded:
with open('/settings.toml', 'r') as f:
settings = parse_toml_simple(f.read())

5.3 传感器管理

class WeightSensor:
"""称重传感器类"""

def __init__(self, i2c, address, sensor_id):
self.i2c = i2c
self.address = address
self.sensor_id = sensor_id
self.weight = 0.0

def read_weight(self):
"""读取重量数据"""
try:
buffer = bytearray(4)
while not self.i2c.try_lock():
time.sleep(0.01)
try:
self.i2c.writeto_then_readfrom(
self.address,
bytes([0x10]),
buffer
)
weight = struct.unpack('<f', buffer)[0]
if -1000 < weight < 10000:
self.weight = weight
return weight
finally:
self.i2c.unlock()
except:
pass
return self.weight

def set_led(self, r, g, b):
"""设置LED颜色"""
data = bytes([r, g, b])
self.i2c.writeto(self.address, bytes([LED_REG]) + data)

5.4 稳定性检测

def check_stability(sensor_id, weight):
"""
检测重量稳定性

三次采样波动小于2g认为稳定

Args:
sensor_id: 传感器ID
weight: 当前重量值

Returns:
tuple: (是否稳定, 稳定值是否变化)
"""
global weight_history, stable_weights

if sensor_id not in weight_history:
weight_history[sensor_id] = []

weight_history[sensor_id].append(weight)

# 保留最近3次采样
if len(weight_history[sensor_id]) > 3:
weight_history[sensor_id] = weight_history[sensor_id][-3:]

# 检测稳定性
if len(weight_history[sensor_id]) >= 3:
max_diff = max(weight_history[sensor_id]) - min(weight_history[sensor_id])
if max_diff <= 2: # 波动小于2g
new_stable = int(round(sum(weight_history[sensor_id]) / 3))

# 检测变化
old_stable = stable_weights.get(sensor_id)
stable_weights[sensor_id] = new_stable

if old_stable is None:
return True, False
elif abs(new_stable - old_stable) >= WEIGHT_CHANGE_THRESHOLD:
return True, True
return True, False

return False, False

5.5 数据上报

def send_sensor_data():
"""
发送传感器数据

通过MQTT协议上报重量数据
"""
global sensors

for sensor_id, sensor in sensors.items():
weight = sensor.read_weight()

data = {
"device_id": BOARD_ID,
"sensor_id": sensor_id,
"weight": weight,
"timestamp": time.time()
}

# 通过MQTT上报
mqtt_client.publish(MQTT_TOPIC_WEIGHT, json.dumps(data))

六、硬件功能展示图及说明

6.1 硬件整体展示


6.2 显示界面

6.2.1 启动界面

=== Cardputer ===
Weight Monitor v1.0
Connecting WiFi...

6.2.2 运行状态

=== MONITOR ===
Sensors: 3
C1: 125g (物品1)
C2: 89g (物品2)
C3: 45g (物品3)
Uptime: 2h 35m

6.3 系统运行日志

==================================================
Cardputer Weight Monitor v1.0
Device ID: cardputer_01
==================================================
MAC: AA:BB:CC:DD:EE:FF
[Display] Init OK
[I2C] Bus init OK
[Sensor] C1 (0x26) init OK
[Sensor] C2 (0x27) init OK
[WiFi] Connecting to: YourWiFi
[WiFi] Connected, IP: 192.168.1.100
[MQTT] Connecting to broker.emqx.io:1883
[MQTT] Connected
==================================================
[Main] Running...

七、设计中遇到的难题和解决方法

7.1 I2C接口兼容性

问题描述:Cardputer的定制CircuitPython固件没有标准的board.SCLboard.SDA属性。

解决方案

  1. 使用board.I2C()函数式访问
  2. 尝试多种I2C初始化方式
  3. 实现自动探测功能
# 定制固件的正确方式
i2c = board.I2C() # 函数调用,不是属性访问

# 或者使用PORTA接口
i2c = board.PORTA_I2C()

7.2 重量稳定性检测

问题描述:称重传感器读数存在波动,难以判断重量是否稳定。

解决方案

  1. 采用滑动窗口算法
  2. 连续3次采样波动小于2g认为稳定
  3. 稳定后清空历史数据,重新开始检测
# 稳定性检测算法
def check_stability(weight_history):
if len(weight_history) >= 3:
max_diff = max(weight_history) - min(weight_history)
return max_diff <= 2 # 波动小于2g
return False

7.3 配置文件解析

问题描述:CircuitPython没有内置TOML解析库。

解决方案

  1. 实现简单的TOML解析器
  2. 支持基本数据类型和嵌套结构
def parse_toml_simple(content):
"""简单解析TOML配置文件"""
config = {}
current_section = None

for line in content.split('\n'):
line = line.strip()
if not line or line.startswith('#'):
continue

# 解析节
if line.startswith('[') and line.endswith(']'):
current_section = line[1:-1].strip()
continue

# 解析键值对
if '=' in line:
key, value = line.split('=', 1)
# 处理不同类型...

7.4 MQTT连接稳定性

问题描述:MQTT连接可能因网络波动断开。

解决方案

  1. 实现自动重连机制
  2. 断线时缓存数据
def mqtt_reconnect():
"""MQTT自动重连"""
global mqtt_client
try:
mqtt_client.connect()
print("[MQTT] Reconnected")
except Exception as e:
print("[MQTT] Reconnect failed:", e)

7.5 多传感器管理

问题描述:多个传感器同时工作需要有效管理。

解决方案

  1. 使用字典存储传感器实例
  2. 自动分配传感器ID
  3. 统一的数据上报接口
# 传感器管理
sensors = {}
for addr in found_addresses:
sensor_id = "C{}".format(len(sensors) + 1)
sensors[sensor_id] = WeightSensor(i2c, addr, sensor_id)

八、心得体会

8.1 项目收获

  1. 物联网架构设计:深入理解了物联网系统的数据采集和上报架构
  2. 传感器技术:掌握了I2C传感器通信和数据处理技术
  3. 嵌入式开发:熟悉了CircuitPython开发环境和API
  4. 网络协议应用:实践了MQTT协议在物联网中的应用
  5. 算法设计:实现了重量稳定性检测算法

8.2 技术亮点

  1. 自动传感器发现:自动扫描I2C总线,无需手动配置
  2. 稳定性检测算法:滑动窗口算法准确检测重量变化
  3. 多传感器管理:支持多个传感器同时工作
  4. 实时状态显示:TFT屏幕实时显示各传感器状态

8.3 改进建议

  1. 智能网络发现:实现ESP-NOW网络自动发现和组网功能,设备开机自动检测现有网络,智能选择加入或创建网络
  2. 双模式通信:支持ESP-NOW局域通信和MQTT云端通信,实现网关自动选举和数据转发
  3. 安全配对机制:按键确认机制防止未授权设备加入网络,提高系统安全性
  4. 远程配置:支持通过MQTT远程更新传感器映射,实现设备配置的动态更新
  5. 心跳机制:定期发送心跳保持MQTT连接,实现设备在线状态监控
  6. 增加加密:ESP-NOW消息加密,提高数据传输安全性
  7. 优化功耗:实现低功耗模式,延长电池寿命
  8. 增强稳定性:增加断线重连和异常恢复机制
  9. 扩展功能:支持OTA升级和远程调试

创意方向关联

本项目的技术创新为以下创意方向提供了新的思路:

1. 人工智能在嵌入式系统中的应用

本项目的传感器数据处理技术为AI应用提供了基础:

  • 故障保护:人工智能判断:稳定性检测算法可发展为AI驱动的设备健康预警系统
  • 计算机视觉:结合摄像头实现设备状态可视化监控
  • 图像识别:识别设备异常状态图像

2. 楼宇自动化

健康监测节点是楼宇自动化的核心组件:

  • 设备状态监测:监测楼宇设备运行状态
  • 能源管理:监测设备能耗,实现智能节能
  • 预测性维护:提前预警设备故障

3. 无线 / 5G / WiFi-7

项目集成的MQTT通信功能:

  • 无线连接在智能建筑中的应用:MQTT是智能建筑数据传输的标准协议
  • 5G物联网:MQTT架构可迁移到5G物联网终端开发
  • WiFi-7技术储备:高速无线通信实现实时数据上报

技术迁移价值

本项目开发的技术方案可迁移到:

  • 人工智能应用:设备健康预警、异常检测
  • 楼宇自动化:设备监测、能源管理、预测性维护
  • 无线通信:MQTT物联网、5G终端

致谢

感谢 DigiKey电子森林 提供的FastBond4活动支持,本次活动链接:https://www.eetree.cn/page/digikey-fastbond



附件下载
source_code.zip
ProPrj_1.zip
原理图和PCB
ProPrj_1.epro
原理图和PCB
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号