118ELEC | مجله خبری الکترونیک و رباتیک
  • خانه
  • اخبار
    • اخبار الکترونیک
    • اخبار رباتیک
  • آموزش ها
    • الکترونیک
      • الکترونیک مقدماتی
        • معرفی قطعات الکترونیک
        • تجهیزات اندازه‌گیری
      • الکترونیک پیشرفته
      • الکترونیک دیجیتال
      • الکترونیک صنعتی
    • میکروکنترلرها
      • میکروکنترلر چیست و انواع آن
    • آردوینو
      • آردوینو چیست
      • پروژه آردوینو
    • اینترنت اشیاء
      • اینترنت اشیاء مقدماتی
      • اینترنت اشیاء پیشرفته
    • شبکه‌های کامپیوتری و ارتباط داده
      • can
    • طراحی و ساخت PCB
      • روش های ساخت پی سی بی
    • باتری‌ها
      • باتری چیست؟
      • باتری لیتیوم یون
    • موتور و درایور
      • درایور موتور
      • موتور DC
    • رباتیک
      • مباحث پایه رباتیک
      • ربات مسیر یاب
      • ربات جنگجو
      • سایر ربات ها
  • پروژه
    • پروژه آردوینو
    • پروژه Esp
  • سرگرمی الکترونیک
  • درباره ما
    • درباره ما
    • تماس با ما
  • نویسنده شو!
    • راهنمای ثبت نام و درج مقاله
    • نشر مقاله
    • ثبت نام
    • ورود
    • بازیابی رمز عبور
بدون نتیجه
مشاهده همه نتیجه
  • خانه
  • اخبار
    • اخبار الکترونیک
    • اخبار رباتیک
  • آموزش ها
    • الکترونیک
      • الکترونیک مقدماتی
        • معرفی قطعات الکترونیک
        • تجهیزات اندازه‌گیری
      • الکترونیک پیشرفته
      • الکترونیک دیجیتال
      • الکترونیک صنعتی
    • میکروکنترلرها
      • میکروکنترلر چیست و انواع آن
    • آردوینو
      • آردوینو چیست
      • پروژه آردوینو
    • اینترنت اشیاء
      • اینترنت اشیاء مقدماتی
      • اینترنت اشیاء پیشرفته
    • شبکه‌های کامپیوتری و ارتباط داده
      • can
    • طراحی و ساخت PCB
      • روش های ساخت پی سی بی
    • باتری‌ها
      • باتری چیست؟
      • باتری لیتیوم یون
    • موتور و درایور
      • درایور موتور
      • موتور DC
    • رباتیک
      • مباحث پایه رباتیک
      • ربات مسیر یاب
      • ربات جنگجو
      • سایر ربات ها
  • پروژه
    • پروژه آردوینو
    • پروژه Esp
  • سرگرمی الکترونیک
  • درباره ما
    • درباره ما
    • تماس با ما
  • نویسنده شو!
    • راهنمای ثبت نام و درج مقاله
    • نشر مقاله
    • ثبت نام
    • ورود
    • بازیابی رمز عبور
بدون نتیجه
مشاهده همه نتیجه
118ELEC | مجله خبری الکترونیک و رباتیک
بدون نتیجه
مشاهده همه نتیجه

راه اندازی سنسور MPU6050 با آردوینو

ادمین 2 توسط ادمین 2
31 تیر 1400
در پروژه آردوینو
6

در این پروژه می خواهیم چگونگی راه اندازی سنسور MPU6050 با آردوینو را بررسی کنیم. سنسور ژیروسکوپ و شتاب سنج MPU6050 یک IMU یا Inertial Measurement Unit است. این سنسور دارای یک شتاب ‌سنج سه محوره و یک ژیروسکوپ سه محوره است که در یک چیپ (تراشه) کوچک مجتمع شده‌اند. خروجی ژیروسکوپ بر حسب درجه بر ثانیه است بنابراین با داشتن سرعت زاویه ای می‌توان زاویه های سنسور نسبت به محورها را به دست آورد. از طرف دیگر، شتاب‌ سنج MPU6050 ، شتاب گرانشی در امتداد هر سه محور را اندازه می‌گیرد و با کمی محاسبات مثلثاتی می‌توان زاویه های مربوط به موقعیت سنسور را به دست آورد. بنابراین، با ترکیب داده‌های خروجی ژیروسکوپ و شتاب‌ سنج، موقعیت و جهت قرار گرفتن سنسور با دقت خیلی خوبی به دست خواهد آمد.

