espressif/touch_sensor_fsm

0.9.1~1

Latest
uploaded 14 hours ago
Touch sensor enhanced FSM for better anti-interference performance.

Readme

# Touch Sensor FSM

## Version 0.9.1~1 SDK integration

Version 0.9.1~1 adds an ESP-IDF 6.2 development snapshot to its
SDK/target matrix, including ESP32-S31. Published version 0.9.1 contains only
IDF 5.5, 6.0 and 6.1 libraries and cannot be used with IDF 6.2.
The validated 6.2 development snapshot is ESP-IDF commit
`383dda6c182e3dabf6355160166fe007df775629`; this does not establish
compatibility with every 6.2 development commit.
Use a library built for your SDK minor version and target; renaming an older
library directory does not establish compatibility. Future SDK minor versions
remain unsupported until matching libraries are supplied.

`touch_sensor_fsm` provides configurable touch-state detection for one to
three sample configurations per channel. It accepts samples from polling or
user-push applications and reports debounced active/inactive state changes.

The current package requires ESP-IDF 5.5, 6.0, 6.1, or the pinned 6.2 snapshot and
`touch_sensor_lowlevel` 1.0.1 or later. ESP-IDF 5.5 and 6.0 cover ESP32-S2, ESP32-S3,
ESP32-P4, and Linux; ESP-IDF 6.1 and the pinned 6.2 snapshot also cover ESP32-H4 and ESP32-S31 when those
targets are available in the SDK.

Registry version 0.9.1~1 contains precompiled libraries for the supported ESP-IDF
version and target combinations. Select the matching ESP-IDF version and target;
a missing library causes configuration to fail.
Each library is accompanied by its build provenance and full effective
sdkconfig. Keep these files with the library when integrating or reporting an issue.

## Features

- Single- and multi-frequency touch detection.
- Startup initialization from measured samples or optional preset values.
- Configurable active/inactive thresholds and debounce.
- Polling callbacks and user-push input, including ISR-safe sample submission.
- Runtime state, sample, threshold, and signal-quality information.
- Deep copies of channel, active/inactive threshold, and optional initialization arrays.

## Add the Component

```bash
idf.py add-dependency "espressif/touch_sensor_fsm^0.9.1~1"
```

The component declares its compatible `touch_sensor_lowlevel` 1.x dependency.

## Polling Mode

Discover the effective sample count and scan period from lowlevel before
resolving the FSM defaults. Start lowlevel successfully before starting the FSM.

```c
#include "esp_check.h"
#include "touch_sensor_fsm.h"
#include "touch_sensor_lowlevel.h"

static void polling_cb(fsm_handle_t handle, uint32_t channel,
                       uint32_t *raw_data, void *user_data)
{
    (void)handle;
    (void)user_data;
    ESP_ERROR_CHECK(touch_sensor_lowlevel_get_data(channel, raw_data));
}

void app_main(void)
{
    uint32_t channels[] = {10};
    uint32_t thresholds_active[] = {70};
    uint32_t thresholds_inactive[] = {0}; /* 0 selects active / 2. */
    touch_lowlevel_config_t lowlevel_config = {
        .channel_num = 1,
        .channel_list = channels,
        .channel_type = NULL,
        .sample_period_ms = 20,
        .sample_cfg_num = 0,
    };

    ESP_ERROR_CHECK(touch_sensor_lowlevel_create(&lowlevel_config));
    ESP_ERROR_CHECK(touch_sensor_lowlevel_start());

    touch_lowlevel_info_t lowlevel_info = {0};
    ESP_ERROR_CHECK(touch_sensor_lowlevel_get_info(&lowlevel_info));

    fsm_config_t fsm_config;
    ESP_ERROR_CHECK(touch_sensor_fsm_get_default_config(
        lowlevel_info.sample_cfg_num, lowlevel_info.sample_period_ms,
        &fsm_config));
    fsm_config.channel_num = lowlevel_info.channel_num;
    fsm_config.channel_list = (uint32_t *)lowlevel_info.channel_list;
    fsm_config.freq_num = lowlevel_info.sample_cfg_num;
    fsm_config.threshold_active = thresholds_active;
    fsm_config.threshold_inactive = thresholds_inactive;
    fsm_config.sample_period_ms = lowlevel_info.sample_period_ms;
    fsm_config.polling_cb = polling_cb;

    fsm_handle_t fsm = NULL;
    ESP_ERROR_CHECK(touch_sensor_fsm_create(&fsm_config, &fsm));
    ESP_ERROR_CHECK(touch_sensor_fsm_control(fsm, FSM_CTRL_START, NULL));

    while (true) {
        ESP_ERROR_CHECK(touch_sensor_fsm_handle_events(fsm));
        vTaskDelay(pdMS_TO_TICKS(20));
    }
}
```

Keep the first configured electrode untouched and the board stable while
lowlevel starts and FSM initialization collects its initial samples. A
lowlevel startup error is returned by `touch_sensor_lowlevel_start()`; do not
start the FSM until that call succeeds. The FSM also needs valid no-touch
samples before normal interaction.

## User-Push Mode

Use user-push mode when samples arrive from an application callback or ISR:

