Acelerómetro e xiroscopio

Descrición

O módulo GY-521 MPU-6050 conta de un acelerómetro de 3 eixes, un xiroscopio e un sensor de temperatura.

Pódenos servir para proxectos nos que teñamos que detectar o movemento (aceleración e xiro) dun obxecto e actuar en consecuencia.

Acelerómetro

[imaxe de developers.google.com]
Un acelerómetro serve para coñecer o movemento e orientación dun dispositivo. Por exemplo, nun móbil serve para cambiar a orientación da pantalla. É un compoñente microelectromecánico (MEMS) que funciona detectando a aceleración dunha peza móbil nos tres eixes, X, Y e Z. Segundo sexa o movemento desta peza obtemos cambios na capacitancia e diferentes voltaxes nos tres eixes, voltaxes que nos valen como datos para coñecer a orientación.

[imaxe de luisllamas.es]

Xiroscopio

[imaxe de developers.google.com]
O xiroscopio é outro sistema MEMS que complementa a información sobre a orientación do dispositivo que ofrece o acelerómetro engadindo a medición da rotación ou xiro sobre si mesmo.  Grazas a el podemos medir pequenos xestos e xiros que realizamos, por exemplo, no mando dun xogo de carreiras de coches.

Cando o dispositivo xira sobre si mesmo actúa a forza de Coriolis provocando unha vibración que produce un cambio na capacitancia do sistema nos distintos eixes. Deste xeito podemos medir a velocidade angular que se produce e coñecer o xiro.

Nesta páxina hai unhas animacións moi boas para entender como funciona: lastminuteengineers.com

Conexión

A comunicación entre o sensor e a placa arduino realízase mediante o protocolo I2C, polo que a conexión é moi sinxela:

  • SDA: pin A4
  • SCL:pin A5
  • VCC a 5V e GND

Configuración

Necesitamos a biblioteca Adafruit_MPU6050.h, Wire.h e Adafruit_Sensor.h

Dependendo do módulo utilizado pode ser necesario coñecer o enderezo I2C utilizando o programa I2C scanner no teu Arduino.

//Librerías

#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

//Módulo
Adafruit_MPU6050 mpu;

void setup() {
  
 Serial.begin(9600);
 Serial.println(F("Iniciando"));
 Wire.begin();
 // 0x68 é o enderezo que obtivemos co programa I2C scanner https://playground.arduino.cc/Main/I2cScanner/
 
 if (!mpu.begin(0x68)) {
   Serial.println("Failed to find MPU6050 chip");
   while (1) {
     delay(10);
   }
 }
 
 mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
 mpu.setGyroRange(MPU6050_RANGE_250_DEG);
 mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
 
}

void loop() {
  
}

Prácticas

1. Lectura de datos

Con este programa imos ler os datos do módulo na consola:

void loop() {
  
 readMPU();
 delay(100);
 
}

// Función de lectura de datos do sensor

void readMPU( ) { 

  // Ler de datos:
  
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  // Imprimir datos na consola:
  
  Serial.print("Aceleración X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.print(" m/s^2");
  Serial.print("  ---  ");
  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.print(" rad/s");
  Serial.print(" --- ");
  Serial.print("Temperatura: ");
  Serial.print(temp.temperature);
  Serial.println("°C");
  Serial.println("");

  delay(1000);
}

2. servo

Imos mover un servo un ángulo que depende da inclinación do sensor. Conectamos o servo no pin 7 e incluímos a librería Servo.h

//Librerías

#include <Wire.h>                 
#include <Adafruit_MPU6050.h> 
#include <Adafruit_Sensor.h> 

#include <Servo.h>

//Módulo

Adafruit_MPU6050 sensorMPU;

// Servo

Servo servo1;

// Variables

int x = 0; // Eixe que imos medir

int ang  = 0;   // ängulo do servo

// Configuración

void setup() {

 servo1.attach(7);
  
 Serial.begin(9600);
 Serial.println(F("Iniciando"));

 Wire.begin();

 // 0x68 é o enderezo que obtivemos co programa I2C scanner https://playground.arduino.cc/Main/I2cScanner/
 
 if (!sensorMPU.begin(0x68)) {
   Serial.println("Failed to find sensorMPU6050 chip");
   while (1) {
     delay(10);
   }
 }
 
 sensorMPU.setAccelerometerRange(MPU6050_RANGE_16_G);
 sensorMPU.setGyroRange(MPU6050_RANGE_250_DEG);
 sensorMPU.setFilterBandwidth(MPU6050_BAND_21_HZ);
 
}

// LOOP

void loop() {
  
  sensors_event_t a, g, temp;
  sensorMPU.getEvent(&a, &g, &temp);

  x = a.acceleration.x;   // Miramos o dato en X

  ang = map(x, -5, 5, 0, 180);  // Calculamos o ángulo
  servo1.write(ang);            // Facemos que o sevo xire ata ese ángulo
  
  Serial.println("x=" + String(x) + " ang=" + String(ang));
  
}

Propostas

  • Evita que o servo tremelique engadindo un valor de sensibilidade (por exemplo, 5 graos), de modo que só se mova o servo cando a diferenza entre o valor novo e o anterior supere a sensibilidade.
  • Conecta 2 servos e fai que se movan en función da posición do sensor nos eixes X e Y.