Forum: Mikrocontroller und Digitale Elektronik BMA020: Fehlerhafte z-Achse oder Denkfehler?


von Daniel V. (voda) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo und guten Morgen liebes Forum.

Ich habe hier einen BMA020 und dieser gibt mir einen m.E. unplausiblen 
z-Wert heraus, die Werte für x und y scheinen zu stimmen.

Hier mein Code zum Auslesen:
1
float bma020_read_accel(float* acc)
2
{  
3
  uint8_t tmp1, tmp2;
4
  int16_t acc_s[3];
5
  
6
  /* Lese LSB  acc_x */
7
  tmp1 = bma020_read_register(0x02);
8
  delay_us(80);
9
  /* Lese MSB  acc_x */
10
  tmp2 = bma020_read_register(0x03);
11
  delay_us(80);
12
  acc_s[0] = ((uint16_t)tmp2 << 8) | tmp1;
13
  acc_s[0] >>= 6;
14
  
15
  /* Lese LSB acc_y */
16
  tmp1 = bma020_read_register(0x04);
17
  delay_us(80);
18
  /* Lese MSB acc_y */
19
  tmp2 = bma020_read_register(0x05);
20
  delay_us(80);
21
  acc_s[1] = ((uint16_t)tmp2 << 8) | tmp1;
22
  acc_s[1] >>= 6;
23
  
24
  /* Lese LSB acc_z */
25
  tmp1 = bma020_read_register(0x06);
26
  delay_us(80);
27
  /* Lese MSB of acc_z */
28
  tmp2 = bma020_read_register(0x07);
29
  delay_us(80);
30
  acc_s[2] = ((uint16_t)tmp2 << 8) | tmp1;
31
  acc_s[2] >>= 6;
32
  
33
  /* Lese Bereich */
34
  tmp1 = bma020_read_register(0x14);
35
  delay_us(80);
36
  tmp1 = (tmp1 >> 3) & 0x03;
37
  
38
  /* Berechne die Beschleunigung */
39
  switch (tmp1)
40
  {
41
   case 0: // 2g
42
     tmp2 = 2;
43
     break;
44
   case 1: // 4g
45
     tmp2 = 4;
46
     break;
47
   case 2: // 8g
48
     tmp2 = 8;
49
     break;
50
   default:
51
     tmp2 = 0;
52
  }
53
  acc[0] = (float)acc_s[0] * 9.8f * tmp2 / 512.0f;
54
  acc[1] = (float)acc_s[1] * 9.8f * tmp2 / 512.0f;
55
  acc[2] = (float)acc_s[2] * 9.8f * tmp2 / 512.0f;
56
  
57
//return sqrtf(acc[0] * acc[0] + acc[1] * acc[1] + acc[2] * acc[2]);
58
}

Habe ich irgendwo einen Denkfehler? Auch ändern sich die Werte kaum, 
außer in z-Richtung.

Danke und Gruß
Daniel

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Der Sensor liegt etwas schräg und misst die 9,81 m/s² Erdbeschleunigung.

Falls er flach auf dem Tisch liegt, sollte man sich IMO eher die X und Y 
Werte mal ansehen. Schau Dir auch mal die Rohwerte an, einfache Float 
Anzeigen haben gerne mal Bugs.

von Daniel V. (voda) Benutzerseite


Angehängte Dateien:

Lesenswert?

Jim M. schrieb:
> Der Sensor liegt etwas schräg und misst die 9,81 m/s²
> Erdbeschleunigung.
>
> Falls er flach auf dem Tisch liegt, sollte man sich IMO eher die X und Y
> Werte mal ansehen. Schau Dir auch mal die Rohwerte an, einfache Float
> Anzeigen haben gerne mal Bugs.

Der Sensor liegt flach auf den Tisch bzw ist verbaut auf meiner Platine.
Hebe und senke ich den Sensor also in z-Richtung ändern sich die Werte, 
jedoch nicht in x und y-Richtung.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Ja, ist doch alles richtig so.
Die Erdanziehung bewirkt eine permanente Beschleunigung nach unten, 
deswegen fallen alle Sachen nach unten, wenn man sie loslässt.

von Daniel V. (voda) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Ja, ist doch alles richtig so.
> Die Erdanziehung bewirkt eine permanente Beschleunigung nach unten,
> deswegen fallen alle Sachen nach unten, wenn man sie loslässt.

