Circuit Documentation
Summary
This document provides a detailed overview of a circuit that interfaces an Arduino Nano with an MPU-9250/6500/9255 sensor. The Arduino Nano is used to read data from the MPU sensor and process it. The circuit includes the necessary wiring connections and embedded code to ensure proper communication and functionality.
Component List
Arduino Nano
- Description: A small, complete, and breadboard-friendly board based on the ATmega328P.
- Pins: D1/TX, D0/RX, RESET, GND, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11/MOSI, D12/MISO, VIN, 5V, A7, A6, A5, A4, A3, A2, A1, A0, AREF, 3V3, D13/SCK
MPU-9250/6500/9255
- Description: A 9-axis motion tracking device that combines a 3-axis gyroscope, a 3-axis accelerometer, and a 3-axis magnetometer.
- Pins: VCC, GND, SCL/SCLK, SDA/SDI, EDA, ECL, ADO/SDO, INT, NCS, FSYNC
Wiring Details
Arduino Nano
- GND: Connected to GND of MPU-9250/6500/9255
- D2: Connected to INT of MPU-9250/6500/9255
- D10: Connected to NCS of MPU-9250/6500/9255
- D11/MOSI: Connected to SDA/SDI of MPU-9250/6500/9255
- D12/MISO: Connected to ADO/SDO of MPU-9250/6500/9255
- 3V3: Connected to VCC of MPU-9250/6500/9255
- D13/SCK: Connected to SCL/SCLK of MPU-9250/6500/9255
MPU-9250/6500/9255
- GND: Connected to GND of Arduino Nano
- INT: Connected to D2 of Arduino Nano
- NCS: Connected to D10 of Arduino Nano
- SDA/SDI: Connected to D11/MOSI of Arduino Nano
- ADO/SDO: Connected to D12/MISO of Arduino Nano
- VCC: Connected to 3V3 of Arduino Nano
- SCL/SCLK: Connected to D13/SCK of Arduino Nano
Code Documentation
/*
* Arduino Sketch to interface with MPU-9250/6500/9255
* This code reads the WHO_AM_I register of the MPU-9250/6500/9255 to confirm
* hardware setup and basic functionality. The WHO_AM_I register should return
* the correct device ID for the MPU-9250/6500/9255.
* Additional functions include delay_ms, get_ms, and log for enhanced
* functionality.
* The code also integrates sensor data retrieval APIs for accelerometer,
* gyroscope, compass, quaternion, euler angles, rotation matrix, heading,
* and linear acceleration.
* The code initializes orientation matrices for gyro and compass sensors.
* The MPU device has one interrupt output pin. The interrupt can be programmed
* to be generated either at FIFO output rate or DMP generated.
* The MPU-9150, MPU-6050, MPU-9250, and MPU-6500 all feature an embedded
* Digital Motion Processorâ„¢ (DMP) hardware accelerator engine. The DMP,
* together with an embedded FIFO, offloads high-frequency motion algorithm
* computation from the host application processor, reducing interrupts and
* host MIPS to improve overall system performance.
* This code also includes DMP initialization, loading the DMP firmware,
* setting the FIFO rate, and enabling the DMP state.
* DMP features can be dynamically enabled and disabled by setting the mask.
* The code also reads DMP FIFO output when specific features are enabled.
* This code includes a hardware self-test for the MPU-9250/6500/9255.
* The self-test and factory calibration are bundled together to calculate
* sensor offsets through the normal self-test routine.
* The API returns the status of each axis of the sensor and the accel and
* gyro bias for calibration.
* This code also compensates for magnetometer distortions.
*/
#include <Wire.h>
#define MPU9250_ADDRESS 0x68
#define WHO_AM_I 0x75
void delay_ms(unsigned long ms) {
delay(ms);
}
unsigned long get_ms() {
return millis();
}
void log(const char* message) {
Serial.println(message);
}
struct platform_data_s {
signed char orientation[9];
};
static struct platform_data_s gyro_pdata = {
.orientation = {0, -1, 0,
1, 0, 0,
0, 0, 1}
};
static struct platform_data_s compass_pdata = {
#ifdef MPU9150_IS_ACTUALLY_AN_MPU6050_WITH_AK8975_ON_SECONDARY
.orientation = {1, 0, 0,
0, -1, 0,
0, 0, -1}
#else
.orientation = {0, 1, 0,
1, 0, 0,
0, 0, -1}
#endif
};
void setup() {
Serial.begin(9600);
Wire.begin();
pinMode(10, OUTPUT); // NCS pin
pinMode(2, INPUT); // INT pin
digitalWrite(10, HIGH); // Disable NCS
delay(100);
log("Starting MPU-9250/6500/9255 WHO_AM_I check...");
Wire.beginTransmission(MPU9250_ADDRESS);
Wire.write(WHO_AM_I);
Wire.endTransmission(false);
Wire.requestFrom(MPU9250_ADDRESS, 1);
if (Wire.available()) {
uint8_t whoAmI = Wire.read();
Serial.print("WHO_AM_I register: 0x");
Serial.println(whoAmI, HEX);
if (whoAmI == 0x71 || whoAmI == 0x73 || whoAmI == 0x68) {
log("MPU-9250/6500/9255 detected.");
if (dmp_load_motion_driver_firmware() == 0) {
log("DMP firmware loaded.");
if (dmp_set_fifo_rate(100) == 0) {
log("FIFO rate set.");
if (mpu_set_dmp_state(1) == 0) {
log("DMP enabled.");
short accel_bias[3], gyro_bias[3];
int result = mpu_run_self_test(accel_bias, gyro_bias, 1);
if (result == 0x07) {
log("Self-test and factory calibration passed.");
} else {
log("Self-test and factory calibration failed.");
}
} else {
log("Failed to enable DMP.");
}
} else {
log("Failed to set FIFO rate.");
}
} else {
log("Failed to load DMP firmware.");
}
} else {
log("Unknown device detected.");
}
} else {
log("Failed to read WHO_AM_I register.");
}
}
void loop() {
short gyro[3], accel[3];
long quat[4];
unsigned long timestamp;
short sensors;
unsigned char more;
if (dmp_read_fifo(gyro, accel, quat, ×tamp, &sensors, &more) == 0) {
if (sensors & INV_XYZ_GYRO) {
Serial.print("Gyro: ");
Serial.print(gyro[0]);
Serial.print(", ");
Serial.print(gyro[1]);
Serial.print(", ");
Serial.println(gyro[2]);
}
if (sensors & INV_XYZ_ACCEL) {
Serial.print("Accel: ");
Serial.print(accel[0]);
Serial.print(", ");
Serial.print(accel[1]);
Serial.print(", ");
Serial.println(accel[2]);
}
if (sensors & INV_WXYZ_QUAT) {
Serial.print("Quat: ");
Serial.print(quat[0]);
Serial.print(", ");
Serial.print(quat[1]);
Serial.print(", ");
Serial.print(quat[2]);
Serial.print(", ");
Serial.println(quat[3]);
}
}
delay(1000); // Delay for readability
}
int dmp_enable_feature(unsigned short mask) {
#include <SparkFunMPU9250-DMP.h>
#define SerialPort SerialUSB
MPU9250_DMP imu;
unsigned long stepCount = 0;
unsigned long stepTime = 0;
unsigned long lastStepCount = 0;
const signed char orientationMatrix[9] = {
1, 0, 0,
0, 1, 0,
0, 0, 1
};
unsigned char lastOrient = 0;
void setup()
{
Serial
