Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

So verfolgen Sie die Orientierung mit Arduino und dem ADXL345-Beschleunigungsmesser

In diesem Tutorial lernen wir, wie man mit dem Arduino und dem Beschleunigungssensor ADXL345 die Winkel- und Spurausrichtung misst. Sie können sich das folgende Video ansehen oder das schriftliche Tutorial unten lesen, um weitere Einzelheiten zu erfahren.

Übersicht

Zuerst werde ich erklären, wie der Sensor funktioniert und wie die Daten daraus gelesen werden, und dann werden wir mithilfe der Processing-Entwicklungsumgebung eine 3D-Visualisierung der Ausrichtung des Beschleunigungssensors erstellen.

Funktionsweise des ADXL345-Beschleunigungsmessers

Schauen wir uns zunächst an, wie der ADXL345-Sensor funktioniert. Dies ist ein 3-Achsen-Beschleunigungsmesser, der sowohl statische als auch dynamische Beschleunigungskräfte messen kann. Die Erdanziehungskraft ist ein typisches Beispiel für statische Kraft, während dynamische Kräfte durch Vibrationen, Bewegungen usw. verursacht werden können.

Die Maßeinheit für die Beschleunigung ist Meter pro Quadratsekunde (m/s^2). Beschleunigungssensoren drücken die Messungen jedoch normalerweise in „g“ oder Schwerkraft aus. Ein „g“ ist der Wert der Erdanziehungskraft, die 9,8 Meter pro Quadratsekunde entspricht.

Wenn wir also einen Beschleunigungsmesser haben, der flach positioniert ist und dessen Z-Achse nach oben zeigt, entgegengesetzt zur Gravitationskraft, beträgt die Z-Achsen-Ausgabe des Sensors 1 g. Andererseits sind die X- und Y-Ausgänge Null, da die Gravitationskraft senkrecht zu diesen Achsen steht und sie überhaupt nicht beeinflusst.

Wenn wir den Sensor auf den Kopf stellen, beträgt die Ausgabe auf der Z-Achse -1 g. Das bedeutet, dass die Ausgänge des Sensors aufgrund seiner Ausrichtung zur Schwerkraft von -1 g bis +1 g variieren können.

Anhand dieser Daten und mithilfe einiger Trigonometrie-Mathematik können wir also den Winkel berechnen, in dem der Sensor positioniert ist.

So lesen Sie ADXL345-Beschleunigungsmesserdaten mit Arduino

Ok, jetzt wollen wir sehen, wie wir die ADXL345-Beschleunigungsmesserdaten mit dem Arduino lesen können. Dieser Sensor verwendet das I2C-Protokoll für die Kommunikation mit dem Arduino, sodass wir nur zwei Drähte zum Anschließen benötigen, plus die zwei Drähte für die Stromversorgung.

Die für dieses Arduino-Tutorial benötigten Komponenten erhalten Sie über die folgenden Links:

  • ADXL345 Beschleunigungsmesser ………………. Amazon / Banggood / AliExpress
  • Arduino-Board …………………………….. 
  • Steckbrett und Schaltdrähte ………… 

ADXL345 Accelerometer Arduino Code

Hier ist der Arduino-Code zum Lesen der ADXL345-Beschleunigungsmesserdaten.

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

Beschreibung: Also müssen wir zuerst die Wire.h-Bibliothek einbinden, die für die I2C-Kommunikation verwendet wird. Wenn Sie mehr darüber erfahren möchten, wie die I2C-Kommunikation funktioniert und wie sie mit Arduino verwendet wird, können Sie mein anderes ausführliches Tutorial dafür lesen.

Jedes Gerät, das die I2C-Kommunikation verwendet, hat eine eindeutige I2C-Adresse, und diese Adresse finden Sie im Datenblatt des Sensors (ADXL345-Datenblatt). Nachdem wir also die Adresse und die Variablen für die drei Ausgänge im Setup-Bereich definiert haben, müssen wir zuerst die Drahtbibliothek initialisieren und dann den Beschleunigungssensor in den Messmodus versetzen. Wenn wir uns das Datenblatt noch einmal ansehen, sehen wir, dass wir dazu das Bit D3 des POWER_CTL-Registers auf HIGH setzen müssen.