Das ist richtig, aber wenn ich z.B. die Beschleunigung in x bzw in y- 
Richtung bestimmen will, ist das ja ein Vektor g=[x,y,z]. Die Länge des 
Vektors (Wurzel aus der Summe der Quadratwerten) gibt ja meine 
Gesamteschleunigung an. Wenn ich dies integrieren möchte (im diesen 
Falle numerisch) kommt nur Unsinn raus, klar, weil der Sensor zum 
Erdmittelpunkt hin beschleunigt wird.

Ich wurde stuzig, als ich dies hier gelesen habe:

http://meineweltinmeinemkopf.blogspot.de/2012/06/beschleunigungssensor-auslesen-mit_3.html

Der Verfasser hat für z ganz andere Werte ermittelt.

Eigentlich interessiere ich mich nur im Endeffekt für die 
Geschwindigkeiten in x- und y- Richtung, welche ich mir aus den 
gelieferten Werten berechnen wollte.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Daniel V. schrieb:
> Ich habe hier einen BMA020 und dieser gibt mir einen m.E. unplausiblen
> z-Wert heraus

Was ist daran unplausibel?

Daniel V. schrieb:
> Wenn ich dies integrieren möchte (im diesen
> Falle numerisch) kommt nur Unsinn raus, klar, weil der Sensor zum
> Erdmittelpunkt hin beschleunigt wird.

Wenn du (blind) integrieren willst, musst du natürlich alle auf den 
Gegenstand wirkenden Kräfte berücksichtigen, nicht nur das, was der 
Beschleunigungssensor erfasst. Der Tisch, auf dem er liegt, kompensiert 
die Beschleunigungskräft in Richtung der Schwerebeschleunigung. Die 
musst du für die Berechnung der Bewegung schon abziehen. Lass deinen 
Sensor doch mal einen freien Fall machen, nachdem du den Offset 
abgeglichen hast.

von Stefan F. (Gast)


Lesenswert?

> kommt nur Unsinn raus

Du möchtest vermutlich die Erdanziehung heraus rechnen. Das ist ganz 
einfach: Beim Programmstart soll das Gerät auf einer ebene Fläche 
stehen. Dabei leist du die Werte der drei Achsen aus und speicherst sie 
als Offset ab (die haben sowieso alle einen Offset - auch ohne 
Beschleunigung).

Danach darf das Gerät bewegt/beschleunigt werden. Nun ziehst du immer 
die drei Offset Werte von den aktuellen Messwerten ab und machst damit 
deine weitere Berechnung. Dann kommt genau das heraus, was du erwartest.

Schau mal in die Bedienungsanleitung von fliegenden Spielzeugen. Die 
machen das nämlich alle genau so.

> Lass deinen Sensor doch mal einen freien Fall machen

