Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Tutorial de acelerómetro y giroscopio Arduino y MPU6050

En este tutorial aprenderemos a utilizar el sensor acelerómetro y giroscopio MPU6050 con el Arduino. Primero, explicaré cómo funciona el MPU6050 y cómo leer los datos del mismo, y luego haremos dos ejemplos prácticos.

Puede ver el siguiente video o leer el tutorial escrito a continuación.

Resumen

En el primer ejemplo, utilizando el entorno de desarrollo Processing, haremos una visualización en 3D de la orientación del sensor, y en el segundo ejemplo haremos una plataforma autoestabilizadora simple o un Gimbal de bricolaje. Basándonos en la orientación del MPU6050 y sus datos fusionados de acelerómetro y giroscopio, controlamos los tres servos que mantienen la plataforma nivelada.

Cómo funciona

La IMU MPU6050 tiene un acelerómetro de 3 ejes y un giroscopio de 3 ejes integrados en un solo chip.

El giroscopio mide la velocidad de rotación o la tasa de cambio de la posición angular a lo largo del tiempo, a lo largo de los ejes X, Y y Z. Utiliza la tecnología MEMS y el efecto Coriolis para medir, pero para obtener más detalles al respecto, puede consultar mi tutorial particular Cómo funcionan los sensores MEMS. Las salidas del giroscopio están en grados por segundo, por lo que para obtener la posición angular solo necesitamos integrar la velocidad angular.

Por otro lado, el acelerómetro MPU6050 mide la aceleración de la misma manera que se explicó en el video anterior para el sensor acelerómetro ADXL345. Brevemente, puede medir la aceleración gravitacional a lo largo de los 3 ejes y, utilizando algunas matemáticas de trigonometría, podemos calcular el ángulo en el que se coloca el sensor. Entonces, si fusionamos o combinamos los datos del acelerómetro y el giroscopio, podemos obtener información muy precisa sobre la orientación del sensor.

La IMU MPU6050 también se denomina dispositivo de seguimiento de movimiento de seis ejes o dispositivo de 6 DoF (seis grados de libertad), debido a sus 6 salidas, o las 3 salidas de acelerómetro y las 3 salidas de giroscopio.

Arduino y MPU6050

Veamos cómo podemos conectarnos y leer los datos del sensor MPU6050 usando el Arduino. Estamos utilizando el protocolo I2C para la comunicación con el Arduino, por lo que solo necesitamos dos cables para conectarlo, más los dos cables para la alimentación.

Puede obtener los componentes necesarios para este tutorial de Arduino desde los siguientes enlaces:

  • MPU6050 IMU …………………………..…. AmazonasBanggood / AliExpress
  • Placa Arduino ………………………….…..
  • Protoboard y cables de salto ………… 

Código Arduino MPU6050

Aquí está el código Arduino para leer los datos del sensor MPU6050. Debajo del código puede encontrar una descripción detallada del mismo.

/*
   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);
}Code language: Arduino (arduino)

Descripción del código: Entonces, primero debemos incluir la biblioteca Wire.h que se usa para la comunicación I2C y definir algunas variables necesarias para almacenar los datos.

En la sección de configuración, necesitamos inicializar la biblioteca de cables y restablecer el sensor a través del registro de administración de energía. Para hacer eso, debemos echar un vistazo a la hoja de datos del sensor desde donde podemos ver la dirección de registro.

Además, si queremos, podemos seleccionar el rango de escala completa para el acelerómetro y el giroscopio usando sus registros de configuración. Para este ejemplo, usaremos el rango predeterminado de +- 2 g para el acelerómetro y el rango de 250 grados/s para el giroscopio, así que dejaré esta parte del código comentada.

// 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);
  */Code language: Arduino (arduino)

En la sección de bucle empezamos leyendo los datos del acelerómetro. Los datos de cada eje se almacenan en dos bytes o registros y podemos ver las direcciones de estos registros en la hoja de datos del sensor.

Para leerlos todos, comenzamos con el primer registro, y usando la función requiestFrom() solicitamos leer los 6 registros para los ejes X, Y y Z. Luego, leemos los datos de cada registro y, dado que las salidas son complemento a dos, los combinamos adecuadamente para obtener los valores correctos.

// === 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 valueCode language: Arduino (arduino)

Para obtener valores de salida de -1g a +1g, adecuados para el cálculo de los ángulos, dividimos la salida con la sensibilidad previamente seleccionada.

