Skip to content

Commit

Permalink
samples: sensor: Barometric pressure interrupt generic example
Browse files Browse the repository at this point in the history
Reports generic barometric sensor interrupts
* Data ready interrupt
* Pressure threshold interrupt
* Pressure changed interrupt

Signed-off-by: Remi Buisson <remi.buisson@tdk.com>
  • Loading branch information
rbuisson-invn committed Feb 18, 2025
1 parent 8dcf975 commit a37bc76
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 0 deletions.
12 changes: 12 additions & 0 deletions samples/sensor/pressure_interrupt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Copyright (c) 2024 TDK Invensense
#
# SPDX-License-Identifier: Apache-2.0
#

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(icp201xx)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
31 changes: 31 additions & 0 deletions samples/sensor/pressure_interrupt/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright (c) 2024, TDK Invensense
# SPDX-License-Identifier: Apache-2.0

config LOG
default y

config LOG_PRINTK
default y

config SENSOR_LOG_LEVEL
default 4

config PRESSURE_DRDY
bool "Enable pressure data ready interrupt"
default y

config PRESSURE_THRESHOLD
bool "Enable pressure threshold interrupt"
default y

config PRESSURE_DELTA
bool "Enable pressure delta interrupt"
default y

choice ICP201XX_TRIGGER_MODE
default ICP201XX_TRIGGER_GLOBAL_THREAD
depends on ICP201XX

endchoice

source "Kconfig.zephyr"
73 changes: 73 additions & 0 deletions samples/sensor/pressure_interrupt/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
.. zephyr:code-sample:: pressure_interrupt
:name: Barometric pressure and temperature sensor interrupt example
:relevant-api: sensor_interface

Manage interrupts from a barometric pressure and temperature sensor.

Overview
********

This sample application uses a pressure sensor interrupt line to:

* Inform when a measure is available in the sensor FIFO.
Temperature and pressure data are read and displayed in terminal.
If floats are supported, estimated altitude is also displayed.
* Inform when the pressure value crosses a specified threshold.
Threshold corresponds to around a 50cm altitude increase.
A message is displayed in the terminal.
* Inform when the pressure value changed more than the specified
value between two consecutive samples.
Change value corresponds to a finger pressing the sensor.
A message is displayed in the terminal.

Wiring
*******

This sample uses an external breakout for the sensor. A devicetree
overlay must be provided to identify the I2C/SPI bus and GPIO used to
control the sensor.

Building and Running
********************

This sample supports pressure sensor devices. Device needs
to be aliased as ``pressure-sensor``. For example:

.. code-block:: devicetree
/ {
aliases {
pressure-sensor = &icp201xx;
};
};
Make sure the aliases are in devicetree, then build and run with:

.. zephyr-app-commands::
:zephyr-app: samples/sensor/pressure_interrupt
:board: nrf52dk/nrf52832
:goals: build flash

Sample Output
=============

.. code-block:: console
## Default configuration

[00:00:00.266,479] <inf> PRESS_INT_SAMPLE: Starting ICP201xx sample.
[00:00:00.273,803] <inf> PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.271438 kPa, altitude 447.208465 m
[00:00:00.280,914] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.271331 kPa, altitude 447.234161 m
[00:00:00.288,024] <inf> PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.266685 kPa, altitude 447.636077 m
[00:00:00.295,135] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267951 kPa, altitude 447.537078 m
[00:00:00.302,246] <inf> PRESS_INT_SAMPLE: temp 25.51 Cel, pressure 96.268577 kPa, altitude 447.488281 m
[00:00:00.309,356] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.269340 kPa, altitude 447.414978 m
[00:00:00.316,467] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.268562 kPa, altitude 447.473663 m
[00:00:00.323,547] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267341 kPa, altitude 447.596496 m
<repeats endlessly>

<when sensor is pressed>
[00:00:09.819,061] <inf> PRESS_INT_SAMPLE: PRESSURE CHANGE INTERRUPT

<when the sensor pressure crosses defined threhold>
[00:00:09.859,039] <inf> PRESS_INT_SAMPLE: PRESSURE THRESHOLD INTERRUPT
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024, TDK Invensense
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* Get a node identifier for pressure sensor.
*/
/ {
aliases {
pressure-sensor = &icp201xx;
};
};

/*
* Example configuration of a icp201xx device on an Arduino I2C bus.
*
* Device address 0x63 is assumed. Your device may have a different
* address; check your device documentation if unsure.
*/
&arduino_i2c {
status = "okay";
icp201xx: icp201xx@63 {
compatible = "invensense,icp201xx";
reg = <0x63>;
int-gpios = <&arduino_header 8 GPIO_ACTIVE_LOW>; /* D2 */
};
};

/*
* Increase native UART speed to report sensor data.
*/
&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <1000000>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, TDK Invensense
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* Get a node identifier for pressure sensor.
*/
/ {
aliases {
pressure-sensor = &icp201xx;
};
};

/* Example configuration of a ICP2021XX device on an Arduino SPI bus. */
&arduino_spi {
status = "okay";
cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
icp201xx: icp201xx@0 {
compatible = "invensense,icp201xx";
reg = <0>;
spi-max-frequency = <500000>; /* conservatively set to 500k */
int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */
drive-strength = "current_4mA_1_8V"; /* Avoid cross talk */
};
};

/*
* Increase native UART speed.
*/
&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <1000000>;
};
17 changes: 17 additions & 0 deletions samples/sensor/pressure_interrupt/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Copyright (c) 2024 TDK Invensense
#
# SPDX-License-Identifier: Apache-2.0
#

