Einen wunderschönen guten Abend wünsche ich euch. Probiere gerade einen
Gyrosensor auszulesen und einen Winkel zu bestimmen. Mit dem
Beschleunigungssensor vom Board geht es soweit auch wunderbar, aber
leider schaffe ich das mit dem Gyrosensor nicht.
Als Sensor habe ich den MPU92.65.
Das mit dem Offset klappt denke ich so weit auch ganz gut. Jedoch hängt
es gerade mit dem drauf Rechnen der Winkelbeschleunigungswerte. Hat von
euch eventuell jmd einen Tipp oder Anregung.
Ein Gyro misst die Winkelgeschwindigkeit. Um auf einen Winkel zu kommen,
muss über die Zeit integriert (aka aufsummiert) werden, aber eine
Multiplikation mit einer Zeitdifferenz sehe ich in deinem Code nirgens.
zz_summe_off wird anfangs nicht auf 0 gesetzt. Dadurch ist der
ermittelte Offset möglicherweise falsch. Auch gz sollte initialisiert
werden, um nachvollziehbare Ergebnisse zu erhalten. Vielleicht haben
beide Variablen anfangs zufälligerweise den Wert 0, aber garantiert ist
das in C nicht.
Das eigentliche Problem liegt aber hier:
1
gz+=(z_summe_off+z_off);
Du musst den Offset nicht addieren, sondern subtrahieren:
1
gz+=(z_summe_off-z_off);
Des Weiteren vermisse ich hier (wie auch "jemand") einen Zeitfaktor. Um
von der Winkelgeschwindigkeit auf einen Winkeländerung zu kommen, musst
du erstere mit der Zeitdauer zwischen jeweils zwei Sensorabfragen
multiplizieren, also:
1
gz+=(z_summe_off-z_off)*delta_t;
Bei konstanter Abfragerate kannst du delta_t auf einen festen Wert
setzen, andernfalls musst du delta_t für jede Abfrage mittels Timer
bestimmen.
Abgesehen davon sind deine Variablennamen teilweise sehr verwirrend.
Warum heißt bspw. die Winkelgeschwindigkeit in der while-Schleife
z_summe_off?
Wieder einmal wünsche ich euch einen wunderschönen Guten Abend und
bedanke mich bei yalau und dem netten Gast für die Tipps.
@yalu Kannst du mir mal einen kleinen Denkanstoß geben, wie ich die
Zeitkonstante Variabel über einen Timer lösen kann. Habe mich schon die
ganze Zeit gefragt, wie das mit der Zeitkonstante gehen soll. Hier in
meinem Code ist ja der Ablauf periodisch, aber wenn dem nicht so wäre,
hätte man ja nie einen genauen Messwert.
Dadurch das ich den Offset jetzt Subtrahiere und eine Zeitkonstante mit
eingebaut habe, bleibt der Winkel relativ Konstant bei 0°. Wenn ich mir
auch ganz viel Zeit nehme und den Sensor sehr sehr langsam um 90° Drehe,
lande ich auch bei 90° und nach dem zurück drehen wieder bei 0°.
Wenn ich den Sensor aber schnell um 90° Drehe, werden die Werte
verschluckt und der Winkel ändert sich vielleicht um 2-3°. Dachte es
liegt daran, das ich jeden Wert am Rechner ausgebe, aber daran liegt es
leider nicht.
Habe den Code auch mal aufgeräumt und ein wenig "lesbarer" gemacht :)
Was mich auch sehr wundert, meine Zeitkonstante ist 0,5625µs. Wenn ich
mir aber ein Messdurchlauf anschaue, messe ich 2,2µs.
Vielleicht hat von euch jmd noch einen Tipp für mich. Drehe mich
irgendwie im Kreis.
Einen schönen Sonntag wünsche ich euch alle.
Habe jetzt meinen Code nocheinmal geändert und einen timer integriert.
So weit geht die Messung, jedoch nur bei langsamen Änderungen und was
ich auch nicht verstehe, trotz des Timers muss ich noch mit einen festen
Wert multiplizieren, um die Änderungen in Winkel zu haben.
Meine Einstellungen:
Full Scale Range: +-2000 °/s
Sensitivity Scale Factor: 16.4LSB/(º/s)
Bin auch so langsam mit meinem Latein am Ende und weiß nicht was ich
noch machen kann -.- Ein Schleifendurchlauf dauert 119µs und die
Abtastrate vom Sensor ist 8000Hz, also alle 125µs einmal Abtasten
1
/********//******/
2
/*Messen*//*Gyro*/
3
/********//******/
4
z_high_low_summe=0;
5
i=0;
6
while(1)
7
{
8
i++;//Zähler fpr den Printf
9
timer.start();
10
11
ncs=0;
12
spi.write(0xc7);//Z_OUT_H
13
z_high=spi.write(0x0);
14
ncs=1;
15
wait_us(1);
16
17
ncs=0;
18
spi.write(0xc8);//Z_OUT_L
19
z_low=spi.write(0x0);
20
ncs=1;
21
wait_us(70);
22
zeit=timer.read_us();
23
timer.reset();
24
timer.start();
25
26
z_high_low=z_low+z_high<<8;//Low und High Byte zusammenfügen
27
z_high_low_summe=z_high_low-z_off;//Offset vom Messwert subtrahieren
28
z_winkel=z_winkel+(z_high_low_summe*zeit*0.0000000003);//Messwert multipliziert mit der Zeitdifferenz