Skip to content

Commit b6dd1a6

Browse files
committed
samples: sensor: Barometric pressure interrupt generic example
Reports generic barometric sensor interrupts * Data ready interrupt * Pressure threshold interrupt * Pressure changed interrupt Signed-off-by: Remi Buisson <[email protected]>
1 parent 3d590c8 commit b6dd1a6

File tree

7 files changed

+335
-0
lines changed

7 files changed

+335
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2024 TDK Invensense
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
project(icp201xx)
10+
11+
FILE(GLOB app_sources src/*.c)
12+
target_sources(app PRIVATE ${app_sources})
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Copyright (c) 2024, TDK Invensense
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config LOG
5+
default y
6+
7+
config LOG_PRINTK
8+
default y
9+
10+
config SENSOR_LOG_LEVEL
11+
default 4
12+
13+
config PRESSURE_DRDY
14+
bool "Enable pressure data ready interrupt"
15+
default y
16+
17+
config PRESSURE_THRESHOLD
18+
bool "Enable pressure threshold interrupt"
19+
default y
20+
21+
config PRESSURE_DELTA
22+
bool "Enable pressure delta interrupt"
23+
default y
24+
25+
choice ICP201XX_TRIGGER_MODE
26+
default ICP201XX_TRIGGER_GLOBAL_THREAD
27+
depends on ICP201XX
28+
29+
endchoice
30+
31+
source "Kconfig.zephyr"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.. zephyr:code-sample:: pressure_interrupt
2+
:name: Barometric pressure and temperature sensor interrupt example
3+
:relevant-api: sensor_interface
4+
5+
Manage interrupts from a barometric pressure and temperature sensor.
6+
7+
Overview
8+
********
9+
10+
This sample application uses a pressure sensor interrupt line to:
11+
12+
* Inform when a measure is available in the sensor FIFO.
13+
Temperature and pressure data are read and displayed in terminal.
14+
If floats are supported, estimated altitude is also displayed.
15+
* Inform when the pressure value crosses a specified threshold.
16+
Threshold corresponds to around a 50cm altitude increase.
17+
A message is displayed in the terminal.
18+
* Inform when the pressure value changed more than the specified
19+
value between two consecutive samples.
20+
Change value corresponds to a finger pressing the sensor.
21+
A message is displayed in the terminal.
22+
23+
Wiring
24+
*******
25+
26+
This sample uses an external breakout for the sensor. A devicetree
27+
overlay must be provided to identify the I2C/SPI bus and GPIO used to
28+
control the sensor.
29+
30+
Building and Running
31+
********************
32+
33+
This sample supports pressure sensor devices. Device needs
34+
to be aliased as ``pressure-sensor``. For example:
35+
36+
.. code-block:: devicetree
37+
38+
/ {
39+
aliases {
40+
pressure-sensor = &icp201xx;
41+
};
42+
};
43+
44+
Make sure the aliases are in devicetree, then build and run with:
45+
46+
.. zephyr-app-commands::
47+
:zephyr-app: samples/sensor/pressure_interrupt
48+
:board: nrf52dk/nrf52832
49+
:goals: build flash
50+
51+
Sample Output
52+
=============
53+
54+
.. code-block:: console
55+
56+
## Default configuration
57+
58+
[00:00:00.266,479] <inf> PRESS_INT_SAMPLE: Starting ICP201xx sample.
59+
[00:00:00.273,803] <inf> PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.271438 kPa, altitude 447.208465 m
60+
[00:00:00.280,914] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.271331 kPa, altitude 447.234161 m
61+
[00:00:00.288,024] <inf> PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.266685 kPa, altitude 447.636077 m
62+
[00:00:00.295,135] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267951 kPa, altitude 447.537078 m
63+
[00:00:00.302,246] <inf> PRESS_INT_SAMPLE: temp 25.51 Cel, pressure 96.268577 kPa, altitude 447.488281 m
64+
[00:00:00.309,356] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.269340 kPa, altitude 447.414978 m
65+
[00:00:00.316,467] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.268562 kPa, altitude 447.473663 m
66+
[00:00:00.323,547] <inf> PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267341 kPa, altitude 447.596496 m
67+
<repeats endlessly>
68+
69+
<when sensor is pressed>
70+
[00:00:09.819,061] <inf> PRESS_INT_SAMPLE: PRESSURE CHANGE INTERRUPT
71+
72+
<when the sensor pressure crosses defined threhold>
73+
[00:00:09.859,039] <inf> PRESS_INT_SAMPLE: PRESSURE THRESHOLD INTERRUPT
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2024, TDK Invensense
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* Get a node identifier for pressure sensor.
9+
*/
10+
/ {
11+
aliases {
12+
pressure-sensor = &icp201xx;
13+
};
14+
};
15+
16+
/* Example configuration of a ICP2021XX device on an Arduino SPI bus. */
17+
&arduino_spi {
18+
status = "okay";
19+
cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
20+
icp201xx: icp201xx@0 {
21+
compatible = "invensense,icp201xx";
22+
reg = <0>;
23+
spi-max-frequency = <500000>; /* conservatively set to 500k */
24+
int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */
25+
drive-strength = "current_4mA_1_8V"; /* Avoid cross talk */
26+
};
27+
};
28+
29+
/*
30+
* Increase native UART speed.
31+
*/
32+
&uart0 {
33+
compatible = "nordic,nrf-uarte";
34+
status = "okay";
35+
current-speed = <1000000>;
36+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# Copyright (c) 2024 TDK Invensense
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
CONFIG_SENSOR=y
8+
9+
# Floating point format support
10+
# Selecting this increases stack size requirements slightly, but increases code size significantly.
11+
CONFIG_CBPRINTF_FP_SUPPORT=y
12+
13+
# Buffer size for console. The defaults are optimized to save RAM
14+
CONFIG_CONSOLE_SUBSYS=y
15+
CONFIG_CONSOLE_GETCHAR=y
16+
CONFIG_CONSOLE_GETCHAR_BUFSIZE=16
17+
CONFIG_CONSOLE_PUTCHAR_BUFSIZE=512
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sample:
2+
name: Pressure sensor interrupt
3+
tests:
4+
sample.sensor.pressure_interrupt:
5+
build_only: true
6+
tags: sensors
7+
filter: dt_alias_exists("pressure-sensor")
8+
integration_platforms:
9+
- nrf52dk/nrf52832
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Copyright (c) 2024 TDK Invensense
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/device.h>
9+
#include <zephyr/devicetree.h>
10+
#include <zephyr/drivers/sensor.h>
11+
#include <stdio.h>
12+
#include <zephyr/logging/log.h>
13+
14+
LOG_MODULE_REGISTER(PRESS_INT_SAMPLE, CONFIG_SENSOR_LOG_LEVEL);
15+
16+
/*
17+
* Get a device structure from a devicetree node from alias
18+
* "pressure_sensor".
19+
*/
20+
static const struct device *get_pressure_sensor_device(void)
21+
{
22+
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(pressure_sensor));
23+
24+
if (!device_is_ready(dev)) {
25+
printk("\nError: Device \"%s\" is not ready; "
26+
"check the driver initialization logs for errors.\n",
27+
dev->name);
28+
return NULL;
29+
}
30+
31+
printk("Found device \"%s\", getting sensor data\n", dev->name);
32+
return dev;
33+
}
34+
35+
#ifdef CONFIG_PRESSURE_DRDY
36+
static void data_ready_handler(const struct device *dev, const struct sensor_trigger *trig)
37+
{
38+
39+
if (trig->type == SENSOR_TRIG_DATA_READY) {
40+
int rc = sensor_sample_fetch_chan(dev, trig->chan);
41+
42+
if (rc < 0) {
43+
printf("sample fetch failed: %d\n", rc);
44+
printf("cancelling trigger\n");
45+
(void)sensor_trigger_set(dev, trig, NULL);
46+
return;
47+
} else if (rc == 0) {
48+
49+
struct sensor_value pressure;
50+
struct sensor_value temperature;
51+
struct sensor_value altitude;
52+
53+
sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
54+
sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
55+
sensor_channel_get(dev, SENSOR_CHAN_ALTITUDE, &altitude);
56+
57+
LOG_INF("temp %.2f Cel, pressure %f kPa, altitude %f m",
58+
sensor_value_to_double(&temperature),
59+
sensor_value_to_double(&pressure),
60+
sensor_value_to_double(&altitude));
61+
}
62+
}
63+
}
64+
#endif
65+
66+
#ifdef CONFIG_PRESSURE_THRESHOLD
67+
static void threshold_handler(const struct device *dev, const struct sensor_trigger *trig)
68+
{
69+
if (trig->type == SENSOR_TRIG_THRESHOLD) {
70+
LOG_INF("PRESSURE THRESHOLD INTERRUPT");
71+
}
72+
}
73+
#endif
74+
75+
#ifdef CONFIG_PRESSURE_DELTA
76+
static void delta_handler(const struct device *dev, const struct sensor_trigger *trig)
77+
{
78+
if (trig->type == SENSOR_TRIG_DELTA) {
79+
LOG_INF("PRESSURE CHANGE INTERRUPT\n");
80+
}
81+
}
82+
#endif
83+
84+
int main(void)
85+
{
86+
static struct sensor_trigger data_ready_trigger;
87+
const struct device *dev = get_pressure_sensor_device();
88+
#ifdef CONFIG_PRESSURE_THRESHOLD
89+
static struct sensor_trigger threshold_trigger;
90+
struct sensor_value pressure, pressure_threshold;
91+
#endif
92+
#ifdef CONFIG_PRESSURE_DELTA
93+
static struct sensor_trigger delta_trigger;
94+
struct sensor_value pressure_delta;
95+
#endif
96+
97+
if (dev == NULL) {
98+
return 0;
99+
}
100+
#ifdef CONFIG_PRESSURE_DRDY
101+
/* Configure data ready trigger */
102+
data_ready_trigger = (struct sensor_trigger){
103+
.type = SENSOR_TRIG_DATA_READY,
104+
.chan = SENSOR_CHAN_ALL,
105+
};
106+
if (sensor_trigger_set(dev, &data_ready_trigger, data_ready_handler) < 0) {
107+
printf("Cannot configure data trigger!!!\n");
108+
return 0;
109+
}
110+
#endif
111+
112+
#ifdef CONFIG_PRESSURE_THRESHOLD
113+
/* Configure pressure threshold trigger */
114+
/* Interrupt is triggered if sensor is lifted of about 50cm */
115+
/* Read current pressure */
116+
k_sleep(K_MSEC(50));
117+
sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS);
118+
sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure);
119+
120+
/* Retrieve 5 Pa, around 50cm altitude increase */
121+
pressure_threshold.val1 = pressure.val1;
122+
pressure_threshold.val2 = pressure.val2 - 5000;
123+
sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_LOWER_THRESH, &pressure_threshold);
124+
125+
LOG_INF("Pressure at reset %.3f kPa, interrupt sets at %.3f kPa.\n",
126+
sensor_value_to_double(&pressure), sensor_value_to_double(&pressure_threshold));
127+
128+
threshold_trigger = (struct sensor_trigger){
129+
.type = SENSOR_TRIG_THRESHOLD,
130+
.chan = SENSOR_CHAN_PRESS,
131+
};
132+
if (sensor_trigger_set(dev, &threshold_trigger, threshold_handler) < 0) {
133+
printf("Cannot configure threshold trigger!!!\n");
134+
return 0;
135+
}
136+
#endif
137+
138+
#ifdef CONFIG_PRESSURE_DELTA
139+
/* Configure pressure delta trigger */
140+
/* Set pressure delta to 0.01 kPa to detect a press on the sensor */
141+
pressure_delta.val1 = 0;
142+
pressure_delta.val2 = 10000;
143+
sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_SLOPE_TH, &pressure_delta);
144+
delta_trigger = (struct sensor_trigger){
145+
.type = SENSOR_TRIG_DELTA,
146+
.chan = SENSOR_CHAN_PRESS,
147+
};
148+
if (sensor_trigger_set(dev, &delta_trigger, delta_handler) < 0) {
149+
printf("Cannot configure threshold trigger!!!\n");
150+
return 0;
151+
}
152+
#endif
153+
154+
LOG_INF("Starting pressure event sample.\n");
155+
156+
return 0;
157+
}

0 commit comments

Comments
 (0)