Genau, nur dann liefern alle drei Achsen den Wert 0 (wenn sie ideal 
wären und keinen Offset hätten.

von Daniel V. (voda) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Du möchtest vermutlich die Erdanziehung heraus rechnen. Das ist ganz
> einfach: Beim Programmstart soll das Gerät auf einer ebene Fläche
> stehen. Dabei leist du die Werte der drei Achsen aus und speicherst sie
> als Offset ab (die haben sowieso alle einen Offset - auch ohne
> Beschleunigung).
>
> Danach darf das Gerät bewegt/beschleunigt werden. Nun ziehst du immer
> die drei Offset Werte von den aktuellen Messwerten ab und machst damit
> deine weitere Berechnung. Dann kommt genau das heraus, was du erwartest.

Ahhh, jetzt wird mir das klar, das heißt, ich lese die ersten Werte in 
einer Offset-Variable und ziehe diese voneinander ab. Mache ich das 
sinnvollerweise im µC oder später im Matlab-Programm, Ich wüsste jetzt 
gerade nicht, wie ich das gerade umsetzen soll :(

von Wolfgang (Gast)


Lesenswert?

Daniel V. schrieb:
> Mache ich das
> sinnvollerweise im µC oder später im Matlab-Programm, Ich wüsste jetzt
> gerade nicht, wie ich das gerade umsetzen soll :(

Macht dir die Subtraktion Sorgen oder was weisst du gerade nicht?

von Daniel V. (voda) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> Daniel V. schrieb:
>> Mache ich das
>> sinnvollerweise im µC oder später im Matlab-Programm, Ich wüsste jetzt
>> gerade nicht, wie ich das gerade umsetzen soll :(
>
> Macht dir die Subtraktion Sorgen oder was weisst du gerade nicht?

Alles gut.

In der Main lese ich diese Werte erstmalig und ziehe diese dann in der 
while-Schleife voneinander ab ;)

von Wolfgang (Gast)


Lesenswert?

Daniel V. schrieb:
> In der Main lese ich diese Werte erstmalig und ziehe diese dann in der
> while-Schleife voneinander ab ;)

Ich würde sie eher bei Kalibierung des Modules messen und im EEPROM 
ablegen. Sonst hat man jedes Mal beim Starten die ganze Prozedur.

Neben der Schwerkraft muss Der Offset der Achsen doch auch noch bestimmt 
werden. Sonst misst du plötzlich scheinbar lineare Beschleunigungen, 
obwohl du nur deinen Sensor im Raum gedreht hast. Oder hattest du vor, 
nur mit dem Skalar der Beschleunigung, unabhängig von der Richtung, zu 
arbeiten?

von Daniel V. (voda) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> Daniel V. schrieb:
>> In der Main lese ich diese Werte erstmalig und ziehe diese dann in der
>> while-Schleife voneinander ab ;)
>
> Ich würde sie eher bei Kalibierung des Modules messen und im EEPROM
> ablegen. Sonst hat man jedes Mal beim Starten die ganze Prozedur.
>
> Neben der Schwerkraft muss Der Offset der Achsen doch auch noch bestimmt
> werden. Sonst misst du plötzlich scheinbar lineare Beschleunigungen,
> obwohl du nur deinen Sensor im Raum gedreht hast. Oder hattest du vor,
> nur mit dem Skalar der Beschleunigung, unabhängig von der Richtung, zu
> arbeiten?

Ein klassisches EEPROM hat mein STM32 nicht ;). Ich möchte letztendlich 
nur die Geschwindigkeiten in x- und y-Richtung durch numerische 
Integration bestimmen.

Danke euch ;)

von Stefan F. (Gast)


Lesenswert?

> Ich möchte letztendlic nur die Geschwindigkeiten bestimmen.

Sorry, dass ich dich bremse. Aber der Sensor kann nur Beschleunigung 
messen, nicht Geschwindigkeit. Wenn Du ihn vom nächsten Funkturm fallen 
lässt, wird er während des freien Falls fast gar keine Beschleunigung 
erfassen ob er ziemlich schnell in Bewegung ist - bis zum Aufprall.

von Daniel V. (voda) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Sorry, dass ich dich bremse. Aber der Sensor kann nur Beschleunigung
> messen, nicht Geschwindigkeit.

Daher die numerische Integration der Beschleunigungswerte über die Zeit 
;)

: Bearbeitet durch User
von Thomas V. (thomas_v70)


Lesenswert?

Ui Daniel,

Darüber reden wir dann nochmal im Detail wen Du wieder im Labor bist ;-)
Schöne Ostertage bis dahin


Gruss
Thomas

von Daniel V. (voda) Benutzerseite


Lesenswert?

Thomas V. schrieb:
> Darüber reden wir dann nochmal im Detail wen Du wieder im Labor bist ;-)
> Schöne Ostertage bis dahin

Chef liest mit xD. Dir auch frohe Ostern und schönen Urlaub auf 
Teneriffa ;)

von Stefan F. (Gast)


Lesenswert?

>> Sorry, dass ich dich bremse. Aber der Sensor kann nur Beschleunigung
>> messen, nicht Geschwindigkeit.

> Daher die numerische Integration der Beschleunigungswerte über die Zeit

Glaube mir, das geht nicht. Nichtmal Ansatzweise. Ich hatte mal einen 
Hersteller von solchen Sensoren nach einer brauchbaren Lösung gefragt. 
Die erklärten mir damals, dass das eine völlig bekloppte Idee sei. 
Nichtmal die sensibelsten Sensoren, die sie produzierten, seien dazu 
geeignet.

von Stefan F. (Gast)


Lesenswert?

Ich habe gerade einen Tippfehler entdeckt, der den Sinn des Satzes 
kaputt macht:

>  Wenn Du ihn vom nächsten Funkturm fallen
> lässt, wird er während des freien Falls fast gar keine Beschleunigung
> erfassen ob er ziemlich schnell in Bewegung ist - bis zum Aufprall.

Soll heissen: ... obwohl er ziemlich schnell in Bewegung ist ...

von Sven B. (scummos)


Lesenswert?

