سنسور MPU6050 عملکردهای زیادی روی یک تراشه دارد و شامل شتابسنج ممز، ژیروسکوپ ممز و سنسور دماست. این ماژول هنگام تبدیل مقادیر آنالوگ به دیجیتال بسیار دقیق است؛ زیرا برای هر کانال یک سختافزار مبدل آنالوگ به دیجیتال ۱۶بیتی دارد. این ماژول قادر است کانال x و y و z را بهطور همزمان ضبط کند و دارای یک رابط I2C برای برقراری ارتباط با کنترلر میزبان است. ماژول MPU6050 یک تراشه فشرده است که هم شتابسنج و هم ژیروسکوپ دارد و یک دستگاه بسیار مفید برای پهپادها، رباتها و سنسورهای حرکتی محسوب میشود. به این ماژول، ژیروسکوپ یا شتابسنج سهمحوره نیز میگویند. در ادامه، با اتصال ژیروسکوپ MPU6050 به آردوینو، مقادیر را روی السیدی 16×2 نشان خواهیم داد.
قطعات موردنیاز
- آردوینو اونو (Arduino Uno)
- MPU-6050
- پتانسیومتر 10K
- سیم جامپر
- بِرِد بورد
- کابل USB
- منبع تغذیه
سنسور ژیروسکوپ MPU6050
MPU-6050 یک شتابسنج و ژیروسکوپ ششمحوره ۸ پین در یک تراشه است. این ماژول بهصورت پیشفرض روی ارتباط سریال I2C کار میکند اما میتوان با پیکربندی، آن را برای رابط SPI تنظیم کرد. برای ارتباط I2C، ماژول دارای خطوط SDA و SCL است. تقریباً همه پینها چندمنظوره هستند، اما در اینجا فقط با پینهای مد I2C پیش میرویم.
پیکربندی پینها
VCC: این پین برای تغذیه ماژول MPU6050 نسبت به زمین استفاده میشود.
GND: این پین، پین زمین است.
SDA: پین SDA برای دادههای بین کنترلر و ماژول MPU6050 مورد استفاده قرار میگیرد.
SCL: این پین برای ورودی ساعت بهکار میرود.
XDA: خط دادههای I2C SDA سنسور برای پیکربندی و خواندن از طریق سنسورهای خارجی است (اختیاری؛ در اینجا استفاده نمیشود).
XCL: خط ساعت I2C SCL سنسور برای پیکربندی و خواندن از طریق سنسورهای خارجی است (اختیاری؛ در اینجا استفاده نمیشود).
ADO: شامل I2C Slave Address LSB (در اینجا قابل اجرا نیست).
INT: پین وقفه برای اعلام آماده بودن دادهها.
در اینجا با استفاده از MPU6050 متصل به آردوینو، دما،داده های سنسور ژیروسکوپ و شتابسنج را روی LCD نشان میدهیم. این ماژول، مقادیر سطری و مقادیر نرمالشده را در خروجی به ما میدهد، اما مقادیر سطری پایدار نیستند؛ بنابراین در اینجا مقادیر نرمالشده را روی LCD نشان میدهیم. اگر فقط مقدار شتابسنج را میخواهید، میتوانید از شتابسنج ADXL335 با آردوینو نیز استفاده کنید.
همانطور که در تصاویر زیر نشان داده شده است، در این پروژه، نخست مقدار دما، پس از ۱۰ ثانیه مقادیر ژیروسکوپ و ۱۰ ثانیه بعد نیز داده های سنسور شتابسنج را نمایش میدهیم.
نمایش داده های سنسور شتابسنج در تصویر زیر نشان داده شده است.
مدار سنسور ژیروسکوپ MPU6050
نمودار مدار اتصال MPU6050 به آردوینو بسیار ساده است. ما در اینجا از یک LCD و MPU6050 و منبع تغذیه USB لپتاپ استفاده کردهایم. یک پتانسیومتر 10k نیز برای کنترل روشنایی LCD استفاده میشود. در ماژول MPU6050، پنج اتصال صورت گرفته است: منبع تغذیه 3.3v و پین زمین MPU6050 به پین 3.3v و پین زمین آردوینو، پینهای SCL و SDA ماژول MPU6050 به پین A4 و A5 آردوینو و پین INT ماژول به پین وقفه 0 آردوینو (D2) متصل شده است. پین RS، RW و EN السیدی مستقیماً به پین 8، gnd و 9 آردوینو و پین دادهها نیز مستقیماً به پین دیجیتال شماره 10، 11، 12 و 13 متصل هستند.
کدنویسی سنسور ژیروسکوپ MPU6050 در آردوینو
برنامهنویسی برای این پروژه آسان است. در اینجا برای ارتباط با آردوینو، از کتابخانه MPU6050 استفاده میکنیم. بنابراین، ابتدا باید کتابخانه MPU6050 را از لینک زیر دانلود کرده و آن را در IDE Arduino نصب کنیم.
https://www.arduino.cc/reference/en/libraries/mpu6050/
پس از آن، میتوان کدهای نمونه را در این مثال پیدا کرد. ممکن است کاربر آن کد را با آپلود مستقیم در آردوینو تست کند و بتواند مقادیر را روی نمایشگر سریال ببیند یا از کدی که در انتهای مطلب آورده شده است، برای نمایش مقادیر روی LCD و نمایشگر سریال استفاده کند.
در برنامهنویسی، برخی از کتابخانههای موردنیاز مانند MPU6050 و LCD را قرار دادهایم.
1 2 3 4 | #include<LiquidCrystal.h> LiquidCrystal lcd(8,9,10,11,12,13); #include <Wire.h> #include <MPU6050.h> |
در تابع setup، به هر دو دستگاه مقدار اولیه میدهیم و پیام خوشامدگویی را روی LCD مینویسیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void setup() { lcd.begin(16,2); lcd.createChar(0, degree); Serial.begin(9600); Serial.println("Initialize MPU6050"); while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { lcd.clear(); lcd.print("Device not Found"); Serial.println("Could not find a valid MPU6050 sensor, check wiring!"); delay(500); } count=0; mpu.calibrateGyro(); mpu.setThreshold(3); |
در تابع loop، هر ۱۰ ثانیه سه تابع را برای نمایش دما، ژیروسکوپ و قرائت شتابسنج روی LCD فرامیخوانیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | void loop() { lcd.clear(); lcd.print("Temperature"); long st=millis(); Serial.println("Temperature"); while(millis()<st+period) { lcd.setCursor(0,1); tempShow(); } lcd.clear(); lcd.print("Gyro"); delay(2000); st=millis(); Serial.println("Gyro"); while(millis()<st+period) { lcd.setCursor(0,1); gyroShow(); } lcd.clear(); lcd.print("Accelerometer"); delay(2000); st=millis(); |
سه تابع مذکور، tempShow ،gyroShow و accelShow هستند که میتوانید در کد کامل آردوینو زیر، آنها را بررسی کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | #include<LiquidCrystal.h> LiquidCrystal lcd(8,9,10,11,12,13); #include <Wire.h> #include <MPU6050.h> #define period 10000 MPU6050 mpu; int count=0; char okFlag=0; byte degree[8] = { 0b00000, 0b00110, 0b01111, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }; void setup() { lcd.begin(16,2); lcd.createChar(0, degree); Serial.begin(9600); Serial.println("Initialize MPU6050"); while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { lcd.clear(); lcd.print("Device not Found"); Serial.println("Could not find a valid MPU6050 sensor, check wiring!"); delay(500); } count=0; mpu.calibrateGyro(); mpu.setThreshold(3); lcd.clear(); lcd.print("MPU6050 Interface"); lcd.setCursor(0,1); lcd.print(" Circuit Digest"); delay(2000); lcd.clear(); } void loop() { lcd.clear(); lcd.print("Temperature"); long st=millis(); Serial.println("Temperature"); while(millis()<st+period) { lcd.setCursor(0,1); tempShow(); } lcd.clear(); lcd.print("Gyro"); delay(2000); st=millis(); Serial.println("Gyro"); while(millis()<st+period) { lcd.setCursor(0,1); gyroShow(); } lcd.clear(); lcd.print("Accelerometer"); delay(2000); st=millis(); Serial.println("Accelerometer"); while(millis()<st+period) { lcd.setCursor(0,1); accelShow(); } } void tempShow() { float temp = mpu.readTemperature(); Serial.print(" Temp = "); Serial.print(temp); Serial.println(" *C"); lcd.clear(); lcd.print("Temperature"); lcd.setCursor(0,1); lcd.print(temp); lcd.write((byte)0); lcd.print("C"); delay(400); } void gyroShow() { //lcd.setCursor(0,0); lcd.clear(); lcd.print(" X Y Z"); Vector rawGyro = mpu.readRawGyro(); Vector normGyro = mpu.readNormalizeGyro(); lcd.setCursor(0,1); lcd.print(normGyro.XAxis,1); lcd.setCursor(6,1); lcd.print(normGyro.YAxis,1); lcd.setCursor(12,1); lcd.print(normGyro.ZAxis,1); Serial.print(" Xnorm = "); Serial.print(normGyro.XAxis); Serial.print(" Ynorm = "); Serial.print(normGyro.YAxis); Serial.print(" Znorm = "); Serial.println(normGyro.ZAxis); delay(200); } void accelShow() { // lcd.setCursor(0,0); lcd.clear(); lcd.print(" X Y Z"); Vector rawAccel = mpu.readRawAccel(); Vector normAccel = mpu.readNormalizeAccel(); lcd.setCursor(0,1); lcd.print(normAccel.XAxis,1); lcd.setCursor(6,1); lcd.print(normAccel.YAxis,1); lcd.setCursor(12,1); lcd.print(normAccel.ZAxis,1); Serial.print(" Xnorm = "); Serial.print(normAccel.XAxis); Serial.print(" Ynorm = "); Serial.print(normAccel.YAxis); Serial.print(" Znorm = "); Serial.println(normAccel.ZAxis); delay(200); } |
شتابسنج و ژیروسکوپ MPU6050 هر دو برای تشخیص موقعیت و جهت هر دستگاهی بهکار میروند. ژیروسکوپ از گرانش زمین برای تعیین موقعیتهای محور x، y و z استفاده میکند و شتابسنج نیز براساس نرخ تغییر حرکت، موقعیت را تشخیص میدهد.
با عرض سلام و ارادت
سنسور های IMU بیشتر در محاسبه زوایای اویلر کاربرد دارن که از طریق اون میشه یه سیستم ناوبری رو راه اندازی کرد. گرفتن اطلاعات خام سنسور یا حتی محاسبه زوایای اویلر با این سنسور ها به راحتی قابل انجامه ولی چیزی که مهمه و به راحتی هم قابل انجام نیست کاهش نویز و رانش دیتای خروجیه که لازمش ترکیب اطلاعات سنسور توسط فیلتر های مختلف مثل فیلتر کالمن، فیلتر مکمل یا فیلتر ماهونی هست. بدون ترکیب داده ها عملا استفاده چندانی از این سنسور ها نمیشه کرد علی الخصوص در مورد پروژه های ساخت پهپاد چون سیگنال سنسور به شدت نویز پذیره.
اگر امکانش هست لطفا یه مقاله تخصصی تر در این مورد (Data fusion) معرفی بفرمایید.
متشکرم
درود بر شما .
در پاسخ باید عرض کنم در سیستم های ناوبری هوایی عموما از سینکرو وامثالهم به عنوان حسگر و نمایشگر استفاده میشود. اگر عمری باقی بماند، توضیحاتی در خصوص این سیستم ها خواهیم داد.
IMU ها برای هدایت اینرسیایی یا ناوبری کور کاربرد دارد و برای محاسبه موقعیت مکانی و هندسی با توجه به زوایا و نیرو هاست .
از این سخت افزار ها الزاما در ناوبری پرنده ها و خزنده های کوچولو موچولو استفاده نمیشود…. در بازو های روباتیک هم برای بهبود کنترل حرکت و مسایل دیگر کاربرد دارند.
سلام
ممنون از پاسخ شما.
در مورد ناوبری کوادکاپتر اگر اطلاعاتی دارید یا منابعی رو میشناسید ممنون میشم راهنمایی بفرمایید. من درگیر یه پروژه فلایت کنترل برای کواد های کمتر از 100 گرم هستم و تو بحث تعادل پرواز مشکل جدی دارم. اول از همین MPU6050 استفاده میکردم که دیدم زیاد جالب نیست رفتم سراغ BMI270 ولی بازم اون چیزی که میخوام درنمیاد و کواد به سرعت از تعادل خارج میشه. تا جایی که میدونم نمونه های تجاری فلایت کنترل هم از همین BMI270 دارن استفاده میکنن منتهی احتمالا از فیلترینگ خیلی بهتری استفاده میکنن. به هر حال اگر دیتایی در این زمینه دارید بسیار لطف میکنید اگر به اشتراک بذارید.
با سپاس