MPU6050 Force / Kraftmessung

Hallo ich benutze derzeit ein Programm um mir die einwirkende Kraft anzuzeigen zu lassen. Und nun hätte ich ein paar Fragen dazu.

Wenn der Sensor sich im "Stillstand" befindet (Nicht bewegt wird) zeigt er fast 1G an. Ist diese Kraft die Erdanziehungskraft ?

Ich habe dieses Programm schon einmal getestet bei einer Beschleunigung von 0 auf 30 km/h mit dem PKW und da sind mir Werte von zirka 1,10 g anzeigt worden. Ist dieser Wert plausibel ?

Ich suche nach einem Programm um den MPU6050 zu kalibrieren zu können für genauere Wertangaben. Hätte von euch jemand einen Link dazu, weil ich wurde nicht fündig.

Mein verwendeter Code:

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 mpu;


/* =========================================================================
   NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
   depends on the MPU-6050's INT pin being connected to the Arduino's
   external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
   digital I/O pin 2.
 * ========================================================================= */



//#define OUTPUT_READABLE_QUATERNION
//#define OUTPUT_READABLE_EULER
//#define OUTPUT_READABLE_YAWPITCHROLL
#define OUTPUT_READABLE_REALACCEL
//#define OUTPUT_READABLE_WORLDACCEL
//#define OUTPUT_TEAPOT



#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '

LG, 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===              INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;    // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

// ================================================================
// ===                      INITIAL SETUP                      ===
// ================================================================

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

// initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial.begin(115200);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

// initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();

// verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

delay(1000);

// load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

// supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
    mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);

// make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

// enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

// set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

// get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

// configure LED for output
    pinMode(LED_PIN, OUTPUT);
 
}

// ================================================================
// ===                    MAIN PROGRAM LOOP                    ===
// ================================================================

void loop() {
 
  float x = mpu.getAccelerationX()/2048.0;
  float y = mpu.getAccelerationY()/2048.0;
  float z = mpu.getAccelerationZ()/2048.0;

Serial.println(sqrt(xx+yy+z*z));

delay(25);

}


LG

Ich habe dieses Programm schon einmal getestet bei einer Beschleunigung von 0 auf 30 km/h mit dem PKW und da sind mir Werte von zirka 1,10 g anzeigt worden. Ist dieser Wert plausibel ?

4m/s² sind schon sehr sportliche Beschleunigungswerte für ein KFZ
Bei modernen Bremsen mögen -10m/s² drin sein. Auch schon recht sportlich.

Eine Beschleunigung von 1g entspricht ca. knapp 3 Sekunden von 0-100 km/h.

Es gibt Autos, die das annährend schaffen, z.B. ein Porsche GT3 oder ein Tesla S.

Oder ein Bugatti Veyron, der liegt bei 2,5 Sekunden (mit 1001 PS...).

Wenn Du ein ein Mobil dieser Leistungs-Liga fährst, sind die Werte plausibel, sonst eher nicht.

Gruß,

Helmuth

In Ruhe misst du 1.0g Das ist richtig.
Um 1.1g zu messen musst du also etwas zusätzlich beschleunigen.
Fragt sich eher, wie du die Richtung der Beschleunigung ( x-y-z ) behandelst.

Serial.println(sqrt(xx+yy+z*z));

Da deine 1.1g die resultierende Beschleunigung ist, musst du zu 1.0 in z-Richtung ca. 0.45g in x-Richtung dazugeben, sagt Pythagoras ( wenn ich mich nicht vertan habe )

Du hast mehr davon, wenn du die drei Komponenten einzeln anzeigst. :wink:

Du meinst das ich mir lieber X , Y , Z einzel anzeigen lassen sollte ?

Ich möchte in meinem Projekt mit dem MPU6050 mir die Kraft anzeigen lassen die bei Beschleunigungsmomenten in einem PKW entstehen/einwirken.

Könnte ich eigentlich der Z - Achse einen fixen Wert zuweißen, weil Z ist ja die Achse für "Rauf und Runter" oder ?

Wenn der Sensor genau waagerecht eingebaut ist, zeigen die Z - Werte eher Bodenunebenheiten und Federung an. (Und, ob das Auto waagerecht bleibt, beim Bremsen/Kurve fahren)

Wenn du die x und y Werte einzeln anzeigst, hast du größere Unterschiede und auch positive/negative Werte.

Die Kräfte die auf dein Auto einwirken, hängen auch von dessen Gewicht ab (oder umgekehrt) :wink:

Michael danke du hast mir gerade sehr geholfen, weil ich drauf gekommen bin das ich den Sensor eigentlich "falsch" rum eingebaut habe. Und daher die Z- Achse in die falsche Richtung zeigt.

Wie ich nun das mit den x und y Werte mache überlege ich mir mal und teile es dann mit ;=)

Vielen Dank !

Speedcore016:
… die Z- Achse in die falsche Richtung zeigt…

wenn alles einigermassen Sinn macht, also x / y / z mit sinnvollen Richungen relativ zum Auto übereinstimmt, würde ich mechanisch nichts umbauen. :slight_smile:

