From 0b9b2fbb5e0167fc6381180d7cfe30bce64a460a Mon Sep 17 00:00:00 2001 From: Aurelie Fontaine Date: Thu, 5 Dec 2024 18:06:06 +0100 Subject: [PATCH] samples: sensor: 6DOF motion DRDY generic sample It reports IMU 6-axis accelerometer and gyroscope data using DRDY interrupt. Signed-off-by: Aurelie Fontaine --- .../sensor/6dof_motion_drdy/CMakeLists.txt | 12 ++ samples/sensor/6dof_motion_drdy/README.rst | 56 +++++++++ .../boards/nrf52dk_nrf52832_i2c.overlay | 43 +++++++ .../boards/nrf52dk_nrf52832_spi.overlay | 41 +++++++ samples/sensor/6dof_motion_drdy/prj.conf | 19 +++ samples/sensor/6dof_motion_drdy/sample.yaml | 9 ++ samples/sensor/6dof_motion_drdy/src/main.c | 113 ++++++++++++++++++ 7 files changed, 293 insertions(+) create mode 100644 samples/sensor/6dof_motion_drdy/CMakeLists.txt create mode 100644 samples/sensor/6dof_motion_drdy/README.rst create mode 100644 samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay create mode 100644 samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay create mode 100644 samples/sensor/6dof_motion_drdy/prj.conf create mode 100644 samples/sensor/6dof_motion_drdy/sample.yaml create mode 100644 samples/sensor/6dof_motion_drdy/src/main.c diff --git a/samples/sensor/6dof_motion_drdy/CMakeLists.txt b/samples/sensor/6dof_motion_drdy/CMakeLists.txt new file mode 100644 index 00000000000..892aaf5ed8a --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/CMakeLists.txt @@ -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(6dof_motion_drdy) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/6dof_motion_drdy/README.rst b/samples/sensor/6dof_motion_drdy/README.rst new file mode 100644 index 00000000000..811259b795d --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/README.rst @@ -0,0 +1,56 @@ +.. zephyr:code-sample:: 6dof_motion_drdy + :name: Generic 6DOF Motion Dataready + :relevant-api: sensor_interface + + Get 6-Axis accelerometer and gyroscope data from a sensor (data ready interrupt mode). + +Overview +******** + +This sample application periodically (100 Hz) measures the 6-axis IMU sensor with +temperature, acceleration, and angular velocity, displaying the +values on the console along with a timestamp since startup. +Trigger options could be configured through KConfig. + +Wiring +****** + +This sample uses an external breakout for the sensor. A devicetree +overlay must be provided to identify the 6-axis motion sensor, the SPI or I2C bus interface and the interrupt +sensor GPIO. + +Building and Running +******************** + +This sample supports up to 6-Axis IMU devices. Each device needs +to be aliased as ``6dof-motion-drdyN`` where ``N`` goes from ``0`` to ``9``. For example: + +.. code-block:: devicetree + + / { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; + }; + +Make sure the aliases are in devicetree, then build and run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/6dof_motion_drdy + :board: nrf52dk/nrf52832 + :goals: build flash + +Sample Output +============= + +.. code-block:: console + +Found device "icm42670p@68", getting sensor data +[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 +[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 +[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 +[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 +[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 +[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 + + diff --git a/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay new file mode 100644 index 00000000000..24a82484942 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_i2c.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for 6-axis IMU sensor. + */ +/ { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; +}; + +/* + * Example configuration of a ICM42670-P device on i2c0 compatible with an Arduino I2C bus. + * + * Device address 0x68 is assumed. Your device may have a different + * address; check your device documentation if unsure. + * + * Configure 100Hz IMU data reporting + */ +&arduino_i2c { + status = "okay"; + icm42670p: icm42670p@68 { + compatible = "invensense,icm42670p"; + reg = <0x68>; + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <100>; + gyro-hz = <100>; + accel-fs = <16>; + gyro-fs = <2000>; + }; +}; + +/* + * Increase native UART speed to report all IMU data at 100Hz. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay new file mode 100644 index 00000000000..d74e8bd092f --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/boards/nrf52dk_nrf52832_spi.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for 6-axis IMU sensor. + */ +/ { + aliases { + 6dof-motion-drdy0 = &icm42670p; + }; +}; + +/* Example configuration of a ICM42670-P device on spi2 compatible with an Arduino SPI bus. + * + * Configure 100Hz IMU data reporting + */ +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + icm42670p: icm42670p@0 { + compatible = "invensense,icm42670p"; + reg = <0>; + spi-max-frequency = <1000000>; /* conservatively set to 1MHz */ + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + accel-hz = <100>; + gyro-hz = <100>; + accel-fs = <16>; + gyro-fs = <2000>; + }; +}; + +/* + * Increase native UART speed to report all IMU data at 100Hz. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/6dof_motion_drdy/prj.conf b/samples/sensor/6dof_motion_drdy/prj.conf new file mode 100644 index 00000000000..30d93977483 --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/prj.conf @@ -0,0 +1,19 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SENSOR=y +CONFIG_LOG=y +CONFIG_SENSOR_LOG_LEVEL_DBG=n + +# Floating point format support +# Selecting this increases stack size requirements slightly, but increases code size significantly. +CONFIG_CBPRINTF_FP_SUPPORT=y + +# nrf52dk/nrf52832 specific +CONFIG_USE_SEGGER_RTT=n + +# Trigger mode: sample is using interrupt triggering +CONFIG_ICM42670_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/6dof_motion_drdy/sample.yaml b/samples/sensor/6dof_motion_drdy/sample.yaml new file mode 100644 index 00000000000..02932da4ebd --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: 6DOF Motion dataready sample +tests: + sample.sensor.6dof_motion_drdy: + build_only: true + tags: sensors + filter: dt_alias_exists("6dof_motion_drdy0") + integration_platforms: + - nrf52dk/nrf52832 diff --git a/samples/sensor/6dof_motion_drdy/src/main.c b/samples/sensor/6dof_motion_drdy/src/main.c new file mode 100644 index 00000000000..547c86b51da --- /dev/null +++ b/samples/sensor/6dof_motion_drdy/src/main.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static struct sensor_trigger data_trigger; + +/* Flag set from IMU device irq handler */ +static volatile int irq_from_device; + +/* + * Get a device structure from a devicetree node from alias + * "6dof_motion_drdy0". + */ +static const struct device *get_6dof_motion_device(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(6dof_motion_drdy0)); + + 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; +} + +static const char *now_str(void) +{ + static char buf[16]; /* ...HH:MM:SS.MMM */ + uint32_t now = k_uptime_get_32(); + unsigned int ms = now % MSEC_PER_SEC; + unsigned int s; + unsigned int min; + unsigned int h; + + now /= MSEC_PER_SEC; + s = now % 60U; + now /= 60U; + min = now % 60U; + now /= 60U; + h = now; + + snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", h, min, s, ms); + return buf; +} + +static void handle_6dof_motion_drdy(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 due to failure: %d\n", rc); + (void)sensor_trigger_set(dev, trig, NULL); + return; + } else if (rc == 0) { + irq_from_device = 1; + } + } +} + +int main(void) +{ + const struct device *dev = get_6dof_motion_device(); + struct sensor_value accel[3]; + struct sensor_value gyro[3]; + struct sensor_value temperature; + + if (dev == NULL) { + return 0; + } + + data_trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_DATA_READY, + .chan = SENSOR_CHAN_ALL, + }; + if (sensor_trigger_set(dev, &data_trigger, handle_6dof_motion_drdy) < 0) { + printf("Cannot configure data trigger!!!\n"); + return 0; + } + + k_sleep(K_MSEC(1000)); + + while (1) { + + if (irq_from_device) { + sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, accel); + sensor_channel_get(dev, SENSOR_CHAN_GYRO_XYZ, gyro); + sensor_channel_get(dev, SENSOR_CHAN_DIE_TEMP, &temperature); + + printf("[%s]: temp %.2f Cel " + " accel %f %f %f m/s/s " + " gyro %f %f %f rad/s\n", + now_str(), sensor_value_to_double(&temperature), + sensor_value_to_double(&accel[0]), sensor_value_to_double(&accel[1]), + sensor_value_to_double(&accel[2]), sensor_value_to_double(&gyro[0]), + sensor_value_to_double(&gyro[1]), sensor_value_to_double(&gyro[2])); + irq_from_device = 0; + } + } + return 0; +}