Finalmente, utilizando estas dos fórmulas, calculamos los ángulos de balanceo y cabeceo a partir de los datos del acelerómetro.

// 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)Code language: Arduino (arduino)

Luego, utilizando el mismo método, obtenemos los datos del giroscopio.

Leemos los seis registros del giroscopio, combinamos sus datos adecuadamente y los dividimos por la sensibilidad previamente seleccionada para obtener la salida en grados por segundo.

// === 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;Code language: Arduino (arduino)

Aquí puede notar que corrijo los valores de salida con algunos pequeños valores de error calculados, que explicaré cómo los obtenemos en un minuto. Entonces, como las salidas están en grados por segundo, ahora debemos multiplicarlas por el tiempo para obtener solo grados. El valor de tiempo se captura antes de cada iteración de lectura mediante la función 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;Code language: Arduino (arduino)

Finalmente, fusionamos los datos del acelerómetro y el giroscopio usando un filtro complementario. Aquí, tomamos el 96% de los datos del giroscopio porque es muy preciso y no sufre fuerzas externas. La desventaja del giroscopio es que se desvía o introduce un error en la salida a medida que pasa el tiempo. Por lo tanto, a largo plazo, usamos los datos del acelerómetro, 4% en este caso, suficiente para eliminar el error de deriva del giroscopio.

// Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;Code language: Arduino (arduino)

Sin embargo, como no podemos calcular el Yaw a partir de los datos del acelerómetro, no podemos implementar el filtro complementario en él.

Antes de echar un vistazo a los resultados, déjame explicarte rápidamente cómo obtener los valores de corrección de errores. Para calcular estos errores, podemos llamar a la función personalizada compute_IMU_error() mientras el sensor está en posición plana. Aquí hacemos 200 lecturas para todas las salidas, las sumamos y las dividimos por 200. Mientras mantenemos el sensor en posición plana, los valores de salida esperados deberían ser 0. Entonces, con este cálculo podemos obtener el error promedio del sensor. hace.

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);
}Code language: Arduino (arduino)

Simplemente imprimimos los valores en el monitor serie y una vez que los conocemos, podemos implementarlos en el código como se mostró anteriormente, tanto para el cálculo de balanceo y cabeceo, como para las 3 salidas del giroscopio.

Finalmente, usando la función Serial.print podemos imprimir los valores de Roll, Pitch y Yaw en el monitor serial y ver si el sensor funciona correctamente.

MPU6050 Orientation Tracking – Visualización 3D

A continuación, para hacer el ejemplo de visualización 3D, solo necesitamos aceptar estos datos que Arduino está enviando a través del puerto serie en el entorno de desarrollo de procesamiento. Aquí está el código de procesamiento completo:

