Skip to content

Commit 4a1c638

Browse files
samples: sensor: 6DOF motion DRDY generic sample
It reports IMU 6-axis accelerometer and gyroscope data using DRDY interrupt. Signed-off-by: Aurelie Fontaine <[email protected]>
1 parent 6f8e286 commit 4a1c638

File tree

7 files changed

+298
-0
lines changed

7 files changed

+298
-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(6dof_motion_drdy)
10+
11+
FILE(GLOB app_sources src/*.c)
12+
target_sources(app PRIVATE ${app_sources})
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
.. zephyr:code-sample:: 6dof_motion_drdy
2+
:name: Generic 6DOF Motion Dataready
3+
:relevant-api: sensor_interface
4+
5+
Get 6-Axis accelerometer and gyroscope data from a sensor (data ready interrupt mode).
6+
7+
Overview
8+
********
9+
10+
This sample application periodically (100 Hz) measures the 6-axis IMU sensor with
11+
temperature, acceleration, and angular velocity, displaying the
12+
values on the console along with a timestamp since startup.
13+
Trigger options could be configured through KConfig.
14+
15+
Wiring
16+
******
17+
18+
This sample uses an external breakout for the sensor. A devicetree
19+
overlay must be provided to identify the 6-axis motion sensor, the SPI or I2C bus interface and the interrupt
20+
sensor GPIO.
21+
22+
Building and Running
23+
********************
24+
25+
This sample supports up to 6-Axis IMU devices. Each device needs
26+
to be aliased as ``6dof-motion-drdyN`` where ``N`` goes from ``0`` to ``9``. For example:
27+
28+
.. code-block:: devicetree
29+
30+
/ {
31+
aliases {
32+
6dof-motion-drdy0 = &icm42670p;
33+
};
34+
};
35+
36+
Make sure the aliases are in devicetree, then build and run with:
37+
38+
.. zephyr-app-commands::
39+
:zephyr-app: samples/sensor/6dof_motion_drdy
40+
:board: nrf52dk/nrf52832
41+
:goals: build flash
42+
43+
Sample Output
44+
=============
45+
46+
.. code-block:: console
47+
48+
Found device "icm42670p@68", getting sensor data
49+
[0:00:01.716]: temp 23.00 Cel accel 0.150839 -0.140065 9.994899 m/s/s gyro -0.001597 0.005859 0.001597 rad/s
50+
[0:00:01.726]: temp 23.00 Cel accel 0.140065 -0.146050 9.988914 m/s/s gyro -0.002663 0.005859 0.003195 rad/s
51+
[0:00:01.736]: temp 23.50 Cel accel 0.146050 -0.130487 9.988914 m/s/s gyro -0.001597 0.006391 0.003195 rad/s
52+
[0:00:01.746]: temp 23.00 Cel accel 0.149642 -0.136473 9.990111 m/s/s gyro -0.002663 0.004261 0.002663 rad/s
53+
[0:00:01.756]: temp 23.00 Cel accel 0.146050 -0.136473 9.979337 m/s/s gyro -0.002130 0.005326 0.001597 rad/s
54+
[0:00:01.766]: temp 23.00 Cel accel 0.136473 -0.147247 9.986519 m/s/s gyro -0.001065 0.005859 0.002663 rad/s
55+
56+
<repeats endlessly>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2024, TDK Invensense
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* Get a node identifier for 6-axis IMU sensor.
9+
*/
10+
/ {
11+
aliases {
12+
6dof-motion-drdy0 = &icm42670p;
13+
};
14+
};
15+
16+
/*
17+
* Example configuration of a ICM42670-P device on i2c0 compatible with an Arduino I2C bus.
18+
*
19+
* Device address 0x68 is assumed. Your device may have a different
20+
* address; check your device documentation if unsure.
21+
*
22+
* Configure 100Hz IMU data reporting
23+
*/
24+
&arduino_i2c {
25+
status = "okay";
26+
icm42670p: icm42670p@68 {
27+
compatible = "invensense,icm42670p";
28+
reg = <0x68>;
29+
int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */
30+
accel-hz = <100>;
31+
gyro-hz = <100>;
32+
accel-fs = <16>;
33+
gyro-fs = <2000>;
34+
};
35+
};
36+
37+
/*
38+
* Increase native UART speed to report all IMU data at 100Hz.
39+
*/
40+
&uart0 {
41+
compatible = "nordic,nrf-uarte";
42+
current-speed = <1000000>;
43+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2024, TDK Invensense
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* Get a node identifier for 6-axis IMU sensor.
9+
*/
10+
/ {
11+
aliases {
12+
6dof-motion-drdy0 = &icm42670p;
13+
};
14+
};
15+
16+
/* Example configuration of a ICM42670-P device on spi2 compatible with an Arduino SPI bus.
17+
*
18+
* Configure 100Hz IMU data reporting
19+
*/
20+
&arduino_spi {
21+
status = "okay";
22+
cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
23+
icm42670p: icm42670p@0 {
24+
compatible = "invensense,icm42670p";
25+
reg = <0>;
26+
spi-max-frequency = <1000000>; /* conservatively set to 1MHz */
27+
int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */
28+
accel-hz = <100>;
29+
gyro-hz = <100>;
30+
accel-fs = <16>;
31+
gyro-fs = <2000>;
32+
};
33+
};
34+
35+
/*
36+
* Increase native UART speed to report all IMU data at 100Hz.
37+
*/
38+
&uart0 {
39+
compatible = "nordic,nrf-uarte";
40+
current-speed = <1000000>;
41+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#
2+
# Copyright (c) 2024 TDK Invensense
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
CONFIG_SENSOR=y
8+
9+
CONFIG_LOG=y
10+
CONFIG_LOG_PRINTK=y
11+
CONFIG_SENSOR_LOG_LEVEL_DBG=y
12+
13+
# Floating point format support
14+
# Selecting this increases stack size requirements slightly, but increases code size significantly.
15+
CONFIG_CBPRINTF_FP_SUPPORT=y
16+
17+
# Buffer size for console. The defaults are optimized to save RAM
18+
CONFIG_CONSOLE_SUBSYS=y
19+
CONFIG_CONSOLE_GETCHAR=y
20+
CONFIG_CONSOLE_GETCHAR_BUFSIZE=16
21+
CONFIG_CONSOLE_PUTCHAR_BUFSIZE=512
22+
23+
# Trigger mode: sample is using interrupt triggering
24+
CONFIG_ICM42670_TRIGGER_OWN_THREAD=y
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sample:
2+
name: 6DOF Motion dataready sample
3+
tests:
4+
sample.sensor.6dof_motion_drdy:
5+
build_only: true
6+
tags: sensors
7+
filter: dt_alias_exists("6dof_motion_drdy0")
8+
integration_platforms:
9+
- nrf52dk/nrf52832
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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+
13+
static struct sensor_trigger data_trigger;
14+
15+
/* Flag set from IMU device irq handler */
16+
static volatile int irq_from_device;
17+
18+
/*
19+
* Get a device structure from a devicetree node from alias
20+
* "6dof_motion_drdy0".
21+
*/
22+
static const struct device *get_6dof_motion_device(void)
23+
{
24+
const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(6dof_motion_drdy0));
25+
26+
if (!device_is_ready(dev)) {
27+
printk("\nError: Device \"%s\" is not ready; "
28+
"check the driver initialization logs for errors.\n",
29+
dev->name);
30+
return NULL;
31+
}
32+
33+
printk("Found device \"%s\", getting sensor data\n", dev->name);
34+
return dev;
35+
}
36+
37+
static const char *now_str(void)
38+
{
39+
static char buf[16]; /* ...HH:MM:SS.MMM */
40+
uint32_t now = k_uptime_get_32();
41+
unsigned int ms = now % MSEC_PER_SEC;
42+
unsigned int s;
43+
unsigned int min;
44+
unsigned int h;
45+
46+
now /= MSEC_PER_SEC;
47+
s = now % 60U;
48+
now /= 60U;
49+
min = now % 60U;
50+
now /= 60U;
51+
h = now;
52+
53+
snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms);
54+
return buf;
55+
}
56+
57+
static void handle_6dof_motion_drdy(const struct device *dev, const struct sensor_trigger *trig)
58+
{
59+
if (trig->type == SENSOR_TRIG_DATA_READY) {
60+
int rc = sensor_sample_fetch_chan(dev, trig->chan);
61+
62+
if (rc < 0) {
63+
printf("sample fetch failed: %d\n", rc);
64+
printf("cancelling trigger due to failure: %d\n", rc);
65+
(void)sensor_trigger_set(dev, trig, NULL);
66+
return;
67+
} else if (rc == 0) {
68+
irq_from_device = 1;
69+
}
70+
}
71+
}
72+
73+
int main(void)
74+
{
75+
const struct device *dev = get_6dof_motion_device();
76+
struct sensor_value accel[3];
77+
struct sensor_value gyro[3];
78+
struct sensor_value temperature;
79+
80+
if (dev == NULL) {
81+
return 0;
82+
}
83+
84+
data_trigger = (struct sensor_trigger){
85+
.type = SENSOR_TRIG_DATA_READY,
86+
.chan = SENSOR_CHAN_ALL,
87+
};
88+
if (sensor_trigger_set(dev, &data_trigger, handle_6dof_motion_drdy) < 0) {
89+
printf("Cannot configure data trigger!!!\n");
90+
return 0;
91+
}
92+
93+
k_sleep(K_MSEC(1000));
94+
95+
while (1) {
96+
97+
if (irq_from_device) {
98+
sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, accel);
99+
sensor_channel_get(dev, SENSOR_CHAN_GYRO_XYZ, gyro);
100+
sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &temperature);
101+
102+
printf("[%s]: temp %.2f Cel "
103+
" accel %f %f %f m/s/s "
104+
" gyro %f %f %f rad/s\n",
105+
now_str(), sensor_value_to_double(&temperature),
106+
sensor_value_to_double(&accel[0]), sensor_value_to_double(&accel[1]),
107+
sensor_value_to_double(&accel[2]), sensor_value_to_double(&gyro[0]),
108+
sensor_value_to_double(&gyro[1]), sensor_value_to_double(&gyro[2]));
109+
irq_from_device = 0;
110+
}
111+
}
112+
return 0;
113+
}

0 commit comments

Comments
 (0)