ژیروسکوپ سه محوره

سنسور MPU6050

همانطور که گفته شد، MPU6050 دارای یک ژیروسکوپ سه محوره است که می‌تواند سرعت چرخشی سنسور را در امتداد سه محور x، y و z با استفاده از فناوری MEMS اندازه بگیرد.

شتاب‌سنج سه محوره

ماژول شتاب سنج سه محوره MMA7260

MPU6050 دارای یک شتاب‌سنج سه محوره است که می‌تواند اندازه زاویه انحراف جسم نسبت به محورهای مختصات را با استفاده از فناوری MEMS تعیین کند. شتاب در راستای محورهای مختصات که موجب انحراف جسم می‌شود، باعث تغییر اندازه ظرفیت خازن‌ها در ساختار سنسور MEMS می‌شود که با اندازه ‌گیری این تغییر می‌توان مقدار شتاب را به دست آورد. دیجیتال شدن مقادیر توسط یک ADC 16 بیتی انجام می‌شود. محدوده اندازه‌ گیری خروجی 8g ، ±4g، ±2g± و 16g± است. در حالتی که جسم روی یک سطح صاف و در وضعیت عادی خود قرار دارد، مقدار شتاب در راستای محورهای x، y و z به ترتیب 0g، 0g و 1g+ است.

سنسور دما روی چیپ

خروجی سنسور دما توسط ADC به مقدار دیجیتال تبدیل می‌شود و در خروجی ماژول قابل خواندن است.

پردازشگر حرکت دیجیتال (Digital motion Processor (DMP))

این بخش یک پردازنده تعبیه شده در ماژول برای انجام محاسبات روی داده‌های سنسور است. با خواندن رجیسترهای DMP می‌توان به مقادیر حاصل شده از بخش DMP دست پیدا کرد. وجود این بخش در MPU6050 از حجم محاسبات پردازنده میزبان مانند آردوینو می‌کاهد.

پایه‌های MPU6050

پایه های سنسور MPU6050

این ماژول دارای 8 پایه است:

INT: خروجی دیجیتال وقفه است. این پایه نشان می‌دهد که داده‌ای برای خواندن توسط میکروکنترلر در دسترس است.

AD0: LSB آدرس slave در ارتباط I2C را مشخص می‌کند. این پایه کم ارزش‌ترین بیت در آدرس 7 بیتی  slave است. در واقع زمانی که از یک میکروکنترلر برای ارتباط با چندین MPU6050 استفاده می‌شود، این پایه برای تفکیک آدرس‌ها به کار گرفته می‌شود.

XCL: خط کلاک کمکی ارتباط سریال I2C است. این پایه برای اتصال پایه SCL دیگر واسط‌های I2C به MPU6050 استفاده می‌شود.

XDA: خط داده کمکی ارتباط سریال I2C است. این پایه برای اتصال پایه SDA دیگر واسط‌های I2C به MPU6050 استفاده می‌شود.

SCL: پایه کلاک ارتباط سریال I2C است. این پایه به پایه SCL میکروکنترلر متصل می‌شود.

SDA: پایه داده ارتباط سریال I2C است. این پایه به پایه SDA میکروکنترلر متصل می‌شود.

GND: پایه زمین است.

VCC: پایه تغذیه است که ولتاژ آن می‌تواند از 3 ولت تا 5 ولت باشد.

راه اندازی سنسور MPU6050 با آردوینو