Hallo ich hätte noch eine Frage und zwar wenn ich mir die Kraft im Serial Monitor anzeigen lasse bleibt dieser manchmal stecken und ich muss diesen neustarten, dass er wieder geht.

An was liegt das ?

Speedcore016:
Hallo ich hätte noch eine Frage und zwar wenn ich mir die Kraft im Serial Monitor anzeigen lasse bleibt dieser manchmal stecken und ich muss diesen neustarten, dass er wieder geht.

An was liegt das ?

Das liegt daran, dass dein Programm einen Fehler hat.
Erst ein Reset bringt deinen Arduino wieder in Spur… bis zum nächsten mal…

Okay hättest du vielleicht eine Idee wo dieser Fehler sein könnte, weil ich wüsste nicht wo dieser seien könnte

LG

Nöö..

Dein Programm sieht so aus:

...
void loop() {
  float x = mpu.getAccelerationX()/2048.0;
  float y = mpu.getAccelerationY()/2048.0;
  float z = mpu.getAccelerationZ()/2048.0;
  
  Serial.println(sqrt(x*x+y*y+z*z));
 
  delay(25);  
}

Die serielle Schnittstelle wird mit Serial.begin(115200); initialisiert. ( Das delay(25) ist also wenig, aber ausreichend )

Wenn du noch nicht mal sagst was du genau unter
"...bleibt dieser manchmal stecken..." verstehst, kann man dir nicht wirklich helfen.

Ich rate mal, dass das nicht der Code ist, der hängen bleibt :wink:

Besser ausgerückt der Moinitor zeigt nach einer gewissen Zeit keine Werte mehr an. Es ist manchmal früher und manchmal später aber er stoppt auf jeden Fall und erst wenn ich den Monitor erneut öffne dann zeigt er wieder Werte an

Sowas ähnliches hatte ich auch schon. Lass mal die Pin 13 LED per millis() blinken. Dann siehst du ob das Programm noch läuft. Das war bei mir dir Fall.

Du kannst mal probieren ob es mit einem anderen Terminal Programm besser wird:

Hallo

Ich habe den anderen Terminal und das mit der LED ausprobiert leider kein Erfolg.
Danach hab ich das Programm zusammen gekürzt und eine LED am Ausgang geschalten wenn die Kraft einen gewissen Wert erreicht. Leider auch kein Erfolg.

#include "I2Cdev.h"
#include "Wire.h"
#include "MPU6050_6Axis_MotionApps20.h"

MPU6050  mpu;

int switchPin1 = 8;
int ledgn2 = 50;

void setup() {

  Serial.begin(9600);

  pinMode(switchPin1, INPUT_PULLUP);
  pinMode(ledgn2, OUTPUT);

}

void loop() {
    
  double x = mpu.getAccelerationX()/2048.0;
  double y = mpu.getAccelerationY()/2048.0;
  double z = mpu.getAccelerationZ()/2048.0;

  double gforce = sqrt(x*x+y*y+z*z);
  Serial.println(gforce);
  delay(150);
  

  if(gforce <= 1){
    digitalWrite(ledgn2, true);
  }
  else
  {
    digitalWrite(ledgn2, false);
  }
  
   
}

Kann es sein das der Speicher EEPROM voll wird ?
Würde es vielleicht das Problem lösen wenn ich nach einer gewissen Zeit immer wiederholend den Speicher zurück auf 0 setzen würde mit dem Programm EEPROM Clear ?

LG

Wo verwendest du EEPROM Speicher ? Seh ich nicht.

Verstehe ich das richtig: Eine Zeitlang zeigt das Terminalprogramm Zahlen um die 1.00 an, mal größer, mal kleiner, je nachdem wie man den Sensor schüttelt und bewegt, und die LED flackert dazu. Irgendwann bleibt die LED wie sie war und am Terminal kommt auch nichts mehr ( oder kommt dann konstant immer derselbe Wert ? )

Sehr seltsam.
Das bedeutet, dass loop() irgendwo in mpu.getAccelerationXYZ() hängt, also vermutlich in der I2C Kommunikation (geraten), aber da müsste man in deine Libraries reinschauen.

Noch einfacher:

#include "I2Cdev.h"
#include "Wire.h"
#include "MPU6050_6Axis_MotionApps20.h"

MPU6050  mpu;

const int ledgn2 = 50;

void setup() {
  pinMode(ledgn2, OUTPUT);
}

void loop() {
  double x = mpu.getAccelerationX();
  digitalWrite(ledgn2, (x>0.0));
}

So solltest du wackeln in x-Richtung direkt an der LED sehen. (Beliebig lange)

Also nach einer gewissen Zeit bleibt die LED wie sie war und am Terminal kommen keine Werte mehr an.
Sollte ich vielleicht mal die Libaries tauschen falls das möglich ist ?

LG

Wenn mein voriges Beispiel ( "noch einfacher" ) auch hängt, kann es ja nur an mpu.getAccelerationX() liegen.

Libraries sind auch nur Software, die man ansehen, auseinandernehmen und verstehen sollte.

Okay ich werde mal dein Beispiel ausprobieren bei mir.

Falls das auch nicht funktioniert probiere ich mal verschiedene Bibliotheken aus