# IQ电压信号处理工程流程图 ## 系统架构图 ```mermaid graph TB A[雷达传感器] --> B[ADC采集
ADC1_CH8/CH9
200Hz采样] B --> C[IQ数据处理模块
radar_vitals.cpp] C --> D[状态判断] C --> E[频率估计] D --> F[输出结果] E --> F F --> G[串口输出] style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#ffe1f5 style D fill:#e1ffe1 style E fill:#e1ffe1 style F fill:#f5e1ff style G fill:#e1f5ff ``` ## 详细处理流程图 ```mermaid flowchart TD Start([开始]) --> ADC1[ADC数据采集] subgraph ADC采集 ADC1 --> ADC2[读取ADC1_CH8
I通道原始值] ADC1 --> ADC3[读取ADC1_CH9
Q通道原始值] ADC2 --> ADC4[采样率: 200Hz] ADC3 --> ADC4 ADC4 --> ADC5[数据长度: 1024点
5.12秒] ADC5 --> ADC6[转换为电压
V = ADC/4095 × 3.3V] end ADC6 --> DC[去直流处理] subgraph 去直流 DC --> DC1[计算I平均值
meanI] DC --> DC2[计算Q平均值
meanQ] DC1 --> DC3[I'n = In - meanI] DC2 --> DC4[Q'n = Qn - meanQ] end DC3 --> Phase[相位转换] DC4 --> Phase subgraph 相位转换 Phase --> Phase1[φn = atan2 Qn, In] end Phase1 --> Unwrap[相位展开] subgraph 相位展开 Unwrap --> Unwrap1[计算相位差
Δφ = φn - φn-1] Unwrap1 --> Unwrap2{Δφ > π?} Unwrap2 -->|是| Unwrap3[Δφ -= 2π] Unwrap2 -->|否| Unwrap4{Δφ < -π?} Unwrap4 -->|是| Unwrap5[Δφ += 2π] Unwrap4 -->|否| Unwrap6[保持Δφ] Unwrap3 --> Unwrap7[φn = φn-1 + Δφ] Unwrap5 --> Unwrap7 Unwrap6 --> Unwrap7 end Unwrap7 --> EmptyCheck[空人判断] subgraph 空人判断 EmptyCheck --> EC1[计算相位均值
μ = mean φ] EC1 --> EC2[计算相位方差
Var = Eφ-μ²] EC2 --> EC3{Var < 1e-4?} EC3 -->|是| EC4[NO_PERSON
无人] EC3 -->|否| MotionCheck[活动检测] end MotionCheck --> MC1[计算相位差分能量
E = mean φn-φn-1²] MC1 --> MC2{E > 0.05?} MC2 -->|是| MC3[MOTION
人体运动] MC2 -->|否| MC4[STATIC_HUMAN
人体静止] EC4 --> End([结束]) MC3 --> Downsample[降采样] MC4 --> Downsample subgraph 降采样 Downsample --> DS1[呼吸数据
1024→51点
10Hz] Downsample --> DS2[心率数据
1024→256点
50Hz] end DS1 --> RespFreq[呼吸频率估计] DS2 --> HeartFreq[心率估计] subgraph 呼吸频率估计 RespFreq --> RF1[频率扫描
0.1-0.6Hz] RF1 --> RF2[DFT计算
Xf = Σ φn × e-j2πfn] RF2 --> RF3[找最大能量频率] RF3 --> RF4[转换为BPM
BPM = f × 60] end subgraph 心率估计 HeartFreq --> HF1[频率扫描
0.6-3.0Hz] HF1 --> HF2[DFT计算
Xf = Σ φn × e-j2πfn] HF2 --> HF3[找最大能量频率] HF3 --> HF4[转换为BPM
BPM = f × 60] end RF4 --> Filter[后处理滤波] HF4 --> Filter subgraph 后处理滤波 Filter --> F1[异常值检测
心率: 40-180 BPM
呼吸: 4-40 BPM] F1 --> F2[5点移动平均滤波] F2 --> F3[四舍五入取整] end F3 --> Output[输出结果] subgraph 输出 Output --> O1[人体状态] Output --> O2[心率 BPM] Output --> O3[呼吸率 BPM] Output --> O4[串口打印] end O4 --> End style Start fill:#90EE90 style End fill:#FFB6C1 style ADC1 fill:#87CEEB style DC fill:#DDA0DD style Phase fill:#F0E68C style Unwrap fill:#98FB98 style EmptyCheck fill:#FFA07A style Downsample fill:#20B2AA style RespFreq fill:#FF6347 style HeartFreq fill:#FF6347 style Filter fill:#9370DB style Output fill:#00CED1 ``` ## 数据流图 ```mermaid graph LR subgraph 输入 A[ADC原始数据
12位, 0-4095] end subgraph 预处理 B[去直流
I'Q'] C[相位转换
φ = atan2Q,I] D[相位展开
连续相位] end subgraph 特征提取 E[相位方差
空人检测] F[差分能量
活动检测] end subgraph 频率分析 G[降采样
呼吸/心率] H[DFT频谱分析] I[峰值检测] end subgraph 后处理 J[异常值过滤] K[移动平均] L[取整输出] end subgraph 输出 M[人体状态] N[心率 BPM] O[呼吸率 BPM] end A --> B --> C --> D D --> E D --> F D --> G --> H --> I --> J --> K --> L E --> M F --> M L --> N L --> O style A fill:#FFE4B5 style B fill:#E0FFFF style C fill:#E0FFFF style D fill:#E0FFFF style E fill:#FFDAB9 style F fill:#FFDAB9 style G fill:#98FB98 style H fill:#98FB98 style I fill:#98FB98 style J fill:#DDA0DD style K fill:#DDA0DD style L fill:#DDA0DD style M fill:#F0E68C style N fill:#F0E68C style O fill:#F0E68C ``` ## 关键参数说明 | 参数 | 值 | 说明 | |------|-----|------| | ADC采样率 | 200 Hz | 基础采样频率 | | 基础数据长度 | 1024 点 | 对应5.12秒数据 | | ADC分辨率 | 12位 | 0-4095 | | 参考电压 | 3.3V | 电压转换基准 | | 呼吸采样率 | 10 Hz | 降采样后频率 | | 心率采样率 | 50 Hz | 降采样后频率 | | 呼吸频率范围 | 0.1-0.6 Hz | 6-36 BPM | | 心率频率范围 | 0.6-3.0 Hz | 36-180 BPM | | 空人阈值 | 方差 < 1e-4 | 相位方差阈值 | | 活动阈值 | 能量 > 0.05 | 差分能量阈值 | ## 算法核心公式 ### 1. 去直流 ``` I'(n) = I(n) - mean(I) Q'(n) = Q(n) - mean(Q) ``` ### 2. 相位计算 ``` φ(n) = atan2(Q'(n), I'(n)) ``` ### 3. 相位展开 ``` Δφ = φ(n) - φ(n-1) if Δφ > π: Δφ -= 2π if Δφ < -π: Δφ += 2π φ_unwrap(n) = φ_unwrap(n-1) + Δφ ``` ### 4. 空人判断 ``` Var(φ) = E[(φ - μ)²] if Var(φ) < 1e-4 → NO_PERSON ``` ### 5. 活动检测 ``` E = E[(φ(n) - φ(n-1))²] if E > 0.05 → MOTION else → STATIC_HUMAN ``` ### 6. DFT频率估计 ``` X(f) = Σ φ(n) × e^(-j2πfn) f_peak = arg max |X(f)|² BPM = f_peak × 60 ``` ## 任务调度图 ```mermaid graph TB subgraph FreeRTOS任务 T1[雷达数据采集任务
优先级: 4
Core: 1] T2[串口数据任务
优先级: 3
Core: 1] end subgraph 处理流程 P1[ADC采集循环
1024点 @ 200Hz] P2[调用radar_process] P3[状态判断] P4[频率估计] P5[串口输出] end T1 --> P1 --> P2 --> P3 --> P4 --> P5 T2 --> P5 style T1 fill:#FFB6C1 style T2 fill:#87CEEB style P1 fill:#98FB98 style P2 fill:#98FB98 style P3 fill:#F0E68C style P4 fill:#F0E68C style P5 fill:#DDA0DD ``` ## 状态机图 ```mermaid stateDiagram-v2 [*] --> NO_PERSON: 相位方差 < 1e-4 NO_PERSON --> STATIC_HUMAN: 相位方差 ≥ 1e-4
且差分能量 ≤ 0.05 NO_PERSON --> MOTION: 相位方差 ≥ 1e-4
且差分能量 > 0.05 STATIC_HUMAN --> MOTION: 差分能量 > 0.05 MOTION --> STATIC_HUMAN: 差分能量 ≤ 0.05 STATIC_HUMAN --> NO_PERSON: 相位方差 < 1e-4 MOTION --> NO_PERSON: 相位方差 < 1e-4 note right of NO_PERSON 无人状态 不进行频率估计 end note note right of STATIC_HUMAN 人体静止 进行呼吸/心率估计 end note note right of MOTION 人体运动 进行呼吸/心率估计 但可能不准确 end note ``` ## 文件结构 ``` Rader_IQ第1版/ ├── src/ │ ├── main.cpp # 主程序,任务调度 │ ├── radar_vitals.cpp # IQ信号处理核心算法 │ ├── radar_vitals.h # 接口定义和常量 │ ├── io_flash.cpp # Flash存储 │ └── io_flash.h ├── include/ # 头文件目录 ├── lib/ # 库文件目录 ├── test/ # 测试目录 └── platformio.ini # 项目配置 ``` ## 核心函数调用关系 ```mermaid graph TD A[main.cpp
radarDataTask] --> B[radar_process] B --> C[去直流处理] C --> D[相位转换] D --> E[相位展开] E --> F[空人判断] E --> G[活动检测] E --> H[降采样] H --> I[呼吸频率估计] H --> J[心率估计] I --> K[后处理滤波] J --> K K --> L[radar_get_state] K --> M[radar_get_heart_bpm] K --> N[radar_get_resp_bpm] style A fill:#FFB6C1 style B fill:#87CEEB style C fill:#E0FFFF style D fill:#E0FFFF style E fill:#E0FFFF style F fill:#FFDAB9 style G fill:#FFDAB9 style H fill:#98FB98 style I fill:#F0E68C style J fill:#F0E68C style K fill:#DDA0DD style L fill:#90EE90 style M fill:#90EE90 style N fill:#90EE90 ```