DEV Community

GOROman
GOROman

Posted on

GAITAME IMU:Documentation: A High-Precision IMU for Spresense (CXD5602PWBIMU)

CXD5602PWBIMU Documentation: A High-Precision IMU for Spresense

Introduction

The CXD5602PWBIMU is an Inertial Measurement Unit (IMU) sensor available for use with the Spresense board. What makes this sensor special is that it contains 16 consumer-grade IMUs, each with a 3-axis accelerometer and 3-axis gyroscope, enabling high-precision motion detection and measurement through sensor fusion. Remarkably, you can even stack two boards for a total of 32 IMUs (though this comes at a higher price point - around 90,000 yen!).

This product is intended for the Japanese domestic market. It falls under export trade control regulations (items 1-15 of the Export Trade Control Order and Foreign Exchange Order in Japan). When exporting this product or providing it to non-residents, proper procedures must be followed in accordance with foreign exchange laws.

IMU board image

Key Features

High Precision

  • Low Bias Variation: Bias stability below 0.39 deg/h (when combining 16 IMUs)
  • Low Noise Density: Below 1.0 mdps/√Hz. Even capable of gyrocompass functionality through earth rotation detection
  • Further precision improvement possible with dual-board stacking
  • Pre-calibrated

High Robustness

  • Strong fault tolerance through redundant multiple IMUs
  • Real-time outlier rejection via majority voting logic

Note: SPRESENSE main board is not included.

The board appears to use two PSoC6 chips for signal processing:
PSoC6 image

Here's how the IMUs are arranged:
IMU array image

Setting Up the Development Environment

  • Install the Spresense development environment (SDK)
  • Firmware v3.4.0 is required, but for some reason it's not yet available on the official site (you'll need to figure this out) It appears v3.3.0 works fine
  • While it should work with Arduino as well, no sample code for Arduino was available at the time of writing

Basic Usage

Device Path

The CXD5602PWBIMU sensor can be accessed at the following device path:

/dev/imu0
Enter fullscreen mode Exit fullscreen mode

API Reference

IOCTL Commands

Command Description Parameter
SNIOC_SSAMPRATE Set sampling rate int type (15, 30, 60, 120, 240, 480, 960, 1920)
SNIOC_SDRANGE Set dynamic range cxd5602pwbimu_range_t structure
SNIOC_SFIFOTHRESH Set hardware FIFO threshold int type (1-4)
SNIOC_ENABLE Enable/disable sensor int type (1=enable, 0=disable)

Data Structures

// Structure for dynamic range settings
typedef struct {
  int accel;  // Accelerometer range (2, 4, 8, 16)
  int gyro;   // Gyroscope range (125, 250, 500, 1000, 2000, 4000)
} cxd5602pwbimu_range_t;

// Sensor data structure
typedef struct {
  uint32_t timestamp;  // Timestamp
  float temp;          // Temperature
  float gx;            // Gyroscope X-axis
  float gy;            // Gyroscope Y-axis
  float gz;            // Gyroscope Z-axis
  float ax;            // Accelerometer X-axis
  float ay;            // Accelerometer Y-axis
  float az;            // Accelerometer Z-axis
} cxd5602pwbimu_data_t;
Enter fullscreen mode Exit fullscreen mode

Code Examples

Sensor Initialization and Configuration

#include <nuttx/sensors/cxd5602pwbimu.h>

int fd;
int ret;
cxd5602pwbimu_range_t range;

// Open the device
fd = open("/dev/imu0", O_RDONLY);
if (fd < 0) {
  printf("Error: Could not open device\n");
  return 1;
}

// Set sampling rate (example: 480Hz)
ret = ioctl(fd, SNIOC_SSAMPRATE, 480);
if (ret) {
  printf("Error: Failed to set sampling rate\n");
  close(fd);
  return 1;
}

// Set dynamic range (example: acceleration=2G, gyro=125dps)
range.accel = 2;
range.gyro = 125;
ret = ioctl(fd, SNIOC_SDRANGE, (unsigned long)(uintptr_t)&range);
if (ret) {
  printf("Error: Failed to set dynamic range\n");
  close(fd);
  return 1;
}

