Skip to content

可穿戴设备解决方案

可穿戴设备分类

类型典型产品通信方案功耗要求
智能手表Apple Watch 类BLE + Wi-Fi / Cat.1中(每天充电)
健康手环运动手环BLE低(一周充电)
医疗级可穿戴心电贴片、血糖贴片BLE + Cat.1极低(一次性)
老人定位手表防走失手表Cat.1 + GNSS低(两天充电)
儿童手表儿童电话手表Cat.1 + GNSS中(每天充电)

老人/儿童定位手表方案

硬件架构

┌─────────────────────────────────────────────────────┐
│                  定位手表硬件                          │
│                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │ Cat.1 模组│  │ GNSS 模组│  │  主控 MCU         │  │
│  │ EC200U   │  │ L76K     │  │  (低功耗 ARM)     │  │
│  └──────────┘  └──────────┘  └──────────────────┘  │
│                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │ 显示屏   │  │ 麦克风   │  │  电池(300mAh)   │  │
│  │ 1.3寸   │  │ 扬声器   │  │  + 充电管理       │  │
│  └──────────┘  └──────────┘  └──────────────────┘  │
│                                                      │
│  传感器:加速度计(计步/跌倒检测)/ 心率传感器(可选)  │
└─────────────────────────────────────────────────────┘

核心功能实现

python
# QuecPython 定位手表核心逻辑
import utime
import gnss
import dataCall
import voiceCall
import request
import ujson
import machine

# 配置
DEVICE_ID = "WATCH_SN_001"
SERVER_URL = "https://watch.example.com/api"
SOS_NUMBERS = ["+8613800138000", "+8613900139000"]  # 紧急联系人

# 初始化加速度计(跌倒检测)
accel = machine.I2C(machine.I2C.I2C1, machine.I2C.STANDARD_MODE)

class SmartWatch:
    def __init__(self):
        self.location = None
        self.step_count = 0
        self.fall_detected = False
        self.sos_triggered = False
    
    def get_location(self):
        """获取 GPS 位置"""
        gnss.init()
        gnss.on(1)
        
        # 等待定位(最多60秒)
        for _ in range(60):
            loc = gnss.getLocation()
            if loc and loc[0] != 0:
                self.location = {
                    "lat": loc[0],
                    "lng": loc[1],
                    "speed": loc[2],
                    "accuracy": loc[3]
                }
                return self.location
            utime.sleep(1)
        
        return None
    
    def detect_fall(self):
        """跌倒检测(基于加速度计)"""
        # 读取三轴加速度
        # 跌倒特征:先有大加速度(跌落),后有小加速度(静止)
        samples = []
        for _ in range(50):
            # 读取 MPU6050 加速度数据
            data = accel.read(0x68, 6)
            ax = (data[0] << 8 | data[1]) / 16384.0
            ay = (data[2] << 8 | data[3]) / 16384.0
            az = (data[4] << 8 | data[5]) / 16384.0
            total_g = (ax**2 + ay**2 + az**2) ** 0.5
            samples.append(total_g)
            utime.sleep_ms(20)
        
        max_g = max(samples)
        min_g = min(samples[-10:])  # 最后10个样本的最小值
        
        # 跌倒判断:峰值 > 2.5g 且随后静止 < 0.5g
        if max_g > 2.5 and min_g < 0.5:
            self.fall_detected = True
            return True
        return False
    
    def trigger_sos(self):
        """触发 SOS 紧急求救"""
        self.sos_triggered = True
        
        # 获取位置
        location = self.get_location()
        
        # 上报 SOS 事件
        sos_data = {
            "device_id": DEVICE_ID,
            "event": "SOS",
            "location": location,
            "timestamp": utime.time()
        }
        
        try:
            request.post(SERVER_URL + "/sos", json=sos_data)
        except:
            pass
        
        # 依次拨打紧急联系人
        for number in SOS_NUMBERS:
            try:
                voiceCall.callStart(number)
                utime.sleep(30)  # 通话30秒
                voiceCall.callEnd()
                break
            except:
                continue
    
    def report_location(self):
        """定期上报位置"""
        location = self.get_location()
        if not location:
            return
        
        data = {
            "device_id": DEVICE_ID,
            "location": location,
            "steps": self.step_count,
            "battery": self.get_battery_level(),
            "timestamp": utime.time()
        }
        
        try:
            request.post(SERVER_URL + "/location", json=data)
        except Exception as e:
            print(f"Upload failed: {e}")
    
    def get_battery_level(self):
        """获取电池电量"""
        adc = machine.ADC()
        raw = adc.read(machine.ADC.ADC0)
        voltage = raw * 4.2 / 4095
        # 简化的电量估算
        soc = max(0, min(100, (voltage - 3.3) / (4.2 - 3.3) * 100))
        return int(soc)
    
    def run(self):
        """主运行循环"""
        # 等待网络
        while dataCall.getInfo(1, 0)[2][0] != 1:
            utime.sleep(1)
        
        last_report = 0
        
        while True:
            # 跌倒检测
            if self.detect_fall():
                print("跌倒检测!")
                # 等待5秒,如果用户没有取消则触发SOS
                utime.sleep(5)
                if self.fall_detected:
                    self.trigger_sos()
                    self.fall_detected = False
            
            # 每5分钟上报位置
            now = utime.time()
            if now - last_report >= 300:
                self.report_location()
                last_report = now
            
            utime.sleep(1)

watch = SmartWatch()
watch.run()

医疗级心电贴片

连续心电监测

产品形态:
  一次性心电贴片(佩戴7-14天)
  尺寸:约 50×30×5mm
  重量:< 10g
  防水:IPX7

技术方案:
  心电采集:ADS1292R(德州仪器,医疗级 ECG AFE)
  主控:STM32L4(超低功耗)
  通信:BLE(连接手机)+ Cat.1(直连云端,可选)
  存储:本地 Flash(断网时缓存)
  电池:100mAh 锂电池(支持7天连续监测)

数据处理:
  采样率:250Hz(满足心电分析要求)
  分辨率:24位 ADC
  本地算法:R波检测、心率计算、房颤初筛
  云端算法:12导联重建、心律失常分析、AI 诊断

心率变异性(HRV)分析

python
import numpy as np

def analyze_hrv(rr_intervals_ms):
    """
    心率变异性分析
    rr_intervals_ms: RR 间期列表(毫秒)
    """
    rr = np.array(rr_intervals_ms)
    
    # 时域指标
    mean_rr = np.mean(rr)
    sdnn = np.std(rr)  # RR 间期标准差
    
    # RMSSD:相邻 RR 间期差值的均方根
    diff_rr = np.diff(rr)
    rmssd = np.sqrt(np.mean(diff_rr ** 2))
    
    # pNN50:相邻 RR 间期差值 > 50ms 的比例
    pnn50 = np.sum(np.abs(diff_rr) > 50) / len(diff_rr) * 100
    
    # 心率
    heart_rate = 60000 / mean_rr
    
    # HRV 评分(简化)
    hrv_score = min(100, rmssd / 50 * 100)
    
    return {
        "heart_rate_bpm": round(heart_rate, 1),
        "mean_rr_ms": round(mean_rr, 1),
        "sdnn_ms": round(sdnn, 1),
        "rmssd_ms": round(rmssd, 1),
        "pnn50_percent": round(pnn50, 1),
        "hrv_score": round(hrv_score, 0),
        "stress_level": "低" if hrv_score > 60 else "中" if hrv_score > 30 else "高"
    }

褚成志的笔记