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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Neste tutorial, vamos aprender como usar o sensor MPU6050 Acelerômetro e Giroscópio com o Arduino. Primeiro, explicarei como o MPU6050 funciona e como ler os dados dele, e então 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 autoestabilizadora simples ou um Gimbal DIY. Baseado na orientação do MPU6050 e seus dados fundidos de acelerômetro e giroscópio, controlamos os três servos que mantêm a plataforma nivelada.

Como Funciona

A IMU MPU6050 tem tanto acelerômetro de 3 eixos quanto giroscópio de 3 eixos integrados em um único chip.

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

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

A IMU MPU6050 também é chamada de dispositivo de rastreamento de movimento de seis eixos ou 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 ver 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.

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Você pode obter os componentes necessários para este Tutorial Arduino nos links abaixo:

  • IMU MPU6050 …………………………..…. Amazon / Banggood / AliExpress
  • Placa Arduino ………………………….…..
  • Protoboard e Fios Jumpers …………

Código Arduino MPU6050

Aqui está o código Arduino para ler os dados do sensor MPU6050. Abaixo do código, você encontra uma descrição detalhada dele.

/* Arduino e MPU6050 Acelerômetro e Giroscópio Sensor Tutorial por Dejan, https://howtomechatronics.com */ #include <Wire.h> const int MPU = 0x68; // Endereço I2C do MPU6050 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(); // Inicializa comunicação Wire.beginTransmission(MPU); // Inicia comunicação com MPU6050 // MPU=0x68 Wire.write(0x6B); // Fala com registrador 6B Wire.write(0x00); // Faz reset - coloca 0 no registrador 6B Wire.endTransmission(true); // fim da transmissão /* // Configura Sensibilidade do Acelerômetro - Escala Completa (padrão +/- 2g) Wire.beginTransmission(MPU); Wire.write(0x1C); // Fala com registrador ACCEL_CONFIG (1C hex) Wire.write(0x10); // Define bits do registrador como 00010000 (+/- 8g escala completa) Wire.endTransmission(true); // Configura Sensibilidade do Giroscópio - Escala Completa (padrão +/- 250graus/s) Wire.beginTransmission(MPU); Wire.write(0x1B); // Fala com registrador GYRO_CONFIG (1B hex) Wire.write(0x10); // Define bits do registrador como 00010000 (1000graus/s escala completa) Wire.endTransmission(true); delay(20); */ // Chame esta função se precisar obter os valores de erro do IMU para seu módulo calculate_IMU_error(); delay(20); } void loop() { // === Ler dados do acelerômetro === // Wire.beginTransmission(MPU); Wire.write(0x3B); // Inicia com registrador 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU, 6, true); // Lê 6 registradores total, cada valor de eixo armazenado em 2 registradores // Para faixa de +-2g, precisamos dividir valores brutos por 16384, segundo datasheet AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo X AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo Y AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo Z // Calculando Roll e Pitch a partir dos dados do acelerômetro accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) Veja função calculate_IMU_error() personalizada para mais detalhes accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58) // === Ler dados do giroscópio === // previousTime = currentTime; // Tempo anterior armazenado antes da leitura do tempo atual currentTime = millis(); // Leitura do tempo atual real elapsedTime = (currentTime - previousTime) / 1000; // Divide por 1000 para obter segundos Wire.beginTransmission(MPU); Wire.write(0x43); // Primeiro endereço de registrador de dados do giroscópio 0x43 Wire.endTransmission(false); Wire.requestFrom(MPU, 6, true); // Lê 4 registradores total, cada valor de eixo armazenado em 2 registradores GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // Para faixa 250graus/s, dividimos valor bruto por 131.0, segundo datasheet GyroY = (Wire.read() << 8 | Wire.read()) / 131.0; GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0; // Corrige saídas com valores de erro calculados GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56) GyroY = GyroY - 2; // GyroErrorY ~(2) GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8) // Atualmente valores brutos estão em graus por segundo, graus/s, então precisamos multiplicar por segundos (s) para obter ângulo em graus gyroAngleX = gyroAngleX + GyroX * elapsedTime; // graus/s * s = graus gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Filtro complementar - combina valores de ângulo do acelerômetro e giroscópio roll = 0.96 * gyroAngleX + 0.04 * accAngleX; pitch = 0.96 * gyroAngleY + 0.04 * accAngleY; // Imprime valores no monitor serial Serial.print(roll); Serial.print("/"); Serial.print(pitch); Serial.print("/"); Serial.println(yaw); } void calculate_IMU_error() { // Podemos chamar esta função na seção setup para calcular erro dos dados do acelerômetro e giroscópio. Daqui obteremos os valores de erro usados nas equações acima impressos no Monitor Serial. // Nota: devemos colocar a IMU plana para obter valores adequados, para que então possamos corrigir os valores // Ler valores do acelerômetro 200 vezes 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 ; // Soma todas leituras 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 soma por 200 para obter valor do erro AccErrorX = AccErrorX / 200; AccErrorY = AccErrorY / 200; c = 0; // Ler valores do giroscópio 200 vezes 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(); // Soma todas leituras GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c++; } // Divide soma por 200 para obter valor do erro GyroErrorX = GyroErrorX / 200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Imprime valores de erro no Monitor Serial 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); }

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

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Também, se quisermos, podemos selecionar a Faixa de Escala Completa para o acelerômetro e o giroscópio usando seus registradores de configuração. Para este exemplo, usaremos a faixa padrão de +-2g para o acelerômetro e 250 graus/s para o giroscópio, então deixarei esta parte do código comentada.