Daniel V. schrieb:
> Stefan U. schrieb:
>> Sorry, dass ich dich bremse. Aber der Sensor kann nur Beschleunigung
>> messen, nicht Geschwindigkeit.
>
> Daher die numerische Integration der Beschleunigungswerte über die Zeit
> ;)

Das wird nix, das driftet dir innerhalb von Sekunden weg. Die ganze 
Sache ist leider ein schwieriges Problem :(

von Daniel V. (voda) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Glaube mir, das geht nicht. Nichtmal Ansatzweise. Ich hatte mal einen
> Hersteller von solchen Sensoren nach einer brauchbaren Lösung gefragt.
> Die erklärten mir damals, dass das eine völlig bekloppte Idee sei.
> Nichtmal die sensibelsten Sensoren, die sie produzierten, seien dazu
> geeignet.

Sven B. schrieb:
> Das wird nix, das driftet dir innerhalb von Sekunden weg. Die ganze
> Sache ist leider ein schwieriges Problem :(

Dann in der Tat, das war ein Denkfehler. Mein Gedanke war, ich 
integriere numerisch aber die Fehler werden ebenfalls mitsummiert (wie 
Steven es schon gesagt hat).

Die Werte stimmen jetzt soweit, ich habe eine Funktion geschrieben, 
welche mir beim Start die Offsetlage in ein Array speichern und die 
folgenden  Messwerte werden nun von diesen Offsetwerte abgezogen.

Danke für eure Hinweise :)

Gruß
Daniel

PS:
Beitrag "Geschwindigkeitsberechnung durch Accelerometer?"

Ich bin wohl nicht der erste mit den Gedanken gewesen ;)

: Bearbeitet durch User
von Forist (Gast)


Lesenswert?

Daniel V. schrieb:
> Die Werte stimmen jetzt soweit, ich habe eine Funktion geschrieben,
> welche mir beim Start die Offsetlage in ein Array speichern und die
> folgenden  Messwerte werden nun von diesen Offsetwerte abgezogen.

Für eine längere Integration kommst du damit nicht weit. Da brauchst du, 
selbst wenn der Sensor nicht driftet, Nachkommastellen. Du musst also 
zumindest deinen Offset als Mittelwert von vielen Messungen bestimmen 
und bei der Integration auch mit erhöhter Genauigkeit rechnen, z.B. 
indem du eine Fixkommapräsentation für die Rechnung verwendest.

von Stefan F. (Gast)


Lesenswert?

Dazu kommt noch, dass der BMA020 eher ein grobes Schätzeisen ist. Damit 
kannst du vielleicht die Startgeschwindigkeit eines Flugzeiges messen, 
aber sicher nicht eine Kiste Tracken, die jemand zu Fuß von A nach B 
trägt.

von eProfi (Gast)


Lesenswert?

Dafür eignet sich eher so etwas:
Beitrag "[V] IMU Analog Devices -- ADIS16480 - Gyro,Acc;Mag *neu*"
Kostet halt ein bisschen mehr.

von Dieter F. (Gast)


Lesenswert?

Daniel V. schrieb:
> Hier mein Code zum Auslesen:
>
> float bma020_read_accel(float* acc)
...
>   acc[2] = (float)acc_s[2] * 9.8f * tmp2 / 512.0f;
>
> //return sqrtf(acc[0] * acc[0] + acc[1] * acc[1] + acc[2] * acc[2]);
> }
>
> Habe ich irgendwo einen Denkfehler? Auch ändern sich die Werte kaum,
> außer in z-Richtung.
>
> Danke und Gruß
> Daniel

Nö, das ist nur ein Ausschnitt ...

von Peter (Gast)


Lesenswert?

Hi,
ich stimme mal den Vorrednern zu was die genauigkeit angeht. Selbst wenn 
du den Offset perfekt kalibrierst und du keine Sensordrift hast sorgt 
schon allein die Auflösung für einen Fehler der innerhalb von Sekunden 
Meter erreicht. (Einfach mal nachrrechnen)

Um überhaupt eine Chanche zu haben musst du sehr genau deine Lage im 
Raum kennen. Den jeder Lagefehler führt aufgrund der Erdbeschleunigung 
zu einem Geschwindigkeitsfehler. Schau mal nach Strap Down Rechnung und 
Kalmanfilter. Aber wenn du nicht gerade sehr schnell beschleunigende 
Objekte hast vergiss es.

Gruß
Peter

von Daniel V. (voda) Benutzerseite