معمولا میکروکنترلرها دارای ارتباط I2C هستند و برخی از پایه‌های آن ها نیز به این ارتباط سریال اختصاص داده شده است. برای مثال در آردوینو Nano که در این مقاله برای راه‌اندازی سنسور MPU6050 استفاده شده، پایه های A4 و A5 به ترتیب برای SDA و SCL ارتباط I2C در نظر گرفته شده‌اند. بنابراین، در اتصال آردوینو و ماژول، پایه A4 آردوینو باید به SDA ماژول و پایه A5 به SCL ماژول متصل شود. یکی از ماژول‌هایی که دارای سنسور MPU6050 هستند، ماژول GY-521 است که در اینجا از آن برای راه‌اندازی سنسور MPU6050 استفاده می‌شود. علاوه بر اتصالات ارتباط I2C، زمین و تغذیه‌ی ماژول و آردوینو نیز باید به یکدیگر متصل شوند.

راه اندازی سنسور MPU6050  با آردوینو و نحوه اتصال دو ماژول به یکدیگر

کد نویسی برای راه اندازی سنسور MPU6050 با آردوینو

در این قسمت برنامه‌ای برای خواندن داده از سنسور MPU6050 آورده شده است.

/*
   Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial
   by Dejan, https://howtomechatronics.com
*/

#include <Wire.h>

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(19200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  /*
  // Configure Accelerometer Sensitivity - Full Scale Range (default +/- 2g)
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register (1C hex)
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro Sensitivity - Full Scale Range (default +/- 250deg/s)
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000deg/s full scale)
  Wire.endTransmission(true);
  delay(20);
  */
  // Call this function if you need to get the IMU error values for your module
  calculate_IMU_error();
  delay(20);

}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
  // Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
  // Correct the outputs with the calculated error values
  GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2; // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;

  // Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;
  
  // Print the values on the serial monitor
  Serial.print(roll);
  Serial.print("/");
  Serial.print(pitch);
  Serial.print("/");
  Serial.println(yaw);
}


void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  GyroErrorZ = GyroErrorZ / 200;
  // Print the error values on the Serial Monitor
  Serial.print("AccErrorX: ");
  Serial.println(AccErrorX);
  Serial.print("AccErrorY: ");
  Serial.println(AccErrorY);
  Serial.print("GyroErrorX: ");
  Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: ");
  Serial.println(GyroErrorY);
  Serial.print("GyroErrorZ: ");
  Serial.println(GyroErrorZ);
}

توضیحات کد

 در ابتدای کد کتابخانه Wire.h به منظور به کارگیری ارتباط I2C افزوده شده است. علاوه بر آن چند متغیر نیز برای ذخیره کردن داده‌ها تعریف شده است.

/*
   Arduino and MPU6050 Accelerometer and Gyroscope Sensor Tutorial
   by Dejan, https://howtomechatronics.com
*/

#include <Wire.h>

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;


در تابع setup ابتدا تنظیمات اولیه کتابخانه Wire انجام  و سپس سنسور از طریق رجیستر مدیریت تغذیه‌ی آن ریست می‌شود. برای شروع ارسال دستور به ماژول از دستور Wire.beginTransmission(Module) استفاده می‌شود. در این دستور، به جای Module آدرس ماژول مورد نظر قرار می‌گیرد. به طور کلی برقراری ارتباط با سنسور MPU6050 از طریق رجیسترهای آن انجام می‌گیرد که جزئیات آن‌ها در دیتاشیت سنسور آمده است. با مطالعه دیتاشیت سنسور مشاهده می‌شود که آدرس ماژول در رجیستر 117 به نام  “Who Am I” ذخیره شده است که به صورت پیش فرض برابر با 0x68 است. دستورات ()Wire.write و ()Wire.read به یک آدرس مشخص، داده می‌فرستد یا از آن داده می‌خواند. در نهایت، دستور ()Wire.endTransmission انتهای پیام ارسالی را به ماژول اطلاع می‌دهد.

رجیستر 0x6B آدرس مربوط به رجیستر مدیریت توان ماژول است که با نوشتن صفر در آن ماژول ریست می‌شود.

