

The ICM-20948 is a compact, low-power 9-axis MEMS motion tracking device manufactured by Generic. It integrates a 3-axis accelerometer, a 3-axis gyroscope, and a 3-axis magnetometer into a single package, enabling precise motion and orientation tracking in three-dimensional space. This sensor is widely used in applications such as robotics, smartphones, wearable devices, drones, and gaming controllers.
Its small form factor and low power consumption make it ideal for battery-powered devices, while its high accuracy and versatility ensure reliable performance in dynamic environments.








Below are the key technical details of the ICM-20948:
| Parameter | Value |
|---|---|
| Operating Voltage | 1.71V to 3.6V |
| Accelerometer Range | ±2g, ±4g, ±8g, ±16g |
| Gyroscope Range | ±250°/s, ±500°/s, ±1000°/s, ±2000°/s |
| Magnetometer Range | ±4900 µT |
| Communication Interface | I²C (up to 400 kHz) / SPI (up to 7 MHz) |
| Power Consumption | 2.5 mA (typical, full operation) |
| Operating Temperature Range | -40°C to +85°C |
| Package Size | 3 mm x 3 mm x 1 mm |
The ICM-20948 has 14 pins. Below is the pin configuration and description:
| Pin Number | Pin Name | Description |
|---|---|---|
| 1 | VDD | Power supply input (1.71V to 3.6V). |
| 2 | VDDIO | I/O voltage supply (1.71V to 3.6V). |
| 3 | GND | Ground connection. |
| 4 | SCL/SCLK | I²C clock line / SPI clock line. |
| 5 | SDA/SDI | I²C data line / SPI data input. |
| 6 | SDO/ADO | SPI data output / I²C address selection. |
| 7 | INT | Interrupt output pin. |
| 8 | FSYNC | Frame synchronization input. |
| 9 | AUX_CL | Auxiliary I²C clock line for external sensors. |
| 10 | AUX_DA | Auxiliary I²C data line for external sensors. |
| 11 | RESV | Reserved. Leave unconnected. |
| 12 | RESV | Reserved. Leave unconnected. |
| 13 | RESV | Reserved. Leave unconnected. |
| 14 | RESV | Reserved. Leave unconnected. |
Below is an example of how to interface the ICM-20948 with an Arduino UNO using the I²C protocol:
#include <Wire.h>
// ICM-20948 I2C address (default is 0x68 when ADO is low)
#define ICM20948_ADDR 0x68
// Register addresses
#define WHO_AM_I 0x00
#define PWR_MGMT_1 0x06
#define ACCEL_XOUT_H 0x2D
void setup() {
Wire.begin(); // Initialize I2C communication
Serial.begin(9600); // Initialize serial communication for debugging
// Wake up the ICM-20948
Wire.beginTransmission(ICM20948_ADDR);
Wire.write(PWR_MGMT_1); // Power management register
Wire.write(0x01); // Set clock source
Wire.endTransmission();
// Verify communication by reading the WHO_AM_I register
Wire.beginTransmission(ICM20948_ADDR);
Wire.write(WHO_AM_I);
Wire.endTransmission();
Wire.requestFrom(ICM20948_ADDR, 1);
if (Wire.available()) {
byte whoAmI = Wire.read();
Serial.print("WHO_AM_I: 0x");
Serial.println(whoAmI, HEX);
} else {
Serial.println("Failed to communicate with ICM-20948.");
}
}
void loop() {
// Read accelerometer data
Wire.beginTransmission(ICM20948_ADDR);
Wire.write(ACCEL_XOUT_H); // Start with the high byte of X-axis acceleration
Wire.endTransmission();
Wire.requestFrom(ICM20948_ADDR, 6); // Request 6 bytes (X, Y, Z axes)
if (Wire.available() == 6) {
int16_t accelX = (Wire.read() << 8) | Wire.read();
int16_t accelY = (Wire.read() << 8) | Wire.read();
int16_t accelZ = (Wire.read() << 8) | Wire.read();
Serial.print("Accel X: ");
Serial.print(accelX);
Serial.print(" | Accel Y: ");
Serial.print(accelY);
Serial.print(" | Accel Z: ");
Serial.println(accelZ);
}
delay(500); // Delay for readability
}
No Communication with the Sensor:
Incorrect or No Data:
High Noise in Readings:
Q: Can the ICM-20948 operate in SPI mode?
A: Yes, the ICM-20948 supports both I²C and SPI communication protocols. Configure the pins accordingly.
Q: How do I calibrate the magnetometer?
A: Perform a figure-eight motion with the sensor to collect data for hard and soft iron calibration. Use software libraries to process the data.
Q: What is the maximum sampling rate?
A: The ICM-20948 supports a maximum sampling rate of 1 kHz for the accelerometer and gyroscope.
Q: Can I use this sensor with a 5V microcontroller?
A: Yes, but you must use a level shifter or ensure the I/O voltage (VDDIO) matches the microcontroller's logic level.