آموزش پروژه‌محور حسگر حرکت شش‌محوره

راه‌اندازی MPU6050 با ESP32؛ از دیتاشیت تا کالیبراسیون ژیروسکوپ

در این راهنما MPU6050 را به‌عنوان یک IMU شش‌محوره واقعی می‌شناسیم، تفاوت تراشه خام و برد آماده را روشن می‌کنیم و آدرس I2C، محدوده‌های اندازه‌گیری، سیم‌کشی، کد عملی، تحلیل خروجی و عیب‌یابی را قدم‌به‌قدم پیش می‌بریم. همه مقادیر فنی با اسناد رسمی TDK/InvenSense و API کتابخانه Adafruit تطبیق داده شده‌اند.

برد واقعی Adafruit MPU6050 متصل به یک برد توسعه و نمایشگر OLED روی بردبورد، با سیم‌های I2C
عکس واقعی برد Adafruit MPU6050 در یک آزمایش سیم‌کشی‌شده؛ اثر Bryan Siepert با مجوز CC BY-SA 3.0، تغییر اندازه بدون برش برای LCENJ.
نوع حسگرشتاب‌سنج ۳محوره + ژیروسکوپ ۳محوره
تغذیه تراشه خام2.375 تا 3.46V
رابط MPU6050I2C تا 400kHz
آدرس هفت‌بیتی0x68 یا 0x69

MPU6050 چیست و چه چیزی را اندازه می‌گیرد؟

MPU6050 یک واحد اندازه‌گیری اینرسی یا IMU با شش درجه آزادی است: شتاب خطی و اثر گرانش را روی محورهای X، Y و Z می‌سنجد و سرعت زاویه‌ای را روی همان سه محور گزارش می‌کند. هر شش کانال ADC شانزده‌بیتی دارند. این قطعه مغناطیس‌سنج ندارد؛ بنابراین از داده خام آن به‌تنهایی نمی‌توان جهت مطلق نسبت به شمال را به‌دست آورد.

کنترل تعادل ربات، تشخیص شیب، ثبت حرکت، کنترلر حرکتی، پایش لرزش و تخمین Roll و Pitch از کاربردهای مناسب‌اند. برای زاویه پایدار باید داده ژیروسکوپ و شتاب‌سنج با الگوریتمی مانند Complementary یا Kalman ترکیب شوند. انتگرال‌گیری ساده از ژیروسکوپ به‌دلیل بایاس و نویز در طول زمان Drift می‌کند.

کاربردهای مناسب و محدودیت‌های مهم

ربات تعادلی

شتاب‌سنج مرجع بلندمدت گرانش و ژیروسکوپ پاسخ سریع چرخش را فراهم می‌کند. کنترل‌کننده باید نرخ نمونه‌برداری ثابت، فیلتر و کالیبراسیون بایاس داشته باشد.

تشخیص شیب

وقتی حرکت خطی کم است می‌توان جهت بردار گرانش را برای Roll و Pitch استفاده کرد. در شتاب شدید، این فرض موقتاً معتبر نیست.

پایش حرکت و لرزش

محدوده اندازه‌گیری و پهنای باند باید متناسب با دامنه و فرکانس پدیده انتخاب شوند؛ انتخاب فیلتر خیلی کند می‌تواند بخش مهم حرکت را حذف کند.

قطب‌نما و Heading

MPU6050 به‌تنهایی شمال مغناطیسی را نمی‌سنجد. Heading مطلق به مغناطیس‌سنج، کالیبراسیون و Sensor Fusion مناسب نیاز دارد.

چطور دیتاشیت MPU6050 را درست بخوانیم؟

ابتدا تفاوت MPU-6000 و MPU-6050 را ببینید: MPU-6000 رابط I2C و SPI دارد، اما MPU-6050 فقط I2C را پشتیبانی می‌کند و پایه VLOGIC جداگانه دارد. عددهای زیر مربوط به تراشه خام MPU6050 هستند، نه الزاماً ورودی تغذیه یک ماژول آماده.

پارامتر رسمیمقدارنتیجه عملی
تغذیه VDD تراشه2.375 تا 3.46Vتراشه خام را مستقیم به 5V وصل نکنید.
مرجع منطق VLOGIC1.71V تا VDDسطح I2C باید با میزبان و مدار برد سازگار باشد.
دمای کاری-40 تا +85°Cکالیبراسیون بایاس در یک دما برای همه دماها کافی نیست.
رابط اصلیI2C Fast Mode تا 400kHzبرای بردبورد و سیم کوتاه از 100kHz شروع کنید.
رزولوشن خروجیADC شانزده‌بیتی برای هر محوررزولوشن کد با دقت واقعی یا نویز صفر برابر نیست.
بافر FIFO1024 byteبرای خواندن Burst و کاهش بار میزبان مفید است.
جریان شش محور + DMPتیپیک 3.9mAعدد دیتاشیت برای تراشه و شرایط تعریف‌شده است.

