1. 项目背景与需求分析
摩擦纳米发电机(TENG)技术近年来在医疗健康监测领域掀起了一场革命。作为一名长期从事可穿戴设备开发的工程师,我最近完成了一个将TENG呼吸监测系统从蓝牙升级到WiFi通信的改造项目。这个看似简单的通信协议切换,实际上涉及到硬件架构调整、嵌入式代码重构和上位机软件重写三个层面的系统性工程。
传统呼吸监测设备往往需要外部供电,而TENG传感器的自供能特性彻底改变了这一局面。我们的系统通过在用户胸部或腹部贴附柔性TENG传感器,将呼吸运动产生的机械形变直接转化为电信号。初始版本采用蓝牙传输数据,在实际测试中发现两个致命缺陷:一是传输距离受限(通常不超过10米),二是无法直接接入医院或家庭的现有WiFi网络进行云端数据同步。
硬件层面已经完成了两项关键改造:
- 将四通道采集精简为单通道设计(呼吸监测单点数据已足够)
- 用ESP8266 WiFi模块替换原来的HC-05蓝牙模块
但软件系统仍存在以下待解决问题:
- 嵌入式端需要重写通信协议栈
- 上位机需要支持WiFi Socket通信
- 数据可视化界面需要优化刷新机制
- 要增加CSV导出功能供后续分析使用
关键提示:选择ESP8266而非更先进的ESP32是经过实际测试的折中方案 - 在保证TCP吞吐量的前提下,ESP8266的功耗更低(约80mA),更适合电池供电的可穿戴设备。
2. 硬件架构深度解析
2.1 传感器信号链路设计
TENG传感器产生的原始信号具有高阻抗(>10MΩ)和微幅值(mV级)的特点,需要经过特殊调理:
code复制[传感器] → 阻抗匹配电路 → 前置放大(×100) → 带通滤波(0.1-10Hz) → ADC采集
我们选用TI的INA128仪表放大器作为前置级,关键参数配置:
- 增益电阻Rg = 499Ω → G=1+50kΩ/Rg≈101
- 供电电压±2.5V(使用TPS7A30/49生成)
- 输入偏置电流<1nA(避免影响TENG输出)
2.2 STM32最小系统设计
主控采用STM32F103C8T6(Cortex-M3),其ADC配置要点:
- 12位分辨率,1Msps采样率
- 采用DMA循环缓冲模式(256样本/缓冲区)
- 定时器触发采样(100Hz采样率)
- 参考电压使用专用REF3030(3.0V)
c复制// ADC初始化代码片段
void ADC1_Init(void) {
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
}
2.3 ESP8266通信模块集成
ESP8266通过UART与STM32通信,硬件连接方案:
code复制STM32_USART1_TX → ESP8266_RX (3.3V电平)
STM32_USART1_RX → ESP8266_TX
STM32_GPIO_PA4 → ESP8266_RST (硬件复位)
波特率选择115200bps,实际测试数据传输稳定性:
| 数据间隔(ms) | 丢包率(%) |
|---|---|
| 10 | 0.12 |
| 5 | 0.35 |
| 1 | 1.78 |
最终采用10ms间隔发送策略,在数据时效性和可靠性间取得平衡。
3. 嵌入式软件实现
3.1 WiFi通信协议设计
采用轻量级自定义协议格式:
code复制[HEAD(0xAA)][LEN][TIMESTAMP][DATA][CHECKSUM]
- HEAD:固定0xAA作为帧头
- LEN:数据长度(1字节)
- TIMESTAMP:32位系统滴答计数
- DATA:ADC采样值(2字节)
- CHECKSUM:异或校验和
协议状态机实现:
c复制typedef enum {
STATE_WAIT_HEAD,
STATE_WAIT_LEN,
STATE_WAIT_PAYLOAD,
STATE_WAIT_CHECKSUM
} ParserState;
void parse_byte(uint8_t byte) {
static ParserState state = STATE_WAIT_HEAD;
static uint8_t buffer[32], idx = 0;
static uint8_t expected_len = 0;
switch(state) {
case STATE_WAIT_HEAD:
if(byte == 0xAA) {
state = STATE_WAIT_LEN;
}
break;
// ...其他状态处理
}
}
3.2 数据采集与发送协同
采用双缓冲机制避免数据丢失:
- DMA循环填充BufferA
- 当BufferA满时触发中断,切换至BufferB
- 主循环处理BufferA数据并通过WiFi发送
c复制volatile uint16_t adc_buffer[2][256];
volatile uint8_t active_buffer = 0;
void DMA1_Channel1_IRQHandler(void) {
if(DMA_GetITStatus(DMA1_IT_TC1)) {
DMA_ClearITPendingBit(DMA1_IT_TC1);
active_buffer ^= 1; // 切换缓冲
DMA_SetCurrDataCounter(DMA1_Channel1, 256);
// 触发新缓冲处理标志
process_flag = 1;
}
}
4. 上位机软件实现
4.1 Python通信核心模块
使用socket + threading实现异步接收:
python复制class DataReceiver(threading.Thread):
def __init__(self, ip, port):
threading.Thread.__init__(self)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((ip, port))
self.buffer = bytearray()
def run(self):
while True:
data = self.sock.recv(1024)
if not data: break
self.buffer.extend(data)
self.process_buffer()
def process_buffer(self):
while len(self.buffer) >= 6: # 最小完整帧长度
if self.buffer[0] != 0xAA:
self.buffer.pop(0)
continue
# 解析完整帧...
4.2 实时可视化实现
基于PyQt5+pyqtgraph的高性能绘图:
python复制class RealTimePlot(pg.PlotWidget):
def __init__(self):
super().__init__()
self.curve = self.plot(pen='y')
self.data = np.zeros(1000)
self.ptr = 0
def update_plot(self, value):
self.data[self.ptr] = value
self.ptr = (self.ptr + 1) % len(self.data)
self.curve.setData(self.data[:self.ptr])
4.3 数据存储模块设计
支持CSV按时间分片存储:
python复制def save_to_csv(filename, data):
with open(filename, 'a', newline='') as f:
writer = csv.writer(f)
if os.stat(filename).st_size == 0: # 新文件写表头
writer.writerow(['timestamp', 'value'])
writer.writerow([time.time(), data])
5. 系统集成与测试
5.1 通信压力测试
在不同网络环境下进行72小时连续测试:
| 网络环境 | 平均延迟(ms) | 最大丢包率 |
|---|---|---|
| 办公室WiFi | 12.3 | 0.05% |
| 家庭路由器 | 18.7 | 0.12% |
| 公共热点 | 56.2 | 1.25% |
5.2 呼吸信号质量对比
原始蓝牙系统与WiFi改造后信号质量指标对比:
| 指标 | 蓝牙版本 | WiFi版本 |
|---|---|---|
| SNR(dB) | 42.1 | 45.3 |
| 波形失真度(%) | 3.2 | 2.8 |
| 延迟(ms) | 65 | 28 |
5.3 典型问题排查指南
-
ESP8266频繁断连
- 检查天线阻抗匹配(PCB天线需50Ω匹配)
- 降低UART波特率到57600测试
- 增加硬件复位电路
-
上位机显示卡顿
- 减少绘图数据点数量(如只显示最近500点)
- 使用QTimer固定刷新间隔(如50ms)
- 关闭抗锯齿效果
-
CSV文件时间戳错乱
- 确保使用NTP同步系统时间
- 采用UTC时间戳避免时区问题
- 文件写入加锁避免多线程冲突
6. 项目优化方向
在实际部署中,我们发现几个值得改进的要点:
-
动态采样率调整:根据呼吸频率自动调节采样率(平静时50Hz,运动时100Hz),可降低30%功耗。
-
离线缓存机制:在ESP8266中加入512KB Flash缓存,网络中断时暂存数据,恢复后重传。
-
自适应滤波算法:采用LMS自适应滤波器消除运动伪影,实测可提升信号质量约15%。
这个改造项目让我深刻体会到,通信协议的升级不仅仅是简单的模块替换,更需要从系统层面考虑硬件资源分配、软件架构调整和用户体验优化。特别是在医疗健康监测领域,可靠性永远是第一位的设计准则。