MPU-6050 (GY-521) Arduino Tutorial

Ciao a tutti, eccomi di nuovo qui con un nuovo tutorial molto interessante. In questo tutorial vi mostrerò il funzionamento di un accelerometro/giroscopio con un Arduino UNO. In particolare utilizzerò un sensore InvenSense MPU-6050. 

Il sensore InvenSense MPU-6050 contiene, in un singolo integrato, un accelerometro MEMS a 3 assi ed un giroscopio MEMS a 3 assi. Con lo giroscopio possiamo misurare l’accelerazione angolare di un corpo su di un proprio asse, mentre con l’accelerometro possiamo misurare l’accelerazione di un corpo lungo una direzione. È molto preciso, in quanto ha un convertitore AD (da analogico a digitale) da 16 bit per ogni canale. Perciò cattura i canali x, y e z contemporaneamente. Il sensore possiede un protocollo di comunicazione standard I²C, quindi facile da interfacciare con il mondo arduino.

Il sensore MPU-6050 non è nemmeno costoso, forse è il più economico sul mercato, soprattutto in considerazione del fatto che combina un accelerometro e un giroscopio.

mpu6050-assi

Ecco alcune caratteristiche del sensore MPU-6050:

  • Chip con Convertitore AD a 16 bit Integrato
  • Range di misura giroscopio: ±250, 500, 1000 e 2000°/s
  • Range di misura accelerometro: +2, +4 , +8 , +16 g
  • Interfaccia: I²C
  • Alimentazione: da 3V a 5V

Potete trovare il datasheet del MPU-6050 QUI.

Per le mie prove ho acquistato un modulo GY-521 in modo d’avere il sensore MPU-6050 già pronto per l’utilizzo. Ecco lo schema elettrico del modulo GY-521 per chi vuole costruirselo da solo:

GY-521

mpu-6050

Ora passiamo al tutorial vero e proprio andando a vedere come utilizzare questo modulo con un Arduino Uno.

Lista del materiale:

  • Arduino UNO (o altro, leggi nota più in basso)
  • Modulo GY-521

Schema

GY-521_Schema_Arduino

BreadBoard

GY-521_BreadBoard_Arduino

Collegamenti per Arduino Uno:

GY-521 Arduino Uno
VCC 3.3V
GNS GND
SCL A5
SDA A4

 

N.B. : Lo schema ed i collegamenti sono indirizzati solo per Arduino Uno, ma il tutorial è valido anche per tutte le altre board di Arduino. L’unica cosa che cambia nei collegamenti sono i 2 pin I2C, ovvero SDA e SCL (Es. su Arduino Uno il pin SCL si trovare sul pin A5 mentre su Arduino Mega si trova sul pin 20). Basta consultare il datasheet o fare delle ricerche su google per trovare gli ingressi I2C della propria board.

Ora passiamo allo sketch di verifica, in questo modo verificheremo se il nostro modulo GY-521 è collegato correttamente ad Arduino.

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
 
#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

Dopo aver caricato lo sketch su Arduino aprite il Monitor Seriale.

Se uscirà questo messaggio:

I2C_YES

Avete fatto tutto bene fin ora 🙂 … Mentre se uscirà questo:

I2C_NO

Avete sicuramente sbagliato qualche collegamento 🙁 …

 

Bene! Se avete fatto la verifica ed è andato tutto bene non ci resta che proseguire il tutorial e provare le funzionalità del sensore MPU-6050, ovvero la lettura dei 3 assi (X,Y,Z) del giroscopio, dell’accelerometro e per finire anche la misurazione della temperatura in gradi celsius (°C).

Prima di tutto dovete caricate questo sketch sulla board arduino:

// MPU-6050 Short Example Sketch
#include<Wire.h>
const int MPU=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  
  Serial.print("Accelerometer: ");
  Serial.print("X = "); Serial.print(AcX);
  Serial.print(" | Y = "); Serial.print(AcY);
  Serial.print(" | Z = "); Serial.println(AcZ);
  //equation for temperature in degrees C from datasheet
  Serial.print("Temperature: "); Serial.print(Tmp/340.00+36.53); Serial.println(" C "); 
  
  Serial.print("Gyroscope: ");
  Serial.print("X = "); Serial.print(GyX);
  Serial.print(" | Y = "); Serial.print(GyY);
  Serial.print(" | Z = "); Serial.println(GyZ);
  Serial.println(" ");
  delay(333);
}