Lesenswert?

Ich hatte ja eine Funktion geschrieben, welche mir die Offsetwerte 
zwischenspeichert. Diese habe ich anschließend von den normalen 
Messwerten abgezogen. Aus irgendeinen Grund läuft es nicht mehr und ich 
seh den Wald vor lauter Bäumen nicht:

Meine Quick&Dirtylösung in der Main:
1
int i,j;
2
uint8_t *p;
3
float accel_v[3], accel, accel_c[3], accel_w;
4
5
for (j=1;j<1000;j++)
6
{
7
  DEBUG_LED_ON;
8
  accel_w = bma020_read_accel(accel_c); // Die Funktion im Eingangspost
9
  p=(uint8_t*)&accel_w;
10
}
11
DEBUG_LED_OFF;

später in der while habe ich folgendes gemacht:
1
for (i = 0; i < 1; i++)  /*30*/
2
{
3
  accel = bma020_read_accel(accel_v);
4
  sprintf(acc_text, "\nx:%f, y:%f, z:%f\n", p[0] - accel_v[0], p[1]-accel_v[1], p[2]-accel_v[2]);
5
  sendText(acc_text); 
6
}


Danke und Gruß
Daniel

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

> Aus irgendeinen Grund läuft es nicht mehr

Was genau läuft nicht mehr und was passiert stattdessen?
Das ist der Moment, wo ein Debugger serh hilfreich sein kann, oder ein 
Simulator.

Oder wenigstens viel mehr Log-Meldungen von allen Variablen und 
Zwischenschritten der Berechnung.

Was mir hier aber sofort auffällt: Du rechnest da mit float Datentypen 
herum. Das ist unnötig aufwändig und bringt zudem höhere Rundungsfehler 
mit sich, als simple Integer-Operationen hätten.

Speichere deine Messwerte und Offset Werte als Integer. Rechne als 
Integer.

Und nur ganz zum Schluss, wenn du die Werte anzeigst, rechne sie auf 
Float um.

von Daniel V. (voda) Benutzerseite


Angehängte Dateien:

Lesenswert?

Stefan U. schrieb:
> Was genau läuft nicht mehr und was passiert stattdessen?
> Das ist der Moment, wo ein Debugger sehr hilfreich sein kann, oder ein
> Simulator.

Sehr gerne :-)

Die Bilder zeigt das Fehlerbild. Das kuriose war ja, es hat mal 
funktioniert und irgendwie habe ich jetzt ein absolutes Bett vor dem 
Kopf

Ergebnis zeigt die aktuellen kalibrierten Messwerte. OK.

Mein Gedanke war, ich speichere die Werte beim Start (entweder warte 
ich, bis der Sensor "eingeschwungen" ist oder den Mittelwert aus 1000 
Einzelwerte) und speichere diese in ein Array. Diese ziehe ich von den 
Messwerten ab.

Das Ergebnis ist die For-Schleife.

Ziehe ich diese Werte ab, so kommen unplausible Ergebnisse zustande. Das 
zeigt das Bild Mit_dieser_Funktion.

Die Debugmeldung ist im Bild Debug zu sehen.

Absolut seltsames Verhalten :(

von Daniel V. (voda) Benutzerseite


Lesenswert?

Es ist mir ja peinlich, aber ich stehe zu meinen Fehlern. Ich habe ein 
Flag auskommentiert und dann habe ich alle Kommentare zur besseren 
Lesbarkeit zum hochladen auch noch gelöscht. Naja, was ne Stunde Schlaf 
so ausmachen kann ;)

Gruß
Daniel

von Stefan F. (Gast)


Lesenswert?

> Die Bilder zeigt das Fehlerbild.

Du hast vergessen, den Fehler zu kennzeichnen oder zu Beschreiben. Ich 
habe ja keine Ahnung, welche der vielen Zahlen nicht deiner Erwartung 
entsprechen.

In Zukunft vergiss bitte nicht, immer hin zu schreiben, was du erwartet 
hast und was du stattdessen erhalten hast.

von Wolfgang (Gast)


Lesenswert?

Daniel V. schrieb:
> Ergebnis.PNG

Die Daten erinnern mich an die wundersame Brotvermehrung. Der Sensor hat 
eine Auflösung von 10 Bit, also 3 gültige Stellen und du generiest 
daraus Zahlen mit 7 Stellen.

Das ist viel unnötiger Lesestoff - eildiweil Hausnummer.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.