1/***************************************************************
3 * @brief Minimal I2C bring-up for 7Semi ICM-20948 on ESP32/UNO +
4 * continuous gyroscope readout.
7 * - I2C init on default/custom pins
8 * - IMU begin() on I2C (addr 0x68/0x69)
9 * - Safe defaults (applyBasicDefaults)
10 * - Optional sensor gating: gyro only
11 * - Gyro config: DLPF, full-scale, ODR, AVG
12 * - Read gyro (dps) at ~2 Hz print
14 * Wiring (Arduino UNO, I2C)
17 * - VCC -> 3V3 (or 5V if your board supports it)
21 * - SDA -> GPIO21 (default)
22 * - SCL -> GPIO22 (default)
27 * - Default ICM-20948 I2C address is 0x68 (AD0=LOW). If AD0=HIGH, use 0x69.
28 ***************************************************************/
31#include <DevLab_ICM20948.h>
33/* ====================== User Config =======================
34 * - Edit pins/addr if needed
35 * - UNO uses fixed SDA=A4, SCL=A5 (no need to call Wire.begin with pins)
36 * - ESP32 can use default Wire (SDA=21, SCL=22) or custom pins via Wire.begin(sda,scl)
39/* ====================== User Config ======================= */
40/** @brief I2C SDA pin used by the example board. */
42/** @brief I2C SCL pin used by the example board. */
44/** @brief I2C bus speed in hertz. */
45#define I2C_FREQ 400000UL
46/** @brief ICM-20948 I2C address selected by the AD0 pin. */
49/** @brief Global ICM-20948 driver instance. */
53 * @brief Configure the IMU for gyroscope-only operation over I2C.
55 * The function initializes the I2C interface, applies safe defaults, enables
56 * the gyroscope, and configures DLPF, full-scale range, and output data rate.
61 Serial.println(F("ICM-20948 — I2C Basic"));
62 Wire.begin(SDA_PIN, SCL_PIN);
64 if (!imu.beginI2C(ICM_ADDR, Wire, 400000)) {
65 Serial.println(F("ERROR: beginI2C() failed"));
69 /* Apply safe defaults. */
70 if (!imu.applyBasicDefaults()) {
71 Serial.println(F("ERROR: applyBasicDefaults() failed."));
75 Serial.println(F("ICM-20948 ready."));
77 /* Optional: gate sensors
78 * - setSensors(accel_on, gyro_on, temp_on)
79 * - Here: enable only gyro (accel/temp off)
81 if (!imu.setSensors(/*accel*/ false, /*gyro*/ true, /*temp*/ false)) {
82 Serial.println(F("setSensors failed."));
85 /* ----------------- GYRO DLPF Config (reference) ----------------
86 * GyroConfig(DLPFCFG, FS_SEL, FCHOICE, XGYRO, YGYRO, ZGYRO, AVGCFG)
87 * - DLPF : GYRO_DLPFCFG_0..7 (use 3 or 4 for balanced settings)
88 * - FS_SEL : dps250 / dps500 / dps1000 / dps2000
89 * - FCHOICE : false → DLPF path (recommended), true → bypass (very wide BW)
90 * - XGYRO/YGYRO/ZGYRO : per-axis enable (true = enable axis)
91 * - AVGCFG : 0..7 internal averaging (higher = more smoothing, more delay)
92 * FCHOICE=0 (DLPF on):
93 * - GYRO_DLPFCFG_1 : 3dB ≈ 196.6 Hz, NBW ≈ 229.8 Hz
94 * - GYRO_DLPFCFG_2 : 3dB ≈ 151.8 Hz, NBW ≈ 187.6 Hz
95 * - GYRO_DLPFCFG_3 : 3dB ≈ 119.5 Hz, NBW ≈ 154.3 Hz ← good default
96 * - GYRO_DLPFCFG_4 : 3dB ≈ 51.2 Hz, NBW ≈ 73.3 Hz
97 * - GYRO_DLPFCFG_5 : 3dB ≈ 23.9 Hz, NBW ≈ 35.9 Hz
98 * - GYRO_DLPFCFG_6 : 3dB ≈ 5.7 Hz, NBW ≈ 8.3 Hz
99 * - GYRO_DLPFCFG_7 : 3dB ≈ 473 Hz, NBW ≈ 499 Hz
101 * FCHOICE=1 (Bypass) : very wide (use with care; highest noise)
103 if (!imu.GyroConfig(/*DLPFCFG*/ GYRO_DLPFCFG_4,
105 /*FCHOICE*/ true, // DLPF ON (recommended)
106 /*X*/ true, /*Y*/ true, /*Z*/ true,
108 Serial.println(F("GyroConfig failed."));
111 /* Set gyroscope output data rate (ODR)
112 * - Gyro_SMPLRT(rate_hz)
113 * - Base (DLPF path) = 1100 Hz
114 * - Valid range: ~4.3–1100 Hz
117 if (!imu.Gyro_SMPLRT(1000)) {
118 Serial.println(F("Gyro_SMPLRT failed."));
123 * @brief Read and print gyroscope data in degrees per second.
126 float gx, gy, gz; // gyro X/Y/Z in dps
134 if (imu.readGyro(gx, gy, gz)) {
135 Serial.print("GYRO [dps]: ");
140 Serial.println(gz, 3);
142 Serial.println(F("GYRO read failed"));
145 Serial.println(F("-----------------------------"));