Índice:

MPU 6050 Gyro, comunicação do acelerômetro com Arduino (Atmega328p): 5 etapas
MPU 6050 Gyro, comunicação do acelerômetro com Arduino (Atmega328p): 5 etapas
Anonim
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)
MPU 6050 Gyro, acelerômetro de comunicação com Arduino (Atmega328p)

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.

As saídas do giroscópio são em graus por segundo, portanto, para obter a posição angular, precisamos apenas integrar a velocidade angular.

Por outro lado, o acelerômetro MPU6050 mede a aceleração medindo 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.

Giroscópio de 3 eixos O MPU-6050 consiste em um giroscópio de 3 eixos que pode detectar a velocidade de rotação ao longo dos eixos x, y, z com tecnologia de sistema micro eletromecânico (MEMS). Quando o sensor é girado ao longo de qualquer eixo, uma vibração é produzida devido ao efeito Coriolis que é detectado pelo ADC de MEMS. 16 bits é usado para digitalizar a tensão para amostrar cada eixo. + / - 250, +/- 500, +/- 1000, +/- 2000 são a faixa de escala completa de saída. A velocidade angular é medida ao longo de cada eixo em graus por unidade de segundo.

Link útil: …………….

Placa Arduino:. ……….

MPU6050 IMU ……………

Etapa 1: Módulo MPU-6050

Módulo MPU-6050
Módulo MPU-6050

O módulo MPU-6050 tem 8 pinos,

INT: interrompe o pino de saída digital.

AD0: Pino LSB do endereço do escravo I2C. Este é o 0º bit no endereço escravo de 7 bits do dispositivo. Se conectado ao VCC, ele é lido como uma alteração de endereço lógico e de escravo.

XCL: pino Auxiliary Serial Clock. Este pino é usado para conectar outro pino SCL de sensores habilitados para interface I2C ao MPU-6050.

XDA: Pino auxiliar de dados seriais. Este pino é usado para conectar outro pino SDA de sensores habilitados para interface I2C ao MPU-6050.

SCL: pino do relógio serial. Conecte este pino ao pino SCL dos microcontroladores. SDA: Pino de dados seriais. Conecte este pino ao pino SDA dos microcontroladores.

GND: Pino de aterramento. Conecte este pino à conexão de aterramento.

VCC: Pino da fonte de alimentação. Conecte este pino à alimentação de + 5 Vcc. O módulo MPU-6050 tem endereço escravo (quando AD0 = 0, ou seja, não está conectado ao Vcc) como, Endereço de gravação do escravo (SLA + W): 0xD0

Endereço de leitura escravo (SLA + R): 0xD1

Etapa 2: Cálculos

Cálculos
Cálculos

Os dados do sensor do giroscópio e do acelerômetro do módulo MPU6050 consistem em dados brutos de 16 bits na forma de complemento de 2.

Os dados do sensor de temperatura do módulo MPU6050 consistem em dados de 16 bits (não na forma de complemento de 2).

Agora, suponha que tenhamos selecionado,

  • - Faixa de escala completa do acelerômetro de +/- 2g com fator de escala de sensibilidade de 16, 384 LSB (contagem) / g.
  • - Faixa de escala completa do giroscópio de +/- 250 ° / s com fator de escala de sensibilidade de 131 LSB (contagem) / ° / s. então,

Para obter dados brutos do sensor, precisamos primeiro realizar o complemento de 2 nos dados do sensor do acelerômetro e giroscópio. Depois de obter os dados brutos do sensor, podemos calcular a aceleração e a velocidade angular dividindo os dados brutos do sensor com seu fator de escala de sensibilidade da seguinte forma -

Valores do acelerômetro em g (força g)

  • Aceleração ao longo do eixo X = (dados brutos do eixo X do acelerômetro / 16384) g.
  • Aceleração ao longo do eixo Y = (dados brutos do eixo Y do acelerômetro / 16384) g.
  • Aceleração ao longo do eixo Z = (dados brutos do eixo Z do acelerômetro / 16384) g.

