Too big g force values even though it's just a little touch(using mpu6050)

Hi there, im having a project with a mpu6050, its a punch acceleration sensor, but there's a problem with it, well i use this algorithm to measure acceleration of a punch using the mpu6050:

  float gForceX = (float(ax) / 32767.0) * 16.0;
  float gForceY = (float(ay) / 32767.0) * 16.0;
  float gForceZ = (float(az) / 32767.0) * 16.0;
  
  float accelX = gForceX * 9.81;
  float accelY = gForceY * 9.81;
  float accelZ = gForceZ * 9.81;
  float accelTotal = (sqrt(pow(accelX, 2) + pow(accelY, 2) + pow(accelZ, 2))) - 9.81;

and when i touch it a little bit, some how the value jumps all the way up to 262 m/s^2 which makes me wonder that is this really a true value
Heres my code
Cheers!

#include <MPU6050.h>
MPU6050 mpu;

#define EXPIRED                    true
#define stillTIMING                false

#define CLOSED                     LOW   
#define OPEN                       HIGH

#define ENABLED                    true
#define DISABLED                   false

#define YES                        true
#define NO                         false

const float thresholdForce = 5.0;
const unsigned long resetInterval = 500;
static float peakForce = 0, lastPeakForce = 0;
static unsigned long lastPeakMs = 0;


//const int arraySize = 200; //array size
//float dataArray[arraySize]; // array for storing values
//byte currentIndex = 0; // current index of the array

struct makeTIMER
{
  unsigned long Time;           //when the TIMER started
  unsigned long Interval;       //delay time in ms which we are looking for
  bool          timerFlag;      //is the TIMER enabled ? ENABLED/DISABLED
  bool          Restart;        //restart this TIMER ? YES/NO

  //****************************************
  //fuction to check if the TIMER is enabled and check if the TIMER has expired
  bool checkTIMER()
  {
    //*********************
    //is this TIMER enabled and has this TIMER expired ?
    if (timerFlag == ENABLED && millis() - Time >= Interval)
    {
      //*********************
      //should this TIMER restart again?
      if (Restart == YES)
      {
        //restart this TIMER
        Time = millis();
      }

      //this TIMER is enabled and has expired
      return EXPIRED;
    }

    //this TIMER is disabled and/or has not expired
    return stillTIMING;
  } //END of   checkTime()
}; //END of   struct makeTIMER

makeTIMER forceChecker =
{
  0, 500ul, ENABLED, NO      //Time, Interval, timerFlag, Restart
};


void setup() {
  Serial.begin(115200);
  Serial.begin(9600);
  
  Wire.begin();
  mpu.initialize();
  
  //measure range of mpu6050(±16g)
  mpu.setFullScaleAccelRange(3);

  delay(1000);
}

void loop(){

  int16_t ax, ay, az;
  mpu.getAcceleration(&ax, &ay, &az);
  
  // measuring accel
  float gForceX = (float(ax) / 32767.0) * 16.0;
  float gForceY = (float(ay) / 32767.0) * 16.0;
  float gForceZ = (float(az) / 32767.0) * 16.0;
  
  float accelX = gForceX * 9.81;
  float accelY = gForceY * 9.81;
  float accelZ = gForceZ * 9.81;
  float accelTotal = (sqrt(pow(accelX, 2) + pow(accelY, 2) + pow(accelZ, 2))) - 9.81;



  float myForce = accelTotal;

  if (myForce > thresholdForce && myForce > peakForce){
    peakForce = myForce;
    lastPeakForce = peakForce;
    lastPeakMs = millis();
    Serial.println(lastPeakForce);
    forceChecker.Time = millis();
    
  }

  if(forceChecker.checkTIMER() && peakForce > 0){
    peakForce = 0;
    Serial.println(lastPeakForce); 
  }
}

I moved your topic to an appropriate forum category @coasty.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

1 Like

Check your scaling by just printing out these values, while the accelerometer is held still. Any strictly vertical axis should report 1 g (+ when the axis is pointing up, - when down).

  float accelX = gForceX * 9.81;
  float accelY = gForceY * 9.81;
  float accelZ = gForceZ * 9.81;
1 Like


Its not like what you said, maybe i divided the raw value incorrectly

Please don't post pictures of code and text. Use copy/paste and code tags, instead.

If you want units of m/s/s, then fix the scaling such that a vertical axis reports either + or - 9.8 m/s/s.

Note: there are small differences in scale factor and offset for each accelerometer axis, which can be reduced or eliminated by calibration. See this tutorial (scroll down to six point calibration).

well the main thing is i want to print out only 1 acceleration, like in there are normally 3 acceleration but i want to use only , is there any algorithm that can measure out only one main acceleration from 3 of these acceleration from 3 axis.

You can use a function to sort the three values before printing the top value, or use "if" statements to find and print the maximum.

wait so i just simply use the maximum to find out? not like grabbing 3 of them and then measure g force by this way:
float accelTotal = (sqrt(pow(accelX, 2) + pow(accelY, 2) + pow(accelZ, 2))) - 9.81;
but im wondering that why we only use only one in three of them

The first step is to decide what you really want to do.

well i have a wooden board (a makiwara), then i mount the mpu6050 to the back of the board. Next i try to hit it and then finally it measures the acceleration of my punch.

The total acceleration is a 3D vector (X, Y, Z) that includes the acceleration due to gravity. To measure the acceleration of the punch, you need to subtract the acceleration due to gravity as a 3D vector, then calculate the "norm" of what remains.

If the orientation of the board does not change during the punch (unlikely), measure the static acceleration, store it, and measure acceleration during the punch. subtract the static acceleration from the punch measurements, and compute the norm (vector length, total punch acceleration).

// measure static acceleration
float sax, say, saz;
  mpu.getAcceleration(&sax, &say, &saz);
...
//during punch, measure dynamic acceleration
float ax, ay, az;
  mpu.getAcceleration(&ax, &ay, &az);

// subtract the two
ax=ax-sax;
ay=ay-say;
az=az-saz;

float punch = sqrt(ax*ax + ay*ay + az*az); //vector norm
1 Like

how exactly can i measure the static acceleration?

is static acceleration equal to 9.81 m/s^2 ?

"static" means the board is not moving.

is static acceleration equal to 9.81 m/s^2 ?

On Earth, yes. That is the accepted average value of the acceleration due to gravity. This is high school physics.

2 Likes

well im a high school student tho, just learned that 2 years ago (in secondary school)

so here's how it works, first i calibrate the values (using the method you gave me), then i subtract the static acceleration and finally i use this line:

float punch = sqrt(ax*ax + ay*ay + az*az); //vector norm

is it correct?

I usually mean what I write. Whether the result is accurate depends on the board not changing orientation during the punch, which is pretty unlikely.

but the thing is, the tutorial you gave me was from another sensor, mine is mpu6050.

Physics and math do not depend on the sensor. Scale factors do.

The linked tutorial demonstrates one approach to calibrating accelerometers.

1 Like

The sensor will have a slight arc around the anchor point of the arm, as well as inertia of the sensor, DuPont connectors, and jumper wires zip-tied to the moment arm. The mpu travel is not linear (movement along only one axis).

1 Like