کلمه «۱۶ بیت» به معنی دقت زاویه ۱/۶۵۵۳۶ دور نیست. نویز، بایاس اولیه، تغییر بایاس با دما، خطای Scale Factor، نصب مکانیکی و ارتعاش روی نتیجه اثر دارند. دیتاشیت برای Zero-Rate Output ژیروسکوپ تلرانس اولیه و تغییر با دما تعریف می‌کند؛ به همین دلیل اندازه‌گیری بایاس در شروع پروژه ضروری است.

محدوده‌ها، حساسیت و انتخاب فیلتر

حسگرFull Scaleحساسیت کد خام دیتاشیت
شتاب‌سنج±2g، ±4g، ±8g، ±16gبه‌ترتیب 16384، 8192، 4096 و 2048 LSB/g
ژیروسکوپ±250، ±500، ±1000، ±2000 °/sبه‌ترتیب 131، 65.5، 32.8 و 16.4 LSB/(°/s)

محدوده کوچک‌تر حساسیت عددی بیشتری می‌دهد اما در حرکت بزرگ Saturate می‌شود. برای نمونه آموزشی، ±4g و ±500°/s تعادلی مناسب‌اند؛ این انتخاب نسخه ثابت برای همه پروژه‌ها نیست. اگر ربات شما ضربه شدید یا چرخش سریع دارد، قبل از افزایش محدوده، Peak واقعی را ثبت کنید.

کتابخانه Adafruit انتخاب‌های پهنای باند 260، 184، 94، 44، 21، 10 و 5 هرتز را ارائه می‌کند. فیلتر 21Hz در کد نمونه نویز روی میز را کم می‌کند، اما برای ثبت حرکت سریع ممکن است کند باشد. پهنای باند، نرخ نمونه‌برداری و تأخیر کنترل را با هم طراحی کنید.

تفاوت تراشه خام، GY-521 و برد Adafruit

حد VDD برابر 2.375 تا 3.46 ولت متعلق به خود تراشه است. برد Adafruit نشان‌داده‌شده در تصویر طبق راهنمای رسمی، رگولاتور و مبدل سطح دارد، Vin آن با 3 تا 5 ولت کار می‌کند و روی SDA و SCL مقاومت Pull-up ده‌کیلو اهمی دارد. این مشخصات را نباید به هر برد آبی GY-521 یا ماژول بی‌نام تعمیم داد.

روی برخی GY-521ها رگولاتور تغذیه دیده می‌شود، اما وضعیت Level Shifting و مقدار Pull-up ممکن است متفاوت باشد. پیش از اعمال 5V، شماتیک همان نسخه و ولتاژ واقعی SDA/SCL را بررسی کنید. اتصال امن و ساده برای ESP32 این است که برد مستند را با 3.3V تغذیه کنید و منطق I2C را 3.3V نگه دارید.

پایه‌ها، آدرس I2C و رجیسترهای کلیدی

پایه برد آمادهکاربردنکته
VIN / VCCتغذیه بردحد مجاز را از مستند همان ماژول بخوانید؛ برای برد Adafruit برابر 3 تا 5V است.
GNDزمین مشترکزمین ESP32 و حسگر مشترک باشد.
SDAداده I2Cخط Open-drain با Pull-up مناسب به سطح منطق.
SCLکلاک I2Cاز سیم کوتاه شروع کنید.
AD0انتخاب بیت کم‌ارزش آدرسپایین: 0x68، بالا: 0x69.
INTخروجی وقفهبرای Data Ready، Motion و رویدادهای تنظیم‌شده قابل استفاده است.

Register Map رسمی، رجیستر SMPLRT_DIV را در 0x19، CONFIG را در 0x1A، GYRO_CONFIG را در 0x1B و ACCEL_CONFIG را در 0x1C تعریف می‌کند. داده پیوسته شتاب، دمای تراشه و ژیروسکوپ از 0x3B تا 0x48 قرار دارند. PWR_MGMT_1 در 0x6B و WHO_AM_I در 0x75 است.

سیم‌کشی MPU6050 با ESP32 و Arduino Uno

