An MPU6050 and a XIAO ESP32S3 together are small enough for a wearable, a bicycle alarm or a fall detector. Wire the GY-521 to 3V3, GND, D4 (SDA) and D5 (SCL).
The sketch watches the total acceleration and lights the XIAO’s orange LED when it jumps away from 1 g.
Wiring
| XIAO ESP32S3 | MPU6050 (GY-521) | Wire | Notes |
|---|---|---|---|
| 3V3 | VCC | red | |
| GND | GND | black | |
| D5 | SCL | yellow | |
| D4 | SDA | blue |
3.3–5 V (on-board 3.3 V regulator) part, 3.3 V board. The GY-521 has a 3.3 V regulator and pulls SDA/SCL up to 3.3 V, so it works on both 3.3 V boards and a 5 V Uno without a level shifter.
Board quirks
- The orange user LED is on GPIO21 (
LED_BUILTIN) and is active-LOW:LOW= on. - On the Sense board GPIO21 is also the SD-card chip select. If you use the SD slot, drive a different LED.
- D4/D5 are the default I2C pins; the GY-521 has its own pull-ups and regulator, so 3V3 and four wires are all it needs.
- Shake detection compares total acceleration with 1 g (9.81 m/s²). Tune the 6.0 threshold for your mounting.
Code
// MPU6050 (GY-521) on a Seeed XIAO ESP32S3 — a simple tilt/shake detector.
// VCC → 3V3, GND → GND, SDA → D4 (GPIO5), SCL → D5 (GPIO6). AD0 open = 0x68.
// The orange user LED (GPIO21, active-LOW) lights on a shake.
#include <Wire.h>
#include <Adafruit_MPU6050.h>
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
uint32_t t0 = millis();
while (!Serial && millis() - t0 < 3000) {}
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // off
Wire.begin();
if (!mpu.begin(0x68, &Wire)) {
Serial.println("MPU6050 not found at 0x68 - check wiring (AD0 high = 0x69)");
while (true) delay(1000);
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setFilterBandwidth(MPU6050_BAND_44_HZ);
Serial.println("MPU6050 ready - shake it");
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float total = sqrtf(a.acceleration.x * a.acceleration.x + a.acceleration.y * a.acceleration.y +
a.acceleration.z * a.acceleration.z);
bool shake = fabsf(total - 9.81f) > 6.0f; // more than ~0.6 g away from still
digitalWrite(LED_BUILTIN, shake ? LOW : HIGH);
Serial.printf("|a| %.2f m/s2 X %.2f Y %.2f Z %.2f%s\n", total, a.acceleration.x, a.acceleration.y,
a.acceleration.z, shake ? " SHAKE!" : "");
delay(100);
}// MPU6050 (GY-521) on a Seeed XIAO ESP32S3 — a simple tilt/shake detector.
// VCC → 3V3, GND → GND, SDA → D4 (GPIO5), SCL → D5 (GPIO6). AD0 open = 0x68.
// The orange user LED (GPIO21, active-LOW) lights on a shake.
#include <Wire.h>
#include <Adafruit_MPU6050.h>
Adafruit_MPU6050 mpu;
void setup() {
Serial.begin(115200);
uint32_t t0 = millis();
while (!Serial && millis() - t0 < 3000) {}
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // off
Wire.begin();
if (!mpu.begin(0x68, &Wire)) {
Serial.println("MPU6050 not found at 0x68 - check wiring (AD0 high = 0x69)");
while (true) delay(1000);
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setFilterBandwidth(MPU6050_BAND_44_HZ);
Serial.println("MPU6050 ready - shake it");
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float total = sqrtf(a.acceleration.x * a.acceleration.x + a.acceleration.y * a.acceleration.y +
a.acceleration.z * a.acceleration.z);
bool shake = fabsf(total - 9.81f) > 6.0f; // more than ~0.6 g away from still
digitalWrite(LED_BUILTIN, shake ? LOW : HIGH);
Serial.printf("|a| %.2f m/s2 X %.2f Y %.2f Z %.2f%s\n", total, a.acceleration.x, a.acceleration.y,
a.acceleration.z, shake ? " SHAKE!" : "");
delay(100);
}Library: Adafruit MPU6050 (Adafruit (also install Adafruit Unified Sensor and Adafruit BusIO)) — compiled with Adafruit MPU6050 2.2.9.
Expected serial output
MPU6050 ready - shake it
|a| 9.79 m/s2 X 0.12 Y -0.20 Z 9.78
|a| 17.42 m/s2 X 9.63 Y 3.02 Z 14.11 SHAKE!MPU6050 ready - shake it |a| 9.79 m/s2 X 0.12 Y -0.20 Z 9.78 |a| 17.42 m/s2 X 9.63 Y 3.02 Z 14.11 SHAKE!
Common errors
“MPU6050 not found at 0x68”
Check D4/D5 and AD0. Full fix.
LED never lights
Remember it is active-LOW, and on the Sense board check nothing else uses GPIO21.