// Configura Sensibilidade do Acelerômetro - Escala Completa (padrão +/- 2g) Wire.beginTransmission(MPU); Wire.write(0x1C); // Fala com registrador ACCEL_CONFIG (1C hex) Wire.write(0x10); // Define bits do registrador como 00010000 (+/- 8g escala completa) Wire.endTransmission(true); // Configura Sensibilidade do Giroscópio - Escala Completa (padrão +/- 250graus/s) Wire.beginTransmission(MPU); Wire.write(0x1B); // Fala com registrador GYRO_CONFIG (1B hex) Wire.write(0x10); // Define bits do registrador como 00010000 (1000graus/s escala completa) Wire.endTransmission(true); */

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Para ler todos, começamos com o primeiro registrador, e usando a função requestFrom() solicitamos a leitura de todos os 6 registradores para os eixos X, Y e Z. Então, lemos os dados de cada registrador, e como as saídas são complemento de dois, as combinamos apropriadamente para obter os valores corretos.

// === Ler dados do acelerômetro === // Wire.beginTransmission(MPU); Wire.write(0x3B); // Inicia com registrador 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU, 6, true); // Lê 6 registradores total, cada valor de eixo armazenado em 2 registradores // Para faixa de +-2g, precisamos dividir valores brutos por 16384, segundo datasheet AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo X AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo Y AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // valor eixo Z

Para obter valores de saída de -1g a +1g, adequados para calcular os ângulos, dividimos a saída pela sensibilidade previamente selecionada.

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Finalmente, usando estas duas fórmulas, calculamos os ângulos de roll e pitch a partir dos dados do acelerômetro.

// Calculando Roll e Pitch a partir dos dados do acelerômetro accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) Veja a função calculate_IMU_error() personalizada para mais detalhes accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Lemos os seis registradores do giroscópio, combinamos seus dados apropriadamente e dividimos pela sensibilidade previamente selecionada para obter a saída em graus por segundo.

// === Ler dados do giroscópio === // previousTime = currentTime; // Tempo anterior armazenado antes da leitura do tempo atual currentTime = millis(); // Leitura do tempo atual real elapsedTime = (currentTime - previousTime) / 1000; // Divide por 1000 para obter segundos Wire.beginTransmission(MPU); Wire.write(0x43); // Primeiro endereço de registrador de dados do giroscópio 0x43 Wire.endTransmission(false); Wire.requestFrom(MPU, 6, true); // Lê 4 registradores total, cada valor de eixo armazenado em 2 registradores GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // Para faixa 250graus/s, dividimos primeiro o valor bruto por 131.0, segundo datasheet GyroY = (Wire.read() << 8 | Wire.read()) / 131.0; GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Aqui você pode notar que corrijo os valores de saída com alguns pequenos valores de erro calculados, que explicarei como obtemos em um minuto. Como as saídas estão em graus por segundo, agora precisamos multiplicá-las pelo tempo para obter apenas graus. O valor do tempo é capturado antes de cada iteração de leitura usando a função millis().