برد MPU6050 مستندGeneric ESP32Arduino Uno
VIN3V35V فقط برای برد Adafruit مستند؛ در غیر این صورت مشخصات ماژول
GNDGNDGND
SDAGPIO21A4 / SDA
SCLGPIO22A5 / SCL
AD0GND برای 0x68GND برای 0x68
INTدر این نمونه وصل نیستدر این نمونه وصل نیست

GPIO21 و GPIO22 فقط پیش‌فرض Generic ESP32 هستند. در ESP32-S3، C3 و بردهای سفارشی، پین‌های واقعی برد خود را جایگزین کنید. مستند رسمی Arduino-ESP32 توصیه می‌کند برای تغییر پایه‌ها Wire.setPins را پیش از begin یا فرم مناسب Wire.begin(SDA,SCL) به‌کار ببرید.

راه‌اندازی گام‌به‌گام در Arduino IDE

  1. از Library Manager، کتابخانه‌های Adafruit MPU6050، Adafruit Unified Sensor و Adafruit BusIO را نصب کنید.
  2. برد و پورت درست ESP32 یا Arduino Uno را انتخاب کنید.
  3. سیم‌کشی را با تغذیه قطع انجام دهید و سپس ولتاژ ماژول و سطح خطوط I2C را کنترل کنید.
  4. فایل i2c-scanner.ino را اجرا کنید؛ با AD0 پایین باید 0x68 دیده شود.
  5. حسگر را روی سطح ثابت بگذارید، کد اصلی را آپلود و Serial Monitor را روی 115200 baud باز کنید.
  6. تا پایان 500 نمونه کالیبراسیون، حسگر را لمس نکنید؛ سپس هر محور را آرام حرکت دهید و واحدها را بررسی کنید.

کد عملی MPU6050 برای ESP32 و Arduino

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

#if defined(ESP32)
constexpr int SDA_PIN = 21;
constexpr int SCL_PIN = 22;
#endif

constexpr uint8_t MPU6050_ADDRESS = 0x68;
constexpr uint16_t CALIBRATION_SAMPLES = 500;
Adafruit_MPU6050 mpu;
float biasX = 0, biasY = 0, biasZ = 0;

void calibrateGyro() {
  sensors_event_t a, g, t;
  for (uint16_t i = 0; i < CALIBRATION_SAMPLES; ++i) {
    mpu.getEvent(&a, &g, &t);
    biasX += g.gyro.x;
    biasY += g.gyro.y;
    biasZ += g.gyro.z;
    delay(5);
  }
  biasX /= CALIBRATION_SAMPLES;
  biasY /= CALIBRATION_SAMPLES;
  biasZ /= CALIBRATION_SAMPLES;
}

void setup() {
  Serial.begin(115200);
#if defined(ESP32)
  Wire.begin(SDA_PIN, SCL_PIN);
#else
  Wire.begin();
#endif
  Wire.setClock(100000);

  if (!mpu.begin(MPU6050_ADDRESS, &Wire)) {
    Serial.println(F("MPU6050 not found"));
    while (true) delay(10);
  }
  mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  calibrateGyro();
}

void loop() {
  sensors_event_t a, g, t;
  mpu.getEvent(&a, &g, &t);
  Serial.print(F("aX=")); Serial.print(a.acceleration.x, 3);
  Serial.print(F(" aY=")); Serial.print(a.acceleration.y, 3);
  Serial.print(F(" aZ=")); Serial.print(a.acceleration.z, 3);
  Serial.print(F(" | wX=")); Serial.print(g.gyro.x - biasX, 4);
  Serial.print(F(" wY=")); Serial.print(g.gyro.y - biasY, 4);
  Serial.print(F(" wZ=")); Serial.println(g.gyro.z - biasZ, 4);
  delay(100);
}

تحلیل کد و واحد خروجی

سنسور دمای داخلی چه کاربردی دارد؟

رجیسترهای دما بین داده شتاب و ژیروسکوپ قرار دارند و دیتاشیت رابطه Temperature = TEMP_OUT / 340 + 36.53 را برای تبدیل کد خام به درجه سلسیوس می‌دهد. این دما مربوط به داخل تراشه است و جای سنسور دقیق دمای محیط را نمی‌گیرد.

کاربرد مفید آن، ثبت دمای خود IMU کنار بایاس ژیروسکوپ است. برای محصول دقیق، می‌توان بایاس را در چند دمای کنترل‌شده اندازه گرفت و مدل جبرانی ساخت؛ یک Offset در دمای اتاق برای کل بازه -40 تا +85 درجه تضمین نمی‌شود.

خطاهای رایج و عیب‌یابی MPU6050

