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

Como rastrear a orientação com Arduino e acelerômetro ADXL345


Neste tutorial vamos aprender a medir o ângulo e a orientação da pista usando o Arduino e o sensor do acelerômetro ADXL345. Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo para obter mais detalhes.

Visão geral


Primeiro, explicarei como o sensor funciona e como ler os dados dele e, em seguida, usando o ambiente de desenvolvimento Processing, faremos uma visualização 3D da orientação do acelerômetro.

Como funciona o acelerômetro ADXL345


Para começar, vamos dar uma olhada em como funciona o sensor ADXL345. Este é um acelerômetro de 3 eixos que pode medir forças de aceleração estáticas e dinâmicas. A força gravitacional terrestre é um exemplo típico de força estática, enquanto as forças dinâmicas podem ser causadas por vibrações, movimentos e assim por diante.

A unidade de medida da aceleração é o metro por segundo ao quadrado (m/s^2). No entanto, os sensores do acelerômetro geralmente expressam as medidas em “g” ou gravidade. Um “g” é o valor da força gravitacional da Terra que é igual a 9,8 metros por segundo ao quadrado.

Assim, se tivermos um acelerômetro posicionado plano, com seu eixo Z apontando para cima, oposto à força gravitacional, a saída do eixo Z do sensor será de 1g. Por outro lado, as saídas X e Y serão zero, porque a força gravitacional é perpendicular a esses eixos e não os afeta em nada.

Se virarmos o sensor de cabeça para baixo, a saída do eixo Z será -1 g. Isso significa que as saídas do sensor devido à sua orientação à gravidade podem variar de -1g a +1g.

Então, de acordo com esses dados e usando alguns cálculos de trigonometria, podemos calcular o ângulo em que o sensor está posicionado.

Como ler dados do acelerômetro ADXL345 com Arduino


Ok, agora vamos ver como podemos ler os dados do acelerômetro ADXL345 usando o Arduino. Este sensor usa o protocolo I2C para comunicação com o Arduino, então precisamos apenas de dois fios para conectá-lo, mais os dois fios para alimentá-lo.

Você pode obter os componentes necessários para este tutorial do Arduino nos links abaixo:
  • Acelerômetro ADXL345 ………………. Amazônia / Banggood / AliExpress
  • Placa Arduino ……………………………….. 
  • Breadboard e jump wires ………… 

Código Arduino do Acelerômetro ADXL345


Aqui está o código do Arduino para ler os dados do acelerômetro ADXL345.
/*
    Arduino and ADXL345 Accelerometer Tutorial
     by Dejan, https://howtomechatronics.com
*/

#include <Wire.h>  // Wire library - used for I2C communication

int ADXL345 = 0x53; // The ADXL345 sensor I2C address

float X_out, Y_out, Z_out;  // Outputs

void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device 
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
  X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z_out = Z_out/256;

  Serial.print("Xa= ");
  Serial.print(X_out);
  Serial.print("   Ya= ");
  Serial.print(Y_out);
  Serial.print("   Za= ");
  Serial.println(Z_out);
}Code language: Arduino (arduino)

Descrição: Então, primeiro precisamos incluir a biblioteca Wire.h que é usada para a comunicação I2C. Se você quiser aprender mais sobre como a comunicação I2C funciona e como usá-la com o Arduino, você pode conferir meu outro tutorial detalhado para isso.

Cada dispositivo que utiliza a comunicação I2C possui um endereço I2C único, e este endereço pode ser encontrado na ficha técnica do sensor (Ficha técnica ADXL345). Assim, uma vez que definimos o endereço e as variáveis ​​para as três saídas, na seção de configuração, primeiro precisamos inicializar a biblioteca de fios e depois colocar o acelerômetro no modo de medição. Para isso, se olharmos novamente o datasheet, veremos que precisamos definir o bit D3 do registrador POWER_CTL em HIGH.

Então, usando a função beginTransmission() iniciamos a comunicação, então usando a função write() informamos qual registrador queremos acessar, e novamente usando a função write() colocamos o bit D3 em HIGH, escrevendo o número 8 em decimal que corresponde ao ajuste do bit D3 HIGH.
// Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device 
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 
  Wire.endTransmission();Code language: Arduino (arduino)