Valores do giroscópio em ° / s (graus por segundo)

  • Velocidade angular ao longo do eixo X = (dados brutos do eixo X do giroscópio / 131) ° / s.
  • Velocidade angular ao longo do eixo Y = (dados brutos do eixo Y do giroscópio / 131) ° / s.
  • Velocidade angular ao longo do eixo Z = (dados brutos do eixo Z do giroscópio / 131) ° / s.

Valor da temperatura em ° / c (graus por Celsius)

Temperatura em graus C = ((dados do sensor de temperatura) / 340 + 36,53) ° / c.

Por exemplo, Suponha que, após o complemento de 2 ', obtenhamos o valor bruto dos eixos X do acelerômetro = +15454

Então Ax = +15454/16384 = 0,94 g.

Mais,

Portanto, sabemos que estamos executando a uma sensibilidade de +/- 2G e +/- 250deg / s, mas como nossos valores correspondem a essas acelerações / ângulos.

Ambos são gráficos de linhas retas e podemos deduzir a partir deles que para 1G leremos 16384 e para 1degree / seg leremos 131,07 (embora o.07 seja ignorado devido ao binário), esses valores foram calculados apenas desenhando o gráfico de linha reta com 2G em 32767 e -2G em -32768 e 250 / -250 nos mesmos valores.

Portanto, agora que sabemos nossos valores de sensibilidade (16384 e 131,07), só precisamos diminuir os desvios de nossos valores e, em seguida, desviar pela sensibilidade.

Isso funcionará bem para os valores X e Y, mas como o Z foi registrado em 1G e não 0, precisaremos diminuir 1G (16384) antes de dividirmos por nossa sensibilidade.

Etapa 3: Conexões MPU6050-Atmega328p

Conexões MPU6050-Atmega328p
Conexões MPU6050-Atmega328p
Conexões MPU6050-Atmega328p
Conexões MPU6050-Atmega328p
Conexões MPU6050-Atmega328p
Conexões MPU6050-Atmega328p

Basta conectar tudo conforme mostrado no diagrama…

As conexões são dadas da seguinte forma: -

MPU6050 Arduino Nano

Pino de saída VCC 5v

Pino de aterramento GND

SDA A4 pin // dados seriais

SCL A5 pino // relógio serial

Pitch and Roll Calculation: Roll é a rotação em torno do eixo xe pitch é a rotação ao longo do eixo y.

O resultado está em radianos. (converta em graus multiplicando por 180 e dividindo por pi)

Etapa 4: códigos e explicações

Códigos e Explicações
Códigos e Explicações

