Cảm biến

MPU6050 - cảm biến gia tốc và con quay hồi chuyển cho robot ESP32

7 phút đọc05/07/2026HocLapTrinhRobot
MPU6050 - cảm biến gia tốc và con quay hồi chuyển cho robot ESP32

MPU6050 gồm gia tốc kế và gyro 3 trục giao tiếp I2C - cho robot biết độ nghiêng và tốc độ quay. Nguyên lý, đấu nối ESP32, code đo góc và lọc bù. Trong bài viết này, chúng ta sẽ cùng tìm hiểu chi tiết và ứng dụng thực tế trong robot.

MPU6050 là gì?

MPU6050 là module IMU (Inertial Measurement Unit - đơn vị đo quán tính) 6 bậc tự do, tích hợp gia tốc kế 3 trụccon quay hồi chuyển (gyroscope) 3 trục trên một chip, giao tiếp qua I2C. Với giá chỉ 25.000-40.000 đ, nó là cánh cửa rẻ nhất để robot "cảm nhận được chính mình": đang nghiêng bao nhiêu độ, đang quay nhanh hay chậm, vừa bị va chạm hay đang rơi tự do.

Ứng dụng tiêu biểu: robot tự cân bằng hai bánh, đo góc rẽ chính xác cho xe robot, phát hiện robot bị lật, con trỏ không gian và game điều khiển bằng cử động.

Gia tốc kế và gyro đo gì? Hiểu đúng bản chất

Gia tốc kế (accelerometer)

Đo gia tốc theo 3 trục X, Y, Z với đơn vị g (9.8 m/s²). Khi module nằm yên, nó vẫn đo được gia tốc trọng trường hướng xuống — nhờ đó tính được góc nghiêng tĩnh: nằm ngang thì trục Z đọc 1g, nghiêng đi thì thành phần trọng lực phân bố lại giữa các trục.

Điểm yếu: khi robot rung hoặc tăng tốc, gia tốc chuyển động trộn lẫn với trọng lực khiến góc tính ra nhảy loạn.

Con quay hồi chuyển (gyroscope)

Đo tốc độ quay quanh 3 trục, đơn vị độ/giây. Tích phân tốc độ quay theo thời gian ra góc đã quay — mượt và nhanh, không sợ rung.

Điểm yếu: sai số nhỏ cộng dồn theo thời gian gây trôi (drift) — để yên 5 phút, góc tích phân có thể lệch vài độ đến vài chục độ.

Kết hợp cả hai - lọc bù

Gia tốc kế đúng về lâu dài nhưng nhiễu ngắn hạn; gyro mượt ngắn hạn nhưng trôi dài hạn. Bộ lọc bù (complementary filter) lấy ưu điểm của cả hai bằng một dòng code — xem phần code bên dưới. Đây là bài học xử lý tín hiệu giá trị nhất mà MPU6050 mang lại cho học sinh.

Thông số kỹ thuật

Thông sốGiá trịGhi chú
Giao tiếpI2C, địa chỉ 0x68 (0x69 nếu AD0 nối VCC)2 module trên cùng bus được
Dải gia tốc±2/±4/±8/±16 g chọn được±2g nhạy nhất, hợp đo góc
Dải gyro±250/±500/±1000/±2000 độ/s±250 hợp robot cân bằng
Điện áp3.3-5V (module có ổn áp)Logic I2C 3.3V hợp ESP32
Dòng tiêu thụ~4 mAKhông đáng kể
Tính năng ẩnDMP (bộ xử lý chuyển động), cảm biến nhiệtDMP tính sẵn góc quaternion
Giá module25.000 - 40.000 đGY-521 là tên module phổ biến

Đấu nối với ESP32

I2C chỉ cần 4 dây:

MPU6050ESP32Ghi chú
VCC3V3Module GY-521 có ổn áp, 5V cũng được nhưng 3V3 an toàn nhất
GNDGND
SDAGPIO 21SDA mặc định
SCLGPIO 22SCL mặc định
AD0(bỏ trống = 0x68)Nối 3V3 thành 0x69 khi dùng 2 module

Gắn module chắc chắn vào khung robot (vít hoặc băng dính 2 mặt dày) — module lỏng lẻo rung tự do làm dữ liệu vô nghĩa. Hướng đặt module quyết định trục nào là "nghiêng trước sau" của robot; in trên mạch có mũi tên X, Y để đối chiếu.

Code mẫu - đọc góc nghiêng với lọc bù

Cài thư viện "Adafruit MPU6050" (kèm Adafruit Unified Sensor) từ Library Manager.