CONFIG_SENSOR=y

# Floating point format support
# Selecting this increases stack size requirements slightly, but increases code size significantly.
CONFIG_CBPRINTF_FP_SUPPORT=y

# Buffer size for console. The defaults are optimized to save RAM
CONFIG_CONSOLE_SUBSYS=y
CONFIG_CONSOLE_GETCHAR=y
CONFIG_CONSOLE_GETCHAR_BUFSIZE=16
CONFIG_CONSOLE_PUTCHAR_BUFSIZE=512
9 changes: 9 additions & 0 deletions samples/sensor/pressure_interrupt/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sample:
name: Pressure sensor interrupt
tests:
sample.sensor.pressure_interrupt:
build_only: true
tags: sensors
filter: dt_alias_exists("pressure-sensor")
integration_platforms:
- nrf52dk/nrf52832
155 changes: 155 additions & 0 deletions samples/sensor/pressure_interrupt/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2024 TDK Invensense
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/sensor.h>
#include <stdio.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(PRESS_INT_SAMPLE, CONFIG_SENSOR_LOG_LEVEL);

/*
* Get a device structure from a devicetree node from alias
* "pressure_sensor".
*/
static const struct device *get_pressure_sensor_device(void)
{
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(pressure_sensor));

if (!device_is_ready(dev)) {
printk("\nError: Device \"%s\" is not ready; "
"check the driver initialization logs for errors.\n",
dev->name);
return NULL;
}

printk("Found device \"%s\", getting sensor data\n", dev->name);
return dev;
}

#ifdef CONFIG_PRESSURE_DRDY
static void data_ready_handler(const struct device *dev, const struct sensor_trigger *trig)
{

if (trig->type == SENSOR_TRIG_DATA_READY) {
int rc = sensor_sample_fetch_chan(dev, trig->chan);

if (rc < 0) {
printf("sample fetch failed: %d\n", rc);
printf("cancelling trigger\n");
(void)sensor_trigger_set(dev, trig, NULL);
return;
} else if (rc == 0) {

struct sensor_value pressure;
struct sensor_value temperature;
struct sensor_value altitude;

sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
sensor_channel_get(dev, SENSOR_CHAN_ALTITUDE, &altitude);

LOG_INF("temp %.2f Cel, pressure %f kPa, altitude %f m",
sensor_value_to_double(&temperature),
sensor_value_to_double(&pressure),
sensor_value_to_double(&altitude));
}
}
}
#endif

#ifdef CONFIG_PRESSURE_THRESHOLD
static void threshold_handler(const struct device *dev, const struct sensor_trigger *trig)
{
if (trig->type == SENSOR_TRIG_THRESHOLD) {
LOG_INF("PRESSURE THRESHOLD INTERRUPT");
}
}
#endif

#ifdef CONFIG_PRESSURE_DELTA
static void delta_handler(const struct device *dev, const struct sensor_trigger *trig)
{
if (trig->type == SENSOR_TRIG_DELTA) {
LOG_INF("PRESSURE CHANGE INTERRUPT\n");
}
}
#endif

int main(void)
{
static struct sensor_trigger trigger;
const struct device *dev = get_pressure_sensor_device();
#ifdef CONFIG_PRESSURE_THRESHOLD
struct sensor_value pressure, pressure_threshold;
#endif
#ifdef CONFIG_PRESSURE_DELTA
struct sensor_value pressure_delta;
#endif

if (dev == NULL) {
return 0;
}
#ifdef CONFIG_PRESSURE_DRDY
/* Configure data ready trigger */
trigger = (struct sensor_trigger){
.type = SENSOR_TRIG_DATA_READY,
.chan = SENSOR_CHAN_ALL,
};
if (sensor_trigger_set(dev, &trigger, data_ready_handler) < 0) {
printf("Cannot configure data trigger!!!\n");
return 0;
}
#endif

#ifdef CONFIG_PRESSURE_THRESHOLD
/* Configure pressure threshold trigger */
/* Interrupt is triggered if sensor is lifted of about 50cm */
/* Read current pressure */
k_sleep(K_MSEC(50));
sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS);
sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);

/* Retrieve 5 Pa, around 50cm altitude increase */
pressure_threshold.val1 = pressure.val1;
pressure_threshold.val2 = pressure.val2 - 5000;
sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_LOWER_THRESH, &pressure_threshold);

LOG_INF("Pressure at reset %.3f kPa, interrupt sets at %.3f kPa.\n",
sensor_value_to_double(&pressure), sensor_value_to_double(&pressure_threshold));

trigger = (struct sensor_trigger){
.type = SENSOR_TRIG_THRESHOLD,
.chan = SENSOR_CHAN_PRESS,
};
if (sensor_trigger_set(dev, &trigger, threshold_handler) < 0) {
printf("Cannot configure threshold trigger!!!\n");
return 0;
}
#endif

#ifdef CONFIG_PRESSURE_DELTA
/* Configure pressure delta trigger */
/* Set pressure delta to 0.01 kPa to detect a press on the sensor */
pressure_delta.val1 = 0;
pressure_delta.val2 = 10000;
sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_SLOPE_TH, &pressure_delta);
trigger = (struct sensor_trigger){
.type = SENSOR_TRIG_DELTA,
.chan = SENSOR_CHAN_PRESS,
};
if (sensor_trigger_set(dev, &trigger, delta_handler) < 0) {
printf("Cannot configure threshold trigger!!!\n");
return 0;
}
#endif

LOG_INF("Starting pressure event sample.\n");

return 0;
}

0 comments on commit a37bc76

Please sign in to comment.