راه اندازی MPU9150 با آردوینو – بخش دوم
مقدمه
در جلسه دوم از آموزش راه اندازی MPU9150 قصد داریم این سنسور را به آردوینو وصل کنیم و داده های آن را بخوانیم و کمی با این داده ها کار کنیم. قبل از هر چیزی پیشنهاد میکنم ابتدا جلسه اول مربوط به این آموزش که در آن در مورد MPU9150 و مشخصات آن صحبت کردیم ، را از لینک زیر بخوانید:
اتصال MPU9150 به آردوینو ( بخش سخت افزاری)
به طور پایه ما حداقل به 4 سیم برای اتصال MPU9150 به میکروکنترلر و خواندن داده های آن نیاز داریم. این 4 سیم شامل VCC و GND و پایه مربوط به دیتا و پایه مربوط به کلاک است. ( دو پایه اخیر مربوط به پروتکل I2C است. )
شماتیک اتصال این سنسور به آردوینو به صورت زیر است:
–
نصب کتابخانه و راه اندازی سنسور ( بخش نرم افزاری)[post_shop]
ما برای راه اندازی این سنسور از کتابخانه شرکت Sparkfun استفاده می کنیم. این کتابخانه را میتوانید از لینک زیر دانلود کنید.
در صورتی که با نحوه نصب کتابخانه در آردوینو آشنا نیستید ، پیشنهاد میکنم جلسه مربوط به آموزش نصب کتابخانه ها را از لینک زیر مطالعه کنید: ( البته ما در ادامه روش نصب را به صورت خلاصه توضیح میدهیم)
برای نصب سریع کتابخانه کافی است دو فولدر I2Cdev و MPU6050 را در فولدرLibraries در محل نصب نرم افزار Arduino کپی کنید.
حال وارد نرم افزار Arduino شوید و از قسمت File ، بخش Example و سپس قسمت MPU6050 را انتخاب کنید و مثالی که با نام MPU9150 raw است را باز کنید. کد مربوط به این مثال در زیر آورده شده است. ابتدا به این کد نگاهی بیندازید تا در ادامه تک تک خطوط کد را با یکدیگر بررسی کنیم:
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050.h" // class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for InvenSense evaluation board) // AD0 high = 0x69 MPU6050 accelgyro; int16_t ax, ay, az; int16_t gx, gy, gz; int16_t mx, my, mz; void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) Wire.begin(); // initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(38400); // initialize device Serial.println("Initializing I2C devices..."); accelgyro.initialize(); // verify connection Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); } void loop() { // read raw accel/gyro measurements from device accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz); // these methods (and a few others) are also available //accelgyro.getAcceleration(&ax, &ay, &az); //accelgyro.getRotation(&gx, &gy, &gz); // display tab-separated accel/gyro x/y/z values Serial.print("a/g/m:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.print(gz); Serial.print("\t"); Serial.print(mx); Serial.print("\t"); Serial.print(my); Serial.print("\t"); Serial.println(mz); }
تذکر: در کد بالا یک قسمت کوچک هم مربوط به LED بود که دراینجا برای سادگی ، آن قسمت حذف شده است ولی در کد شما احتمالا آن بخش وجود دارد.
در زیر به صورت خط به خط این کد را بررسی کرده ایم:
#include "I2Cdev.h" #include "MPU6050.h"
این دو خط برای راه اندازی پروتکل I2C و ارتباط با ماژول MPU9150 است. البته توجه کنید که به خاطر شباهت ساختاری و ذاتی سنسورهای MPU9150 و MPU6050 کدهای مربوط به ماژول MPU9150 نیز با همان هدر MPU6050 پیاده سازی شده است.
MPU6050 accelgyro; int16_t ax, ay, az; int16_t gx, gy, gz; int16_t mx, my, mz;
در اولین خط از کد بالا ابتدا یک Object از کلاس MPU6050 تعریف شده است که تعریف این Object به منظور استفاده از متدهاست که در ادامه از آنها استفاده میکنیم.
در سه خط بعد 9 متغیر تعریف شده است که هر متغیر یکی از داده های سه سنسور و در یک جهت خاص را در خود ذخیره می کند. چون هر کدام از محورها سه محور دارند ، برای هر محور یک متغیر تعریف می کنیم و داده های مربوط به آن محور را در آن متغیر ذخیره می کنیم. در اینجا گفتن نکته زیر خالی از لطف نیست:
نکته برنامه نویسی: علت این که در اینجا متغیرهایی از نوع int16_t تعریف شده اند و یک متغیر ساده int تعریف نشده است به صورت زیر می باشد:
در بردهایی مثل برد Arduino UNO یک متغیر int مقدار 16 بیت را در خور ذخیره می کند. در حالی که در بردهایی مانند Arduino DUE این متغیر 32 بیت را در خود ذخیره می کند. حال اگر ما متغیری از جنس int16_t تعریف کنیم ، اندازه این متغیر همیشه 16 بیت است. فرقی ندارد که از چه بردی استفاده میکنیم. از آنجا که داده های ما در اینجا نیز 16 بیتی است ما همیشه نیاز داریم که متغیر int ما 16 بیت را ذخیره کند. به همین علت فارغ از نوع برد ، نوع متغیر را int16_t تعریف میکنیم و خیال خود را از بابت ثابت بودن اندازه Int راحت میکنیم. چون نمیخواهیم حجمی از برنامه توسط متغیرهایی که اندازه زیادی دارند و از آن حجم هم استفاده نمی شود ، اشغال شود.
Wire.begin(); Serial.begin(38400); Serial.println("Initializing I2C devices..."); accelgyro.initialize();
در چهار خط بالا ابتدا با پروتکل I2C ارتباط برقرار کرده ایم و سپس پورت سریال را راه اندازی کرده و بر روی پنجره سریال عبارتی را مینویسیم. در گام آخر نیز تنظیمات اولیه مربوط به سنسور MPU9150 را انجام داده ایم. منظور از تنظیمات اولیه در این خط تنظیم محدوده های اندازه گیری شتاب سنج و ژیروسکوپ و تعیین منبع کلاک و … است. در اینجا محدوده اندازه گیری ژیروسکوپ ±250 درجه بر ثانیه و محدوده اندازه گیری شتاب سنج ±2g تعیین شده است. ( در کتابخانه MPU6050 توضیح دقیق این موارد وجود دارد. )
Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
در این دو خط نیز ابتدا ارتباط بین سنسور و برد آردوینو چک می شود و سپس در صورتی که ارتباط صحیح باشد عبارت MPU6050 connection successful بر روی پنجره سریال نمایش داده می شود و در صورت عدم ارتباط صحیح ، عبارت MPU6050 connection failed بر روی پورت سریال به نمایش در می آید. ( تمرین : به کمک کتابخانه MPU6050 تحقیق کنید که خط مربوط به چک کردن ارتباطات دقیقا چه کاری را انجام می دهد؟ )
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz); Serial.print("a/g/m:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.print(gz); Serial.print("\t"); Serial.print(mx); Serial.print("\t"); Serial.print(my); Serial.print("\t"); Serial.println(mz);
[/post_shop]
در خطوط بالا ابتدا داده ها را از سنسور میخوانیم و سپس تک تک آنها را بر روی پنجره سریال نمایش می دهیم. نتیجه خروجی به شکل زیر است:
خوب دوستان. به پایان این جلسه هم رسیدیم. ما تا حالا فقط داده های خام سنسور را گرفته ایم و هنوز کارهای زیادی با آن داریم. ما در مورد این سنسور چند جلسه دیگر هم خواهیم داشت. مثل همیشه میتوانید ما را در تلگرام و یا اینستاگرام دنبال کنید:
دیدگاهتان را بنویسید