diff --git a/Git提交方法.md b/Git提交方法.md
new file mode 100644
index 0000000..3071c2b
--- /dev/null
+++ b/Git提交方法.md
@@ -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)
diff --git a/IQ信号处理流程图.md b/IQ信号处理流程图.md
new file mode 100644
index 0000000..dacaf7e
--- /dev/null
+++ b/IQ信号处理流程图.md
@@ -0,0 +1,370 @@
+# 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
+```
diff --git a/git.bat b/git.bat
index 4db359b..f12303f 100644
--- a/git.bat
+++ b/git.bat
@@ -22,7 +22,11 @@ if "%commit_msg%"=="" set commit_msg=Update project
%GIT_PATH% commit -m "%commit_msg%"
echo.
-echo [4/5] 推送到远程仓库...
+echo [4/5] 拉取远程代码...
+%GIT_PATH% pull
+echo.
+
+echo [5/5] 推送到远程仓库...
%GIT_PATH% push
echo.
diff --git a/src/main.cpp b/src/main.cpp
index 42560f4..22043da 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -9,6 +9,32 @@
static float I_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) {
Serial.println("📡 雷达数据采集任务启动");
@@ -17,8 +43,8 @@ void radarDataTask(void *parameter) {
while(1) {
for(int i = 0; i < BASE_DATA_LEN; i++) {
- sample.i_value = adc1_get_raw(ADC1_CHANNEL_0);
- sample.q_value = adc1_get_raw(ADC1_CHANNEL_1);
+ sample.i_value = adc1_get_raw(ADC1_CHANNEL_8);
+ sample.q_value = adc1_get_raw(ADC1_CHANNEL_9);
sample.timestamp = millis();
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();
+ 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) {
- 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 {
- 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();
@@ -65,6 +98,9 @@ void setup() {
// 初始化雷达
radar_init();
+ // 初始化Serial1串口 (RX:IO20, TX:IO19, 波特率:115200)
+ Serial1.begin(115200, SERIAL_8N1, 20, 19);
+
// 创建雷达数据任务
xTaskCreatePinnedToCore(
radarDataTask,
@@ -76,6 +112,17 @@ void setup() {
1
);
+ // 创建串口数据任务
+ xTaskCreatePinnedToCore(
+ uartDataTask,
+ "UART Data Task",
+ 4096,
+ NULL,
+ 3,
+ NULL,
+ 1
+ );
+
Serial.println("✅ FreeRTOS任务创建成功");
Serial.println("🎉 系统初始化完成,等待雷达数据...");