Module GY-87 là một bo mạch nhỏ gọn, tích hợp nhiều cảm biến, thường được gọi là IMU (Inertial Measurement Unit) 10 bậc tự do (10-DOF). Đây là một module rất phổ biến trong các dự án điện tử, robot, flycam (drone) và các hệ thống định vị nhờ khả năng cung cấp một lượng lớn dữ liệu chỉ trên một bo mạch duy nhất.
Các Cảm Biến Tích Hợp
MPU-6050: Chuyển động 6-DOF
Gia tốc kế: Đo gia tốc tuyến tính (X, Y, Z).
Con quay hồi chuyển: Đo tốc độ xoay (X, Y, Z).
QMC5883L: Từ trường 3-DOF
Từ kế: Hoạt động như một la bàn số, đo từ trường.
BMP180: Khí áp & Nhiệt độ
Khí áp kế: Đo áp suất để ước tính độ cao.
Nhiệt kế: Đo nhiệt độ môi trường.
Chi Tiết Sơ Đồ Chân (Pinout)
Tên Chân | Chức Năng |
---|---|
VCC_IN | Nguồn cấp chính - 5V |
3.3V | Nguồn cấp phụ - 3.3V (Thường là ngõ ra) |
GND | Nối đất (Ground) |
SCL | Chân xung nhịp I2C (Serial Clock) |
SDA | Chân dữ liệu I2C (Serial Data) |
FSYNC | Ngõ vào đồng bộ (Thường không sử dụng) |
INTA | Chân ngắt từ MPU6050 (Thường không sử dụng) |
DRDY | Chân báo dữ liệu sẵn sàng (Thường không sử dụng) |
Bước 1: Cài Đặt & Kết Nối
Cài Đặt Thư Viện Cần Thiết
Mở Arduino IDE, vào Tools > Manage Libraries... và tìm kiếm, cài đặt các thư viện sau:
- Adafruit MPU6050 (Khi được hỏi, chọn "Install all" để cài các thư viện phụ thuộc).
- Adafruit Unified Sensor
- QMC5883LCompass
- Adafruit BMP085 Library
- GY-87 VCC_IN → Arduino 5V
- GY-87 GND → Arduino GND
- GY-87 SCL → Arduino SCL (hoặc A5 trên Uno R3)
- GY-87 SDA → Arduino SDA (hoặc A4 trên Uno R3)
Bước 2: Kiểm Tra Kết Nối (Scan I2C)
Sử dụng code này để kiểm tra kết nối và tìm địa chỉ I2C của tất cả cảm biến.
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <QMC5883LCompass.h>
// Initialize sensor objects
Adafruit_MPU6050 mpu;
Adafruit_BMP085 bmp;
QMC5883LCompass compass;
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial); // Leonardo: wait for Serial Monitor
Serial.println("\nI2C Scanner");
Serial.println("\nI2C Scanner for GY-87");
Serial.println("---------------------");
// Initialize the MPU-6050 to enable bypass mode
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip. Cannot enable bypass.");
Serial.println("Scanning with bypass disabled...");
} else {
Serial.println("MPU6050 found. Enabling I2C Bypass mode...");
// Enable I2C bypass to allow access to the magnetometer
mpu.setI2CBypass(true);
delay(100); // Give it a moment to settle
Serial.println("Bypass enabled. Starting scan...");
}
}
void loop() {
int nDevices = 0;
Serial.println("Scanning...");
for (byte address = 1; address < 127; ++address) {
// The i2c_scanner uses the return value of
// the Wire.endTransmission to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.print(address, HEX);
Serial.println(" !");
++nDevices;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
}
}
if (nDevices == 0) {
Serial.println("No I2C devices found\n");
} else {
Serial.println("done\n");
}
delay(5000); // Wait 5 seconds for next scan
}
Bước 3: Đọc Dữ Liệu Cảm Biến
Code này đọc và hiển thị dữ liệu từ tất cả cảm biến lên Serial Monitor.
/*
This Arduino code is designed to work with the GY-87 IMU (Inertial Measurement Unit) module,
which is a multi-sensor module containing three individual sensors: MPU6050 (Accelerometer and Gyroscope),
QMC5883L Magnetometer, and BMP180 (Barometric Pressure and Temperature). The code initializes these
sensors and continuously prints their readings to the Serial Monitor.
Board: Arduino Uno R4
Component: GY-87 IMU Module
Library: https://github.com/adafruit/Adafruit_MPU6050 (Adafruit MPU6050 by Adafruit)
https://github.com/mprograms/QMC5883LCompass (QMC5883LCompass by MPrograms)
https://github.com/adafruit/Adafruit-BMP085-Library (Adafruit BMP085 Library by Adafruit)
*/
// Include required libraries
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <QMC5883LCompass.h>
// Initialize sensor objects
Adafruit_MPU6050 mpu;
Adafruit_BMP085 bmp;
QMC5883LCompass compass;
void setup() {
// Initialize the serial communication with a baud rate of 115200
Serial.begin(9600);
// Initialize the MPU6050 sensor (accelerometer and gyroscope)
initializeMPU6050();
// Enable I2C bypass on MPU6050 to directly access the QMC5883L magnetometer
mpu.setI2CBypass(true);
// Initialize the QMC5883L magnetometer sensor
initializeQMC5883L();
// Initialize BMP180 barometric sensor
initializeBMP180();
}
void loop() {
// Print MPU6050 data
printMPU6050();
// Print QMC5883L data
printQMC5883L();
// Print BMP180 data
printBMP180();
delay(500);
}
void initializeQMC5883L() {
compass.init();
// compass.setCalibrationOffsets(-336.00, -179.00, 47.00);
// compass.setCalibrationScales(1.05, 0.94, 1.02);
}
void printQMC5883L() {
Serial.println();
Serial.println("QMC5883L ------------");
int x, y, z, a;
char myArray[3];
compass.read();
x = compass.getX();
y = compass.getY();
z = compass.getZ();
a = compass.getAzimuth();
compass.getDirection(myArray, a);
Serial.print("X: ");
Serial.print(x);
Serial.print(" Y: ");
Serial.print(y);
Serial.print(" Z: ");
Serial.print(z);
Serial.print(" Azimuth: ");
Serial.print(a);
Serial.print(" Direction: ");
Serial.print(myArray[0]);
Serial.print(myArray[1]);
Serial.println(myArray[2]);
Serial.println("QMC5883L ------------");
Serial.println();
}
void initializeMPU6050() {
// Check if the MPU6050 sensor is detected
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1)
; // Halt if sensor not found
}
Serial.println("MPU6050 Found!");
// set accelerometer range to +-8G
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
// set gyro range to +- 500 deg/s
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
// set filter bandwidth to 21 Hz
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.println("");
delay(100);
}
void printMPU6050() {
Serial.println();
Serial.println("MPU6050 ------------");
/* Get new sensor events with the readings */
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
/* Print out the values */
Serial.print("Acceleration X: ");
Serial.print(a.acceleration.x);
Serial.print(", Y: ");
Serial.print(a.acceleration.y);
Serial.print(", Z: ");
Serial.print(a.acceleration.z);
Serial.println(" m/s^2");
Serial.print("Rotation X: ");
Serial.print(g.gyro.x);
Serial.print(", Y: ");
Serial.print(g.gyro.y);
Serial.print(", Z: ");
Serial.print(g.gyro.z);
Serial.println(" rad/s");
Serial.print("Temperature: ");
Serial.print(temp.temperature);
Serial.println(" degC");
Serial.println("MPU6050 ------------");
Serial.println();
}
void initializeBMP180() {
// Start BMP180 initialization
if (!bmp.begin()) {
Serial.println("Could not find a valid BMP180 sensor, check wiring!");
while (1)
; // Halt if sensor not found
}
Serial.println("BMP180 Found!");
}
void printBMP180() {
Serial.println();
Serial.println("BMP180 ------------");
Serial.print("Temperature = ");
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bmp.readPressure());
Serial.println(" Pa");
// Calculate altitude assuming 'standard' barometric
// pressure of 1013.25 millibar = 101325 Pascal
Serial.print("Altitude = ");
Serial.print(bmp.readAltitude());
Serial.println(" meters");
Serial.print("Pressure at sealevel (calculated) = ");
Serial.print(bmp.readSealevelPressure());
Serial.println(" Pa");
Serial.println("BMP180 ------------");
Serial.println();
}
Ứng Dụng Thực Tế
- Flycam (Drones) và Máy bay mô hình: Giữ thăng bằng, tự động ổn định vị trí, định hướng.
- Robot tự hành: Giữ thăng bằng cho robot 2 bánh, định vị trong nhà, điều hướng.
- Thiết bị theo dõi chuyển động (Motion Tracking)
- Hệ thống định vị quán tính (INS)
- Trạm thời tiết mini
Nhận xét