docs: 添加IQ信号处理流程图文档
添加了详细的IQ电压信号处理流程图,包含系统架构图、处理流程图、数据流图、任务调度图、状态机图等多个可视化图表,以及关键参数表和算法核心公式说明。
This commit is contained in:
161
Git提交方法.md
Normal file
161
Git提交方法.md
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
# Git 提交和推送成功方法
|
||||||
|
|
||||||
|
## 项目配置信息
|
||||||
|
|
||||||
|
- **远程仓库地址**: `http://lmhrt.cn:6771/ming/Rader_IQ.git`
|
||||||
|
- **主分支**: `main`
|
||||||
|
- **Git 路径**: `C:\Program Files\Git\bin\git.exe`
|
||||||
|
|
||||||
|
## 方法一:使用 git.bat 脚本(推荐)
|
||||||
|
|
||||||
|
### 脚本位置
|
||||||
|
`git.bat` 位于项目根目录
|
||||||
|
|
||||||
|
### 使用步骤
|
||||||
|
1. 双击运行 `git.bat`
|
||||||
|
2. 查看步骤 1:检查 Git 状态
|
||||||
|
3. 查看步骤 2:添加所有文件到暂存区
|
||||||
|
4. 查看步骤 3:输入提交信息(默认:Update project)
|
||||||
|
5. 查看步骤 4:自动拉取远程代码
|
||||||
|
6. 查看步骤 5:推送到远程仓库
|
||||||
|
|
||||||
|
### 脚本流程
|
||||||
|
```
|
||||||
|
[1/5] 检查 Git 状态
|
||||||
|
[2/5] 添加所有文件到暂存区
|
||||||
|
[3/5] 提交更改
|
||||||
|
[4/5] 拉取远程代码
|
||||||
|
[5/5] 推送到远程仓库
|
||||||
|
```
|
||||||
|
|
||||||
|
## 方法二:手动执行 PowerShell 命令
|
||||||
|
|
||||||
|
### 完整流程
|
||||||
|
```powershell
|
||||||
|
# 1. 查看当前状态
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" status
|
||||||
|
|
||||||
|
# 2. 添加所有修改的文件
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" add -A
|
||||||
|
|
||||||
|
# 3. 提交更改
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" commit -m "你的提交信息"
|
||||||
|
|
||||||
|
# 4. 拉取远程代码(避免冲突)
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" pull
|
||||||
|
|
||||||
|
# 5. 推送到远程仓库
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" push
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题及解决方案
|
||||||
|
|
||||||
|
### 1. 推送失败,提示需要拉取
|
||||||
|
**问题**: 提示远程有新提交
|
||||||
|
```powershell
|
||||||
|
# 解决方案:先拉取远程代码
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" pull
|
||||||
|
|
||||||
|
# 解决冲突后再推送
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 认证失败
|
||||||
|
**问题**: `Authentication failed for 'http://lmhrt.cn:6771/ming/Rader_IQ.git/'`
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
```powershell
|
||||||
|
# 方案1:配置凭据存储
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" config --global credential.helper store
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" push
|
||||||
|
|
||||||
|
# 方案2:在 URL 中包含认证信息
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" remote set-url origin http://用户名:密码@lmhrt.cn:6771/ming/Rader_IQ.git
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 忘记添加 .gitignore
|
||||||
|
**问题**: 不应该被跟踪的文件被提交了
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# 从暂存区移除已添加的文件
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" rm -r --cached .pio
|
||||||
|
|
||||||
|
# 提交更改
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" commit -m "Remove .pio from tracking"
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 修改最后一次提交信息
|
||||||
|
**问题**: 提交信息写错了,但还没有推送
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# 修改最后一次提交(未推送)
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" commit --amend -m "新的提交信息"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 查看文件历史
|
||||||
|
```powershell
|
||||||
|
# 查看指定文件的历史
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" log --follow 文件名
|
||||||
|
|
||||||
|
# 查看指定文件在某次提交的内容
|
||||||
|
& "C:\Program Files\Git\bin\git.exe" show 提交哈希:文件名
|
||||||
|
```
|
||||||
|
|
||||||
|
## 提交信息规范
|
||||||
|
|
||||||
|
### 格式建议
|
||||||
|
```
|
||||||
|
<类型>: <简短描述>
|
||||||
|
|
||||||
|
<详细描述(可选)>
|
||||||
|
|
||||||
|
<相关 issue(可选)>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 类型说明
|
||||||
|
- `feat`: 新功能
|
||||||
|
- `fix`: 修复 bug
|
||||||
|
- `docs`: 文档更新
|
||||||
|
- `style`: 代码格式调整
|
||||||
|
- `refactor`: 重构代码
|
||||||
|
- `test`: 测试相关
|
||||||
|
- `chore`: 构建/工具链相关
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
```
|
||||||
|
feat: 添加心率平滑处理算法
|
||||||
|
|
||||||
|
实现了基于移动平均的心率数据平滑处理,
|
||||||
|
提高了心率监测的稳定性。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 成功案例
|
||||||
|
|
||||||
|
### 本次成功提交
|
||||||
|
- **提交哈希**: `aa57e81`
|
||||||
|
- **提交信息**: `Update project`
|
||||||
|
- **修改文件**: 4 个文件
|
||||||
|
- **新增行数**: 134 行
|
||||||
|
- **删除行数**: 88 行
|
||||||
|
- **推送状态**: ✅ 成功
|
||||||
|
|
||||||
|
### 修改的文件
|
||||||
|
- `src/main.cpp` - 修改
|
||||||
|
- `src/radar_vitals.cpp` - 修改
|
||||||
|
- `src/radar_vitals.h` - 修改
|
||||||
|
- `git.bat` - 新增
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
1. **提交前检查**: 使用 `git status` 确认要提交的文件
|
||||||
|
2. **频繁提交**: 小步快跑,每个功能点完成后立即提交
|
||||||
|
3. **清晰的提交信息**: 使用规范的提交信息格式
|
||||||
|
4. **推送前拉取**: 使用 `git pull` 避免冲突
|
||||||
|
5. **定期同步**: 与团队成员保持代码同步
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- [Git 官方文档](https://git-scm.com/doc)
|
||||||
|
- [Rader_Success_5 项目](http://lmhrt.cn:6771/ming/Rader_Success_5.git)
|
||||||
370
IQ信号处理流程图.md
Normal file
370
IQ信号处理流程图.md
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
# 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
|
||||||
|
```
|
||||||
6
git.bat
6
git.bat
@@ -22,7 +22,11 @@ if "%commit_msg%"=="" set commit_msg=Update project
|
|||||||
%GIT_PATH% commit -m "%commit_msg%"
|
%GIT_PATH% commit -m "%commit_msg%"
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
echo [4/5] 推送到远程仓库...
|
echo [4/5] 拉取远程代码...
|
||||||
|
%GIT_PATH% pull
|
||||||
|
echo.
|
||||||
|
|
||||||
|
echo [5/5] 推送到远程仓库...
|
||||||
%GIT_PATH% push
|
%GIT_PATH% push
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
|
|||||||
55
src/main.cpp
55
src/main.cpp
@@ -9,6 +9,32 @@
|
|||||||
static float I_buf[BASE_DATA_LEN];
|
static float I_buf[BASE_DATA_LEN];
|
||||||
static float Q_buf[BASE_DATA_LEN];
|
static float Q_buf[BASE_DATA_LEN];
|
||||||
|
|
||||||
|
//雷达芯片串口数据打印
|
||||||
|
void uartDataTask(void *parameter) {
|
||||||
|
Serial.println("📡 串口数据读取任务启动");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
if(Serial1.available()) {
|
||||||
|
byte data = Serial1.read();
|
||||||
|
//Serial.printf("%02X ", data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t raw_i = adc1_get_raw(ADC1_CHANNEL_8);
|
||||||
|
uint16_t raw_q = adc1_get_raw(ADC1_CHANNEL_9);
|
||||||
|
float raw_i_voltage = (raw_i / 4095.0f) * 3.3f;
|
||||||
|
float raw_q_voltage = (raw_q / 4095.0f) * 3.3f;
|
||||||
|
|
||||||
|
raw_i = adc1_get_raw(ADC1_CHANNEL_0);
|
||||||
|
raw_q = adc1_get_raw(ADC1_CHANNEL_1);
|
||||||
|
float raw_i_voltage2 = (raw_i / 4095.0f) * 3.3f;
|
||||||
|
float raw_q_voltage2 = (raw_q / 4095.0f) * 3.3f;
|
||||||
|
|
||||||
|
Serial.printf("原:I=%.3f, Q=%.3f 放大:I=%.3f, Q=%.3f\n",raw_i_voltage, raw_q_voltage, raw_i_voltage2, raw_q_voltage2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void radarDataTask(void *parameter) {
|
void radarDataTask(void *parameter) {
|
||||||
Serial.println("📡 雷达数据采集任务启动");
|
Serial.println("📡 雷达数据采集任务启动");
|
||||||
|
|
||||||
@@ -17,8 +43,8 @@ void radarDataTask(void *parameter) {
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
for(int i = 0; i < BASE_DATA_LEN; i++) {
|
for(int i = 0; i < BASE_DATA_LEN; i++) {
|
||||||
sample.i_value = adc1_get_raw(ADC1_CHANNEL_0);
|
sample.i_value = adc1_get_raw(ADC1_CHANNEL_8);
|
||||||
sample.q_value = adc1_get_raw(ADC1_CHANNEL_1);
|
sample.q_value = adc1_get_raw(ADC1_CHANNEL_9);
|
||||||
sample.timestamp = millis();
|
sample.timestamp = millis();
|
||||||
|
|
||||||
I_buf[i] = (sample.i_value / 4095.0f) * 3.3f;
|
I_buf[i] = (sample.i_value / 4095.0f) * 3.3f;
|
||||||
@@ -39,10 +65,17 @@ void radarDataTask(void *parameter) {
|
|||||||
|
|
||||||
human_state_t state = radar_get_state();
|
human_state_t state = radar_get_state();
|
||||||
|
|
||||||
|
uint16_t raw_i = adc1_get_raw(ADC1_CHANNEL_0);
|
||||||
|
uint16_t raw_q = adc1_get_raw(ADC1_CHANNEL_1);
|
||||||
|
float raw_i_voltage = (raw_i / 4095.0f) * 3.3f;
|
||||||
|
float raw_q_voltage = (raw_q / 4095.0f) * 3.3f;
|
||||||
|
|
||||||
if (state == NO_PERSON) {
|
if (state == NO_PERSON) {
|
||||||
Serial.printf("👤 No person - IQ电压: I=%.3fV, Q=%.3fV\n", avgI, avgQ);
|
Serial.printf("0-原始电压: I=%.3fV, Q=%.3fV - 放大电压: I=%.3fV, Q=%.3fV\n",
|
||||||
|
raw_i_voltage, raw_q_voltage, avgI, avgQ);
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("👤 Human static - IQ电压: I=%.3fV, Q=%.3fV - 💓 心率: %.1f BPM, 呼吸: %.1f BPM\n", avgI, avgQ, radar_get_heart_bpm(), radar_get_resp_bpm());
|
Serial.printf("1-原:I=%.3f, Q=%.3f 放大:I=%.3f, Q=%.3f -心率: %.1f BPM, 呼吸: %.1f BPM\n",
|
||||||
|
raw_i_voltage, raw_q_voltage, avgI, avgQ, radar_get_heart_bpm(), radar_get_resp_bpm());
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
@@ -65,6 +98,9 @@ void setup() {
|
|||||||
// 初始化雷达
|
// 初始化雷达
|
||||||
radar_init();
|
radar_init();
|
||||||
|
|
||||||
|
// 初始化Serial1串口 (RX:IO20, TX:IO19, 波特率:115200)
|
||||||
|
Serial1.begin(115200, SERIAL_8N1, 20, 19);
|
||||||
|
|
||||||
// 创建雷达数据任务
|
// 创建雷达数据任务
|
||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
radarDataTask,
|
radarDataTask,
|
||||||
@@ -76,6 +112,17 @@ void setup() {
|
|||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 创建串口数据任务
|
||||||
|
xTaskCreatePinnedToCore(
|
||||||
|
uartDataTask,
|
||||||
|
"UART Data Task",
|
||||||
|
4096,
|
||||||
|
NULL,
|
||||||
|
3,
|
||||||
|
NULL,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
Serial.println("✅ FreeRTOS任务创建成功");
|
Serial.println("✅ FreeRTOS任务创建成功");
|
||||||
|
|
||||||
Serial.println("🎉 系统初始化完成,等待雷达数据...");
|
Serial.println("🎉 系统初始化完成,等待雷达数据...");
|
||||||
|
|||||||
Reference in New Issue
Block a user