```c
fsm_config_t config = DEFAULTS_TOUCH_SENSOR_FSM_CONFIG();
config.mode = FSM_MODE_USER_PUSH;
config.channel_num = 1;
config.channel_list = (uint32_t[]){10};
config.freq_num = 3;
config.threshold_active = (uint32_t[]){70};
config.threshold_inactive = NULL; /* defaults to active / 2 */

fsm_handle_t fsm = NULL;
ESP_ERROR_CHECK(touch_sensor_fsm_create(&config, &fsm));
ESP_ERROR_CHECK(touch_sensor_fsm_control(fsm, FSM_CTRL_START, NULL));

uint32_t samples[] = {12300, 11800, 11500};
ESP_ERROR_CHECK(touch_sensor_fsm_update_data(fsm, 10, samples, 3, false));
ESP_ERROR_CHECK(touch_sensor_fsm_handle_events(fsm));
```

Pass `true` as the final argument of `touch_sensor_fsm_update_data()` only from
ISR context. Continue calling `touch_sensor_fsm_handle_events()` from a task.
Each update must contain exactly `freq_num` values for the configured channel.

## Configuration

Start with `DEFAULTS_TOUCH_SENSOR_FSM_CONFIG()` or
`touch_sensor_fsm_get_default_config()` and override only the values required
by the application.

- `channel_num`, `channel_list`, and `threshold_active` are required. Every
  active threshold must be nonzero and below `UINT32_MAX`.
- `freq_num` must be in the range `1..FSM_MAX_FREQ`.
- Polling mode requires `polling_cb`.
- `threshold_active` and `threshold_inactive` use the amplitude-count units
  returned by `touch_sensor_fsm_get_data()`. The inactive array is optional;
  NULL or a zero entry selects `threshold_active / 2`.
- The smoothing coefficient uses integer permille values in the range
  `0..1000`. Fields documented as automatic use their mode-specific default
  when set to zero.
- `sample_period_ms` defaults to 20 ms. It is the polling rate limit in
  polling mode and the time base for startup windows. Set it to zero when the
  period is unknown.
- `debounce_active` and `debounce_inactive` control the number of consecutive
  samples required for a state change. Both default to one frame; zero also
  selects that one-frame default.
- `freq_sensitivity` is optional per-channel/per-frequency sensitivity data in
  the layout documented by `fsm_config_t`. Values are 100..1000; `NULL` uses
  the default equal sensitivity.
- Configuration arrays are copied during creation and may be released after
  `touch_sensor_fsm_create()` returns.

`touch_sensor_fsm_get_default_config(freq_num, sample_period_ms, &config)`
returns the scalar defaults for a topology. Set the channel and active
threshold arrays before passing that structure to `touch_sensor_fsm_create()`.

## Runtime Information

Call `touch_sensor_fsm_get_state()` for the current public state and
`touch_sensor_fsm_get_data()` for the signed touch amplitude in
normalized counts. Negative values are preserved by this FSM API; wrapper
components may clamp them when exposing a non-negative business amplitude.
The conversion saturates to the `int32_t` range at the API boundary.
Both functions remain available with diagnostics disabled.

Internal snapshots and effective-configuration queries are not public APIs.
The 0.9.1~1 registry library rejects `CONFIG_TOUCH_SENSOR_FSM_DEBUG=y` and does
not ship the private header or diagnostic symbols.

The state callback receives `FSM_STATE_ACTIVE` or `FSM_STATE_INACTIVE` after
debounce. Its data argument is the current non-negative touch amplitude.

## Migration from versions before 0.9.0

Diagnostic types, queries and CSV macros have moved out of the public header.
Callers using `get_info()` only for amplitude must migrate to `get_data()`.
Use the public state/data queries in registry-library applications. Recompile
callers when migrating from the earlier structures.

The removed `baseline_coef`, `baseline_recover_coef`, `long_press_samples`,
`baseline_hold`, `baseline_locked`, `press_timer`, `baseline_recovering`,
`long_press_absorb_count`, and outlier diagnostic fields have no replacement.
Delete reads and configuration assignments for those fields. Keep limiter
overrides at their default values unless required by an existing configuration.

The old `threshold` plus `hysteresis` pair is not a field rename. For example,
old `threshold = 70, hysteresis = 10` compared at active 80 and inactive 60.
The new `threshold_active = 70` with a NULL inactive array compares at active
70 and inactive 35. To preserve the old comparison boundaries, configure
`threshold_active = 80` and `threshold_inactive = 60` explicitly.

The noise-window and noise-margin settings are no longer configurable. Remove
assignments to those former fields.

## Lifecycle

```text
create -> start -> handle/update -> stop -> delete
```

Stop the FSM with `FSM_CTRL_STOP` before calling
`touch_sensor_fsm_delete()`. Stop and delete the lowlevel driver separately
after the FSM no longer uses it. If creation or startup fails, delete any
successfully created instance before retrying.

## Linux Integration

The Linux library supports the user-push API for host integration tests. Supply
complete input frames and an explicit sample period. Hardware validation must
use the intended physical target.

Links

To add this component to your project, run:

idf.py add-dependency "espressif/touch_sensor_fsm^0.9.1~1"

download archive

Stats

  • Archive size
    Archive size ~ 1.71 MB
  • Downloaded in total
    Downloaded in total 1.3k times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 0 times

Badge

espressif/touch_sensor_fsm version: 0.9.1~1
|