Example Code for Arduino-Reading Data via UART and Interrupts

This tutorial demonstrates how to configure a 9 DOF 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

Software Preparation

Wiring Diagram

SEN0694-UART Wiring Diagram

Connect the 9 DOF 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(A0=0,A1=0)

Sample Code

#include "DFRobot_Multi_DOF_IMU.h"

// Only keep UART communication mode
#define IMU_COMM_UART
const uint8_t ADDR = 0x4A;

// ESP32-C5 UART1 mapping: RX = GPIO8(D2), TX = GPIO26(D3)
DFRobot_Multi_DOF_IMU_UART imu(DFRobot_Multi_DOF_IMU::eSensorModel9DOF, &Serial1, 9600, ADDR, /*rx=*/8, /*tx=*/26);

volatile bool int1DataReady = false;
volatile bool int3DataReady = false;

// Data ready interrupt service routine for INT1
void IRAM_ATTR int1ISR() {
  int1DataReady = true;
}

// Data ready interrupt service routine for INT3
void IRAM_ATTR int3ISR() {
  int3DataReady = true;
}

void setup() {
  // Initialize serial monitor (baud rate: 115200)
  Serial.begin(115200);
  while (!Serial) delay(10);

  // Initialize sensor
  while (!imu.begin()) {
    delay(1000);
  }

  // Set sensor to normal mode
  imu.setSensorMode(DFRobot_Multi_DOF_IMU::eNormalMode);
  delay(100);

  // Set accelerometer range to ±2G
  Serial.print("Set accel range ±2G... ");
  while (!imu.setAccelRange(DFRobot_Multi_DOF_IMU::eAccelRange2G)) {
    delay(1000);
  }
  Serial.println("OK");

  // Set gyroscope range to ±250dps
  Serial.print("Set gyro range ±250dps... ");
  while (!imu.setGyroRange(DFRobot_Multi_DOF_IMU::eGyroRange250DPS)) {
    delay(1000);
  }
  Serial.println("OK");

  // Configure INT1 data ready interrupt
  Serial.print("Config INT1 (data ready)... ");
  while (!imu.setInt(DFRobot_Multi_DOF_IMU::eImuIntPin1, DFRobot_Multi_DOF_IMU::eInt1_2DataReady)) {
    delay(1000);
  }
  Serial.println("OK");

  // Configure INT3 data ready interrupt
  Serial.print("Config INT3 (data ready)... ");
  while (!imu.setInt(DFRobot_Multi_DOF_IMU::eImuIntPin3, DFRobot_Multi_DOF_IMU::eInt3DataReady)) {
    delay(1000);
  }
  Serial.println("OK");

  // Attach interrupts for INT1 (GPIO27) and INT3 (GPIO28), rising edge trigger
  attachInterrupt(digitalPinToInterrupt(27), int1ISR, RISING);
  attachInterrupt(digitalPinToInterrupt(28), int3ISR, RISING);
  Serial.println("Interrupts attached (rising edge)");

  // Configuration complete prompt
  Serial.println("\nConfiguration complete. Reading data...");
}

void loop() {
  if (int1DataReady || int3DataReady) {
    if (int1DataReady && int3DataReady) {
      int1DataReady = false;
      int3DataReady = false;

      DFRobot_Multi_DOF_IMU::sSensorData_t accel, gyro, mag;
      if (imu.get9dofData(&accel, &gyro, &mag)) {
        // Print format strictly matches the image
        Serial.print("\nACCEL(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);
      }
    } else {
      // Clear incomplete interrupt flags to avoid deadlock
      if (int1DataReady) int1DataReady = false;
      if (int3DataReady) int3DataReady = false;
    }
  }
  delay(200);
}

Result

SEN0694-UART Result

Was this article helpful?

TOP