Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Tutorial de acelerômetro e giroscópio Arduino e MPU6050


Neste tutorial vamos aprender a usar o Acelerômetro e Sensor Giroscópio MPU6050 com o Arduino. Primeiro, explicarei como o MPU6050 funciona e como ler os dados dele, e depois faremos dois exemplos práticos.

Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo.

Visão geral


No primeiro exemplo, usando o ambiente de desenvolvimento Processing, faremos uma visualização 3D da orientação do sensor, e no segundo exemplo faremos uma plataforma auto-estabilizadora simples ou um DIY Gimbal. Com base na orientação do MPU6050 e em seus dados fundidos do acelerômetro e do giroscópio, controlamos os três servos que mantêm o nível da plataforma.

Como funciona


O MPU6050 IMU possui acelerômetro de 3 eixos e giroscópio de 3 eixos integrados em um único chip.

O giroscópio mede a velocidade rotacional ou taxa de mudança da posição angular ao longo do tempo, ao longo dos eixos X, Y e Z. Ele usa a tecnologia MEMS e o Efeito Coriolis para medição, mas para obter mais detalhes sobre ele, você pode verificar meu tutorial específico Como funcionam os sensores MEMS. As saídas do giroscópio são em graus por segundo, então para obter a posição angular precisamos apenas integrar a velocidade angular.

Por outro lado, o acelerômetro MPU6050 mede a aceleração da mesma forma explicada no vídeo anterior para o sensor do acelerômetro ADXL345. Resumidamente, ele pode medir a aceleração gravitacional ao longo dos 3 eixos e, usando alguma matemática de trigonometria, podemos calcular o ângulo em que o sensor está posicionado. Portanto, se fundirmos ou combinarmos os dados do acelerômetro e do giroscópio, podemos obter informações muito precisas sobre a orientação do sensor.

O MPU6050 IMU também é chamado de dispositivo de rastreamento de movimento de seis eixos ou dispositivo de 6 DoF (seis graus de liberdade), por causa de suas 6 saídas, ou as 3 saídas do acelerômetro e as 3 saídas do giroscópio.

Arduino e MPU6050


Vamos dar uma olhada em como podemos conectar e ler os dados do sensor MPU6050 usando o Arduino. Estamos usando o protocolo I2C para comunicação com o Arduino, então precisamos apenas de dois fios para conectá-lo, mais os dois fios para alimentação.

Você pode obter os componentes necessários para este tutorial do Arduino nos links abaixo:
  • MPU6050 IMU ……………………………..…. AmazôniaBanggood / AliExpress
  • Placa Arduino …………………………….…..
  • Breadboard e jump wires ………… 

Código MPU6050 Arduino