نشانهعلت محتملبررسی پیشنهادی
0x68 دیده نمی‌شودSDA/SCL جابه‌جا، زمین مشترک نیست، تغذیه یا Pull-up نامناسبولتاژ را اندازه بگیرید و اسکنر را با سیم کوتاه و 100kHz اجرا کنید.
فقط 0x69 دیده می‌شودAD0 در سطح High استآدرس کد را به 0x69 تغییر دهید یا AD0 را طبق طراحی پایین بیاورید.
ژیروسکوپ در سکون صفر نیستZero-rate bias طبیعی یا حرکت هنگام کالیبراسیونبرد را ثابت نگه دارید، میانگین را تکرار و دما را ثبت کنید.
زاویه به‌آرامی منحرف می‌شودانتگرال بایاس ژیروسکوپبایاس و نرخ نمونه‌برداری را اصلاح و Sensor Fusion اضافه کنید.
شتاب Z نزدیک صفر نیستاثر گرانشروی سطح افقی، محور هم‌جهت با گرانش باید قدرمطلق نزدیک یک g نشان دهد.
اعداد هنگام موتور پرنویزندارتعاش مکانیکی، زمین/تغذیه یا پهنای باند نامناسبنصب مکانیکی، Decoupling، مسیر زمین و فیلتر را جداگانه آزمایش کنید.
خروجی روی حد می‌چسبدFull Scale کوچک و Saturationمحدوده بزرگ‌تر انتخاب و Peak حرکت واقعی را ثبت کنید.
چند ماژول با هم پاسخ می‌دهندهر دو آدرس یکسان دارندبرای حداکثر دو قطعه، AD0 یکی را پایین و دیگری را بالا قرار دهید.

نکات طراحی PCB، تغذیه و نصب مکانیکی

نتیجه‌گیری

راه‌اندازی مطمئن MPU6050 فقط وصل‌کردن چهار سیم نیست. باید تفاوت تراشه و ماژول، آدرس AD0، محدوده اندازه‌گیری، پهنای باند، واحد خروجی، بایاس ژیروسکوپ و نصب مکانیکی را هم‌زمان در نظر بگیرید. کد این مقاله یک خط مبنای قابل‌تکرار برای خواندن شش محور است؛ مرحله بعد برای تخمین زاویه، طراحی Sensor Fusion و کالیبراسیون متناسب با محصول واقعی است.

پرسش‌های متداول

آدرس MPU6050 برابر 0x68 است یا 0x69؟

هر دو درست‌اند. وقتی پایه AD0 پایین باشد آدرس هفت‌بیتی 0x68 و وقتی AD0 بالا باشد 0x69 است. اسکنر I2C بهترین راه تشخیص وضعیت واقعی برد است.

آیا می‌توان MPU6050 را مستقیم به 5 ولت وصل کرد؟

تراشه خام فقط VDD برابر 2.375 تا 3.46 ولت را می‌پذیرد. فقط ماژولی را با 5 ولت تغذیه کنید که سازنده همان برد وجود رگولاتور و سازگاری منطق را مستند کرده باشد؛ برد Adafruit این قابلیت را دارد.

چرا ژیروسکوپ در حالت سکون صفر دقیق نشان نمی‌دهد؟

ژیروسکوپ بایاس Zero-rate و نویز دارد و بایاس با دما تغییر می‌کند. حسگر را ثابت نگه دارید، چندصد نمونه میانگین بگیرید و برای محصول دقیق، جبران دمایی انجام دهید.

آیا MPU6050 می‌تواند زاویه Yaw یا جهت شمال را دقیق بدهد؟

به‌تنهایی نه. MPU6050 مغناطیس‌سنج ندارد؛ Yaw حاصل از انتگرال ژیروسکوپ در طول زمان Drift می‌کند. جهت مطلق به مرجع خارجی و Sensor Fusion نیاز دارد.

دمای MPU6050 همان دمای محیط است؟

خیر. خروجی دما وضعیت داخل تراشه را نشان می‌دهد و بیشتر برای پایش و جبران رفتار IMU مفید است؛ آن را جای سنسور دقیق دمای هوا استفاده نکنید.

منابع دقیق و ادامه مسیر

اعداد تراشه خام از PS-MPU-6000A-00 Rev.3.4 و رجیسترها از RM-MPU-6000A-00 Rev.4.2 گرفته شده‌اند. مشخصات 3 تا 5 ولت و Pull-up ده‌کیلو اهمی فقط به برد مستند Adafruit تعمیم داده شده‌اند. وضعیت Obsolete از صفحه فعلی TDK Product Center کنترل شده است.