آموزش MPU6050 با ESP32؛ سیمکشی، کد و کالیبراسیون
راهنمای پروژهمحور MPU6050 با ESP32 و Arduino؛ دیتاشیت، محدودهها، آدرس I2C، سیمکشی، کد شش محور، بایاس ژیروسکوپ و عیبیابی.
آموزش پروژهمحور حسگر حرکت ششمحوره
راهاندازی MPU6050 با ESP32؛ از دیتاشیت تا کالیبراسیون ژیروسکوپ
در این راهنما MPU6050 را بهعنوان یک IMU ششمحوره واقعی میشناسیم، تفاوت تراشه خام و برد آماده را روشن میکنیم و آدرس I2C، محدودههای اندازهگیری، سیمکشی، کد عملی، تحلیل خروجی و عیبیابی را قدمبهقدم پیش میبریم. همه مقادیر فنی با اسناد رسمی TDK/InvenSense و API کتابخانه Adafruit تطبیق داده شدهاند.
0x68 یا 0x69MPU6050 چیست و چه چیزی را اندازه میگیرد؟
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 وصل نکنید. |
| مرجع منطق VLOGIC | 1.71V تا VDD | سطح I2C باید با میزبان و مدار برد سازگار باشد. |
| دمای کاری | -40 تا +85°C | کالیبراسیون بایاس در یک دما برای همه دماها کافی نیست. |
| رابط اصلی | I2C Fast Mode تا 400kHz | برای بردبورد و سیم کوتاه از 100kHz شروع کنید. |
| رزولوشن خروجی | ADC شانزدهبیتی برای هر محور | رزولوشن کد با دقت واقعی یا نویز صفر برابر نیست. |
| بافر FIFO | 1024 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 ESP32 | Arduino Uno |
|---|---|---|
| VIN | 3V3 | 5V فقط برای برد Adafruit مستند؛ در غیر این صورت مشخصات ماژول |
| GND | GND | GND |
| SDA | GPIO21 | A4 / SDA |
| SCL | GPIO22 | A5 / SCL |
| AD0 | GND برای 0x68 | GND برای 0x68 |
| INT | در این نمونه وصل نیست | در این نمونه وصل نیست |
GPIO21 و GPIO22 فقط پیشفرض Generic ESP32 هستند. در ESP32-S3، C3 و بردهای سفارشی، پینهای واقعی برد خود را جایگزین کنید. مستند رسمی Arduino-ESP32 توصیه میکند برای تغییر پایهها Wire.setPins را پیش از begin یا فرم مناسب Wire.begin(SDA,SCL) بهکار ببرید.
راهاندازی گامبهگام در Arduino IDE
- از Library Manager، کتابخانههای Adafruit MPU6050، Adafruit Unified Sensor و Adafruit BusIO را نصب کنید.
- برد و پورت درست ESP32 یا Arduino Uno را انتخاب کنید.
- سیمکشی را با تغذیه قطع انجام دهید و سپس ولتاژ ماژول و سطح خطوط I2C را کنترل کنید.
- فایل
i2c-scanner.inoرا اجرا کنید؛ با AD0 پایین باید0x68دیده شود. - حسگر را روی سطح ثابت بگذارید، کد اصلی را آپلود و Serial Monitor را روی 115200 baud باز کنید.
- تا پایان 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);
}
تحلیل کد و واحد خروجی
- شرط
#if defined(ESP32)پایههای Generic ESP32 را صریح میکند؛ Uno از پایههای سختافزاری Wire استفاده میکند. Wire.setClock(100000)برای شروع بردبوردی محافظهکارانه است و از سقف 400kHz دیتاشیت پایینتر میماند.mpu.begin(0x68, &Wire)شناسه WHO_AM_I را از طریق کتابخانه بررسی و تنظیمات اولیه را انجام میدهد.- خروجی شتاب کتابخانه بر حسب m/s² و خروجی ژیروسکوپ بر حسب rad/s است؛ اینها کد خام LSB نیستند.
- میانگین 500 نمونه فقط بایاس ژیروسکوپ در حالت سکون و دمای همان لحظه را تخمین میزند. این روش Scale Factor، Misalignment یا تغییرات دمایی را اصلاح نمیکند.
- از شتابسنج بایاس ثابت کم نشده است، چون در حالت سکون نیز محور همراستا با گرانش تقریباً یک g میبیند و حذف کورکورانه آن خطاست.
سنسور دمای داخلی چه کاربردی دارد؟
رجیسترهای دما بین داده شتاب و ژیروسکوپ قرار دارند و دیتاشیت رابطه 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، تغذیه و نصب مکانیکی
- خازنهای Decoupling و مسیر تغذیه را مطابق Typical Operating Circuit دیتاشیت نزدیک تراشه قرار دهید.
- IMU را نزدیک بخش صلب PCB نصب کنید؛ خمشدن برد و تنش پیچها میتواند بایاس MEMS را تغییر دهد.
- از قرار دادن IMU کنار موتور، سلف قدرت یا منبع گرمای موضعی بدون آزمون خودداری کنید.
- محورهای چاپشده روی ماژول را با دستگاه مختصات محصول مستند کنید؛ چرخش 90 درجه نرمافزاری را صریح اعمال کنید.
- برای کابل بلند، ظرفیت باس، Pull-up و شکل موج SDA/SCL را با اسیلوسکوپ بررسی کنید؛ 400kHz یک سقف رابط است، نه الزام.
- برای کنترل Real-time از زمانبندی ثابت یا وقفه Data Ready استفاده کنید؛
delay(100)فقط برای نمایش آموزشی است. - کالیبراسیون نهایی را پس از مونتاژ در قاب واقعی و در بازه دمایی محصول انجام دهید.
نتیجهگیری
راهاندازی مطمئن 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 مفید است؛ آن را جای سنسور دقیق دمای هوا استفاده نکنید.
منابع دقیق و ادامه مسیر
- صفحه رسمی TDK برای MPU-6050 و وضعیت Obsolete
- دیتاشیت رسمی MPU-6000/MPU-6050، Revision 3.4
- Register Map رسمی MPU-6000/MPU-6050 در بخش Documents صفحه TDK
- راهنمای رسمی برد Adafruit MPU6050
- کتابخانه رسمی Adafruit MPU6050 با مجوز BSD
- مستند رسمی I2C در Arduino-ESP32
- منبع عکس برد، Bryan Siepert، مجوز CC BY-SA 3.0
- آموزش VL53L0X با ESP32 و Arduino
- آموزش SHT31 با ESP32 و Arduino
- دوره رایگان سنسورها در ۷ قدم
- دسته آموزش حرکت و موقعیت
- مرکز آموزش سنسورها در LCENJ
اعداد تراشه خام از PS-MPU-6000A-00 Rev.3.4 و رجیسترها از RM-MPU-6000A-00 Rev.4.2 گرفته شدهاند. مشخصات 3 تا 5 ولت و Pull-up دهکیلو اهمی فقط به برد مستند Adafruit تعمیم داده شدهاند. وضعیت Obsolete از صفحه فعلی TDK Product Center کنترل شده است.
پرسش و پاسخ مقاله
سوال فنی خود را مطرح کنید
پرسشها و پاسخها پس از بررسی مدیر منتشر میشوند. نویسنده، پیشنویس در انتظار بررسی را میبیند.
هنوز پرسش تاییدشدهای برای این مقاله ثبت نشده است.