Hi,
Ich versuche mit dem MPU6050 Sensor menschliche Bewegungen zu erkennen.
Ich bin schon sowei, die Sensordaten aus den Registern auszulesen.
In einem, zu meinem Thema sehr ähnlichen, Artikel schreibt der Autor
davon wie er aus den Rohen Sensordaten (ax, ay, az) die "gravity
acceleration" (gx,gy,gz) und die "body acceleration" (bx, by, bz)
berechnet.
Was sind die einzelnen Beschleunigungen (Rohdaten, graivty acceleration
und body acceleration)?
Was ist der genaue Unterschied zwischen ihnen?
Wie berechne ich die einzelnen Werte (BA, GA und RD)?
Im Moment verwende ich einen im Internet gefunden Code in dem ich die
Register auslese und dann die "gForce" berechne (ist dies schon die
besagt gravity acceleration?):
1
voidrecordAccelRegisters(){
2
Wire.beginTransmission(MPU);
3
Wire.write(0x3B);// starting with register 0x3B (ACCEL_XOUT_H)
4
Wire.endTransmission(false);
5
Wire.requestFrom(MPU,14,true);// request a total of 14 registers
Niklas S. schrieb:> In einem, zu meinem Thema sehr ähnlichen, Artikel schreibt der Autor> davon wie er aus den Rohen Sensordaten (ax, ay, az) die "gravity> acceleration" (gx,gy,gz) und die "body acceleration" (bx, by, bz)> berechnet.
Und? Was schreibt er, wie er das macht?
Das kann ich/man so nicht rauslesen, hier der Wortlaut:
"The measurements from tri-axial accelerometers, known as raw data (RD,
ax, ay, az), can be decomposed into gravity acceleration (G) - due to
each gravity, gx, gy , gz and body acceleration (BA) - which is due to
the human movement bx, by, bz", aus Improving Human Activity Recognition
von Jose Villar, Internation Journal of Neural Systems.
Ich würde mal vermuten, dass die Raw-Werte die Rohdaten sind, die Du vom
Sensor bekommst (also vermutlich irgendwelche Integer-Werte), diese für
die gravity-Werte dann bereits in float-Werte umgewandelt/skaliert sind,
dass die Werte sozusagen in G sind, also der Wert 1.0 bspw. genau der
Beschleunigung durch die Gravitation entspricht.
Und für die "body-acceleration" wird aus den gravity-acceleration-Werten
vermutlich gleich noch die Erdanziehungskraft herausgerechnet - also so,
dass in völliger Ruheposition der Beschleunigungswert sämtlicher Achsen
0 beträgt.
Von daher würde ich vermuten:
AcX/Y/Z sind die Rohdaten
und
gForceX/Y/Z sind in der Tat bereits die "gravity acceleration"-Daten
Niklas S. schrieb:> Wire.read()<<8|Wire.read()
Die Reihenfolge, in welcher der linke und der rechte Operand von |
bestimmt werden, ist in C/C++ nicht festgelegt:
"Unlike the bitwise | operator, the || operator guarantees left-to-right
evaluation [...]"
M.a.W: | wird nicht notwendig von links nach rechts ausgewertet —
übrigens hat das nix mit der Kommutativität von | zu tun; gleiches gilt
sinngemaß etwa auch für - (minus).
Johann L. schrieb:> Niklas S. schrieb:>> Wire.read()<<8|Wire.read()>> Die Reihenfolge, in welcher der linke und der rechte Operand von |> bestimmt werden, ist in C/C++ nicht festgelegt:>> "Unlike the bitwise | operator, the || operator guarantees left-to-right> evaluation [...]">> M.a.W: | wird nicht notwendig von links nach rechts ausgewertet —> übrigens hat das nix mit der Kommutativität von | zu tun; gleiches gilt> sinngemaß etwa auch für - (minus).
Also gehört in meinem Fall ||?
Niklas S. schrieb:> aus Improving Human Activity Recognition> von Jose Villar, Internation Journal of Neural Systems.
Dann meinst du wahrscheinlich den Artikel:
José R. Villar et al, Int. J. Neur. Syst. 25, 1450036 (2015)
/Improving human activity recognition and its application in early
stroke diagnosis/
http://di002.edv.uniovi.es/~villar/Jose_R._Villar/Journal_papers_files/villarIJNSfinal.pdf
Der von dir genannte lapidare Satz am Anfang vom Abschnitt 2.1 müsste
IMHO eine Trivialität ausdrücken, sonst hätte er dort irgendetwas
zitieren (müssen). Vielleicht findet man in einer vorhergehenden
Veröffentlichung mehr Details zu seiner Vorgehensweise.
Hi Leute,
bin jetzt, da ich ja auch die Beschleunigung ohne Gravitation brauche
auf die i2cdevlib umgestiegen um die Beschleunigungsdaten zu erlangen.
Soweit funktioniert alles sehr gut, jedoch bekomme ich nach einigen
Sekunden immer öfters FIFO Overflows und dann stürzt das Programm ab.
Mein Code:
1
// if programming failed, don't try to do anything
2
if(!dmpReady)return;
3
4
// wait for MPU interrupt or extra packet(s) available
5
while(!mpuInterrupt&&fifoCount<packetSize){
6
// other program behavior stuff here
7
// .
8
// .
9
// .
10
// if you are really paranoid you can frequently test in between other
11
// stuff to see if mpuInterrupt is true, and if so, "break;" from the
12
// while() loop to immediately process the MPU data
13
// .
14
// .
15
// .
16
}
17
18
// reset interrupt flag and get INT_STATUS byte
19
mpuInterrupt=false;
20
mpuIntStatus=mpu.getIntStatus();
21
22
// get current FIFO count
23
fifoCount=mpu.getFIFOCount();
24
25
// check for overflow (this should never happen unless our code is too inefficient)
26
if((mpuIntStatus&0x10)||fifoCount==1024){
27
// reset so we can continue cleanly
28
mpu.resetFIFO();
29
Serial.println(F("FIFO overflow!"));
30
31
// otherwise, check for DMP data ready interrupt (this should happen frequently)
32
}elseif(mpuIntStatus&0x02){
33
// wait for correct available data length, should be a VERY short wait
Der Overflow hat eindeutig etwas mit dem Senden (client.print(tmp)) zu
tun, wenn ich es auskommentiere bekomme ich keinen Overflow.
Ich denke mal das Problem liegt dabei, dass der FIFO Buffer sich
schneller füllt als ich ihn auslese, da das Senden sehr viel Zeit in
anspruch nimmt. Liege ich da richtig?
Falls ja, wie kann ich das Problem umgehen?
Gibt es eine Möglichkeit den Buffer langsamer zu füllen, also einfach
mehr Zeit zwischen den Messungen zu lassen?
Alternativ, gibt es eine Möglichkeit das Senden (client.print...) zu
beschleunigen?
Danke, Niklas
Hi Leute,
ich habe nun den Code sehr abgeändert, habe das hier
(http://www.i2cdevlib.com/forums/topic/27-fifo-overflow/#entry99)
versucht und es hat sich auch einiges verbessert.
Jedoch stürzt das Programm trotz allem nach ca. 6 Minuten ab, vorher
wirft es noch einige "Fifo Overflows" raus.
Ich denke aber inzwischen, dass das Problem nicht an dem Holen der Daten
vom MPU liegt, sondern am Senden der Daten über den ESP. Sprich, dass
der FIFO Overflow nur deshalb entsteht, weil ich das WLAN Modul mit dem
Senden überfordere und es steckenbleibt.
Deshalb habe ich auch mal nach dem "clien.send(tmp)" ein delay(40)
drangehängt und es hat auch was gebracht. Jedoch konnte ich so das
Abstürzten des Programms wieder nur nach hinten verschieben, das Problem
gelöst hat das nicht...
Ich denke also, dass beim Senden ein Flaschenhals entsteht, das
Wlan-Modul kommt mit dem Senden nicht hinterher und stürzt dann nach zu
vielen Sendeversuchen ab.
Könnte ich da richtig liegen?
Wenn ja, gibt es irgendeine Lösung für das Problem?
Kann ich die Geschwindigkeit in der das Modul sendet irgendwie erhöhen?
So sieht momentan mein Code aus:
1
// wait for MPU interrupt or extra packet(s) available
2
while(!mpuInterrupt&&fifoCount<packetSize){
3
4
}
5
6
// reset interrupt flag and get INT_STATUS byte
7
mpuInterrupt=false;
8
mpuIntStatus=mpu.getIntStatus();
9
10
// get current FIFO count
11
fifoCount=mpu.getFIFOCount();
12
13
// check for overflow (this should never happen unless our code is too inefficient)
14
if((mpuIntStatus&0x10)||fifoCount==1024){
15
// reset so we can continue cleanly
16
mpu.resetFIFO();
17
Serial.println("FiFO Overflow");
18
// otherwise, check for DMP data ready interrupt (this should happen frequently)
19
}elseif(mpuIntStatus&0x02){
20
// wait for correct available data length, should be a VERY short wait