Mit der Funktion beginTransmission() starten wir also die Kommunikation, dann teilen wir mit der Funktion write() mit, auf welches Register wir zugreifen wollen, und wieder mit der Funktion write() setzen wir das D3-Bit auf HIGH, indem wir die Zahl 8 hineinschreiben dezimal, die dem Setzen des Bits D3 HIGH entsprechen.

// 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(); Codesprache:Arduino (arduino) 

Im Schleifenabschnitt lesen wir nun die Daten vom Sensor. Die Daten für jede Achse werden in zwei Bytes oder Registern gespeichert. Die Adressen dieser Register können wir dem Datenblatt entnehmen.

Um sie alle zu lesen, beginnen wir mit dem ersten Register und mit der Funktion requestionFrom() bitten wir Sie, die 6 Register zu lesen. Dann lesen wir mit der Funktion read() die Daten aus jedem Register, und da die Ausgänge Zweierkomplemente sind, kombinieren wir sie entsprechend, um die richtigen Werte zu erhalten.

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

Die Ausgangswerte des Sensors hängen tatsächlich von der gewählten Empfindlichkeit ab, die von +-2 g bis +-16 g variieren kann. Die Standardempfindlichkeit ist +-2g, deshalb müssen wir die Ausgabe durch 256 teilen, um Werte von -1 bis +1g zu erhalten. Die 256 LSB/g bedeutet, dass wir 256 Zählungen pro g haben.

Je nach Anwendung können wir die passende Empfindlichkeit auswählen. In diesem Fall ist für die Tracking-Orientierung eine Empfindlichkeit von +-2 g in Ordnung, aber für Anwendungen, bei denen wir eine höhere Beschleunigungskraft von plötzlichen Bewegungen, Stößen usw. erfassen müssen, können wir einige der anderen Empfindlichkeitsbereiche mithilfe des DATA_FORMAT-Registers und auswählen seine D1- und D0-Bits.

Kalibrierung des ADXL345-Beschleunigungsmessers

Sobald wir die Daten gelesen haben, können wir sie jedoch einfach auf dem seriellen Monitor drucken, um zu überprüfen, ob die Werte wie erwartet sind. In meinem Fall waren die Werte, die ich erhielt, nicht genau so, wie sie sein sollten, insbesondere die Z-Achse, die einen merklichen Fehler von 0,1 g aufwies.

Um dieses Problem zu lösen, müssen wir den Beschleunigungsmesser mit den 3 Offset-Kalibrierungsregistern kalibrieren, und hier ist, wie wir das tun können. Also müssen wir den Sensor flach positionieren und die RAW-Werte drucken, ohne sie durch 256 zu teilen.

Von hier aus können wir jetzt feststellen, wie stark die Ausgänge ausgeschaltet sind. In meinem Fall lag der Z-Ausgang bei etwa 283. Das ist eine positive Differenz von 27. Jetzt müssen wir diesen Wert durch 4 teilen, und das ergibt die Zahl, die wir in das Offset-Register der Z-Achse schreiben müssen. Wenn wir den Code jetzt hochladen, ist die Ausgabe der Z-Achse genau 256 oder 1 g, wie es sein sollte.

// 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); Codesprache:Arduino (arduino) 

Bei Bedarf sollten wir die andere Achse mit der gleichen Methode kalibrieren. Und nur eine kurze Anmerkung, dass diese Kalibrierung nicht dauerhaft in die Register geschrieben wird. Wir müssen diese Werte bei jedem Einschalten des Sensors in die Register schreiben.

Wenn wir mit der Kalibrierung fertig sind, können wir nun mit diesen beiden Formeln endlich Roll und Pitch, bzw. die Rotation um die X-Achse und die Rotation um die Y-Achse in Grad berechnen.

// 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; Codesprache:Arduino (arduino) 

Weitere Einzelheiten zur Funktionsweise dieser Formeln finden Sie in diesem Anwendungshinweis von Freescale Semiconductor.

Arduino und ADXL345 Accelerometer Orientation Tracking – 3D-Visualisierung

