การทำงานของ Gyroscope (ไจโรสโคป) ในโมดูล MPU-6050 คือการวัด "ความเร็วเชิงมุม" (Angular Velocity) หรืออัตราการหมุนรอบตัวของวัตถุ ว่าหมุนไปด้วยความเร็วเท่าไหร่และหมุนไปในทิศทางไหน (หน่วยเป็นองศาต่อวินาที: $\degree/s$) โดยครอบคลุม 3 แกนหลัก ได้แก่ X, Y และ Z
ภายในชิป MPU-6050 จะมีเทคโนโลยีที่เรียกว่า MEMS (Micro-Electro-Mechanical Systems) ซึ่งจำลองโครงสร้างขนาดจิ๋วระดับไมโครครอน โดยอาศัยหลักการทางฟิสิกส์ที่เรียกว่า Coriolis Effect (แรงโคริออลิส):
การสั่นสะเทือนคงที่: ภายในโครงสร้างของไจโร จะมีมวลขนาดเล็ก (Proof Mass) ที่ถูกขับเคลื่อนให้สั่นสะเทือนเดินหน้า-ถอยหลัง (เข้า-ออก) ในแนวราบด้วยความถี่คงสต็อกตลอดเวลา
เกิดแรงผลักเมื่อมีการหมุน: เมื่อเราพยายามหมุนหรือเอียงตัวเซ็นเซอร์ แรงเฉื่อยและความเร็วในการหมุนจะไปกระทบกับมวลที่กำลังสั่นอยู่ ทำให้ทิศทางการสั่นเกิดการเบี่ยงเบนหรือบิดตัวออกในแนวตั้งฉาก (Coriolis Force)
แปลงเป็นสัญญาณไฟฟ้า: การบิดตัวนี้จะไปเปลี่ยนค่าความจุไฟฟ้า (Capacitance) ของโครงสร้างไมโคร เซ็นเซอร์จะทำการวัดการเปลี่ยนแปลงดังกล่าว แล้วส่งผ่านวงจรภายในเพื่อแปลงสัญญาณอนาล็อกให้เป็นข้อมูลดิจิทัลขนาด 16 บิต (ผ่าน ADC) ผ่านโปรโตคอล I2C ให้ Arduino อ่านค่าออกมา
#include <Wire.h>
#include <math.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// กำหนดขนาดจอ OLED (ส่วนใหญ่ขนาด 0.96 นิ้วจะเป็น 128x64 หรือ 128x32)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1 // ใช้ -1 ถ้าไม่ได้ต่อขา Reset แยก
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int MPU_addr = 0x68; // I2C address ของ MPU-6050
int16_t axis_X, axis_Y, axis_Z;
void setup() {
Serial.begin(115200);
Wire.begin();
// 1. เริ่มต้นใช้งาน MPU-6050 (ปลุกจากโหมด Sleep)
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
// 2. เริ่มต้นใช้งานจอ OLED (I2C Address ปกติคือ 0x3C)
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("ไม่พบจอ OLED! กรุณาตรวจสอบการต่อสาย"));
while(1);
}
// เคลียร์หน้าจอและแสดงข้อความเริ่มต้น
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(10, 20);
display.println(F("MPU6050 + OLED Ready"));
display.display();
delay(1500);
}
void loop() {
// --- ส่วนที่ 1: อ่านค่าและคำนวณมุมเอียงจาก MPU-6050 ---
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, 6, true);
axis_X = Wire.read() << 8 | Wire.read();
axis_Y = Wire.read() << 8 | Wire.read();
axis_Z = Wire.read() << 8 | Wire.read();
float accel_x = (float)axis_X / 16384.0;
float accel_y = (float)axis_Y / 16384.0;
float accel_z = (float)axis_Z / 16384.0;
// คำนวณมุม Pitch และ Roll เป็นองศา
float pitch = atan(-accel_x / sqrt(accel_y * accel_y + accel_z * accel_z)) * 180.0 / PI;
float roll = atan(accel_y / sqrt(accel_x * accel_x + accel_z * accel_z)) * 180.0 / PI;
// --- ส่วนที่ 2: นำค่ามาแสดงผลบนจอ OLED ---
display.clearDisplay(); // ล้างหน้าจอบัฟเฟอร์
// วาดกรอบหัวข้อ
display.setTextSize(1);
display.setCursor(15, 0);
display.print(F("== MPU6050 TILT =="));
// แสดงค่า Pitch (ก้ม-เงย)
display.setCursor(0, 20);
display.print(F("Pitch: "));
display.setTextSize(2); // ขยายตัวอักษรให้ใหญ่อ่านง่าย
display.setCursor(50, 16);
display.print(pitch, 1); // แสดงทศนิยม 1 ตำแหน่ง
display.print(F(" "));
// แสดงค่า Roll (เอียงซ้าย-ขวา)
display.setTextSize(1);
display.setCursor(0, 45);
display.print(F("Roll: "));
display.setTextSize(2);
display.setCursor(50, 41);
display.print(roll, 1);
display.print(F(" "));
display.display(); // สั่งให้จอแสดงผลข้อมูลใหม่
delay(100); // หน่วงเวลาเล็กน้อยเพื่อให้หน้าจออัปเดตลื่นไหล
}