cpp
#include <Adafruit_MPU6050.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;
float angle = 0;          // góc nghiêng quanh trục X (độ)
unsigned long lastTime = 0;

void setup() {
  Serial.begin(115200);
  if (!mpu.begin()) {
    Serial.println("Khong tim thay MPU6050! Kiem tra day I2C.");
    while (true) delay(100);
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
  mpu.setGyroRange(MPU6050_RANGE_250_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_44_HZ);
  lastTime = millis();
}

void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  float dt = (millis() - lastTime) / 1000.0;
  lastTime = millis();

  // Góc từ gia tốc kế (đúng khi đứng yên, nhiễu khi rung)
  float accAngle = atan2(a.acceleration.y, a.acceleration.z) * 180 / PI;

  // Tốc độ quay từ gyro (độ/giây)
  float gyroRate = g.gyro.x * 180 / PI;

  // Lọc bù: 98% tin gyro tích phân, 2% kéo về gia tốc kế
  angle = 0.98 * (angle + gyroRate * dt) + 0.02 * accAngle;

  Serial.print("Goc nghieng: ");
  Serial.println(angle);
  delay(10);  // ~100 lần đọc mỗi giây
}

Chạy thử: nghiêng module từ từ — góc thay đổi mượt; gõ nhẹ vào bàn — góc chỉ nhiễu thoáng qua rồi ổn định lại. Đổi hệ số 0.98 thành 1.0 (chỉ tin gyro) rồi để yên vài phút để tận mắt thấy hiện tượng trôi — thí nghiệm đáng giá cho học sinh.

Hiệu chuẩn - bước bắt buộc cho dữ liệu tốt

Mỗi con MPU6050 xuất xưởng có độ lệch không (offset) riêng: để yên hoàn toàn nhưng gyro vẫn báo quay 1-3 độ/giây. Hiệu chuẩn đơn giản lúc khởi động:

  1. Đặt robot đứng yên tuyệt đối 2 giây sau khi bật nguồn
  2. Đọc 200 mẫu gyro, tính trung bình từng trục — đó là offset
  3. Trừ offset khỏi mọi lần đọc sau

Không hiệu chuẩn, góc tích phân trôi ngay từ giây đầu tiên và robot cân bằng không thể đứng được.

Ứng dụng theo cấp độ

  • Cơ bản: phát hiện robot bị lật (trục Z đổi dấu) để tự tắt động cơ — tính năng an toàn dễ làm
  • Trung bình: rẽ đúng 90 độ — tích phân gyro trục Z trong lúc quay, dừng khi đủ góc; chính xác hơn hàng chục lần so với rẽ theo thời gian delay
  • Nâng cao: robot hai bánh tự cân bằng — đọc góc 100+ lần/giây, PID điều khiển động cơ giữ góc bằng 0; dự án đỉnh cao của chương trình robot phổ thông
  • Chuyên sâu: dùng DMP đọc quaternion cho góc 3D không bị khóa gimbal, kết hợp la bàn HMC5883L thành IMU 9 trục

Câu hỏi thường gặp

Vì sao code báo "Khong tim thay MPU6050"?

Kiểm tra: dây SDA/SCL có đổi chỗ không (21-SDA, 22-SCL); nguồn VCC-GND chắc chưa; chạy chương trình I2C scanner xem địa chỉ có hiện 0x68 không. Module hàng trôi nổi đôi khi chết chip — hiện tượng scanner không thấy gì dù đấu đúng.

MPU6050 có đo được hướng la bàn (heading) không?

Không bền vững — gyro trục Z cho biết đã quay bao nhiêu so với lúc đầu nhưng trôi dần theo thời gian. Muốn hướng tuyệt đối như la bàn cần thêm cảm biến từ trường (HMC5883L/QMC5883) hoặc dùng module 9 trục như MPU9250, BNO055.

MPU6050 và MPU9250 khác gì nhau?

MPU9250 = MPU6050 + la bàn 3 trục (9 bậc tự do), giá gấp 2-3 lần. Robot cân bằng và đo góc nghiêng chỉ cần MPU6050; định hướng tuyệt đối ngoài trời mới cần 9250 hoặc BNO055.

Robot cân bằng cần đọc cảm biến nhanh cỡ nào?

Tối thiểu 100 lần/giây (100 Hz), lý tưởng 200 Hz. Vì vậy vòng loop không được chứa delay dài hay Serial.print quá nhiều — in log 10 lần/giây là đủ, phần còn lại dành cho điều khiển.

Tài nguyên tải về

Tải bản PDF của bài viết để in giáo án hoặc gửi trước cho học viên.

Tải PDF
Chia sẻ bài viết