Na seção de loop agora lemos os dados do sensor. Os dados para cada eixo são armazenados em dois bytes ou registros. Podemos ver os endereços desses registros na folha de dados.

Para ler todos eles, começamos com o primeiro registrador, e usando a função requestionFrom() pedimos para ler os 6 registradores. Em seguida, usando a função read(), lemos os dados de cada registrador e, como as saídas são complementos de dois, combinamos adequadamente para obter os valores corretos.
// === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
  X_out = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y_out = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z_out = Z_out/256;Code language: Arduino (arduino)

Os valores de saída do sensor realmente dependem da sensibilidade selecionada, que pode variar de +- 2g a +-16g. A sensibilidade padrão é +-2g, por isso precisamos dividir a saída por 256 para obter valores de -1 a +1g. O 256 LSB/g significa que temos 256 contagens por g.

Dependendo da aplicação, podemos selecionar a sensibilidade apropriada. Nesse caso, para orientação de rastreamento, a sensibilidade de +-2g é boa, mas para aplicações em que precisamos detectar uma força de aceleração mais alta de movimentos bruscos, choques e assim por diante, podemos escolher algumas das outras faixas de sensibilidade usando o registro DATA_FORMAT e seus bits D1 e D0.

Calibração do acelerômetro ADXL345


No entanto, uma vez lidos os dados, podemos simplesmente imprimi-los no monitor serial para verificar se os valores estão conforme o esperado. No meu caso, os valores que eu estava obtendo não eram exatamente como deveriam ser, especialmente o eixo Z que teve um erro perceptível de 0,1g.

Para resolver esse problema, precisamos calibrar o acelerômetro usando os 3 registros de calibração de deslocamento, e veja como podemos fazer isso. Então, precisamos posicionar o sensor plano e imprimir os valores RAW sem dividi-los por 256.

A partir daqui podemos notar o quanto as saídas estão desligadas, no meu caso, a saída Z ficou em torno de 283. Isso é uma diferença de 27 no positivo. Agora precisamos dividir esse valor por 4, e isso nos dará o número que precisamos escrever no registrador de deslocamento do eixo Z. Se carregarmos o código agora, a saída do eixo Z será exatamente 256, ou 1g como deveria ser.
// This code goes in the SETUP section
// Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E);  // X-axis offset register
  Wire.write(1);
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F); // Y-axis offset register
  Wire.write(-2);
  Wire.endTransmission();
  delay(10);
  
  //Z-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20); // Z-axis offset register
  Wire.write(-7);
  Wire.endTransmission();
  delay(10);Code language: Arduino (arduino)

Se necessário, devemos calibrar o outro eixo usando o mesmo método. E apenas uma nota rápida que esta calibração não é gravada permanentemente nos registros. Precisamos escrever esses valores nos registradores a cada inicialização do sensor.

Quando terminarmos a calibração, podemos finalmente calcular o Roll and Pitch, ou a rotação em torno do eixo X e a rotação em torno do eixo Y em graus, usando essas duas fórmulas.
// Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
  roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
  pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;Code language: Arduino (arduino)

Para obter mais detalhes sobre como essas fórmulas funcionam, você pode verificar esta nota de aplicação da Freescale Semiconductor.

Acompanhamento de orientação do acelerômetro do Arduino e ADXL345 – visualização 3D


Ok, vamos fazer o exemplo de visualização 3D do acelerômetro agora.

Portanto, estamos usando o mesmo código, que envia os valores de Roll e Pitch pela porta serial. Aqui está o código completo do Arduino:
/*
    Arduino and ADXL345 Accelerometer - 3D Visualization Example 
     by Dejan, https://howtomechatronics.com
*/
#include <Wire.h>  // Wire library - used for I2C communication

int ADXL345 = 0x53; // The ADXL345 sensor I2C address

float X_out, Y_out, Z_out;  // Outputs
float roll,pitch,rollF,pitchF=0;