Dopodiché aprendo il Monitor Seriale si dovrebbero vedere i valori degli assi X,Y,Z dell’accelerometro, giroscopio e della temperatura in °C come nell’immagine seguente:

MPU-6050_Test

Quest’ultimo scketch è abbastanza semplice da comprendere, soprattutto se si ha una buona base di programmazione ed un pò di esperienza con arduino. Sulle variabili AcX, AcY, AcZ = accelerometro; Tmp = temperatura; GyX, GyY, GyZ = giroscopio; vengono memorizzati i valori degli assi X,Y,Z . In questo modo potrete gestire questi valori come volete voi, così come vi farò vedere tra breve.

Progetto: Gestione di due Servomotori utilizzando un modulo GY-521

Questo progetto sarà un esempio pratico per farvi capire come sia abbastanza semplice interfacciare il modulo GY-521 con Arduino.  Utilizzerò solo i valori degli assi  dell’accelerometro e calcolerò gli angoli Pitch e Roll (come descritto nel mio tutorial) per far ruotare i due servomotori da 0° a 179° in base alla posizione dell’accelerometro. Prima di proseguire vi consiglio di vedere il video seguente per capire meglio di cosa sto parlando.

Video

Se volete realizzare anche voi questo progetto ecco lo schema elettrico da utilizzare:

Schema

Prog_GY-521_Servo_Schema

BreadBoard

Prog_GY-521_Servo_BreadBoard

Come notate dallo schema elettrico ho alimentato i due servomotori con un’alimentazione esterna da 5V (Questo perchè i miei servo insieme consumano più di 500 mA (500 mA = corrente massima erogabile da una porta USB)). Ora passiamo allo sketch da caricare su Arduino.

Sketch (edit 05/04/2016)

// MPU6050 & Servo
// http://www.giuseppecaccavale.it/
// Giuseppe Caccavale

#include <SPI.h>
#include <Wire.h>
#include <Servo.h>
#define MPU 0x68  // I2C address of the MPU-6050

Servo ServoX, ServoY;
double AcX,AcY,AcZ;
int Pitch, Roll;

void setup(){
  Serial.begin(9600);
  ServoX.attach(8);
  ServoY.attach(9);
  init_MPU(); // Inizializzazione MPU6050
}
 
void loop()
{
  FunctionsMPU(); // Acquisisco assi AcX, AcY, AcZ.
    
  Roll = FunctionsPitchRoll(AcX, AcY, AcZ);   //Calcolo angolo Roll
  Pitch = FunctionsPitchRoll(AcY, AcX, AcZ);  //Calcolo angolo Pitch

  int ServoRoll = map(Roll, -90, 90, 0, 179);
  int ServoPitch = map(Pitch, -90, 90, 179, 0);

  ServoX.write(ServoRoll);
  ServoY.write(ServoPitch);


  Serial.print("Pitch: "); Serial.print(Pitch);
  Serial.print("\t");
  Serial.print("Roll: "); Serial.print(Roll);
  Serial.print("\n");

}

void init_MPU(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  delay(1000);
}

//Funzione per il calcolo degli angoli Pitch e Roll
double FunctionsPitchRoll(double A, double B, double C){
  double DatoA, DatoB, Value;
  DatoA = A;
  DatoB = (B*B) + (C*C);
  DatoB = sqrt(DatoB);
  
  Value = atan2(DatoA, DatoB);
  Value = Value * 180/3.14;
  
  return (int)Value;
}

//Funzione per l'acquisizione degli assi X,Y,Z del MPU6050
void FunctionsMPU(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,6,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
}

Spero vi sia piaciuto questo tutorial, in ogni caso vi ringrazio per la lettura. Se avete problemi non esitate a lasciare un commento. A presto, ciao! 🙂

Download archivio con tutto il progetto.

Ciao, se ti è piaciuto il mio blog e se qualche articolo ti è stato d\'aiuto, se te la senti e se vuoi, incentiva il mio lavoro offrendomi un caffè o qualunque altra cosa preferisci farmi ricevere. Cercherò di dare il meglio di me e di inserire articoli sempre più interessanti e utili 🙂
Clicca QUI per la donazione!