Real time posture detection

Hi currently i was having a project regarding detect posture angle and position by using mpu6050,esp32,buzzer and Blynk Iot platform.
Nw I having few problem...

  1. what is the exact formula for counting the angle for mpu6050?
  2. What is the code when the angle exceed certain degree it will initiate the buzzer?

thanks

#define BLYNK_TEMPLATE_ID "TMPL6fPddz4IZ"
#define BLYNK_TEMPLATE_NAME "mpu"
#define BLYNK_AUTH_TOKEN "OG3wTFZ8Qi80WHZITLWzedkafvmwbb0p"

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

char ssid[] = "....."; // Your WiFi credentials.
char pass[] = "abc123";
 
const int MPU_addr = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
 
int minVal = 265;
int maxVal = 402;

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Serial.begin(9600);
  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
}

void loop() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true);
  AcX = Wire.read() << 8 | Wire.read();
  AcY = Wire.read() << 8 | Wire.read();
  AcZ = Wire.read() << 8 | Wire.read();

  double x1 ; 
  double y1 ; 
  double z1 ; 

  double x2 ; 
  double y2 ; 
  double z2 ;

int xAng = map(AcX,minVal,maxVal,-90,90);
int yAng = map(AcY,minVal,maxVal,-90,90);
int zAng = map(AcZ,minVal,maxVal,-90,90);
 
x1= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
y1= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
z1= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

  double dotProduct = x1 * x2 + y1 * y2 + z1 * z2;

  // Calculate magnitudes
  double magnitude1 = sqrt(x1 * x1 + y1 * y1 + z1 * z1);
  double magnitude2 = sqrt(x2 * x2 + y2 * y2 + z2 * z2);

  // Calculate cosine of the angle
  double cosTheta = dotProduct / (magnitude1 * magnitude2);

  // Calculate angle in radians
  double angleRad = acos(cosTheta);

  // Convert angle to degrees
  double angleDeg = angleRad * RAD_TO_DEG;


  Serial.print("AngleX= ");
  Serial.println(x1);
 
  Serial.print("AngleY= ");
  Serial.println(y1);
 
  Serial.print("AngleZ= ");
  Serial.println(z1);

  Serial.print("Angle between vectors= ");
  Serial.println(angleDeg);

  Serial.println("-----------------------------------------");

  Blynk.virtualWrite(V1, x1);
  Blynk.virtualWrite(V2, y1);
  Blynk.virtualWrite(V3, z1);
  Blynk.virtualWrite(V4, x2);
  Blynk.virtualWrite(V5, y2);
  Blynk.virtualWrite(V6, z2);
  Blynk.virtualWrite(V7, angleDeg);

  delay(1000);
  Blynk.run();
}```

The above is some nonsense that you found somewhere on the web. It keeps cropping up on this forum.

The mathematically correct way to calculate tilt angles using an accelerometer is explained here, and it works well: How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing-DFRobot

Code for the MPU-6050:

// minimal MPU-6050 tilt and roll (sjr). Works with MPU-9250 too.
// works perfectly with GY-521, pitch and roll signs agree with arrows on sensor module 7/2019
//
// Tested with 3.3V eBay Pro Mini with no external pullups on I2C bus (worked with internal pullups)
// Add 4.7K pullup resistors to 3.3V if required. A4 = SDA, A5 = SCL

#include<Wire.h>
const int MPU_addr1 = 0x68;
float xa, ya, za, roll, pitch;

void setup() {

  Wire.begin();                                      //begin the wire communication
  Wire.beginTransmission(MPU_addr1);                 //begin, send the slave adress (in this case 68)
  Wire.write(0x6B);                                  //make the reset (place a 0 into the 6B register)
  Wire.write(0);
  Wire.endTransmission(true);                        //end the transmission
  Serial.begin(9600);
}

void loop() {

  Wire.beginTransmission(MPU_addr1);
  Wire.write(0x3B);  //send starting register address, accelerometer high byte
  Wire.endTransmission(false); //restart for read
  Wire.requestFrom(MPU_addr1, 6); //get six bytes accelerometer data
  int t = Wire.read();
  xa = (t << 8) | Wire.read();
  t = Wire.read();
  ya = (t << 8) | Wire.read();
  t = Wire.read();
  za = (t << 8) | Wire.read();
// formula from https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
  roll = atan2(ya , za) * 180.0 / PI;
  pitch = atan2(-xa , sqrt(ya * ya + za * za)) * 180.0 / PI; //account for roll already applied

  Serial.print("roll = ");
  Serial.print(roll,1);
  Serial.print(", pitch = ");
  Serial.println(pitch,1);
  delay(400);
}

1 Like

Hi thank you for ur help
but can i know the angle which axis u refer to (x,y or z)?

Pitch and roll are about the X and Y axes, with Z approximately vertical.

alright thank you so much

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.