ADX345 - Berechnung Richtungsvektor und Kalibrierung

Hallo in die Runde,

hier mal eine mathematische Verständnisfrage:

Ich versuche gerade einen G-Force-Meter zu bauen, im Einsatz ist ein MEGA2560 i.V.m. einem ADXL345, also einem 3-Achsen Beschleunigungssensor sowie ein LCD.

Ziel ist eine Anzeige ähnlich dieser:

Jetzt möchte ich aber den Sensor an beliebiger Position und damit auch in beliebiger Ausrichtung im 3D-Raum im Fahrzeug befestigen können. Und jetzt geht die Rechnerei los....

Zuerst zur geplanten Vorgehensweise:

  1. Vor der Installation die einzelnen Achsen ausmessen und die Kalibrierungswerte fest einprogrammieren
  2. Einbau
  3. Programmstart und Auslesen der Werte im Stand
    Die einzige in diesem Moment wirkende Kraft ist die Gravitation, deren Richtung (nach unten) und Stärke (1g) sind bekannt
  4. Das Fahrzeug starten und gerade nach vorne (virtuelle Y-Achse) beschleunigen

Damit habe ich zwei Vektoren, Y und Z, lotrecht zu diesen beiden Achsen ist X, das muß also auch berechenbar sein.

Nur wie?

Ich zermattere mir meine alten grauen Zellen und google mir den Wolf, aber ich komm nicht auf die Lösung. Vielleicht weil ich auch nicht genau weiß wonach ich suchen muß...

Wer kann mir einen Lösungsansatz liefern? Wie muß man bei der Berechnung der entsprechenden Korrekturwerte zum Finden des Nullpunktes vorgehen?

Sowas gibts als fertige App, aber ich will's ja verstehen und nicht nur kaufen :slight_smile:
https://itunes.apple.com/de/app/g-force-meter/id623440332?mt=8

Danke für eine Mühe!

Micha

Hallo,

ich spiele auch gerade mit einem ADXL345 rum. Man findet dazu eigentlich viel im Netz. Ich hatte dafür nach “ADXL345 Winkel” gesucht. Die Winkelberechnung erfolgt eigentlich so. Vom Gefühl haut das auch hin bei mir.

Roll und Pitch sind die errechneten Winkel. Die 4.0 und 1024 sind Werte je nach eingestellter Auflösung und Range.
Frage mich jetzt nicht wofür man den “Höhenwert” Z-Achse zur Winkelberechnung benötigt. Der bleibt ja konstant beim kippen. Habe von Vektorrechnung keine Ahnung.

    int DataX0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataX1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    int DataY0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataY1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    int DataZ0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataZ1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    xAxis = (DataX1<<8) | DataX0;  // Rohwert X-Achse
    yAxis = (DataY1<<8) | DataY0;  // Rohwert Y-Achse 
    zAxis = (DataZ1<<8) | DataZ0;  // Rohwert Z-Achse 
    float xxAxis = (float)xAxis*4.0/1024;  //  [g]
    float yyAxis = (float)yAxis*4.0/1024;  //  [g]
    float zzAxis = (float)zAxis*4.0/1024;  //  [g]
    float Roll  = (atan2(-yyAxis,zzAxis)*180.0)/3.14;
    float Pitch = (atan2(xxAxis,sqrt(yyAxis*yyAxis+zzAxis*zzAxis))*180.0)/3.14;
    Serial.print(xAxis); Serial.print('\t');   // Rohwert 
    Serial.print(yAxis); Serial.print('\t');   // Rohwert 
    Serial.print(zAxis); Serial.print('\t');   // Rohwert
    Serial.print(xxAxis,3); Serial.print('\t');  //  [g]
    Serial.print(yyAxis,3); Serial.print('\t');  //  [g]
    Serial.print(zzAxis,3); Serial.print('\t');  //  [g]
    //Serial.print(xxAxis*9.807); Serial.print('\t');  //  m/s^2 (g * 9,80665)
    //Serial.print(yyAxis*9.807); Serial.print('\t');
    //Serial.print(zzAxis*9.807); Serial.print('\t');
    Serial.print(Roll); Serial.print('\t');
    Serial.print(Pitch); Serial.print('\t');

Edit:
moment, du suchst nur nach G Kräften. Na dann brauchste nur deine nackten Sensorwerte mit Range und Auflösung zuverrechnen. Wenn zum Bsp. +/-4g eingestellt sind, mußte dafür 8 einsetzen. 1024 stehen für 10Bit.

Hallo Doc,

danke für deine Antwort. Jedoch hilft mir das leider nicht viel weiter, denn wie ich die Daten aus dem ADXL raus bekomme war mir schon bekannt. Nur, wie muß ich die dann miteinander verrechnen um

  1. Einen quasi „Nullzustand“ zu haben von dem aus ich
  2. Die Beschleunigung des Fahrzeugs ausrechnen kann

Ich muß den Sensor ja erst rechnerisch „nullen“ um daraus dann die dynamische Komponente errechnen zu können.
Also im Ausgangszustand wo nur die Erdanziehung wirkt teilt sich das 1G von mir aus zu 81% auf Z, 12% auf Y und 7% auf X auf, nur wie komme ich auf diese Werte? Messen? Ok.
Und dann kommt ja noch die Umrechnung der einzulernenden „Y-Dynamik“ dazu. Optimalerweise teilt sich diese beim Einlernen ebenfalls auf alle drei Vektoren auf. Wie verrechnen ich das mit der Gravitation?

Und dann erst kann ich ja die eigentliche Fahrdynamik darstellen.

Mir geht es hier erstmal nur um’s Verständnis, die Lösung möchte ich ja selbst erarbeiten…

Wenn du den Sensor nicht mechanisch ausrichten kannst, musst du dich mit
Vektorrechung und Koordinatentransformation auseinandersetzen.

so dass im kalibrierten System deine Beschleunigung im Ruhezustand in Richtung (0/0/-1) geht.
( oder wie auch immer du dein Koordinatensystem definierst )

Hallo,

hmm, wer nach einer Berechnung fragt bekommt dafür eine Antwort. :o
Kalibrierung: Programming and Calibration | ADXL345 Digital Accelerometer | Adafruit Learning System
Das hättest du auch selbst gefunden mit etwas suche ... :wink:

Edit:
Vielleicht hilft dir das auch noch. http://www.mikrocontroller.net/topic/302095
Das einfachste wird wohl sein, die gemessenen "0 Linienwerte" als Korrekturwerte in der Software einzusetzen.