TinyML 咳嗽检测:Arduino Nano 33 BLE Sense 实现早期流感筛查
项目背景与意义
本项目源自 UN Covid Detect & Protect Challenge,旨在开发低成本、易部署的咳嗽声检测系统,用于流感/新冠等呼吸道疾病的早期筛查。利用 Edge Impulse 平台训练 TinyML 模型,部署在 Arduino Nano 33 BLE Sense(Cortex-M4F, 64MHz, 256KB RAM, 内置 PDM 麦克风)上,实现 实时、离线、<20KB RAM 的咳嗽/背景噪声二分类。
硬件要求
- Arduino Nano 33 BLE Sense ×1(或同级 Cortex-M4+ 麦克风板卡)
- Android/iOS 手机(可选,用于数据采集/现场推理验证)
- PC(运行 Edge Impulse CLI、Arduino IDE)
完整开发流程
阶段 1:数据集构建
- 获取种子数据集:下载 cough.zip(含 10 分钟「咳嗽」/「噪声」标注样本)
- Edge Impulse CLI 上传:
$ edge-impulse-uploader --clean $ edge-impulse-uploader --category training training/* $ edge-impulse-uploader --category testing testing/* - 扩充数据(关键):通过手机浏览器扫码连接 Edge Impulse,现场录制更多咳嗽、语音、环境噪音,平衡类别分布,提升泛化能力
阶段 2:Impulse 设计(信号处理 + 学习模块)
- 时间窗:1000ms 窗长,500ms 步长(50% 重叠)
- 处理块:Audio (MFCC) - 提取 13 维梅尔频率倒谱系数,生成频谱图
- 学习块:Neural Network (Keras) - 2D CNN 分类器
阶段 3:模型架构(Keras 专家模式)
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import *
model = Sequential([
InputLayer(input_shape=(X_train.shape[1],), name='x_input'),
Reshape((int(X_train.shape[1]/13), 13, 1)),
Conv2D(10, 5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)),
AveragePooling2D(2, padding='same'),
Conv2D(5, 5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)),
AveragePooling2D(2, padding='same'),
Flatten(),
Dense(classes, activation='softmax', name='y_pred', kernel_constraint=MaxNorm(3))
])
opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=32, epochs=9, validation_data=(X_test, Y_test), verbose=2)
设计要点:
- 2D Conv 处理频谱图,类比图像分类,捕捉时频局部模式
MaxNorm(3)权重约束防止过拟合,适配量化部署- 最小置信度 0.70 抑制低置信误报
阶段 4:训练与验证
- 训练集性能:Accuracy ~95%+(视数据质量)
- 设备端性能估算:DSP 495ms + 分类 84ms + 异常检测 0ms = ~580ms/推理周期,RAM < 20KB,Flash ~100KB
- 实测混淆矩阵:重点关注「咳嗽→噪声」漏报率与「噪声→咳嗽」误报率
阶段 5:部署与实测
手机端 (WebAssembly)
- 手机浏览器刷新 Edge Impulse 项目页
- 点击 "Switch to classification mode" → 自动编译 WASM 包 → 离线持续推理(飞行模式可用)
Nano 33 BLE Sense 固件烧录
- Deployment 页面选择 "Arduino Nano 33 BLE Sense" → Build
- 按提示进入 Bootloader 模式(双击复位)烧录
.bin - 串口 115200 波特率,发送
AT+RUNIMPULSE启动持续推理
串口实时输出示例
> AT+RUNIMPULSE
Inferencing settings:
Interval: 0.06 ms.
Frame size: 16000
Sample length: 1000 ms.
No. of classes: 2
Starting inferencing, press 'b' to break
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
cough: 0.01562
noise: 0.98438
...
Predictions ...:
cough: 0.86719 ← 检测到咳嗽
noise: 0.13281
关键技术指标
| 指标 | 数值 | 备注 |
|---|---|---|
| 模型大小 | ~100 KB Flash | 含 TensorFlow Lite Micro 运行时 |
| RAM 峰值 | < 20 KB | 张量竞技场 + MFCC 缓冲区 |
| 推理延迟 | ~580 ms | DSP 占比 85%,可用 CMSIS-NN 加速 |
| 采样率 | 16 kHz | PDM 麦克风硬件降采样 |
| 功耗(推理中) | ~15 mA @ 3.3V | 约 50 mW,电池可运行数天 |
进阶优化方向
- 数据增强:时移、加噪、音高变换、混合背景噪声,提升鲁棒性
- 新增类别:语音、打喷嚏、清喉咙、笑声等,转为多类分类
- 模型压缩:量化感知训练 (QAT) → INT8 模型,推理加速 3-4×,精度损失 <1%
- 异常检测:引入 GMM/自编码器识别分布外样本(如麦克风故障、异常环境音)
- 多模态融合:结合 3 轴加速度计(体动/体位)提升特异性
- 联邦学习:多设备本地训练 + 云端聚合,保护隐私持续迭代
工程化落地清单
- 外壳设计:声学透声腔 + 防风棉,固定麦克风位置,减少摩擦噪声
- 供电方案:18650 锂电池 + 低压差 LDO,或太阳能充电板
- 数据上报:LoRaWAN/NB-IoT/WiFi 定时上传检测事件与统计摘要
- 固件 OTA:Arduino OTA 或 Edge Impulse 模型热更新机制
- 合规认证:医疗器械分类确认、数据隐私合规 (GDPR/HIPAA)、EMC 测试
同类应用迁移指南
同套流程可直接迁移至:
- 工业设备故障声纹识别(轴承异响、泵气蚀、电机啸叫)
- 老人跌倒/呼救声检测
- 野生动物鸣叫监测(鸟类、蝙蝠超声)
- 城市声环境监测(施工噪音、车辆鸣笛、广场舞)
仅需替换数据集、调整标签、微调预处理参数(采样率、窗长、MFCC 系数数),核心流程 100% 复用。
完整教程、数据集、模型文件请访问 Edge Impulse Studio 项目页或 Hackster.io 原文链接。
制造工艺
- K30 CO₂ 传感器:室内空气质量实时监测
- 基于 1Sheeld 与 Arduino 的盲聋人士沟通辅助系统
- 智能存钱罐:Arduino Nano 控制硬币识别器实现余额显示
- Arduino + HC-05 蓝牙控制 LED:MIT App Inventor 手机 App 开发全攻略
- DFRobot 电容指纹传感器 (ID809) 接入 Arduino/ESP8266 完整教程
- 基于 Arduino Mega 与 Nextion 显示屏的交互式气象站
- Arduino Mega 驱动 Wii Nunchuk 控制 6 自由度机械臂
- TinyML 植物健康评估:Arduino Nano 33 BLE Sense + 步进电机扫描建模
- 实时森林火灾监测系统:短信报警方案
- Arduino UNO + 以太网盾板实现低成本太阳辐射测量仪(热电堆原理)
- 紧凑型Arduino雷达系统:HC-SR04超声波传感器配1.8英寸显示屏
- Arduino智能防碰撞预警系统:超声波测距+声光分级报警