Capacitive Sensor library

nRF5 SDK v15.3.0

The Capacitive Sensor library provides support for capacitive sensing using buttons, sliders, and wheels. The library has only one instance but supports unlimited number of sensors.

Main features:

Implementation details The library uses simple algorithms to process the samples that are read from the sensor pads using Capacitive Sensor low-level library . The module acquires values from every enabled channel and then decides what to do, based on the algorithm. The following diagram shows the behavior of this library:

csense_getting_values.svg
Diagram 1. Algorithm for getting values.

When the module senses that a slider or wheel was dragged, a new step must be calculated. Based on the algorithms, the module decides which of the pads were touched because one analog channel may be connected to two different pads. Then, it calculates the average from normalized values that were read on these pads and scales it to the abstract steps value that is provided by the user when creating the instance:

Page-1 Start/End-point Value on one of the pads is above threshold and at least on o... Value on one of the pads is above threshold and at least on one change exceeded NRF_CSENSE_HYSTERESIS. Process.245 Find a mask of the pads that might have been touched, i.e. ar... Find a mask of the pads that might have been touched, i.e. are connected to one analog input and the highest value was read on this input. Update the minimum or maximum value on every channel. Calculate ratio for each channel and normalize raw values to NRF_CSENSE_MAX_VALUE. Decision.254 Is there only one pad connected to the channel with the highe... Is there only one pad connected to the channel with the highest read value? Process.230 Calculate the step by taking the average of values from the t... Calculate the step by taking the average of values from the touched pad and the two pads that are placed next to it. Start/End-point.231 Return the calculated pad in the event handler. Return the calculated pad in the event handler. Process.232 Find the touched pad, based on the values of the pads placed ... Find the touched pad, based on the values of the pads placed next to it. Flowline1 Flowline1.234 Flowline1.235 Yes Yes Flowline1.236 Flowline2 No Straight Edge.28 N Straight Edge.29 N No Flowline2.240 Straight Edge.28 N Straight Edge.29 N
Diagram 2. Algorithm for getting steps.

The auto-calibrating functionality means that the user does not need to provide minimum and maximum values that can be read on analog channels which are needed to normalize the read values, and can be hardware dependent.

Resource usage

You can create only one instance of this library. The number of pads in a single sensor is limited by the number of available analog input channels.

Using the same analog input for two different sensors is not recommended. This can cause an error when calculating the value due to different maximum and minimum values on them.

Using the same analog input channel on different pads within the same sensor is possible but has a limitation. The same two analog input channels cannot be set as neighboring pads more than once. See the figures below for details.

Correct design where analog inputs are never connected to neighboring pads more than once:

Page-1 Process.245 Chevron.10 Chevron.310 Chevron.311 Chevron.312 Chevron.313 Chevron.314 Flowline1 AIN1 AIN1 Flowline1.318 AIN2 AIN2 Flowline1.319 AIN3 AIN3 Flowline1.320 AIN4 AIN4 Flowline1.321 AIN1 AIN1 Flowline1.322 AIN3 AIN3
Correct implementation of the Capacitive Sensor library.

Wrong design where pads 1 and 2, as well as 4 and 5, are connected to AIN1 and AIN2:

Page-1 Process.245 Chevron.10 Chevron.310 Chevron.311 Chevron.312 Chevron.313 Chevron.314 Flowline1 AIN1 AIN1 Flowline1.318 AIN2 AIN2 Flowline1.319 AIN3 AIN3 Flowline1.320 AIN1 AIN1 Flowline1.321 AIN2 AIN2 Flowline1.322 AIN4 AIN4 Sheet.323 Sheet.324
Wrong implementation of the Capacitive Sensor library.

Initialization and starting

  1. Initialize library. The configuration contains only the address of the event handler function and a number of app_timer ticks.
  2. Create an instance of the sensor that you want to use. There are macros like NRF_CSENSE_BUTTON_DEF that will help you do that. The minimum required configuration is to provide the name of the instance and some basic information about the pads that are used in your instance, such as:
    • Analog input that the pad is connected to and threshold value above which the module will sense touch on this pad.
    • For instances like sliders and wheels, you also need to provide a steps number that represents a range of values returned by the sensor <1, steps>.
  3. After creating an instance, you must add it to a linked list formed by your instances. The function used for this purpose is nrf_csense_add , which also enables your instance after adding it to the list. Optionally, you can attach an address of any type of data to the instance to make it available from event handler, see nrf_csense_instance_context_set . If none of these functions returns an error, the module is ready to sense touch.

The following is an example of initialization of two sensors. One of them is a slider, the other one is a button:

NRF_CSENSE_BUTTON_DEF (m_button, (7, THRESHOLD_AIN_7));
RANGE,
(4, THRESHOLD_AIN_4),
(1, THRESHOLD_AIN_1),
(2, THRESHOLD_AIN_2),
(4, THRESHOLD_AIN_4));
static void csense_start( void )
{
ret_code_t err_code;
static uint16_t touched_counter = 0;
err_code = nrf_csense_init (nrf_csense_handler, APP_TIMER_TICKS_TIMEOUT);
APP_ERROR_CHECK (err_code);
nrf_csense_instance_context_set (&m_button, ( void *)&touched_counter);
err_code = nrf_csense_add (&m_button);
APP_ERROR_CHECK (err_code);
err_code = nrf_csense_add (&m_slider);
APP_ERROR_CHECK (err_code);
}

Reading values from sensors

Consider the above initialization with added context_setting:

static void slider_handler(uint16_t step)
{
static uint16_t slider_val;
if (slider_val != step)
{
printf( "Slider value: %03d.\n" , step);
slider_val = step;
}
}
static void csense_start( void )
{
(…)
nrf_csense_instance_context_set (&m_button, ( void *)&touched_counter);
nrf_csense_instance_context_set (&m_slider, ( void *)slider_handler);
(…)
}

With the context of m_slider instance set to the slider_handler function, you can printf the step that is read on this slider in the event handler:

void nrf_csense_handler( nrf_csense_evt_t * p_evt)
{
switch (p_evt-> nrf_csense_evt_type )
{
(…)
if ((p_evt-> p_instance == (&m_slider)) && (p_evt-> params . slider . step != UINT16_MAX))
{
((void(*)(uint16_t, uint8_t))p_evt-> p_instance ->p_context)(p_evt-> params . slider . step , 2);
}
break ;
(…)
}
}

Limitations

The maximum number of supported pads on a single slider or wheel is 32.

Example

See the Capacitive Sensor Library Example for a full example that uses the Capacitive Sensor library.