Skip to content

Touch

Capacitive Touch Driver.

Note: the touch driver internally indexes only by GPIO pin id, thus limitign the use of multiple GPIOs with the same pin id on different ports. e.g. PA5 and PC5 cannot be used by the driver simultaneously as they will internally interfere with each other!

Sysprops

The capacitive touch driver does not have any sysprops defined.

Example

Here's a full usage example with a FIR averaging to determine the baseline of the keys.

cpp
#define FIR_HISTORY (8)

typedef struct touch_state_s {
    int gpio;
    int active;
} touch_state_t;

typedef struct touchkey_s {
    int gpio;
    int active;
    int value;
    int hi_value;
    int upper_thresh;
    int fir_reading[FIR_HISTORY];
    int fir_index;
} touchkey_t;

uint16_t touchkey_fir_average (touchkey_t *key);

static int g_touch_num_keys;
static touchkey_t *g_touch_keys;
static int g_touch_dev;

void touchkeys_init (int dev, uint16_t key_gpios[], int num_keys)
{
  g_touch_dev = dev;
  g_touch_num_keys = num_keys;

  g_touch_keys = (touchkey_t *) malloc (num_keys * sizeof (touchkey_t));

  memset (g_touch_keys, 0, num_keys * sizeof (touchkey_t));

 for (int i = 0; i < num_keys; i++)
    {
      g_touch_keys[i].gpio = key_gpios[i];
      g_touch_keys[i].upper_thresh = 50;
    }
}

void touchkey_process (touch_state_t *states, int *changes)
{
  static int calibration_skip = 25;
  static volatile bool calibration_running = true;
  touchkey_t *key;

  // 1st samples aren't representative
  if (calibration_skip > 0)
    {
      for (int j = 0; j < g_touch_num_keys; j++)
        {
          key = &g_touch_keys[j];
          key->value = touch_sample_gpio (g_touch_dev, key->gpio);
          changes[j] = 0;
        }

     calibration_skip--;
     return;
    }

  bool all_calibrated = true;

  for (int j = 0; j < g_touch_num_keys; j++)
    {
      key = &g_touch_keys[j];
      key->value = touch_sample_gpio (g_touch_dev, key->gpio);

      if (calibration_running && (key->value > 20))
        {
          all_calibrated = false;
        }

      changes[j] = 0;
    }

  if (!all_calibrated)
    {
      return;
    }
  else
    {
      calibration_running = false;
    }

  for (int j = 0; j < g_touch_num_keys; j++)
    {
      key = &g_touch_keys[j];
      key->value = touchkey_fir_average (key);

      if (key->value <= (key->hi_value * 0.8F))
        {
          if (key->value < key->upper_thresh)
            {
              key->hi_value = 0;
           }
          if (key->active)
            {
              key->active = false;
              changes[j] = 1;
              touch_reset_gpio (g_touch_dev, key->gpio % 100);
            }
        }
      else if (key->value >= key->upper_thresh)
        {
          if (key->value > key->hi_value)
            {
              key->hi_value = key->value;
            }
          if (!key->active)
            {
              key->active = true;
              changes[j] = 1;
            }
        }
      states[j] = *(touch_state_t *) &g_touch_keys[j];
    }
}

uint16_t
touchkey_fir_average (touchkey_t *key)
{

  uint16_t average = 0;
  // Replace oldest reading
  key->fir_reading[key->fir_index] = key->value;// Sum all reading values

  for (uint8_t i = 0; i < FIR_HISTORY; i++)
    {
      average += key->fir_reading[i];
    }
  // Divide by the history window size
  // NOTE: This operation is efficient
  // as long as HISTORY is a power of 2.
  average = (uint16_t) (average / FIR_HISTORY);

  // Update index for next function call
  key->fir_index++;
  if (key->fir_index >= FIR_HISTORY)
   {
      key->fir_index = 0;
    }

  return average;
}

Functions Overview

Name
CW_DRIVER_FUNCtouch_sample_gpio(int hDev, int gpio_nr)
Function name: touch_sample_gpio.
CW_DRIVER_FUNCtouch_reset_gpio(int hDev, int gpio_nr)
Resets the GPIO pin for touch functionality.

Function Details

function touch_sample_gpio

cpp
CW_DRIVER_FUNC touch_sample_gpio(
    int hDev,
    int gpio_nr
)

Function name: touch_sample_gpio.

Parameters:

  • hDev The handle to the device.
  • gpio_nr The number of the GPIO pin to sample.

Return: An integer indicating the result of the function call.

Description: This function samples the specified GPIO pin for a touch event on the given device handle. it returns a positive integer value, indicating who strong the detected capacitive touch at the GPIO is. You need to do some baselining yourself to detect an actual touch.

function touch_reset_gpio

cpp
CW_DRIVER_FUNC touch_reset_gpio(
    int hDev,
    int gpio_nr
)

Resets the GPIO pin for touch functionality.

Parameters:

  • hDev The handle of the device.
  • gpio_nr The GPIO number to be reset.

Return: An integer value indicating the success or failure of the operation.

This function resets the touch drivers internal filtering.