| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Capacitive Sensor library

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:

- Can support any number of sensors (including buttons, sliders, and wheels).
- Auto-calibrating functionality.
- Uses the power-efficient Capacitive Sensor driver.

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

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:

Diagram 2. Algorithm fo 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 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:

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:

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 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, for that 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));
NRF_CSENSE_SLIDER_4_DEF(m_slider,
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)
{
(…)
case NRF_CSENSE_SLIDER_EVT_DRAGGED:
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.