MEMS 3-Axis Accelerometer (ADXL345 / MPU6050)
Complete engineering manual covering physical operating principles, pinout architecture, circuit schematics, non-blocking Arduino/ESP32 code, and troubleshooting.

What is a 3-Axis MEMS Accelerometer?
A 3-axis MEMS accelerometer measures proper acceleration—the rate of change of velocity experienced by a body relative to free fall. It senses both static acceleration forces (such as the continuous 1g downward pull of Earth's gravity) and dynamic acceleration forces (such as impact, shake, vibration, or rapid robotics movement).
Built with microscopic polysilicon surface-micromachined structures, MEMS chips like the ADXL345 and MPU6050 translate physical mechanical deflection into differential capacitance, which is digitized via onboard high-resolution ADCs and transmitted over I2C or SPI serial buses to microcontrollers.
Key Technical Specifications
Triple-Axis Sensing (X, Y, Z)
Full 3D spatial acceleration vector measurement across orthogonal axes.
Selectable ±2g to ±16g Range
Configurable dynamic sensitivity for subtle tilt sensing or aggressive drone impact analysis.
Standard I2C & SPI Interface
Easy two-wire (SDA/SCL) bus connectivity with address selection pin.
High-Resolution 13-bit ADC
Maintains 4 mg/LSB scale factor across all g-ranges for precision angle estimation.
Configurable Output Data Rate
Sampling rates selectable from 0.1 Hz up to 3200 Hz for vibration harmonics.
Ultra-Low Power Mode
Consumes as little as 23 µA in measurement mode and 0.1 µA in standby sleep.
Components Required
| Component | Quantity | Engineering Purpose |
|---|---|---|
| MEMS 3-Axis Module | 1x | Primary physical environmental sensing module |
| Arduino Uno R3 or ESP32 DevKit | 1x | Microcontroller for ADC sampling and digital processing |
| Solderless Breadboard (830 tie-points) | 1x | Prototyping circuit layout and common power rail distribution |
| Jumper Wires (Male-to-Male, Male-to-Female) | 6x | Interconnecting microcontroller GPIO, power, and ground |
| Decoupling Capacitor (100nF Ceramic) | 1x | Filtering power rail high-frequency switching transient noise |
| Pull-up / Current Limiting Resistor (10kΩ / 220Ω) | 1x | Level conditioning and bus stability |
Pin Configuration & Connection Diagram
VCC
3.3V DC power rail (or 5V if using a module with onboard 3.3V LDO regulator).
GND
Common reference ground connection.
SCL
I2C Serial Clock line. Synchronizes data transfer pulses from MCU master.
SDA
I2C Serial Data bidirectional line for register read and write operations.
| Sensor Pin | Arduino Uno | ESP32 Node | Signal Description |
|---|---|---|---|
| VCC | 3.3V (or 5V for regulated module) | 3.3V | Primary power supply line. Ensure voltage matches module specifications. |
| GND | GND | GND | Common electrical ground return. |
| SCL | A5 (or dedicated SCL pin) | GPIO 22 | I2C Clock line. Requires 4.7kΩ pull-up to 3.3V if not present on breakout. |
| SDA | A4 (or dedicated SDA pin) | GPIO 21 | I2C Data line. Connect directly to hardware I2C peripheral. |
Electrical Best Practices & Noise Mitigation:
- When wiring the MEMS 3-Axis, ensure power leads are kept short to minimize stray loop inductance and inductive bounce during rapid current draw changes.
- If using an analog sensor output with a 3.3V microcontroller like an ESP32 or STM32, verify the maximum sensor output does not exceed 3.3V. If operating from a 5V supply, insert a 2:1 resistive voltage divider (e.g. 2kΩ / 1kΩ) on the signal line.
- Place a 100nF ceramic capacitor across the sensor VCC and GND pins as close to the module package as physically possible to shunt high-frequency ripple generated by nearby motors, servos, or Wi-Fi transients.
Working Principle & Mathematical Modeling
MEMS Capacitive Transduction & Tilt Mathematics
Inside the chip, a microscopic proof mass is suspended by polysilicon springs between fixed capacitive plates. When subjected to acceleration or gravity, inertia displaces the proof mass, altering the differential capacitance between the moving fingers and fixed plates. An internal phase-locked demodulator measures this delta-C and converts it into voltage.
When stationary on a flat table, the sensor measures +1g (approx. 9.81 m/s²) along the Z-axis and 0g on the X and Y axes. By computing trigonometry angles on the static gravity vector, the exact Pitch (tilt forward/back) and Roll (tilt side-to-side) angles can be derived without needing a gyroscope.
Tilt Angle Calculation Equations (Static Condition):
Pitch Angle θ = atan2(Ax, sqrt(Ay² + Az²)) × (180 / π)
Roll Angle ψ = atan2(Ay, sqrt(Ax² + Az²)) × (180 / π)
Resultant Total Acceleration = sqrt(Ax² + Ay² + Az²)
Gravitational Calibration Factor: 1g ≈ 9.80665 m/s²
Note: In dynamic robotics, sudden linear acceleration pollutes gravity tilt angles. Fuse the accelerometer with a gyroscope via a Kalman filter or Complementary filter for accurate orientation.
Arduino & ESP32 Implementation Code
// Production-Grade I2C Accelerometer Reader (ADXL345 / MPU6050)
// Platform: Arduino / ESP32 (volt-X Lab Implementation)
#include <Wire.h>
const int MPU_ADDR = 0x68; // I2C address of MPU6050
int16_t rawAx, rawAy, rawAz;
void setup() {
Serial.begin(115200);
Wire.begin();
// Wake up MPU6050 (clear SLEEP bit in PWR_MGMT_1 register 0x6B)
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B);
Wire.write(0x00);
Wire.endTransmission(true);
Serial.println(F("MEMS Accelerometer Initialized via I2C (400kHz)"));
}
void loop() {
// Request 6 bytes starting from register 0x3B (ACCEL_XOUT_H)
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 6, true);
if (Wire.available() >= 6) {
rawAx = (Wire.read() << 8) | Wire.read();
rawAy = (Wire.read() << 8) | Wire.read();
rawAz = (Wire.read() << 8) | Wire.read();
// Scale factor for ±2g range: 16384 LSB/g
float ax = rawAx / 16384.0f;
float ay = rawAy / 16384.0f;
float az = rawAz / 16384.0f;
// Calculate pitch and roll in degrees
float pitch = atan2(ax, sqrt(ay * ay + az * az)) * 180.0f / PI;
float roll = atan2(ay, sqrt(ax * ax + az * az)) * 180.0f / PI;
Serial.print(F("Ax: ")); Serial.print(ax, 2); Serial.print(F("g | "));
Serial.print(F("Ay: ")); Serial.print(ay, 2); Serial.print(F("g | "));
Serial.print(F("Az: ")); Serial.print(az, 2); Serial.print(F("g | "));
Serial.print(F("Pitch: ")); Serial.print(pitch, 1); Serial.print(F("° | "));
Serial.print(F("Roll: ")); Serial.print(roll, 1); Serial.println(F("°"));
}
delay(100);
}Code Architecture Breakdown:
- Direct Register Addressing: Communicates directly over the I2C bus with register 0x6B to wake the power management state machine.
- Atomic 6-Byte Burst Read: Reads X, Y, and Z acceleration registers in a single transaction, preventing skew between separate axis measurements.
- 16-Bit Signed Integer Stitching: Merges high and low bytes `(Wire.read() << 8) | Wire.read()` to reconstruct true two's complement binary readings.
- Trigonometric Pitch and Roll: Uses atan2() for full four-quadrant angle resolution without division-by-zero singularities.
Real-World Engineering Applications
Quadcopter & Drone Flight Stabilization
Measures tilt angle relative to the gravity horizon to maintain level hovering flight.
Industrial Machine Vibration Monitoring
Detects bearing wear, imbalance, and mechanical resonance in rotating motors and gearboxes.
Automotive Crash Detection & Airbag Deployment
Triggers emergency vehicle braking and safety restraints when deceleration exceeds 5g.
Wearable Step Counting & Activity Trackers
Applies peak detection algorithms to periodic walking and running acceleration waveforms.
✅ Engineering Advantages
- Provides absolute drift-free gravity reference vector when stationary.
- Microscopic semiconductor footprint fits into the smallest wearable and IoT form factors.
- Extremely low current consumption allows continuous battery operation for years.
⚠️ Physical Constraints & Limitations
- Sensitive to external mechanical vibrations and motor noise that corrupt tilt angles.
- Cannot measure yaw (rotation around the vertical gravity axis) without a magnetometer.
- Double integration of acceleration to find position suffers from quadratic drift error.
Diagnostic & Troubleshooting Guide
| Fault / Symptom | Probable Root Cause | Corrective Action |
|---|---|---|
| I2C scanner fails to detect device address (0x68 / 0x53) | Loose SDA/SCL lines, incorrect pull-up resistors, or AD0 pin floating. | Tie the AD0 pin to GND for address 0x68 (or VCC for 0x69) and verify 4.7kΩ pull-ups on SDA/SCL. |
| Z-axis does not read 1.0g when resting flat on table | Zero-g bias offset error present from factory manufacturing stress. | Perform a simple offset calibration: subtract the resting deviation in software. |
| Readings freeze after a few seconds of motor operation | Electromagnetic interference (EMI) from motors causing I2C bus lockup. | Keep I2C wires under 15 cm, use shielded twisted pair, and add 100nF decoupling capacitors. |
Frequently Asked Questions (EE/ECE Reference)
Q: What is the fundamental difference between an accelerometer and a gyroscope?
An accelerometer measures linear acceleration (rate of change of velocity) and detects Earth's static gravity vector (1g). A gyroscope measures angular velocity (rate of rotation in degrees per second). Accelerometers provide an absolute drift-free tilt reference when still, while gyroscopes provide smooth fast tracking during motion but drift over time.
Q: How do you calculate tilt angles (pitch and roll) from accelerometer readings?
When a 3-axis accelerometer is stationary, the total measured acceleration vector equals 1g pointing downward toward Earth's center. By taking the arctangent of the orthogonal components (atan2(Ax, sqrt(Ay² + Az²))), you can derive pitch and roll angles in degrees without needing any external references.
Q: Why does an accelerometer alone struggle to measure orientation on a moving robot?
During robot acceleration, braking, or turning, dynamic forces add to Earth's gravity vector. The accelerometer cannot distinguish between gravity and linear acceleration, causing calculated tilt angles to falsely tilt. This is solved by using a sensor fusion algorithm (such as a Kalman or Complementary filter) with a gyroscope.
Q: Can you calculate distance or position by double-integrating accelerometer data?
In theory yes (velocity = ∫a dt, position = ∫v dt), but in low-cost MEMS sensors it is practically impossible for more than a few seconds. Minor offset noise and sensor bias accumulate quadratically over time (Error ∝ t²), causing calculated position to drift by meters within seconds.