/*
    Arduino and MPU6050 IMU - 3D Visualization Example 
     by Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch,yaw;
void setup() {
  size (2560, 1440, P3D);
  myPort = new Serial(this, "COM7", 19200); // starts the serial communication
  myPort.bufferUntil('\n');
}
void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);
  // Rotate the object
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));
  
  // 3D 0bject
  textSize(30);  
  fill(0, 76, 153);
  box (386, 40, 200); // Draw box
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
  //delay(10);
  //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) { 
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('\n');
  // if you got any bytes other than the linefeed:
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, '/');
    if (items.length > 1) {
      //--- Roll,Pitch in degrees
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}Code language: Arduino (arduino)

Aquí leemos los datos entrantes del Arduino y los colocamos en las variables Roll, Pitch y Yaw apropiadas. En el ciclo de dibujo principal, usamos estos valores para rotar el objeto 3D, en este caso es un cuadro simple con un color y texto en particular.

Si ejecutamos el boceto, podemos ver qué tan bueno es el sensor MPU6050 para rastrear la orientación. El objeto 3D rastrea la orientación del sensor con bastante precisión y también responde muy bien.

Como mencioné, el único inconveniente es que Yaw se desviará con el tiempo porque no podemos usar el filtro complementario para ello. Para mejorar esto necesitamos usar un sensor adicional. Por lo general, es un magnetómetro que se puede usar como una corrección a largo plazo para la deriva de guiñada del giroscopio. Sin embargo, el MPU6050 en realidad tiene una característica que se llama Procesador de movimiento digital que se utiliza para los cálculos a bordo de los datos y es capaz de eliminar la deriva de Yaw.

Aquí está el mismo ejemplo 3D con el Procesador de movimiento digital en uso. Podemos ver qué tan preciso es el seguimiento de la orientación ahora, sin la desviación de guiñada. El procesador integrado también puede calcular y generar cuaterniones que se utilizan para representar orientaciones y rotaciones de objetos en tres dimensiones. En este ejemplo, en realidad estamos usando cuaterniones para representar la orientación que tampoco sufre el bloqueo de cardán que ocurre cuando se usan ángulos de Euler.

Sin embargo, obtener estos datos del sensor es un poco más complicado de lo que explicamos anteriormente. En primer lugar, necesitamos conectar un cable adicional a un pin digital Arduino. Ese es un pin de interrupción que se usa para leer este tipo de datos del MPU6050.

El código también es un poco más complicado, por eso vamos a usar la biblioteca i2cdevlib de Jeff Rowberg. Esta biblioteca se puede descargar desde GitHub e incluiré un enlace en el artículo del sitio web.

Una vez que instalamos la biblioteca, podemos abrir el ejemplo MPU6050_DMP6 desde la biblioteca. Este ejemplo está bien explicado con comentarios para cada línea.

Aquí podemos seleccionar qué tipo de salida queremos, cuaterniones, ángulos de Euler, guiñada, cabeceo y balanceo, valor de aceleraciones o cuaterniones para la visualización 3D. Esta biblioteca también incluye un boceto de procesamiento para el ejemplo de visualización 3D. Simplemente lo modifiqué para obtener la forma de caja como en el ejemplo anterior. Aquí está el código de procesamiento de visualización 3D que funciona con el ejemplo MPU6050_DPM6, para la salida "OUTPUT_TEAPOT" seleccionada:

/*
    Arduino and MPU6050 IMU - 3D Visualization Example 
     by Dejan, https://howtomechatronics.com
*/
import processing.serial.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
Serial myPort;
String data="";
float roll, pitch,yaw;
void setup() {
  size (2560, 1440, P3D);
  myPort = new Serial(this, "COM7", 19200); // starts the serial communication
  myPort.bufferUntil('\n');
}
void draw() {
  translate(width/2, height/2, 0);
  background(233);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);
  // Rotate the object
  rotateX(radians(-pitch));
  rotateZ(radians(roll));
  rotateY(radians(yaw));
  
  // 3D 0bject
  textSize(30);  
  fill(0, 76, 153);
  box (386, 40, 200); // Draw box
  textSize(25);
  fill(255, 255, 255);
  text("www.HowToMechatronics.com", -183, 10, 101);
  //delay(10);
  //println("ypr:\t" + angleX + "\t" + angleY); // Print the values to check whether we are getting proper values
}
// Read data from the Serial Port
void serialEvent (Serial myPort) { 
  // reads the data from the Serial Port up to the character '.' and puts it into the String variable "data".
  data = myPort.readStringUntil('\n');
  // if you got any bytes other than the linefeed:
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, '/');
    if (items.length > 1) {
      //--- Roll,Pitch in degrees
      roll = float(items[0]);
      pitch = float(items[1]);
      yaw = float(items[2]);
    }
  }
}Code language: Arduino (arduino)

Así que aquí usando la función serialEvent() recibimos los cuaterniones provenientes del Arduino, y en el bucle de dibujo principal los usamos para rotar el objeto 3D. Si ejecutamos el boceto, podemos ver lo buenos que son los cuaterniones para rotar objetos en tres dimensiones.

Para no sobrecargar este tutorial, coloqué el segundo ejemplo, DIY Arduino Gimbal o plataforma autoestabilizadora, en un artículo aparte.

Siéntase libre de hacer cualquier pregunta relacionada con este tutorial en la sección de comentarios a continuación y tampoco olvide consultar mi colección de Proyectos Arduino.


Proceso de manufactura

  1. Tutorial de bloqueo RFID de Arduino
  2. Animación LCD y juegos
  3. Control del servomotor con Arduino y MPU6050
  4. Python3 y comunicación Arduino
  5. Radio FM usando Arduino y RDA8057M
  6. Convertir la aceleración en ángulo desde el sensor MPU6050 I2C
  7. Tutorial del sensor de huellas dactilares Arduino
  8. Tutorial de Arduino:Mini piano
  9. Raspberry Pi y portátil Arduino
  10. Reconocimiento de gestos con acelerómetro y ESP
  11. Tutorial de Arduino 01:Primeros pasos