Example Code for Arduino-Reading Data via UART and Interrupts
This tutorial demonstrates how to configure a 9-axis IMU sensor to trigger a hardware interrupt when data is ready, and read acceleration, angular velocity, and magnetometer data in the interrupt service routine to achieve efficient data acquisition.
Hardware Preparation
- DFR1222 FireBeetle 2 ESP32-C5 ×1
- SEN0694 Gravity: 9 DOF IMU Sensor ×1
Software Preparation
- Download and install Arduino IDE: Download Arduino IDE
- Download and install the DFRobot_Multi_DOF_IMU library: Download DFRobot_Multi_DOF_IMU Library
- Download and install the DFRobot_RTU library: Download DFRobot_RTU Library
- Library Installation Guide: View Installation Guide
Wiring Diagram

Connect the 9-axis IMU sensor to the ESP32-C5 as shown in the diagram. The main connections are as follows:
- Sensor pin “+” → ESP32-C5 3.3V
- Sensor pin “-” → ESP32-C5 GND
- Sensor pin “INT1” → ESP32-C5 GPIO27
- Sensor pin “INT3” → ESP32-C5 GPIO28
- Sensor UART pin “RX” → ESP32-C5 D3 (GPIO26)
- Sensor UART pin “TX” → ESP32-C5 D2 (GPIO8)
- Sensor DIP switch configuration: Set the communication mode to UART, and set the address to 0x4A
Sample Code
#include "DFRobot_Multi_DOF_IMU.h"
const uint8_t ADDR = 0x4A;
DFRobot_Multi_DOF_IMU_UART imu(DFRobot_Multi_DOF_IMU::eSensorModel9DOF, &Serial1, 9600, ADDR, /*rx*/ 8, /*tx*/ 26);
// Interrupt pin definitions
const uint8_t INT1_PIN = 27;
const uint8_t INT3_PIN = 28;
// Interrupt flags
volatile bool int1Flag = false;
volatile bool int3Flag = false;
// Interrupt service routines (must be placed in IRAM)
void IRAM_ATTR int1ISR() { int1Flag = true; }
void IRAM_ATTR int3ISR() { int3Flag = true; }
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println("\n=== ESP32 9DOF IMU UART Example ===\n");
// Initialize sensor
Serial.print("Initializing IMU... ");
while (!imu.begin()) {
Serial.println("FAILED! Check wiring and address.");
delay(1000);
}
Serial.println("OK");
// Configure sensor parameters
Serial.print("Set normal mode... ");
imu.setSensorMode(DFRobot_Multi_DOF_IMU::eNormalMode);
Serial.println("OK");
Serial.print("Set accel range ±2G... ");
imu.setAccelRange(DFRobot_Multi_DOF_IMU::eAccelRange2G);
Serial.println("OK");
Serial.print("Set gyro range ±250dps... ");
imu.setGyroRange(DFRobot_Multi_DOF_IMU::eGyroRange250DPS);
Serial.println("OK");
// Configure interrupts
Serial.print("Config INT1 (data ready)... ");
imu.setInt(DFRobot_Multi_DOF_IMU::eImuIntPin1, DFRobot_Multi_DOF_IMU::eInt1_2DataReady);
Serial.println("OK");
Serial.print("Config INT3 (data ready)... ");
imu.setInt(DFRobot_Multi_DOF_IMU::eImuIntPin3, DFRobot_Multi_DOF_IMU::eInt3DataReady);
Serial.println("OK");
// Attach interrupts
attachInterrupt(digitalPinToInterrupt(INT1_PIN), int1ISR, RISING);
attachInterrupt(digitalPinToInterrupt(INT3_PIN), int3ISR, RISING);
Serial.println("Interrupts attached (rising edge)\n");
Serial.println("Configuration complete. Reading data...\n");
}
void loop() {
if (int1Flag || int3Flag) {
// Read interrupt status
uint16_t int1Status = imu.getIntStatus(DFRobot_Multi_DOF_IMU::eImuIntPin1);
uint16_t int3Status = imu.getIntStatus(DFRobot_Multi_DOF_IMU::eImuIntPin3);
bool int1Ready = (int1Status & INT1_2_INT_STATUS_DRDY) != 0;
bool int3Ready = (int3Status & INT3_INT_STATUS_DRDY) != 0;
// Read data only when both interrupts are ready (ensure all sensor data updated)
if (int1Ready && int3Ready) {
int1Flag = false;
int3Flag = false;
DFRobot_Multi_DOF_IMU::sSensorData_t accel, gyro, mag;
if (imu.get9dofData(&accel, &gyro, &mag)) {
Serial.print("ACCEL(g): ");
Serial.print(accel.x, 3); Serial.print(", ");
Serial.print(accel.y, 3); Serial.print(", ");
Serial.println(accel.z, 3);
Serial.print("GYRO(dps): ");
Serial.print(gyro.x, 2); Serial.print(", ");
Serial.print(gyro.y, 2); Serial.print(", ");
Serial.println(gyro.z, 2);
Serial.print("MAG(uT): ");
Serial.print(mag.x, 2); Serial.print(", ");
Serial.print(mag.y, 2); Serial.print(", ");
Serial.println(mag.z, 2);
Serial.println();
} else {
Serial.println("Failed to read 9DOF data!");
}
} else {
// Clear flags for interrupts that are not ready
if (int1Flag && !int1Ready) int1Flag = false;
if (int3Flag && !int3Ready) int3Flag = false;
}
}
}
Result

Was this article helpful?