/*

Tutorial do sensor de acelerômetro e giroscópio Arduino e MPU6050 por Dejan, https://howtomechatronics.com * / #include const int MPU = 0x68; // endereço MPU6050 I2C 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 a comunicação Wire.beginTransmission (MPU); // Inicia a comunicação com MPU6050 // MPU = 0x68 Wire.write (0x6B); // Fale com o registrador 6B Wire.write (0x00); // Faça reset - coloque um 0 no registro 6B Wire.endTransmission (true); // finalizar a transmissão / * // Configurar a sensibilidade do acelerômetro - Faixa de escala total (padrão +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Fale com o registrador ACCEL_CONFIG (1C hex) Wire.write (0x10); // Defina os bits de registro como 00010000 (+/- 8g intervalo de escala completa) Wire.endTransmission (true); // Configurar Sensibilidade do Gyro - Faixa de Escala Total (padrão +/- 250deg / s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Fale com o registrador GYRO_CONFIG (1B hex) Wire.write (0x10); // Defina os bits de registro como 00010000 (escala total de 1000deg / s) Wire.endTransmission (true); atraso (20); * / // Chame esta função se você precisar obter os valores de erro IMU para seu módulo calcul_IMU_error (); atraso (20); } void loop () {// === Ler dados do acelerômetro === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Comece com o registro 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, verdadeiro); // Lê o total de 6 registros, cada valor do eixo é armazenado em 2 registros // Para um intervalo de + -2g, precisamos dividir os valores brutos por 16384, de acordo com a folha de dados AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // valor do eixo X AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // valor do eixo Y AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // valor do 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 a função personalizada calcule_IMU_error () 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; // A hora anterior é armazenada antes da hora real read currentTime = millis (); // Hora atual hora real lida elapsedTime = (currentTime - previousTime) / 1000; // Divida por 1000 para obter os segundos Wire.beginTransmission (MPU); Wire.write (0x43); // Endereço do primeiro registro dos dados do giroscópio 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, verdadeiro); // Lê 4 registros no total, cada valor do eixo é armazenado em 2 registros GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // Para um intervalo de 250g / s, temos que dividir primeiro o valor bruto por 131,0, de acordo com a folha de dados GyroY = (Wire.read () << 8 | Wire.read ()) / 131,0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131,0; // Corrija 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 segundos, graus / s, então precisamos multiplicar por sendonds (s) para obter o ângulo em graus gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg / s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Filtro complementar - combina os valores do acelerômetro e do ângulo do giro roll = 0.96 * gyroAngleX + 0.04 * accAngleX; pitch = 0,96 * giroAngleY + 0,04 * accAngleY; // Imprime os valores no monitor serial Serial.print (roll); Serial.print ("/"); Serial.print (pitch); Serial.print ("/"); Serial.println (guinada); } void calcul_IMU_error () {// Podemos chamar essa função na seção de configuração para calcular o acelerômetro e o erro de dados do giroscópio. A partir daqui, obteremos os valores de erro usados nas equações acima impressos no Monitor Serial. // Observe que devemos colocar o IMU plano a fim de obter os valores adequados, para que possamos os valores corretos // Ler os valores do acelerômetro 200 vezes while (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, verdadeiro); 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 de todas as 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 ++; } // Divida a soma por 200 para obter o valor do erro AccErrorX = AccErrorX / 200; AccErrorY = AccErrorY / 200; c = 0; // Lê os valores do giroscópio 200 vezes enquanto (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, verdadeiro); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Soma todas as leituras GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131,0); GyroErrorZ = GyroErrorZ + (GyroZ / 131,0); c ++; } // Divida a soma por 200 para obter o valor do erro GyroErrorX = GyroErrorX / 200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Imprime os valores de erro no 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); } ------------------------------------------------- ---------------------------------------------- Resultados: - X = Y = Z = --------------------------------------------- ----------------------------------------------- Nota importante: - ----------------

Na seção de loop, começamos lendo os dados do acelerômetro. Os dados de cada eixo são armazenados em 2 bytes ou registros e podemos ver os endereços desses registros no 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 registro e, como as saídas são complementos de dois, nós os combinamos apropriadamente para obter os valores corretos.

Etapa 5: Compreendendo o ângulo de inclinação

Acelerômetro

A gravidade da Terra é uma aceleração constante onde a força está sempre apontando para baixo, para o centro da Terra.

Quando o acelerômetro estiver paralelo à gravidade, a aceleração medida será de 1G, quando o acelerômetro estiver perpendicular à gravidade, ele medirá 0G.

O ângulo de inclinação pode ser calculado a partir da aceleração medida usando esta equação:

θ = sin-1 (aceleração medida / aceleração da gravidade)

GyroGyro (também conhecido como sensor de taxa) é usado para medir a velocidade angular (ω).

Para obter o ângulo de inclinação de um robô, precisamos integrar os dados do giroscópio, conforme mostrado na equação abaixo:

ω = dθ / dt, θ = ∫ ω dt

Fusão do sensor do giroscópio e do acelerômetroApós estudar as características do giroscópio e do acelerômetro, sabemos que eles têm seus próprios pontos fortes e fracos. O ângulo de inclinação calculado a partir dos dados do acelerômetro tem um tempo de resposta lento, enquanto o ângulo de inclinação integrado dos dados do giroscópio está sujeito a deriva ao longo de um período de tempo. Em outras palavras, podemos dizer que os dados do acelerômetro são úteis a longo prazo, enquanto os dados do giroscópio são úteis a curto prazo.

Link para melhor compreensão: Clique aqui

Recomendado: