Geschwindigkeitsmessung mit mpu6050

Hallo,
ich möchte einen mpu 6050, die an den Arduino mega angeschlossen ist, dazu bringen, dass er mir die Geschwindigkeit berechnen kann.
(ja ich weiß, dass das auf dauer ungenau wird... Aber das ist in diesem Fall nicht relevant)
Da dies aber mein erstes Projekt ist was mit Programmieren zu tun hat und ich keine Vorkenntnisse besitze, komme ich nicht weiter....
Ich benutze die libary von Jeff Rowberg, die ich aber leider nicht ganz verstehe...
Mein Code lautet wie folgt:

unsigned int xReal;
int _step = 0;
int offset = 0;
float ax =0;
float ax1 = 0;
float ax2 = 0;
float da = 0 ;
int oldax = 0;
int newax = 0;
unsigned long T = 0 ;
unsigned long T11 = 0 ;
float T1 = 0 ;
float T2 = 0 ;
float dT = 0 ;
float V = 0 ;
int V1 = 0;
float dV = 0;
int index;
long mitwert =0;
long xwert;
if(_step <4501)
    {
      delay(1);
      _step++ ;
    }


    else if (_step >= 4500&&_step < 5501) 
    {
 
      mitwert = mitwert + aaReal.x ;
      
      if(_step== 5500)
      {
        offset = mitwert/1000;
              
        if (offset <0)
        {
          offset *=-1; 
        }
  
      }
      _step++; 
    }
    else
    {
      if (aaReal.x < 0)
      {
        xwert = aaReal.x + offset ;
      }
      if (aaReal.x > 0)
      {
        xwert = aaReal.x - offset ;

      }


      ax = (16.0f/16384)*xwert  ; // Beschleunigungswert


      if (ax < -0,21 && ax > 0,21 ) // Schwelle
      {
        newax = (int)(ax *1000);


        if (oldax != newax)
        {
          oldax = (int)(ax* 1000) ;
          ax1 = ax;
          T2 = millis () ;
          T2 /= 1000.0f ;
          da =ax1 ; // Beschleunigungsänderung
          dT = T1 - T2 ; // Zeitänderung
          dV = da*dT ; // Geschwindigkeitsänderung
          V = V + dV ; // Endgültige Geschwindigkeit
        
        }           

        else 
        {  
          T1 = millis () ;
          T1 /= 1000.0f ;
 

        }
      }

      else 
      {
        V = 0 ;
      }
             Serial.println (V) ;          

    }

dies sollte eigentlich funtkionieren. Dennoch zeigt es mir unteranderem "-" Werte an, die nicht sein dürfeten.
Desshalb die Frage ist etwas an meinem Code falsch und/oder muss ich irgendetwas an der libary ändern?
Auch kann die mpu nicht wieder 0 anzeigen, sobald sie einmal aus der Schwelle getreten ist.

if (V < 0,01 && V > -0,01)
                {
                  V = 0 ;
                }

Dies wäre meine Idee wie es wieder auf 0 kommt,
allerdings weis ich nicht wo ich dies in meiner Schleife hinsetzten kann.

Bin dankbar für jede Hilfe.

if (V < 0.01 && V > -0.01)    V = 0 ;  // DezimalPunkt statt Komma, sonst ok

kannst du, wenn erforderlich, irgendwo hinsetzen, zwischen Berechnung und Anzeige,
allerdings rundet Serial.println(V); sowieso, und wird dir Werte unter 0.005 als 0.00 anzeigen.

wofür

if(_step <4501)
    {
      delay(1);
      _step++ ;
    }

gut sein soll, ist mir unklar.

Ich sehe es als eine etwas ungenaue Abart von

   delay (4500-_step); 
  _step = 4501;

Wenn dein Code die Ganze loop() darstellt, machst du nach dem Reset erstmal ein delay von 4.5 sec, um dann mit max. Geschwindigkeit
1000 mal aaReal.x ( was ist das und wie ändert es sich?) zu lesen und zu mitteln ( falls es sich in dieser kurzen Zeit ändert ).
Danach wird es unklar für mich, wieso du den Absolutwert von offset bildest und diesen je nach Vorzeich des aktuellen aaReal.x entweder addierst oder subtrahierst ?

Der Berechnungszyklus nach den ersten 4.5 sec hängt übrigens nur daran, dass der Serial-Ausgabepuffer dauernd voll ist, ist das Absicht ?

Weiter meinst du entweder

if (ax < -0.21 || ax > 0.21 )

oder

if (ax > -0.21 && ax < 0.21 )

, oder ?

Das grundsätzliche Problem mit dem V != 0 liegt daran, dass die Geschwindigkeit eben nicht Null ist, sondern immer relativ.
Es ist falsch, bei geringer Beschleunigung einfach v=0 zu setzen.
Bei reinem Aufsummieren bleibt immer ein Fehler, und v=0 ist eben kein besonderer Zustand, den dein mpu entdecken könnte.

danke für deine Antwort michael_x ,

aaReal.x ist der Beschleunigungswert auf der x-Achse, den ich ja umwandeln will in eine Geschwindigkeit.

[code]if(_step <4501)
    {
      delay(1);
      _step++ ;
    }

ist, wie du sagst das gleiche, jedoch bin ich nicht darauf gekommen es anders dazustellen.
Dies wird aber auch nur ein einziges mal durchgeführt und dient dazu, dass der mpu erstmal inruhe hochläuft und ich genug Zeit habe den mpu in einer Ruhestellung hinzulegen.

aaReal.x wird so oft ausgelesen um einen gesunden Mittelwert zu erzeugem haben, da die mpu ja nie zu 100% still liegt.

Danach wird es unklar für mich, wieso du den Absolutwert von offset bildest und diesen je nach Vorzeich des aktuellen aaReal.x 
entweder addierst oder subtrahierst ?

dies sollte dazu dienen dass die Werte immer positiv sind.

Der Berechnungszyklus nach den ersten 4.5 sec hängt übrigens nur daran, dass der Serial-Ausgabepuffer 
dauernd voll ist, ist das Absicht ?

da versteh ich leider nicht was du meinst

Weiter meinst du entweder
Code:

if (ax < -0.21 || ax > 0.21 )

oder
Code:

if (ax > -0.21 && ax < 0.21 )[/code]

da habe ich , und . unbeabsicht vertauscht
aber habe schon das erste gemeint, da nämlich der mpu nie wirklich 0 anzeigt wollte ich das so
"erzwingen" dass das Fehler auslöst ist mir bewust aber ich weis leider keine andere Möglichkeik.

dies sollte dazu dienen dass die Werte immer positiv sind.

Ein evtl. offset sollte doch eher daher rühren, dass der Sensor nicht genau flach liegt. Das Vorzeichen sollte doch richtig mitberücksichtigt werden, oder ?

aaReal.x ist der Beschleunigungswert auf der x-Achse, den ich ja umwandeln will in eine Geschwindigkeit.

Das Ganze ist ja eine numerische Integration, da spielt die Zykluszeit eine wichtige Rolle, und die hängt bei dir hauptsächlich an Serial.println und deinen float Berechnungen. millis() dürfte eher zu grob für einigermassen genaue Integrationen sein.

Hast du dir den DMP Modus des Sensors und der Library mal angesehen?

Wenn die Beschleunigung null ist, heißt das, daß die geradlinige Geschwindigkeit konstant ist. Du spürst die Beschleunigung im Auto ja auch nur beim gasgeben und beim bremsen (Kurvenfahrt mal außer acht gelassen weil das keine lineare bewegung ist)

Mal generell gesagt. wenn die Bewegung geradlinig ist kannst Du die geschwindigkeit grob aus der Beschleunigung berechen. Falls Du aber Kurven fährst ist das ohne Gyroskop nicht mehr möglich.
Grüße Uwe

Wenn die Beschleunigung null ist, heißt das, daß die geradlinige Geschwindigkeit konstant ist

Leider nicht ganz richtig, Uwe:
Wenn die Beschleunigung null ist, fällt dein mpu grade vom Tisch und ist noch so langsam, dass der Luftwiderstand gering ist. :wink:

Sonst hat er idealerweise in z - Richtung eine Beschleunigung von 1g, und in x- und y-Richtung 0.
Wirkt die auf der Erde übliche Beschleunigung nicht genau in z-Richtung des Sensors, sind auch x und/oder y ungleich 0.

Rotationen sind nochmal komplizierter, das stimmt, dafür hat der mpu auch 6 Koordinaten.

danke Michael_x und Uwefed für eure antworten,

Ein evtl. offset sollte doch eher daher rühren, dass der Sensor nicht genau flach liegt. Das Vorzeichen sollte doch richtig mitberücksichtigt werden, oder ?

ja sollte es hast du recht ^^

Das Ganze ist ja eine numerische Integration, da spielt die Zykluszeit eine wichtige Rolle, und die hängt bei dir  hauptsächlich an Serial.println und deinen float Berechnungen. millis() dürfte eher zu grob für einigermassen genaue Integrationen sein.

zu grob?, weil einen anderen Befehl zum Zeitmessen kenne ich nicht...

Wenn die Beschleunigung null ist, heißt das, daß die geradlinige Geschwindigkeit konstant ist. Du spürst die Beschleunigung im Auto ja auch nur beim gasgeben und beim bremsen (Kurvenfahrt mal außer acht gelassen weil das keine lineare bewegung ist)

und genau das ist ein Problem, da der mpu verstehen muss, dass wenn einmal die Beschleunigung = 0 ist er weiter die Geschwindigkeit anzeigen soll
andererseits, wenn der mpu still ist ist auch die Beschleunigung wieder = 0...

Sonst hat er idealerweise in z - Richtung eine Beschleunigung von 1g, und in x- und y-Richtung 0.
Wirkt die auf der Erde übliche Beschleunigung nicht genau in z-Richtung des Sensors, sind auch x und/oder y ungleich 0.

auch dass ist ein Problem, weil momentan die z- Achse zwar ungefähr 1g ausspuckt.. (um genau zu sein ca. -0,86) allerdings der g-Wert - ist und auch - bleibt wenn man den mpu umdreht, was mich komplett irritiert...

Wenn du Leute zitieren willst, verwende "quote" tags und nicht "code". Bei den Icons ist das das Sprechblasen-Symbol unten rechts. :slight_smile:

Es gibt auch micros() für sub-ms Auflösung

michael_x:

Wenn die Beschleunigung null ist, heißt das, daß die geradlinige Geschwindigkeit konstant ist

Leider nicht ganz richtig, Uwe:
Wenn die Beschleunigung null ist, fällt dein mpu grade vom Tisch und ist noch so langsam, dass der Luftwiderstand gering ist. :wink:

Sonst hat er idealerweise in z - Richtung eine Beschleunigung von 1g, und in x- und y-Richtung 0.
Wirkt die auf der Erde übliche Beschleunigung nicht genau in z-Richtung des Sensors, sind auch x und/oder y ungleich 0.

Rotationen sind nochmal komplizierter, das stimmt, dafür hat der mpu auch 6 Koordinaten.

In der Diskussion ging es bis jetzt um die X-Achse und ich habe mich darauf bezogen. Das bedeutet der Beschleunigungssensor ist waagerecht ausgerichtet und die Bewegung geht nur in richtung x-Achse. in diesem Fall kann man die Z-Achse und damit die Erdbeschleunigung unberücksichtigt lassen

Das was Du sagst ist richtig, aber dann muß man mit 3-dimensionalen Vektoren rechnen und auch noch annehmen, daß der Beschleunigungssensor immer gleich schief hängt.

Grüße Uwe

danke für eure Antworten,

Hast du dir den DMP Modus des Sensors und der Library mal angesehen?

sry das hatte ich überlesen...
Zur Frage zurück ja angesehen habe ich es mir ob ich es verstanden habe ist dann leider wieder ein anderes Thema

momentan möchte ich es ja nur ans laufen bekommen (vorerst) doch dafür muss ich wissen warum der mpu mir nur negative Werte bei der z-Achse sendet und warum er überhaupt negative Werte senden kann weil in der libary steht eigentlich:

// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
// not compensated for orientation, so +X is always +X according to the
// sensor, just without the effects of gravity. If you want acceleration
// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
#define OUTPUT_READABLE_REALACCEL

hat wer eine Idee?