Files
Rader_IQ/IQ信号处理流程图.md
Admin 77bdbe5c1e docs: 添加IQ信号处理流程图文档
添加了详细的IQ电压信号处理流程图,包含系统架构图、处理流程图、数据流图、任务调度图、状态机图等多个可视化图表,以及关键参数表和算法核心公式说明。
2026-03-03 11:33:50 +08:00

371 lines
9.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IQ电压信号处理工程流程图
## 系统架构图
```mermaid
graph TB
A[雷达传感器] --> B[ADC采集<br/>ADC1_CH8/CH9<br/>200Hz采样]
B --> C[IQ数据处理模块<br/>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<br/>I通道原始值]
ADC1 --> ADC3[读取ADC1_CH9<br/>Q通道原始值]
ADC2 --> ADC4[采样率: 200Hz]
ADC3 --> ADC4
ADC4 --> ADC5[数据长度: 1024点<br/>5.12秒]
ADC5 --> ADC6[转换为电压<br/>V = ADC/4095 × 3.3V]
end
ADC6 --> DC[去直流处理]
subgraph 去直流
DC --> DC1[计算I平均值<br/>meanI]
DC --> DC2[计算Q平均值<br/>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[计算相位差<br/>Δφ = φ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[计算相位均值<br/>μ = mean φ]
EC1 --> EC2[计算相位方差<br/>Var = Eφ-μ²]
EC2 --> EC3{Var < 1e-4?}
EC3 -->|是| EC4[NO_PERSON<br/>无人]
EC3 -->|否| MotionCheck[活动检测]
end
MotionCheck --> MC1[计算相位差分能量<br/>E = mean φn-φn-1²]
MC1 --> MC2{E > 0.05?}
MC2 -->|是| MC3[MOTION<br/>人体运动]
MC2 -->|否| MC4[STATIC_HUMAN<br/>人体静止]
EC4 --> End([结束])
MC3 --> Downsample[降采样]
MC4 --> Downsample
subgraph 降采样
Downsample --> DS1[呼吸数据<br/>1024→51点<br/>10Hz]
Downsample --> DS2[心率数据<br/>1024→256点<br/>50Hz]
end
DS1 --> RespFreq[呼吸频率估计]
DS2 --> HeartFreq[心率估计]
subgraph 呼吸频率估计
RespFreq --> RF1[频率扫描<br/>0.1-0.6Hz]
RF1 --> RF2[DFT计算<br/>Xf = Σ φn × e-j2πfn]
RF2 --> RF3[找最大能量频率]
RF3 --> RF4[转换为BPM<br/>BPM = f × 60]
end
subgraph 心率估计
HeartFreq --> HF1[频率扫描<br/>0.6-3.0Hz]
HF1 --> HF2[DFT计算<br/>Xf = Σ φn × e-j2πfn]
HF2 --> HF3[找最大能量频率]
HF3 --> HF4[转换为BPM<br/>BPM = f × 60]
end
RF4 --> Filter[后处理滤波]
HF4 --> Filter
subgraph 后处理滤波
Filter --> F1[异常值检测<br/>心率: 40-180 BPM<br/>呼吸: 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原始数据<br/>12位, 0-4095]
end
subgraph 预处理
B[去直流<br/>I'Q']
C[相位转换<br/>φ = atan2Q,I]
D[相位展开<br/>连续相位]
end
subgraph 特征提取
E[相位方差<br/>空人检测]
F[差分能量<br/>活动检测]
end
subgraph 频率分析
G[降采样<br/>呼吸/心率]
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[雷达数据采集任务<br/>优先级: 4<br/>Core: 1]
T2[串口数据任务<br/>优先级: 3<br/>Core: 1]
end
subgraph 处理流程
P1[ADC采集循环<br/>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<br/>且差分能量 ≤ 0.05
NO_PERSON --> MOTION: 相位方差 ≥ 1e-4<br/>且差分能量 > 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<br/>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
```