Forum: Mikrocontroller und Digitale Elektronik Mit Gyro (MLX90609) Neigung bestimmen


von Patrick L. (crashdemon)


Lesenswert?

Hallo,

benutze den MLX90609 von Melexis 
(http://www.melexis.com/Sensor_ICs_Inertia/General/MLX90609_582.aspx) 
den ich per SPI digital auslese, dass scheint auch recht gut zu 
funktionieren, allerdings möchte ich ich aus den 11Bit Messwert den mir 
der Sensor gibt, den
Winkel rausrechnen, wie mache ich das?

Im Datenblatt steht was von Voutar(mV) = (25/12) * ADCcode + 400 weis 
nicht ob das hilft?

von Michael H. (morph1)


Lesenswert?

sorry is ein wenig OT, aber woher hast du den bezogen? an solchen 
bauteilen hätt ich großes interesse, kann aber bei meinen haus und hof 
lieferanten nichts vergleichbares finden :/

von Michael L. (Gast)


Lesenswert?

Hallo Patrick,

> allerdings möchte ich ich aus den 11Bit Messwert den mir
> der Sensor gibt, den
> Winkel rausrechnen, wie mache ich das?

Jetzt weiß ich nicht, ob Dein Problem ein Problem mit den Anschlüssen 
ist oder ein prinzipielles.
Ein solcher Sensor gibt die Winkelgeschwindigkeit an. Um den Winkel zu 
erhalten, mußt Du die Meßwerte zeitlich integrieren.

Dabei tritt dann das Problem auf, daß der Drift des Sensors sich in 
einer Änderung der Drehgeschwindigkeit äußert, das heißt in einem mit 
der Zeit linear ansteigenden Fehler des Drehwinkels.


Gruß,
  Michael

von Patrick L. (crashdemon)


Lesenswert?

Michael H. wrote:
> sorry is ein wenig OT, aber woher hast du den bezogen? an solchen
> bauteilen hätt ich großes interesse, kann aber bei meinen haus und hof
> lieferanten nichts vergleichbares finden :/

habe den von der insel über das internet gekauft bei sparkfun, in 
deutschland wüsste ich jetzt nicht wo man den kaufen könnte, vorteil bei 
sparkfun ist das dieser schon auf einen board verlötet ist 
(http://www.sparkfun.com/commerce/product_info.php?products_id=8372) was 
das ganze für mich erheblich erleichtert.
Wenn du fit im SMD löten bist, kannst du ihn naturlich auch roh 
bestellen 
http://www.sparkfun.com/commerce/product_info.php?products_id=8294

von Patrick L. (crashdemon)


Lesenswert?

> Jetzt weiß ich nicht, ob Dein Problem ein Problem mit den Anschlüssen
> ist oder ein prinzipielles.
> Ein solcher Sensor gibt die Winkelgeschwindigkeit an. Um den Winkel zu
> erhalten, mußt Du die Meßwerte zeitlich integrieren.
>
> Dabei tritt dann das Problem auf, daß der Drift des Sensors sich in
> einer Änderung der Drehgeschwindigkeit äußert, das heißt in einem mit
> der Zeit linear ansteigenden Fehler des Drehwinkels.

ja ich habe da warscheinlich noch einige verständnis probleme, wenn ich 
das bis jetzt richtig verstanden müsste ich etwas in der art wie (Summe 
über die Zeit) += (Wert bei Null Grad) - (Aktueller Messwert), den Wert 
bei Null Grad müsste ich dann jeweils über einen Beschleunigungssenor 
kalibrieren?

Was genau meint man den mit Drift? 
(http://www.google.de/search?hl=de&client=firefox-a&rls=org.mozilla%3Ade%3Aofficial&hs=Ywh&q=define%3Adrift&btnG=Suche&meta=)
Soll das den Fehler beschreiben der beim integrieren auftrit?

von Patrick L. (crashdemon)


Lesenswert?

Ich vermute das man von dem Messwert den man erhält, den Zero Rate 
Output (Bias) abziehen muss der bei diesem Sensor bei 1008 liegt, und 
dann muss ich glaube ich über den Initial Scale Factor (sensitivity) 
irgendwie den Winkel ausrechnen.

Habe hier was interessantes gefunden: 
http://tom.pycke.be/mav/70/gyroscope-to-roll-pitch-and-yaw

von Michael L. (Gast)


Lesenswert?

Hallo Patrick,

> ja ich habe da warscheinlich noch einige verständnis probleme, wenn ich
> das bis jetzt richtig verstanden müsste ich etwas in der art wie (Summe
> über die Zeit) += (Wert bei Null Grad) - (Aktueller Messwert), den Wert
> bei Null Grad müsste ich dann jeweils über einen Beschleunigungssenor
> kalibrieren?

Ein Drehratensensor (englisch: angular rate sensor) gibt die 
Drehgeschwindigkeit an, also irgendwas in der Einheit "Grad pro 
Sekunde". Wenn Du daraus den Winkel bekommen willst, mußt Du den 
Anfangswinkel kennen und die Änderungen zeitlich aufsummieren.

> Was genau meint man den mit Drift?
> 
(http://www.google.de/search?hl=de&client=firefox-a&rls=org.mozilla%3Ade%3Aofficial&hs=Ywh&q=define%3Adrift&btnG=Suche&meta=)
> Soll das den Fehler beschreiben der beim integrieren auftrit?
Ja genau.

Normalerweise sollte die Ausgangsspannung bei 0°/s einen konstanten Wert 
haben - ich vermute, in Deinem Fall ist das 2,5V.
Durch einen Drift (z. B. Temperaturdrift) könnte Anzeige bei 0°/s aber 
auch beispielsweise auf 2,51V steigen. Wenn die 0°/s durch die 
Temperaturerhöhung bei 2,51V liegt, erkennst Du eine Drehung, obwohl 
keine da ist.

Zur Erkennung der Neigung ist ein Beschleunigungssensor auf jeden Fall 
besser geeignet.


Gruß,
  Michael

von Patrick L. (crashdemon)


Lesenswert?

> Zur Erkennung der Neigung ist ein Beschleunigungssensor auf jeden Fall
> besser geeignet.

Ja, eine dreiachsen Beschleunigungs habe ich auch in meinem Aufbau, ich 
denke ich werde es so machen. Sobald der Beschleunigungssensor Nulllage 
misst, sprich Null Grad, setze ich den Wert des Gyro auf Null Grad, 
sobald der Testaufbau geneigt wird, Summiere ich die Ausgangswerte des 
Gyros auf, denke ich?

Würde das so funktionieren?

von Patrick L. (crashdemon)


Angehängte Dateien:

Lesenswert?

Hallo habe eine neue Theorie wie ich auf meinen Winkel mittels Gyro 
komme,
die Antwort die ich vom Gyro bekomme ist 11 Bits groß (2^11 ~ 2048) also 
hätte ich als maximalen wert den ich bekommen könnte 2048, allerdings 
ist das aus konstruktionstechnischen gründen nicht möglich, wenn ich das 
datenblatt (ausschnitt siehe anhang) richtig gelesen habe, hier begrenzt 
"output full scale" auf 1920. Der Parameter "Zero rate output"  gibt mir 
allerdings meinen Nullpunkt an von 1008, also müsste ich diesen Wert von 
meinem Messwert abziehen, alle Neigungen die dann an dem Gyro ausgeführt 
werden, würden ja relativ zum nullpunkt auftreten, dementsprechend 
müsste dann mein wert in einem normalen wert liegen, jetzt muss ich nur 
noch diesen wert durch den "Initial Scale Factor" von 3,2 teilen, dann 
müsste ich doch auf meinen Winkel kommen.

Winkel = [[[Messwert per SPI (11 Bit)] - 1008] / 3,2]

von gast (Gast)


Lesenswert?


von Patrick L. (crashdemon)


Lesenswert?

gast wrote:
> GYRO und SENSOREN
> http://www.sander-electronic.de/be00040.html

Habe schon einen Gyro!

von Patrick L. (crashdemon)


Lesenswert?

Hallo,

habe auch noch frage wie ich das mit dem Integrieren softwaretechnisch 
lösen kann, von meinem Verständniss her wäre das so:
1
int i;
2
3
for(i = 0; i < 1024; i++)
4
{
5
    GyroMesswertSumme += GyroMesswert; 
6
}
7
8
Mittelwert = GyroMesswertSumme / 1024;

Würde das so gehen?

von Patrick L. (crashdemon)


Lesenswert?

Hat den keiner eine Antwort / Lösung?

von Maria (Gast)


Lesenswert?

Mann braucht ein festes Zeitraster fDt [s] mit der der Sensorwert fGyro 
aufsummiert wird. fGyro am besten in [rad per second] normiert.

fAngle += fGyro * fDt;

Danch muss man noch den Fall grösser +-PI behandeln.

if (fabs(fAngle) > M_PI)
  fAngle = copysign(2 * M_PI - fabs(fAngle), -fAngle);

Anmerkung:
Diese Aufsummierung driftet weg und taugt nur für kurze Zeit. Wenn man 
die Lage zur Erdoberfläche haben will ist ein 3-achsiges Accelerometer 
(LIS2LV02DQ) besser geeignet.

von Patrick L. (crashdemon)


Lesenswert?

Maria wrote:
> Mann braucht ein festes Zeitraster fDt [s] mit der der Sensorwert fGyro
> aufsummiert wird. fGyro am besten in [rad per second] normiert.
>
> fAngle += fGyro * fDt;
>
> Danch muss man noch den Fall grösser +-PI behandeln.
>
> if (fabs(fAngle) > M_PI)
>   fAngle = copysign(2 * M_PI - fabs(fAngle), -fAngle);
>
> Anmerkung:
> Diese Aufsummierung driftet weg und taugt nur für kurze Zeit. Wenn man
> die Lage zur Erdoberfläche haben will ist ein 3-achsiges Accelerometer
> (LIS2LV02DQ) besser geeignet.

Danke für die schnelle Antwort, das ist genau das was ich gesucht habe, 
allerdings habe ich dazu noch zwei Fragen.

Folgender Code würde ja den jeweiligen Wert des Gyros (fGyro) mit dem 
Zeitraster (fDt) multiplizieren und das stetig auf fAngle aufsummieren.

Jetzt die Fragen dazu:
Würde dann nicht fAngle irgendwann sehr groß werden?
Wie muss ich fDt wählen, kann das ein von mir selbst bestimmter Wert 
sein, oder muss der z.B. in Abhängigkeit des Intervalls in dem der Gyro 
abgefragt wird gewählt werden?

Zu der Anmerkung:
Ja, ich benutze eine Kombination aus 3-achsiges Accelerometer und 
1-Achsen Gyro, die bei zeiten auch Kalman gefiltert werden.

von Maria (Gast)


Lesenswert?

fDt ist das Intervall in dem der Gyro abgefragt wird. Es muss kein 
konstanter Wert sein aber die richtige Zeit zwischen zwei Abfragen.

Die nachfolgende Zeile ist ungetestet. Sie wandelt den mlx90609 Wert in 
[rad/sec].

fGyro = ((sGyroRaw & 0x0FFF) - (1008 << 1)) / (2 * 3.2) * (M_PI/180.0);

von Patrick L. (crashdemon)


Lesenswert?

Maria wrote:
> fDt ist das Intervall in dem der Gyro abgefragt wird. Es muss kein
> konstanter Wert sein aber die richtige Zeit zwischen zwei Abfragen.
>
> Die nachfolgende Zeile ist ungetestet. Sie wandelt den mlx90609 Wert in
> [rad/sec].
>
> fGyro = ((sGyroRaw & 0x0FFF) - (1008 << 1)) / (2 * 3.2) * (M_PI/180.0);

Ja, so in der Art hatte ich es auch schon, nur hat mir da das letzte 
drittel gefehlt, noch eine Frage zu den Zahlen (2 * 3.2) bei 3.2 scheint 
es sich um den Scale Factor zu handeln, nur wieso wird dieser mit 2 
multipliziert?

fGyro = ((sGyroRaw & 0x0FFF) >> 1) - 0x3F0; // // 12Bit ausmaskieren und 
um 1Bit nach rechts schieben, Null Bezug Abziehen

THX

von Maria (Gast)


Lesenswert?

Eigentlich ist das gleich.

2 * 3.2 ist so wie 3.2 << 1

Ich wollte das kleinste Bit von GyroRaw nicht vernichten. Vielleicht 
bauen die mal einen ADC in den Gyro der auch dieses Bit bringt.

von Arno H. (arno_h)


Lesenswert?

Mit einem Gyro mit einer Achse kannst du doch auch nur die Rotation um 
eine Achse messen.
Wie ermittelst du da die Neigung des LFz?
Meines Wissens benötigst du zumindestens die Entsprechung eines 
künstlichen Horizonts und eigentlich auch einen Gyro für die Gierachse 
zur Lageorientierung im Raum, oder übersehe ich da was?

Arno

von Patrick L. (crashdemon)


Lesenswert?

Arno H. wrote:
> Mit einem Gyro mit einer Achse kannst du doch auch nur die Rotation um
> eine Achse messen.
> Wie ermittelst du da die Neigung des LFz?
> Meines Wissens benötigst du zumindestens die Entsprechung eines
> künstlichen Horizonts und eigentlich auch einen Gyro für die Gierachse
> zur Lageorientierung im Raum, oder übersehe ich da was?

Ja, du übersiehst das ich den Gyro nicht alleine einsetze, wie schon des 
öfteren beschrieben, nutze ich unteranderen einen dreiachsen 
Beschleunigungssensor, mit dem ich ja dann meinen Horizont habe, denn 
ich aus dem Verhältnis von zwei Achsen berechne:

Winkel des Beschl. = (atan((y - 512.0) / 102.4) / (((z - 512.0) / 
102.4))) * (180.0 / M_PI); // Zweiachsige Winkelbestimmung

Somit weiß ich wo ich meine Null Grad habe und kann dahingehen den Gyro 
Offset einstellen, sodass ich wenn der Beschleunigungssensor Null Grad 
ausgiebt, der Wert des Gyros "nullgesetzt" werden kann, wird der 
Versuchsaufbau geneigt, wird einfach die abweichung vom Nullpunkt 
aufaddiert.

mfg crashdemon

von Arno H. (arno_h)


Lesenswert?

Dein Aufbau kann also nur in einer Richtung geneigt werden, ok.

Arno

von Patrick L. (crashdemon)


Lesenswert?

Arno H. wrote:
> Dein Aufbau kann also nur in einer Richtung geneigt werden, ok.
>
> Arno

Jup

von Patrick L. (crashdemon)


Lesenswert?

So hatte mal wieder ein wenig Zeit mich weiter mit dem Problem zu 
beschäftigen, habe jetzt folgende Formel benutzt:

fMeas += ((gMeas / 6.4) * fDt) * (180.0 / M_PI); // Winkel des Gyro in 
deg/sec

Wobei:
float fDt = 0.000008;
gMeas = ((GyroMeasRaw & 0x0FFF) >> 1) - 0x3F0;

Das will allerdings nicht so wirklich funktionieren die Werte sind 
teilweise doch sehr am schwanken.

Dann habe ich noch von einem Runge-Kutta Verfahren 
(http://tom.pycke.be/mav/70/gyroscope-to-roll-pitch-and-yaw) gelesen, 
hat das hier schoneinmal jemand erfolgreich eingesetzt?

von Patrick L. (crashdemon)


Angehängte Dateien:

Lesenswert?

So ich habe jetzt mal die Rohen Messwerte meines Gyros per UART an 
meinen Recner geschickt und dann über Hyperterm aufgezeichnet und in 
eine excel-Tabelle verwurstet, die ich mal im Anhang drangehängt habe, 
wäre schön wenn sich das mal jemand ansehen könnte und wir sagen kann ob 
das mit dem Integrierten Messwert richtig umgesetzt ist?

von Maria (Gast)


Lesenswert?

Ich habe mir die Messwerte nicht angeschaut aber dafür einige 
Bemerkungen.

Das Zeitintervall ist viel zu klein. Die Grenzfrequenz des Sensors ist 
75Hz also reicht es alle 5-10ms eine Messprobe zu nehmen (0.005s). 
Timer!

Dann würde ich für Testzwecke dieses schreiben:

int16_t gMeas = ((GyroMeasRaw & 0x0FF0) >> 1) - 0x3F0;

Damit werden unteren Bits gelöscht, die Sache wird unempfindlicher, und 
bei ruhendem Sensor sollte gMeas auch 0 sein. Es wird also 0 
Aufsummierung.

Hast du gMeas als int16_t deklariert?

Wenn du jetzt den Sensor um 90 Grad drehst dann sollte sich der 
aufsummierte Winkel um M_PI / 2 ändern.

von Patrick L. (crashdemon)


Angehängte Dateien:

Lesenswert?

Maria wrote:
> Ich habe mir die Messwerte nicht angeschaut aber dafür einige
> Bemerkungen.
>
> Das Zeitintervall ist viel zu klein. Die Grenzfrequenz des Sensors ist
> 75Hz also reicht es alle 5-10ms eine Messprobe zu nehmen (0.005s).
> Timer!
>
> Dann würde ich für Testzwecke dieses schreiben:
>
> int16_t gMeas = ((GyroMeasRaw & 0x0FF0) >> 1) - 0x3F0;
>
> Damit werden unteren Bits gelöscht, die Sache wird unempfindlicher, und
> bei ruhendem Sensor sollte gMeas auch 0 sein. Es wird also 0
> Aufsummierung.
>
> Hast du gMeas als int16_t deklariert?
>
> Wenn du jetzt den Sensor um 90 Grad drehst dann sollte sich der
> aufsummierte Winkel um M_PI / 2 ändern.

Habe gMeas zur Zeit als float, werde aber mal deinen Rat befolgen und 
ihn als int deklarieren damit die Nachkommastellen wegfallen.

Das mit dem sicherstellen das in einem bestimmten Intervall die 
Messwerte ermittelt werden, das ist für mich noch ein bisschen Tricky, 
ich werde versuchen das über einen Timer zu lösen.

von Patrick L. (crashdemon)


Lesenswert?

So ich hab mir jetzt mal einen Timer gebastelt mit dem ich die Differenz 
der vorherigen und der jetzigen Messung errechnen kann, das war ja das 
Zeitraster wovon du gesprochen hattest.
Wäre schön wenn da mal jemand drüber schauen kann, da es bei mir noch 
nicht so richtig funktioniert.
1
// Globale Variablen
2
uint16_t n = 0; // Aktueller Taktzähler 
3
uint16_t nBefore = 0; // Taktzähler davor
4
uint16_t gMeasRaw = 0; // Rohdaten vom Gyro
5
int16_t fMeas = 0.0; // Über die Zeit Integrierte Daten des Gyros
6
float fDt = 0.0; // Taktzähler Differenz zwischen n und nBefore
7
8
ISR(TIMER0_OVF_vect) // Aufruf bei Interrupt von Timer0 (8 Bit)
9
{
10
    n++;
11
}
12
13
float GyroAngle(void)
14
{
15
    gMeasRaw = 0; // Rohdaten vom Gyrometer
16
    fDt = n - nBefore; // Zeitdifferenz zwischen den Messungen
17
18
    if(fDt < 0) // Wenn Variable übergelaufen da 16Bit int
19
    {
20
        fDt = (((2^16) - nBefore) + n); // Zeit berechnen der Variable
21
    }
22
23
    // CPU_TAKT (4Mhz) / Vorteiler (64) = 62,5KHz = 16us
24
    fDt = fDt * 0.000016; // Taktzyklen mit Periodendauer multiplizieren
25
    nBefore = n; // Aktueller Counterwert, für nächste Messung speichern
26
27
    GyroAdcSetMode(); // 2. Modi setzen, ADC Wandlung  
28
    GyroAdcRead(&gMeasRaw); // 3. Ergebnis der Messung lesen
29
    fMeas += (((gMeasRaw  - 0x3F0) / 3.2) * fDt); // Winkel des Gyro in deg/sec
30
31
    return fMeas;
32
}
33
34
int main(void)
35
{
36
    char gChar[4] = "";
37
    int16_t gAngle = 0;
38
39
    TCCR0 |= (1 << CS01) | (1 << CS00); // Vorteiler 3 (Takt 62,5kHz)
40
    TIMSK |= (1 << TOIE0); // Timer 0 Overflow Interrupt
41
42
    GyroSetMode(); // 1. Gyro "scharf stellen"
43
    sei(); // Globale Interrupts einschalten
44
45
    while(1)
46
    {
47
        gAngle= GyroAngle(); // Funktion die Winkel ermittelt
48
        USART_send(itoa(gAngle, gChar, 10)); // Per USART senden
49
    }
50
51
    GyroSetSleep(); // 4. Gyro schlafen legen
52
    return 0; // Wird niemals erreicht
53
}

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.