# Easydetek Radar 模组通信API 操作指南
`ed_radar` 组件提供了一个针对多款易探雷达(如 `EDQ152`、`EDV163`、`EDV11P` 等)的**面向对象抽象接口层**。通过该层,应用开发者(Apps)无需关注具体型号的数据组包、解包细节及局部结构体差异,可以通过统一的结构完成控制,并且系统提供严格的模型不兼容拦截。
---
## 0. 作为 ESP Component Registry 组件使用
本组件为标准 ESP-IDF 组件(支持 IDF v5.0+),无任何私有依赖,可直接通过组件管理器引用。
### 0.1 在工程中引用
发布到 registry 后,在工程根目录执行:
```bash
idf.py add-dependency "fuhua817/ed_radar^1.0.0"
```
或者在工程的 `main/idf_component.yml` 中手动添加(支持直接从 Git 拉取):
```yaml
dependencies:
ed_radar:
git: https://github.com/fuhua817/ed_radar.git
version: "*"
```
### 0.2 配置组件
```bash
idf.py menuconfig
# -> Component config -> ED Radar Configuration
```
在此选择雷达型号(EDQ152 / EDV163 / EDV163_ASCII / EDV11P)、UART 端口号、TX/RX/EN 引脚、波特率及协议距离单位。
### 0.3 上传组件到 ESP Component Registry
1. 在 [components.espressif.com](https://components.espressif.com) 注册账号(命名空间即账号名,本项目为 `fuhua817`);
2. 配置 API Token(token 在网站账号设置中生成,写入本地配置,不会进入仓库):
```bash
compote config set --api-token <你的token> --default-namespace fuhua817
```
3. 在 ESP-IDF 终端中执行:
```bash
compote component upload --namespace fuhua817 --name ed_radar
```
上传前请确认 `idf_component.yml` 中的 `version`、`url` 已填写正确,每次发布新版本需递增 `version`。
---
## 1. 架构与设计思想
组件采用了**多态(Polymorphism)**与**外观模式(Facade)**:
- **`ed_radar_obj_t`(基类句柄)**:暴露给应用层的抽象句柄,对内通过 `void *ctx` 挂载各型号真实的设备上下文。
- **向下强转拦截**:在每个通用接口内,会按创建实例时指定的设备型号(`obj->config.type`)进行 `switch` 分发。如果当前物理型号支持该功能(比如 XYZ 范围配置),则转化为底层结构并下发;如果不兼容该动作(比如让 EDQ152 设置 XYZ 安装高度),则向控制台抛出预警并拦截(返回 `ED_FAIL`),防止内存或逻辑错误。
---
## 2. 基础使用流程
### 2.1 引入头文件
应用层仅需引入顶层头文件,无需直接涉及底层协议头文件(除非需要穿透配置):
```c
#include "ed_radar.h"
```
### 2.2 创建雷达实例
通过 `ed_radar_config_t` 配置结构体创建雷达句柄(可传入 `NULL` 或 `&ED_RADAR_CONFIG_DEFAULT` 使用 Kconfig 默认配置),底层会自动分配所需的内存与解析结构。
```c
// 示例 1:使用 Kconfig 默认配置(型号在 menuconfig 中选择)
ed_radar_obj_t *my_radar = ed_radar_creat(&ED_RADAR_CONFIG_DEFAULT);
// 示例 2:自定义配置,创建一个 EDV11P 实例
ed_radar_config_t cfg = {
.type = ED_RADAR_DEVICE_EDV11P,
.uart_num = 1,
.pin_tx = 5,
.pin_rx = 4,
.pin_en = 7,
.baudrate = 921600,
.buffer_size = 1024,
};
ed_radar_obj_t *my_radar = ed_radar_creat(&cfg);
if (my_radar == NULL) {
// 实例化失败处理
}
```
### 2.3 数据泵接管(数据收发任务)
在独立的数据接收 Task 中循环调用解析核心即可。底层驱动内部会自动通过 `ed_radar_receive_data()` 从 UART 取数、组帧并分发给具体型号的解析器,应用层**不要**自己先读串口数据(否则会把数据抢走,导致解析器收不到完整帧):
```c
while (1) {
// 内部自动取数并分发给具体型号的解析器
ed_radar_data_handle(my_radar);
vTaskDelay(pdMS_TO_TICKS(10));
}
```
---
## 3. 标准通用 API 概览
所有雷达尽量统一对齐这些方法,传入统一的基于空间(毫米 mm)的物理参数即可。
### 获取设备信息
```c
ed_err_t ed_radar_get_module_info(ed_radar_obj_t *obj);
```
### 系统级控制
```c
ed_err_t ed_radar_factory_reset(ed_radar_obj_t *obj);
ed_err_t ed_radar_set_work_mode(ed_radar_obj_t *obj, uint8_t mode);
ed_err_t ed_radar_set_radar_onoff(ed_radar_obj_t *obj, uint8_t onoff);
```
### 核心空间与边界控制
这些接口通常服务于 2D/3D 空间雷达(如 EDV163/EDV11P):
```c
// 设置雷达实际安装高度
ed_err_t ed_radar_set_install_height(ed_radar_obj_t *obj, uint16_t mm);
// 限制雷达检测高度范围
ed_err_t ed_radar_set_detect_height(ed_radar_obj_t *obj, uint16_t min_mm, uint16_t max_mm);
// 设置空间 XYZ 轴探测边界(统一采用 ed_radar_detect_range_t)
ed_err_t ed_radar_set_detect_range(ed_radar_obj_t *obj, ed_radar_detect_range_t *range);
// 设置屏蔽区 / 感应区
ed_err_t ed_radar_set_shield_areas(ed_radar_obj_t *obj, uint8_t count, ed_radar_area_t *areas);
ed_err_t ed_radar_set_induct_areas(ed_radar_obj_t *obj, uint8_t count, ed_radar_area_t *areas);
```
### 延迟与灵敏度
```c
// 设置无人目标丢失的判定延迟时间
ed_err_t ed_radar_set_detect_delay_time(ed_radar_obj_t *obj, uint16_t delay_seconds);
// 设置动作与存在的整体探测灵敏度(内部会自动展开给多通道雷达的全通道)
ed_err_t ed_radar_set_sensitivity(ed_radar_obj_t *obj, uint8_t motion, uint8_t presence);
```
---
## 4. 特殊定制 API (静默拦截过滤)
部分雷达拥有独特的功能(如 EDQ152 的环境学习模式),在此层面您可以随时调用。若当前实例不支持,日志将打印 `not supported` 警告并返回 `ED_FAIL`。
### EDQ152 环境自学习系列
```c
ed_err_t ed_radar_enter_self_learning(ed_radar_obj_t *obj, uint16_t duration_seconds);
ed_err_t ed_radar_exit_self_learning(ed_radar_obj_t *obj, uint8_t save);
ed_err_t ed_radar_restore_self_learning(ed_radar_obj_t *obj);
ed_err_t ed_radar_get_self_learning_status(ed_radar_obj_t *obj, uint16_t *remaining_seconds);
```
### 特殊强制控制
```c
// EDQ152 等强制定帧输出无人
ed_err_t ed_radar_force_no_person(ed_radar_obj_t *obj);
// EDV11P 的存在检测单独开关
ed_err_t ed_radar_set_presence_switch(ed_radar_obj_t *obj, uint8_t enable);
```
---
## 5. 进阶开发:专属向下穿透策略 (Down-casting)
由于抽象必须妥协,例如 `ed_radar_set_detect_range` 要求通用 XYZ 参数,但如果要对**多扇区雷达 (EDQ152) 进行单通道独立细粒度的配置**,抽象层无法同时覆盖。
`ed_radar_obj_t` 对应用层是**不透明句柄**(内部成员不可直接访问),此时可以通过 `ed_radar_get_ctx()` 安全地取出 `ctx` 指针并调用驱动专属头文件:
```c
#include "ed_radar.h"
#include "radar/edq152.h" // 引用专属驱动头
// type 为创建实例时使用的设备型号(即 ed_radar_config_t.type)
void custom_edq152_setup(ed_radar_obj_t *obj, uint32_t type)
{
// 判断实体是否为 EDQ152
if (type == ED_RADAR_DEVICE_EDQ152) {
edq152_channel_range_t ch_range = {0};
// 独家定制:针对通道1进行 0m 到 3m 的设置
ch_range.channel = 1;
ch_range.min_motion_dist = 0;
ch_range.max_motion_dist = 3000;
// 通过 ed_radar_get_ctx() 取出真实句柄并安全强转为 edq152_t
edq152_set_detect_distance((edq152_t*)ed_radar_get_ctx(obj), ch_range);
}
}
```
通过上述手段:我们兼顾了 **核心层 95% 代码的高度复用统一** ,并保留了 **应用层 5% 对实体特殊性能的安全穿透性**。
idf.py add-dependency "fuhua817/ed_radar^1.0.1"