void setup() {
  Serial.begin(19200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission

 با کمک رجیسترهای پیکربندی سنسور MPU6050 می‌توان محدوده اندازه‌گیری ژیروسکوپ و شتاب‌سنج را تغییر داد. در این مثال، مقادیر پیش فرض 2g± برای شتاب سنج و 250± درجه بر ثانیه برای ژیروسکوپ در نظر گرفته شده است. بنابراین قسمت تنظیمات این رجیسترها در کد، کامنت شده است.

تابع loop با خواندن خروجی شتاب‌سنج شروع شده است. داده‌های مربوط به هر محور در دو بایت یا دو رجیستر ذخیره می‌شود. آدرس این رجیسترها در دیتاشیت سنسور آمده است.

جدول شش رجیستر که در دیتاشیت سنسور آمده است

برای خواندن هر شش رجیستر با هم، از دستور ()Wire.requestFrom استفاده می‌شود. با این دستور تمام رجیسترهای مربوط به سه محور X، Y و Z خوانده می‌شود و سپس داده‌های مربوط به هر محور از آن استخراج می‌شود. با توجه به جدول مربوط به حساسیت سنسور که در دیتاشیت آمده و محدوده اندازه‌گیری خروجی که از g– تا g+ است، خروجی باید بر 16384 تقسیم شود.

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value

در نهایت، با استفاده از روابط موجود در این فایل، می‌توان میزان چرخش Roll (چرخش حول محور X) و Pitch (چرخش حول محور Y) را محاسبه کرد. سنسور شتاب سنج نسبت به چرخش حول محور Z حساسیت ندارد. بنابراین، محاسبه زاویه Yaw به این روش انجام نمی‌شود.

// Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)

برای خواندن خروجی سنسور ژیروسکوپ از روشی مشابه استفاده می‌شود. آدرس رجیسترهای مربوط به خروجی ژیروسکوپ برای هر سه محور در دیتاشیت آمده است.

جدول آدرس رجیسترهای مربوط به خروجی ژیروسکوپ

شش رجیستر ژیروسکوپ با هم خوانده می‌شود و سپس با توجه به مقدار حساسیت برای هر LSB، خروجی ژیروسکوپ بر حسب درجه بر ثانیه محاسبه می‌شود. در این مثال، از آنجا که محدوده اندازه ‌گیری ژیروسکوپ 250± درجه بر ثانیه انتخاب شده است، مقادیر رجیسترها باید بر 131 تقسیم شوند تا خروجی بر حسب درجه بر ثانیه به دست آید.

جدول خروجی ژیروسکوپ بر حسب درجه بر ثانیه
  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;

در خط های بعدی مشاهده می‌شود که مقادیر خروجی ژیروسکوپ با در نظر گرفتن خطا اصلاح شده است. روش به دست آمدن مقادیر خطا در انتهای مقاله توضیح داده شده است. خروجی ژیروسکوپ باید در زمان ضرب شود تا مقادیر بر حسب درجه به دست آید. مقدار زمان قبل از هر تکرار حلقه با استفاده از تابع ()millis محاسبه می‌شود.

// Correct the outputs with the calculated error values
  GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2; // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;

از آنجا که تمامی ابزارهای اندازه‌گیری دارای خطا هستند، باید با روش‌هایی خطا را تا جایی که امکان دارد کاهش داد. یکی از این روش‌ها ترکیب خروجی سنسورهای مختلف است. در مورد سنسور MPU6050 ، خروجی شتاب‌سنج دارای نویز زیاد است. از طرف دیگر، خروجی ژیروسکوپ با اینکه نویز کمتری دارد اما با گذشت زمان خطای آن افزایش می یابد و از مقدار درست فاصله می‌گیرد. برای برطرف کردن این مشکل باید خروجی دو سنسور شتاب‌سنج و ژیروسکوپ را با یکدیگر ترکیب کرد. برای ترکیب خروجی‌های دو سنسور از میانگین وزن‌دار استفاده می‌شود و با توجه به اینکه خروجی سنسور شتاب‌سنج نویز زیادی دارد نباید وزن زیادی به آن تعلق بگیرد. وزن 4 درصد برای جبران انحراف خروجی ژیروسکوپ در طولانی مدت کافی است.

// Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

حال به چگونگی محاسبه مقدار خطا برای اصلاح خروجی ژیروسکوپ پرداخته می‌شود. برای به دست آوردن مقادیر خطا می‌توان از تابع ()calculate_IMU_error در زمانی که سنسور در حالت ثابت روی سطح صاف قرار دارد، استفاده کرد. در اینجا، خروجی ژیروسکوپ 200 بار خوانده و میانگین آن ها محاسبه شده است. زمانی که سنسور بدون زاویه روی سطح صاف است، انتظار می‌رود که خروجی سنسور صفر باشد. اما مشاهده می‌شود که خروجی سنسور در این حالت صفر نیست و مقادیر به دست آمده میانگین خطای سنسور را نشان می‌دهد.

void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  GyroErrorZ = GyroErrorZ / 200;
  // Print the error values on the Serial Monitor
  Serial.print("AccErrorX: ");
  Serial.println(AccErrorX);
  Serial.print("AccErrorY: ");
  Serial.println(AccErrorY);
  Serial.print("GyroErrorX: ");
  Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: ");
  Serial.println(GyroErrorY);
  Serial.print("GyroErrorZ: ");
  Serial.println(GyroErrorZ);
}


در نهایت مقادیر Roll، Pitch و Yaw در قسمت مانیتور سریال نرم افزار آردوینو قابل مشاهده است.

راه اندازی سنسور MPU6050 با آردوینو و نمایش مقادیر Roll، Pitch و Yaw بر روی مانیتور سریال
پست قبلی

معرفی سنسور ژیروسکوپ

پست بعدی

کنترل و راه اندازی موتور براشلس با آردوينو

ادمین 2

ادمین 2

پست بعدی
آموزش کنترل و راه اندازی موتور براشلس با آردوينو

کنترل و راه اندازی موتور براشلس با آردوينو

نظرات 6

  1. امیرحسین طباطبایی می گوید:
    4 سال قبل

    با سلام
    من تمام کار هارو دقیق عین اموزش انجام دادم اما وقتی میخوام خروجی رو ببینم یه اشکال و اعداد عجیب و غریب نشون میده که اصلا قابل خوندن نیستن
    توی تمام اموزش های سایت های دیگه هم اینجوری نشون میده میشه راهنماییم کنید چیکار کنم؟با تشکر

    پاسخ
    • P Y P Y می گوید:
      4 سال قبل

      سلام امیرحسین عزیز،
      اگه می‌تونید پروگرم کنید و مثلا توی exampleهای آردوینو ، برنامه blink رو بریزید و کار بکنه،
      مشکل از بادریت (Baud rate) سریال مانیتوره.

      پاسخ
  2. متین می گوید:
    3 سال قبل

    سلام چرا روی آردوینو مگا کار نمیکنه؟ آیا رجیستری رو باید عوض کرد؟
    میشه توضیح بدین ؟

    پاسخ
    • P Y P Y می گوید:
      3 سال قبل

      سلام دوست عزیز،
      با توجه به اینکه توی این کد فقط از کتابخانه wire استفاده شده و این کتابخانه از آردوینو مگا هم پشتیبانی می‌کنه،
      اگر sda و scl رو به درستی به پایه‌های متناظر (۲۰ و ۲۱) متصل کنید، نباید مشکلی در استفاده از این کد داشته باشید.

      پاسخ
  3. زی می گوید:
    3 سال قبل

    سلام من میخوام به اردینو اونو وصلش کنم کد ارور میده

    پاسخ
    • P Y P Y می گوید:
      3 سال قبل

      سلام دوست عزیز،
      چه اروری میده؟ لطفا برامون بفرستید.

      پاسخ

دیدگاهتان را بنویسید لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

راه اندازی سنسور تشخیص رنگ TCS230/TCS3200 با آردوینو

توسط 118elec .com
20 اسفند 1401
0
راه اندازی سنسور تشخیص رنگ TCS230/TCS3200 با آردوینو

در این مقاله به آموزش تشخیص رنگ با استفاده از سنسور رنگ TCS230 یا TCS3200 و آردوینو پرداخته شده است....

بیشتر بخوانید

نحوه ارتقاء مبدل XL4015

توسط 118elec .com
15 اسفند 1401
0
تغییر مبدل XL4015 با استفاده ازمحدود‌کننده‌های قابل تنظیم جریان

در این آموزش روشی ساده برای ارتقای ماژول XL4015، که یک مبدل DC به DC باک می‌باشد، با استفاده از...

بیشتر بخوانید

پیشرفت نوسان سازها در راستای پاسخ به نیازهای روز تکنولوژی

توسط نویسنده 2
14 شهریور 1401
0
پیشرفت نوسان سازها در راستای پاسخ به نیازهای روز تکنولوژی

Part components inside joystick of a console game نوسان سازهای ساعت، سیگنال مرجع دقیق زمان‌بندی‌شده‌ای برای کنترل مدار الکترونیکی ارائه...

بیشتر بخوانید

درباره ما

وبسایت خبری 118ELEC یک وبسایت تخصصی در زمینه الکترونیک و رباتیک می باشد که تمام تمرکز خود را در این زمینه گذاشته و سعی دارد تا مکانی از هر جهت بی نقص را برای کاربران این حوزه فراهم آورد. اخبار الکترونیک و رباتیک، پروژه الکترونیک و رباتیک، معرفی و آشنایی با قطعات الکترونیک، از برنامه های مهم این مجموعه می باشد.

ارتباط با ما از طریق:

118elec@gmail.com

  • اصول مقاله نویسی
  • درباره ما
  • تماس با ما

Copyright © تمام حقوق این سایت متعلق به 118elec می‌باشد.

بدون نتیجه
مشاهده همه نتیجه
  • خانه
  • اخبار
    • اخبار الکترونیک
    • اخبار رباتیک
  • آموزش ها
    • الکترونیک
      • الکترونیک مقدماتی
      • الکترونیک پیشرفته
      • الکترونیک دیجیتال
      • الکترونیک صنعتی
    • میکروکنترلرها
      • میکروکنترلر چیست و انواع آن
    • آردوینو
      • آردوینو چیست
      • پروژه آردوینو
    • اینترنت اشیاء
      • اینترنت اشیاء مقدماتی
      • اینترنت اشیاء پیشرفته
    • شبکه‌های کامپیوتری و ارتباط داده
      • can
    • طراحی و ساخت PCB
      • روش های ساخت پی سی بی
    • باتری‌ها
      • باتری چیست؟
      • باتری لیتیوم یون
    • موتور و درایور
      • درایور موتور
      • موتور DC
    • رباتیک
      • مباحث پایه رباتیک
      • ربات مسیر یاب
      • ربات جنگجو
      • سایر ربات ها
  • پروژه
    • پروژه آردوینو
    • پروژه Esp
  • سرگرمی الکترونیک
  • درباره ما
    • درباره ما
    • تماس با ما
  • نویسنده شو!
    • راهنمای ثبت نام و درج مقاله
    • نشر مقاله
    • ثبت نام
    • ورود
    • بازیابی رمز عبور

Copyright © تمام حقوق این سایت متعلق به 118elec می‌باشد.

خوش آمدید!

ورود به حساب کاربری خود در زیر

رمز عبور را فراموش کرده اید؟ ثبت نام

ایجاد حساب جدید!

پر کردن فرم های زیر برای ثبت نام

تمام زمینه ها مورد نیاز است. ورود

رمز عبور خود را بازیابی کنید

لطفا نام کاربری یا آدرس ایمیل خود را برای تنظیم مجدد رمز عبور خود وارد کنید.

ورود