Aqui está o código do Arduino para ler os dados do sensor MPU6050. Abaixo do código você pode encontrar uma descrição detalhada do mesmo.
/*
   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)

Descrição do código: Então, primeiro precisamos incluir a biblioteca Wire.h que é usada para a comunicação I2C e definir algumas variáveis ​​necessárias para armazenar os dados.

Na seção de configuração, precisamos inicializar a biblioteca de fios e redefinir o sensor através do registro de gerenciamento de energia. Para isso, precisamos dar uma olhada no datasheet do sensor de onde podemos ver o endereço do registrador.

Além disso, se quisermos, podemos selecionar o Full-Scale Range para o acelerômetro e o giroscópio usando seus registros de configuração. Para este exemplo, usaremos a faixa padrão de +- 2g para o acelerômetro e a faixa de 250 graus/s para o giroscópio, então deixarei esta parte do 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)

Na seção de loop, começamos lendo os dados do acelerômetro. Os dados de cada eixo são armazenados em dois bytes ou registradores e podemos ver os endereços desses registradores a partir do datasheet do sensor.

Para ler todos eles, começamos com o primeiro registro e, usando a função requiestFrom(), solicitamos a leitura de todos os 6 registros para os eixos X, Y e Z. Em seguida, lemos os dados de cada registrador e, como as saídas são complementares de dois, combinamo-las adequadamente para obter os valores corretos.
// === 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 obter valores de saída de -1g a +1g, adequados para calcular os ângulos, dividimos a saída com a sensibilidade selecionada anteriormente.

Finalmente, usando essas duas fórmulas, calculamos os ângulos de rotação e inclinação a partir dos dados do 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)

Em seguida, usando o mesmo método, obtemos os dados do giroscópio.

Lemos os seis registros do giroscópio, combinamos seus dados adequadamente e os dividimos pela sensibilidade selecionada anteriormente para obter a saída em graus 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)

Aqui você pode notar que eu corrijo os valores de saída com alguns pequenos valores de erro calculados, que explicarei como os obtemos em um minuto. Então, como as saídas estão em graus por segundo, agora precisamos multiplicá-las pelo tempo para obter apenas graus. O valor de tempo é capturado antes de cada iteração de leitura usando a função 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, fundimos os dados do acelerômetro e do giroscópio usando um filtro complementar. Aqui, pegamos 96% dos dados do giroscópio porque é muito preciso e não sofre forças externas. O lado negativo do giroscópio é que ele oscila ou introduz um erro na saída com o passar do tempo. Portanto, a longo prazo, usamos os dados do acelerômetro, 4% neste caso, o suficiente para eliminar o erro de desvio do giroscópio.
// 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)

No entanto, como não podemos calcular o Yaw a partir dos dados do acelerômetro, não podemos implementar o filtro complementar nele.

Antes de darmos uma olhada nos resultados, deixe-me explicar rapidamente como obter os valores de correção de erros. Para calcular esses erros, podemos chamar a função personalizada calculate_IMU_error() enquanto o sensor está na posição plana e imóvel. Aqui fazemos 200 leituras para todas as saídas, somamos e dividimos por 200. Como estamos mantendo o sensor em posição plana, os valores de saída esperados devem ser 0. Assim, com este cálculo podemos obter o erro médio do sensor faz.
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)

Simplesmente imprimimos os valores no monitor serial e, uma vez que os conhecemos, podemos implementá-los no código conforme mostrado anteriormente, tanto para o cálculo de roll e pitch, quanto para as 3 saídas do giroscópio.

Finalmente, usando a função Serial.print podemos imprimir os valores de Roll, Pitch e Yaw no monitor serial e ver se o sensor funciona corretamente.

MPU6050 Orientation Tracking – Visualização 3D


Em seguida, para fazer o exemplo de visualização 3D basta aceitar esses dados que o Arduino está enviando pela porta serial no ambiente de desenvolvimento Processing. Aqui está o código de processamento 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)

Aqui lemos os dados recebidos do Arduino e os colocamos nas variáveis ​​Roll, Pitch e Yaw apropriadas. No loop de desenho principal, usamos esses valores para girar o objeto 3D, neste caso, é uma caixa simples com uma cor e texto específicos.

Se executarmos o esboço, podemos ver como o sensor MPU6050 é bom para rastrear a orientação. O objeto 3D rastreia a orientação do sensor com bastante precisão e também é muito responsivo.

Como mencionei, a única desvantagem é que o Yaw irá se deslocar com o tempo porque não podemos usar o filtro complementar para isso. Para melhorar isso, precisamos usar um sensor adicional. Geralmente é um magnetômetro que pode ser usado como uma correção de longo prazo para o desvio de guinada do giroscópio. No entanto, o MPU6050 realmente possui um recurso chamado Digital Motion Processor, que é usado para cálculos integrados dos dados e é capaz de eliminar o desvio de guinada.

Aqui está o mesmo exemplo 3D com o Digital Motion Processor em uso. Podemos ver o quão preciso é o rastreamento de orientação agora, sem o desvio de guinada. O processador integrado também pode calcular e produzir Quaternions que são usados ​​para representar orientações e rotações de objetos em três dimensões. Neste exemplo, estamos realmente usando quatérnios para representar a orientação que também não sofre de travamento do Gimbal que ocorre ao usar ângulos de Euler.

No entanto, obter esses dados do sensor é um pouco mais complicado do que explicamos anteriormente. Antes de tudo, precisamos conectar um fio adicional a um pino digital do Arduino. Esse é um pino de interrupção que é usado para ler esse tipo de dados do MPU6050.

O código também é um pouco mais complicado, por isso vamos usar a biblioteca i2cdevlib de Jeff Rowberg. Esta biblioteca pode ser baixada do GitHub e incluirei um link no artigo do site.

Depois de instalar a biblioteca, podemos abrir o exemplo MPU6050_DMP6 da biblioteca. Este exemplo é bem explicado com comentários para cada linha.

Aqui podemos selecionar que tipo de saída queremos, quatérnions, ângulos de Euler, guinada, pitch and roll, valor de acelerações ou quatérnions para a visualização 3D. Esta biblioteca também inclui um esboço de processamento para o exemplo de visualização 3D. Acabei de modificá-lo para obter a forma da caixa como no exemplo anterior. Aqui está o código de processamento de visualização 3D que funciona com o exemplo MPU6050_DPM6, para a saída “OUTPUT_TEAPOT” selecionada:
/*
    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)

Então aqui usando a função serialEvent() nós recebemos os quaternions vindos do Arduino, e no loop de desenho principal nós os usamos para girar o objeto 3D. Se executarmos o esboço, podemos ver como os quatérnios são bons para girar objetos em três dimensões.

Para não sobrecarregar este tutorial, coloquei o segundo exemplo, o DIY Arduino Gimbal ou plataforma Self-Stabilizing, em um artigo separado.

Sinta-se à vontade para fazer qualquer pergunta relacionada a este tutorial na seção de comentários abaixo e também não se esqueça de verificar minha coleção de projetos do Arduino.

Processo de manufatura

  1. Tutorial de bloqueio RFID do Arduino
  2. Animação de LCD e jogos
  3. Controle do Servo Motor com Arduino e MPU6050
  4. Comunicação Python3 e Arduino
  5. Rádio FM usando Arduino e RDA8057M
  6. Converta a aceleração em ângulo do sensor MPU6050 I2C
  7. Tutorial do sensor de impressão digital Arduino
  8. Tutorial do Arduino:Mini Piano
  9. Raspberry Pi e laptop Arduino
  10. Arduino Tutorial 01:Começando