# 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
```