// Corrige as saídas com os valores de erro calculados GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56) GyroY = GyroY - 2; // GyroErrorY ~(2) GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8) // Atualmente os valores brutos estão em graus por segundo, graus/s, então precisamos multiplicar por segundos (s) para obter o ângulo em graus gyroAngleX = gyroAngleX + GyroX * elapsedTime; // graus/s * s = graus gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime;

Finalmente, fundimos os dados do acelerômetro e do giroscópio usando um filtro complementar. Aqui, pegamos 96% dos dados do giroscópio porque ele é muito preciso e não sofre de forças externas. O lado negativo do giroscópio é que ele deriva, ou introduz erro na saída conforme o tempo passa. Portanto, a longo prazo, usamos os dados do acelerômetro, 4% neste caso, suficiente para eliminar o erro de deriva do giroscópio.

// Filtro complementar - combina valores de ângulo do acelerômetro e giroscópio roll = 0.96 * gyroAngleX + 0.04 * accAngleX; pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

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 ver os resultados, deixe-me explicar rapidamente como obter os valores de correção de erro. Para calcular esses erros, podemos chamar a função personalizada calculate_IMU_error() enquanto o sensor está em posição plana e parada. Aqui fazemos 200 leituras para todas as saídas, somamos e dividimos por 200. Como estamos segurando o sensor em posição plana e parada, os valores de saída esperados devem ser 0. Então, com este cálculo, podemos obter o erro médio que o sensor comete.

