触摸接近感应传感器
touch_proximity_sensor
组件基于 ESP32-S3 内置的触摸传感器进行开发,使用该组件可以轻松实现触摸接近感应功能。
备注
ESP32/ESP32-S2/ESP32-S3 触摸相关组件仅用于测试或演示目的。由于触摸功能的抗干扰能力差,可能无法通过 EMS 测试,因此不建议用于量产产品。
该组件目前仅适用于 ESP32-S3,并且需要 IDF 版本大于等于 v5.0。
实现原理
触摸接近感应传感器是以 ESP32-S3 的触摸传感器接近感应功能为基础实现的,其硬件原理结构图如下:

当目标物体靠近传感器时,其等效电容会发生变化。目标物体可以是人的手指、手或任何导电物体。 当触摸传感器被配置为接近感应模式时,传感器输出的值是累加值,当目标物体靠近传感器面板时,传感器输出的累计值会变大。 基于这一特点,本方案将触摸传感器输出的原始数据(累加值)定义为 raw_value ,并从中衍生出 baseline 和 smooth_value 两个数据变量,再结合合理的阈值检测算法,最终实现接近感应功能。
具体的软件实现有以下三个步骤:
判断新数据的有效性。
依据 smooth_value 和 baseline 的更新逻辑,以 raw_value 为源数据更新 smooth_value 和 baseline 。
判断 smooth_value - baseline 的值是否大于 0,若大于 0 则再判断是否大于 触发阈值 ,若大于则判定为有效的感应触发动作; 若 smooth_value - baseline 的值小于 0,先判断当前是否处于触发状态,若处于触发状态,则再判断其绝对值是否大于 解除触发阈值 ,若大于则判定为有效的触发解除动作。
测试硬件参考
开发板
可以使用的 ESP-S2S3-Touch-DevKit-1 开发套件进行验证测试,主板为
MainBoard v1.1
,接近感应子板为Proximity Board V1.0
。
配置参考
创建接近感应传感器
使用 touch_proximity_sensor
组件,可通过 touch_proxi_config_t
结构体来配置接近感应传感器。
typedef struct {
uint32_t channel_num; /*!< 触摸接近感应通道数量 */
uint32_t *channel_list; /*!< 触摸通道列表 */
float *channel_threshold; /*!< 每个通道的触发阈值 */
uint32_t debounce_times; /*!< 确认状态改变所需的连续读数次数 */
uint32_t *channel_gold_value; /*!< 触摸通道参考值 */
bool skip_lowlevel_init; /*!< 使用现有触摸驱动时跳过低级初始化 */
} touch_proxi_config_t;
主要参数说明:
参数 |
说明 |
---|---|
channel_num |
触摸接近感应通道数量,最多支持 3 个 |
channel_list |
触摸通道列表 |
channel_threshold |
每个通道的触发阈值数组 |
debounce_times |
确认状态改变所需的连续读数次数 |
channel_gold_value |
可选的触摸通道参考值 |
skip_lowlevel_init |
使用现有触摸驱动时跳过低级初始化 |
配置参数后,使用 touch_proximity_sensor_create()
创建接近感应传感器:
touch_proxi_config_t config = {
.channel_num = 1,
.channel_list = channel_list,
.channel_threshold = channel_threshold,
.debounce_times = 2,
};
esp_err_t ret = touch_proximity_sensor_create(&config, &sensor_handle, callback_func, NULL);
事件处理
接近感应传感器需要定期处理事件以更新状态和触发回调。这可以在任务中完成:
void proximity_task(void *arg)
{
while (1) {
touch_proximity_sensor_handle_events(sensor_handle);
vTaskDelay(pdMS_TO_TICKS(20));
}
}
// 创建任务
xTaskCreate(proximity_task, "proximity_task", 2048, NULL, 5, NULL);
删除接近感应传感器
使用 touch_proximity_sensor_delete()
删除接近感应传感器对象,并释放资源:
// Delete the touch proximity sensor
touch_proximity_sensor_delete(sensor_handle);
参数调节参考
channel_num 最大为 3。
channel_list 数组必须赋值为 touch_pad_t 枚举变量中的值。
meas_count 默认值为 20,数值越大,触摸传感器新数据的更新速率越慢。
smooth_coef 默认值为 0.7,是数据平滑处理系数,平滑后的 smooth 值等于 smooth * (1.0 - smooth_coef) + raw * smooth_coef, smooth_coef 数值越大, raw 的权重就越大,平滑效果越差, smooth 波形越抖, smooth 跟随 raw 值速度越快,触发响应越快,抗干扰能力越弱; smooth_coef 数值越小, raw 的权重就越小,平滑效果越好, smooth 波形越平滑, smooth 跟随 raw 值速度越慢,触发响应越慢,抗干扰能力越强。
baseline_coef 默认值为 0.05,是基线更新系数,基线新值等于 baseline * (1.0 - baseline_coef) + smooth * baseline_coef,该值越大,基线跟随 smooth 速度越快,触发响应越慢,抗干扰能力越强。
max_p 默认值为 0.5,当 raw - baseline 的值大于 baseline * max_p 时, raw 值为异常值,忽略掉。
min_n 默认值为 0.05,当 baseline - raw 的值大于 baseline * min_n 时, raw 值为异常值,忽略掉。
threshold_p 值越大,接近感应触发的距离越近,抗干扰能力越强,反之相反。
threshold_n 值越大,接近感应触发的距离越近,抗干扰能力越强,反之相反。
noise_p 默认值为 0.1,和 noise_n 默认值为 0.2,的值越大,基线更容易跟随 smooth,接近感应距离会相应变小,抗干扰能力越好。
debounce_p 和 debounce_n 的值需要参考 meas_count 的值进行调整, meas_count 越小, debounce_p 和 debounce_n 应相应增大,以提高抗干扰能力。
reset_p 默认值为 0,用于基线重置正向去抖动,设置为 0 表示禁用。
reset_n 默认值为 50,用于基线重置负向去抖动。
调参波形对比
默认的触摸接近感应传感器配置参数如下:
参数 |
默认值 |
---|---|
channel_num |
1 |
channel_list |
TOUCH_PAD_NUM8 |
meas_count |
20 |
smooth_coef |
0.7 |
baseline_coef |
0.05 |
max_p |
0.5 |
min_n |
0.05 |
noise_p |
0.1 |
noise_n |
0.2 |
debounce_p |
2 |
debounce_n |
50 |
reset_p |
0 |
reset_n |
50 |
以下调参对比都将在以上参数基础上 仅修改一个参数 进行对比。
修改 meas_count 的值,将改变传感器数据更新速率,其值越大,传感器数据更新速率越慢。 测试现象:将手放在感应面板上方 10cm 处保持 3 秒时间,较小的 meas_count 数值,感应时的波形宽度将更宽,波形对比图如下:
修改 smooth_coef 的值,将改变 smooth 波形的平滑效果。 smooth_coef 值越小,平滑效果越好,抗干扰能力越强, smooth 跟随 raw 越慢,触发响应越慢,反之相反。 不同 smooth_coef 下的波形对比图如下:
修改 baseline_coef 的值,将改变 baseline 的更新效果。 baseline_coef 值越小, baseline 跟随 smooth 越慢,触发响应越慢,触发的持续时间越长,反之相反。 不同 baseline_coef 下的波形对比图如下:
修改 threshold_p 的值,将改变接近感应的距离,其值越小,能够感应的距离越远,但抗干扰能力越差,易引发误触发。 不同 threshold_p 下的波形对比图如下:
修改 hysteresis_p 的值,将改变触发和解除触发的时间点,即触发迟滞和解除触发迟滞。 hysteresis_p 的值越小,触发响应越快,反之相反。 不同 threshold_p 下的波形对比图如下:
修改 noise_p 和 noise_n 的值,将改变 baseline 的更新效果。 noise_p 的值越小, baseline 跟随 smooth 越慢,触发响应越慢,触发的持续时间越长,反之相反。 不同 noise_p 和 noise_n 下的波形对比图如下:
修改 debounce_p 和 debounce_n 的值,将改变触发和解除触发的时间点和抗干扰能力。 debounce_p 的值越大,触发响应越慢,抗干扰能力越强,反之相反; debounce_n 的值越大,解除触发响应越慢,抗干扰能力越强,反之相反。 debounce_p 和 debounce_n 的值需要结合 meas_count 来调节, meas_count 的值减小, debounce_p 和 debounce_n 的值应适当增大。 不同 noise_p 和 noise_n 下的波形对比图如下:
备注
要达到理想的接近感应效果,仅对一两个参数进行简单调节是不够的,需要综合调整多个参数。
示例程序
API Reference
Header File
Functions
-
esp_err_t touch_proximity_sensor_create(touch_proxi_config_t *config, touch_proximity_handle_t *sensor_handle, proxi_cb_t cb, void *cb_arg)
Create a touch proximity sensor instance.
- 参数
config – The touch pad channel configuration.
sensor_handle – The handle of the successfully created touch proximity sensor.
cb – Callback function to handle proximity events.
cb_arg – The callback function argument.
- 返回
ESP_OK: Create the touch proximity sensor successfully.
ESP_ERR_NO_MEM: Failed to create the touch proximity sensor (memory allocation failed).
-
esp_err_t touch_proximity_sensor_delete(touch_proximity_handle_t proxi_sensor)
Delete the touch proximity sensor instance.
This function deletes the touch proximity sensor instance associated with the provided sensor handle.
- 参数
proxi_sensor – Pointer to the handle of the touch proximity sensor instance to be deleted.
- 返回
ESP_OK: Delete the touch proximity sensor instance successfully
-
esp_err_t touch_proximity_sensor_get_data(touch_proximity_handle_t handle, uint32_t channel, uint32_t *data)
Get touch proximity sensor data.
Retrieves the smoothed touch sensor reading from the specified channel.
- 参数
handle – [in] Touch proximity sensor handle
channel – [in] Touch channel number
data – [out] Pointer to store the smoothed touch sensor data
- 返回
ESP_OK on success
ESP_ERR_INVALID_ARG if handle or data is NULL
ESP_ERR_INVALID_STATE if sensor not initialized
ESP_ERR_NOT_FOUND if channel not found
-
esp_err_t touch_proximity_sensor_get_state(touch_proximity_handle_t handle, uint32_t channel, proxi_state_t *state)
Get current state of a proximity channel.
Returns whether the proximity channel is currently considered active (object detected) based on the current sensor readings and configured thresholds.
- 参数
handle – [in] Touch proximity sensor handle
channel – [in] Touch channel number
state – [out] Pointer to store the channel state
- 返回
ESP_OK on success
ESP_ERR_INVALID_ARG if handle or state is NULL
ESP_ERR_INVALID_STATE if sensor not initialized
ESP_ERR_NOT_FOUND if channel not found
-
esp_err_t touch_proximity_sensor_handle_events(touch_proximity_handle_t handle)
Handle pending proximity sensor events.
Processes events from the FSM. This function should be called periodically to update proximity states and trigger callbacks.
- 参数
handle – [in] Touch proximity sensor handle
- 返回
ESP_OK on success
ESP_ERR_INVALID_ARG if handle is NULL
ESP_ERR_INVALID_STATE if sensor not initialized
Structures
-
struct touch_proxi_config_t
Configuration structure for touch proximity sensor.
Public Members
-
uint32_t channel_num
Number of touch proximity sensor channels
-
uint32_t *channel_list
Touch channel list
-
float *channel_threshold
Threshold for touch detection for each channel
-
uint32_t debounce_times
Number of consecutive readings needed to confirm state change
-
uint32_t *channel_gold_value
Reference values for touch channels
-
bool skip_lowlevel_init
Skip low level initialization when working with existing touch driver
-
uint32_t channel_num
Type Definitions
-
typedef struct touch_proximity_sensor_t *touch_proximity_handle_t
-
typedef void (*proxi_cb_t)(uint32_t channel, proxi_state_t event, void *cb_arg)
proximity sensor user callback type