راه‌اندازی سنسور ماژول MPU6050 توسط آردوینو

الکترونیک و رباتیک -> ماژول ها و سنسور ها 2466 2 کاربر آکادمی پارتینه

سنسور MPU6050 شامل یک شتاب‌سنج و یک ژیروسکوپ مبتنی بر فناوری میکروالکترومکانیکی (MEMS) و یک سنسور دما است. این سنسور در تبدیل مقادیر آنالوگ به دیجیتال بسیار دقیق است؛ زیرا برای هرکانال یک مبدل آنالوگ به دیجیتال 16 بیتی دارد. همچنین قادر به ضبط همزمان مقادیر شتاب و سرعت زاویه‌ای در سه جهت محور مختصات است. پروتکل ارتباطی این ماژول  برای برقراری ارتباط با پردازنده I2C بوده و وجود پردازشگر حرکتی دیجیتال (DMP) در این ماژول به دلیل جمع‌آوری و پردازش داده‌ها از شتاب‌سنج و ژیروسکوپ باعث می‌شود بار محاسباتی از پردازشگر میزبان، مانند آردوینو و ... کم شود. در این آموزش مقادیر دما، سرعت زاویه‌ای و شتاب‌خطی توسط ماژول خوانده شده و در نهایت پس از پردازش داده‌ها مقادیر توسط آردوینو بر روی نمایشگر کاراکتری 2016 نمایش داده می‌شوند.

مواد اولیه :
# عنوان تعداد لینک
0 برد آردوینو 1 لینک خرید
1 سنسور شتاب و ژایرو (MPU6050 (GY-521 1 لینک خرید
2 سیم جامپر 1 لینک خرید
3 نمایشگر LCD کاراکتری ۱۶۰۲ 1 لینک خرید

مرحله 1 : اتصالات و دیاگرام مداری

مروری بر ویژگی های سنسور MPU6050

MPU6050 یک سنسور اینرسی 8 پین 6 محوره است. این ماژول به طور پیش‌فرض دارای پروتکل ارتباطی سریال I2C است، اما در برخی از سنسورهای Mpu6050 می‌توان با اعمال تنظیماتی بر روی رجیسترها امکان برقراری ارتباط توسط پروتکل SPI برای این ماژول را فراهم کرد.

معرفی پین های خروجی:

• Vcc: ورودی تغذیه، 3.3V / 5V
• GND: منفی تغذیه 
• SDA: پین داده I2C
• SCL: پین کلاک I2C
• XDA و SDA: این دو پین زمانی استفاده می شود که از این ماژول به عنوان Master استفاده میشود.
• ADO: انتخاب آدرس ماژول به عنوان Slave 
• INT: وقفه خارجی (اختیاری)

دیاگرام مداری 

ارتباط ماژول GY-521 با آردوینو بسیار ساده است. برای تغذیه ماژول و نمایشگر از آردوینو استفاده شده و از یک پتانسیومتر 10 کیلو اهم برای تنظیم نور پس‌زمینه نمایشگر استفاده شده است. پین های SCL وSDA  ماژول به پین‌های I2C آردوینو ( A4 و A5) و پین INT ماژول به وقفه 0 آردوینو (D2) وصل می‌شوند. RS ، RW و EN نمایشگر مستقیماً به پین‌های 8 ، GND و 9 آردوینو متصل می‌شوند. پین‌های دیتا نمایشگر مستقیماً به پین‌های دیجیتال شماره 10 ، 11 ، 12 و 13 وصل می‌شوند.

مرحله 2 : کدنویسی و تنظیمات نرم‌افزاری

در این پروژه از کتابخانه MPU6050 برای ارتباط ماژول با آردوینو استفاده شده است. بنابراین در ابتدا باید کتابخانه ماژول  MPU6050 را از GitHub دانلود کرده و در کامپایلر آردوینو IDE نصب کنیم

گام اول: در این مرحله کتابخانه‌های مورد نیاز از جمله کتابخانه‌ی مربوط به ماژول (MPU6050) ،کتابخانه نمایشگر (LCD) و کتابخانه ارتباط سریال (wire) را فراخوانی می‌کنیم.

#include<LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
#include <Wire.h>
#include <MPU6050.h>

در قسمت تنظیمات برنامه، تمامی قطعات را اندازی اولیه کرده و وضعیت سنسور را توسط نمایشگر نشان می‌دهیم.

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);

در حلقه اصلی برنامه توابعی را برای نمایش دما ، سرعت زاویه‌ای و شتاب بر روی نمایشگر  هر 10 ثانیه فراخوانی می‌کنیم.

این سه تابع عبارتند از: tempShow ، gyroShow و accelShow

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();

کد کامل برنامه:

#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);
}