void calculate_IMU_error() { // Podemos chamar esta função na seção setup para calcular erro dos dados do acelerômetro e giroscópio. Daqui obteremos os valores de erro usados nas equações acima impressos no Monitor Serial. // Nota: devemos colocar a IMU plana para obter valores adequados, para que então possamos corrigir os valores // Ler valores do acelerômetro 200 vezes 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 ; // Soma todas leituras 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 soma por 200 para obter valor do erro AccErrorX = AccErrorX / 200; AccErrorY = AccErrorY / 200; c = 0; // Ler valores do giroscópio 200 vezes 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(); // Soma todas leituras GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c++; } // Divide soma por 200 para obter valor do erro GyroErrorX = GyroErrorX / 200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Imprime valores de erro no Monitor Serial 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); }

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

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.

Rastreamento de Orientação MPU6050 – Visualização 3D

Em seguida, para fazer o exemplo de visualização 3D, só precisamos aceitar estes dados que o Arduino está enviando pela porta serial no ambiente de desenvolvimento Processing. Aqui está o código completo do Processing:

/* Arduino e MPU6050 IMU - Exemplo de Visualização 3D por 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); // inicia comunicação serial myPort.bufferUntil('\n'); } void draw() { translate(width/2, height/2, 0); background(233); textSize(22); text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265); // Rotaciona o objeto rotateX(radians(-pitch)); rotateZ(radians(roll)); rotateY(radians(yaw)); // Objeto 3D textSize(30); fill(0, 76, 153); box (386, 40, 200); // Desenha caixa textSize(25); fill(255, 255, 255); text("www.HowToMechatronics.com", -183, 10, 101); //delay(10); //println("ypr:\t" + angleX + "\t" + angleY); // Imprime valores para verificar se estamos obtendo valores adequados } // Ler dados da Porta Serial void serialEvent (Serial myPort) { // lê dados da Porta Serial até o caractere '.' e coloca na variável String "data" data = myPort.readStringUntil('\n'); // se obteve quaisquer bytes além do linefeed: if (data != null) { data = trim(data); // divide a string em "/" String items[] = split(data, '/'); if (items.length > 1) { //--- Roll,Pitch em graus roll = float(items[0]); pitch = float(items[1]); yaw = float(items[2]); } } }

Aqui, lemos os dados vindos do Arduino e colocamos nas variáveis apropriadas Roll, Pitch e Yaw. No loop principal draw, usamos esses valores para rotacionar o objeto 3D, neste caso uma caixa simples com cor e texto particulares.

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Como mencionei, o único lado negativo é que o Yaw derivará com o tempo porque não podemos usar o filtro complementar para ele. Para melhorar isso, precisamos usar um sensor adicional. Geralmente é um magnetômetro que pode ser usado como correção de longo prazo para a deriva do Yaw do giroscópio. No entanto, o MPU6050 na verdade tem um recurso chamado Processador de Movimento Digital (DMP) que é usado para cálculos embarcados dos dados e é capaz de eliminar a deriva do Yaw.

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Aqui está o mesmo exemplo 3D com o Processador de Movimento Digital em uso. Podemos ver quão preciso é o rastreamento de orientação agora, sem a deriva do Yaw. O processador embarcado também pode calcular e gerar Quaternions, que são usados para representar orientações e rotações de objetos em três dimensões. Neste exemplo, estamos realmente usando quaternions para representar a orientação, que também não sofre de Gimbal lock que ocorre ao usar ângulos de Euler.

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

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 para ela no artigo do site.

Uma vez instalada a biblioteca, podemos abrir o exemplo MPU6050_DMP6 da biblioteca. Este exemplo é bem explicado com comentários para cada linha.

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

Aqui podemos selecionar que tipo de saída queremos: quaternions, ângulos de Euler, yaw, pitch e roll, valores de aceleração ou quaternions para visualização 3D. Esta biblioteca também inclui um sketch Processing para o exemplo de visualização 3D. Apenas o modifiquei para obter a forma de caixa como no exemplo anterior. Aqui está o código de visualização 3D Processing que funciona com o exemplo MPU6050_DMP6, para saída "OUTPUT_TEAPOT" selecionada:

/* Arduino e MPU6050 IMU - Exemplo de Visualização 3D por 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); // inicia comunicação serial myPort.bufferUntil('\n'); } void draw() { translate(width/2, height/2, 0); background(233); textSize(22); text("Roll: " + int(roll) + " Pitch: " + int(pitch), -100, 265); // Rotaciona o objeto rotateX(radians(-pitch)); rotateZ(radians(roll)); rotateY(radians(yaw)); // Objeto 3D textSize(30); fill(0, 76, 153); box (386, 40, 200); // Desenha caixa textSize(25); fill(255, 255, 255); text("www.HowToMechatronics.com", -183, 10, 101); //delay(10); //println("ypr:\t" + angleX + "\t" + angleY); // Imprime valores para verificar se estamos obtendo valores adequados } // Ler dados da Porta Serial void serialEvent (Serial myPort) { // lê dados da Porta Serial até o caractere '.' e coloca na variável String "data" data = myPort.readStringUntil('\n'); // se obteve quaisquer bytes além do linefeed: if (data != null) { data = trim(data); // divide a string em "/" String items[] = split(data, '/'); if (items.length > 1) { //--- Roll,Pitch em graus roll = float(items[0]); pitch = float(items[1]); yaw = float(items[2]); } } }

Então, aqui usando a função serialEvent() recebemos os quaternions vindos do Arduino, e no loop principal draw os usamos para rotacionar o objeto 3D. Se rodarmos o sketch, podemos ver quão bons os quaternions são para rotacionar objetos em três dimensões.

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

Domine o MPU6050: Tutorial de Acelerômetro e Giroscópio para Arduino

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 conferir minha coleção de Projetos Arduino.

Processo de manufatura

  1. Crie uma Fechadura RFID Segura com Arduino – Guia Passo a Passo
  2. Crie Animações e Jogos Envolventes em LCD com Arduino UNO
  3. Arduino e MPU6050: Controle Preciso de Servomotores SG90 e MG996R
  4. Python 3 para Arduino UNO: Controle de Comandos Fácil e Demo com LED
  5. Construa um Rádio FM Compacto com Arduino Nano e RDA5807M
  6. Calcular Ângulos de Inclinação do MPU6050 com Arduino Nano e Visuino
  7. Projeto Sensor de Impressão Digital com Arduino Nano – Tutorial Completo
  8. Construa um Mini Piano com Arduino UNO – Tutorial Passo a Passo
  9. Construa um Laptop com Raspberry Pi 3 e Arduino: Guia Passo a Passo
  10. Tutorial Arduino Iniciante 01: Comece seu Primeiro Projeto