Ok, machen wir jetzt das Beschleunigungssensor-3D-Visualisierungsbeispiel.

Wir verwenden also denselben Code, der die Roll- und Pitch-Werte über die serielle Schnittstelle sendet. Hier ist der vollständige Arduino-Code:

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

Jetzt müssen wir in der Processing-Entwicklungsumgebung diese Werte empfangen und sie verwenden, um das 3D-Objekt zu drehen, das wir erstellen werden. Hier ist der vollständige Verarbeitungscode:

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

Beschreibung: Hier müssen wir also die serielle Bibliothek einschließen, den seriellen Port und die Baudrate definieren, die mit der Baudrate des hochgeladenen Arduino-Sketch übereinstimmen muss. Dann lesen wir die eingehenden Daten und setzen sie in die entsprechenden Roll- und Pitch-Variablen. In der Hauptzeichnungsschleife verwenden wir diese Werte, um das 3D-Objekt zu drehen, und in diesem Fall ist das ein einfaches Feld mit einer bestimmten Farbe und einem Text darauf.

Wenn wir die Skizze ausführen, erscheint das 3D-Objekt und verfolgt die Ausrichtung des Beschleunigungssensors. Wir können hier feststellen, dass das Objekt tatsächlich etwas wackelt, und das liegt daran, dass der Beschleunigungsmesser nicht nur die Gravitationskraft erfasst, sondern auch kleine Kräfte, die durch die Bewegungen unserer Hand erzeugt werden. Um ein glatteres Ergebnis zu erhalten, können wir einen einfachen Tiefpassfilter verwenden. Hier habe ich einen solchen Filter im Arduino-Code implementiert, der 94 % des vorherigen Zustands nimmt und 6 % des aktuellen Zustands oder Winkels hinzufügt.

// Low-pass filter
  rollF = 0.94 * rollF + 0.06 * roll;
  pitchF = 0.94 * pitchF + 0.06 * pitch; Codesprache:Arduino (arduino) 

Mit diesem Filter können wir feststellen, dass sich das Objekt jetzt viel flüssiger bewegt, aber es gibt auch einen Nebeneffekt und das ist eine langsamere Reaktionsfähigkeit. Wir können auch feststellen, dass uns das Gieren oder die Drehung um die Z-Achse fehlt. Wenn wir nur die Daten des 3-Achsen-Beschleunigungsmessers verwenden, können wir das Gieren nicht berechnen.

Um dies zu tun und die Gesamtleistung unseres Orientierungsverfolgungssensors zu verbessern, müssen wir tatsächlich einen zusätzlichen Sensor, ein Gyroskop, einbauen und seine Daten mit dem Beschleunigungsmesser verschmelzen.

Wir können also entweder den ADXL345-Beschleunigungsmesser in Kombination mit einem Gyroskopsensor verwenden oder die MPU6050-IMU verwenden, die sowohl einen 3-Achsen-Beschleunigungsmesser als auch ein 3-Achsen-Gyroskop auf einem einzigen Chip integriert hat. Eine ausführlichere Anleitung zu diesem Sensor finden Sie in meinem nächsten Video.

Ich hoffe, Ihnen hat dieses Tutorial gefallen und Sie haben etwas Neues gelernt. Fühlen Sie sich frei, Fragen im Kommentarbereich unten zu stellen, und vergessen Sie nicht, meine Sammlung von Arduino-Projekten zu überprüfen.


Herstellungsprozess

  1. Steuerung des Servomotors mit Arduino und MPU6050
  2. u-blox LEA-6H 02 GPS-Modul mit Arduino und Python
  3. So liest man Temperatur und Luftfeuchtigkeit auf Blynk mit DHT11
  4. Spracherkennung und -synthese mit Arduino
  5. Wie man mit einem Arduino Musik macht
  6. So verwenden Sie NMEA-0183 mit Arduino
  7. So verwenden Sie Modbus mit Arduino
  8. Smarte Kaffeemaschine mit Arduino und Bluetooth
  9. Animiertes Smart Light mit Alexa und Arduino
  10. Spracherkennung mit Arduino und BitVoicer Server