// Set FIFO threshold (example: 1)
ret = ioctl(fd, SNIOC_SFIFOTHRESH, 1);
if (ret) {
  printf("Error: Failed to set FIFO threshold\n");
  close(fd);
  return 1;
}

// Enable the sensor
ret = ioctl(fd, SNIOC_ENABLE, 1);
if (ret) {
  printf("Error: Failed to enable sensor\n");
  close(fd);
  return 1;
}
Enter fullscreen mode Exit fullscreen mode

Reading Data

cxd5602pwbimu_data_t data;
struct pollfd fds[1];

// Configure poll
fds[0].fd = fd;
fds[0].events = POLLIN;

// Wait for data to become available
ret = poll(fds, 1, 1000); // 1 second timeout
if (ret > 0 && (fds[0].revents & POLLIN)) {
  // Read data
  ret = read(fd, &data, sizeof(data));
  if (ret == sizeof(data)) {
    // Process data
    printf("Temperature: %.2f\n", data.temp);
    printf("Acceleration (G): X=%.6f, Y=%.6f, Z=%.6f\n", data.ax, data.ay, data.az);
    printf("Gyroscope (dps): X=%.6f, Y=%.6f, Z=%.6f\n", data.gx, data.gy, data.gz);
  }
}

// Disable sensor when finished
ioctl(fd, SNIOC_ENABLE, 0);
close(fd);
Enter fullscreen mode Exit fullscreen mode

Sample Applications

The Spresense SDK includes sample applications for using the CXD5602PWBIMU sensor.

Basic Sample (cxd5602pwbimu)

A simple sample demonstrating basic sensor usage. It collects data for 1 second and displays it to standard output. After building and flashing, launch it from UART with the pwbimu command.

Output example

https://x.com/GOROman/status/1895733790229872796

Logger Application (cxd5602pwbimu_logger)

A logger application supporting long-term data collection and various output formats.

cxd5602pwbimu_logger [-s <rate>] [-a <acc_range>] [-g <gyro_range>] [-f <fifo_num>] [-o <out_dev>] [-d] [-h]
Enter fullscreen mode Exit fullscreen mode

Options:

  • -s <rate>: Sampling rate (Hz). Valid values: 15, 30, 60, 120, 240, 480, 960, 1920
  • -a <acc_range>: Accelerometer range (G). Valid values: 2, 4, 8, 16
  • -g <gyro_range>: Gyroscope range (dps). Valid values: 125, 250, 500, 1000, 2000, 4000
  • -f <fifo_num>: FIFO size. Valid values: 1, 2, 3, 4
  • -o <out_dev>: Output device. 'uart', 'net', '/path/to/file.bin', '/path/to/file.txt'
  • -d: Force display data to UART
  • -h: Display help

Recommended Settings by Use Case

General Motion Detection

  • Sampling rate: 60Hz
  • Accelerometer range: 2G
  • Gyroscope range: 250dps
  • FIFO threshold: 1

Sports Activity Tracking

  • Sampling rate: 240Hz
  • Accelerometer range: 8G
  • Gyroscope range: 1000dps
  • FIFO threshold: 2

High-Precision Motion Analysis

  • Sampling rate: 960Hz
  • Accelerometer range: 4G
  • Gyroscope range: 500dps
  • FIFO threshold: 1

Battery Efficiency Priority

  • Sampling rate: 30Hz
  • Accelerometer range: 2G
  • Gyroscope range: 125dps
  • FIFO threshold: 4

Troubleshooting

Data Reading Errors

  • Confirm the device path is correct (/dev/imu0)
  • Check if the sensor is enabled
  • Verify FIFO threshold settings

Inaccurate Data

  • Ignore the first 50ms of data (may contain initialization noise)
  • Confirm dynamic range is appropriately set
  • Check if sampling rate is suitable for your application

Performance Issues

  • Try lowering the sampling rate
  • Increase FIFO threshold to reduce data processing frequency
  • Minimize unnecessary data processing

Applications

Suitable for applications where traditional industrial FOG (Fiber Optic Gyroscope) would be difficult to implement:

  • Structure inspection drones
  • Small autonomous mobile robots
  • Devices requiring precise position and orientation estimation
  • Gyrocompass applications utilizing earth rotation detection

Reference Links

SPRESENSE Official

Working Example

https://x.com/GOROman/status/1896200165670912331

Top comments (0)