void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
 
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // Bit D3 High for measuring enable (8dec -> 0000 1000 binary)
  Wire.endTransmission();
  delay(10);

  //Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E);
  Wire.write(1);
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F);
  Wire.write(-2);
  Wire.endTransmission();
  delay(10);

  //Z-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20);
  Wire.write(-9);
  Wire.endTransmission();
  delay(10);
}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
  X_out = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
  Y_out = Y_out / 256;
  Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
  Z_out = Z_out / 256;

  // Calculate Roll and Pitch (rotation around X-axis, rotation around Y-axis)
  roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;
  pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;

  // Low-pass filter
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch;

  Serial.print(rollF);
  Serial.print("/");
  Serial.println(pitchF);
}Code language: Arduino (arduino)

Agora, no ambiente de desenvolvimento Processing, precisamos receber esses valores e usá-los para girar o objeto 3D que vamos criar. Aqui está o código de processamento completo:
/*
    Arduino and ADXL345 Accelerometer - 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;

void setup() {
  size (960, 640, P3D);
  myPort = new Serial(this, "COM8", 9600); // starts the serial communication
  myPort.bufferUntil('\n');
}

void draw() {
  translate(width/2, height/2, 0);
  background(33);
  textSize(22);
  text("Roll: " + int(roll) + "     Pitch: " + int(pitch), -100, 265);

  // Rotate the object
  rotateX(radians(roll));
  rotateZ(radians(-pitch));
  
  // 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]);
    }
  }
}Code language: Arduino (arduino)

Descrição: Então, aqui, precisamos incluir a biblioteca serial, definir a porta serial e a taxa de transmissão que precisa corresponder à taxa de transmissão do esboço do Arduino carregado. Em seguida, lemos os dados recebidos e os colocamos nas variáveis ​​roll e pitch apropriadas. No loop de desenho principal, usamos esses valores para girar o objeto 3D e, neste caso, é uma caixa simples com uma cor específica e um texto nela.

Se executarmos o esboço, o objeto 3D aparecerá e rastreará a orientação do sensor do acelerômetro. Podemos notar aqui que o objeto está realmente um pouco instável e isso ocorre porque o acelerômetro captura não apenas a força gravitacional, mas também pequenas forças geradas pelos movimentos de nossa mão. Para obter um resultado mais suave, podemos usar um filtro passa-baixa simples. Aqui eu implementei esse filtro no código do Arduino, que pega 94% do estado anterior e adiciona 6% do estado ou ângulo atual.
// Low-pass filter
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch;Code language: Arduino (arduino)

Com este filtro, podemos notar que o objeto se move muito mais suavemente agora, mas também há um efeito colateral e isso é uma resposta mais lenta. Também podemos notar que estamos perdendo a guinada, ou rotação em torno do eixo Z. Usando apenas os dados do acelerômetro de 3 eixos, não podemos calcular a guinada.

Para fazer isso e melhorar o desempenho geral do nosso sensor de rastreamento de orientação, precisamos incluir um sensor adicional, um giroscópio, e fundir seus dados com o acelerômetro.

Portanto, podemos usar o acelerômetro ADXL345 em combinação com algum sensor de giroscópio ou usar o MPU6050 IMU que possui acelerômetro de 3 eixos e giroscópio de 3 eixos integrados em um único chip. Você pode encontrar um tutorial mais detalhado sobre este sensor no meu próximo vídeo.

Espero que tenham gostado deste tutorial e aprendido algo novo. Sinta-se à vontade para fazer qualquer pergunta na seção de comentários abaixo e não se esqueça de verificar minha coleção de projetos do Arduino.

Processo de manufatura

  1. Controle do Servo Motor com Arduino e MPU6050
  2. u-blox LEA-6H 02 Módulo GPS com Arduino e Python
  3. Como ler a temperatura e umidade em Blynk com DHT11
  4. Reconhecimento de fala e síntese com Arduino
  5. Como fazer música com um Arduino
  6. Como usar NMEA-0183 com Arduino
  7. Como usar o Modbus com Arduino
  8. Máquina de café inteligente com Arduino e Bluetooth
  9. Luz inteligente animada com Alexa e Arduino
  10. Reconhecimento de fala com Arduino e BitVoicer Server