Accelerometer to calculate the result does not work

hi i have a code like that to calculate the result (it takes the data from ax and divide by 60 and multiplies by 8 and that's the result) but why doesn't it work? (I apologize for my English I don't speak English well)

int a;








#include "I2Cdev.h"
#include "MPU6050.h"

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

MPU6050 accelgyro;

int16_t ax, ay, az;
int16_t gx, gy, gz;

#define OUTPUT_READABLE_ACCELGYRO




void setup() {
   
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif


    Serial.begin(9600);

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

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


a = (ax) / 64.0 * 8;

 Serial.print(a);  
 delay(1000);  
    
}

void loop() {


  
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

   

    #ifdef OUTPUT_READABLE_ACCELGYRO
       
       
        
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif
 
 
}
    a = (ax) / 64.0 * 8;

is performed in setup() before "ax" is assigned a value.

don't you want to do that computation in loop(), after calling getMotion6() ?

thanks for the reply but now i have this code and it works fine but it doesn't work for calculating proc? :slight_smile:

#include <Wire.h>                  //Include WIre library for using I2C 



const int MPU_addr = 0x68;       //I2C MPU6050 Address

//myservo object for class servo

int16_t axis_X, axis_Y, axis_Z;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;

int pos = 0;
float a;
void setup()
{
  Wire.begin();                        //Begins I2C communication
  Wire.beginTransmission(MPU_addr);    //Begins Transmission with MPU6050
  Wire.write(0x6B);                    //Puts MPU6050 in Sleep Mode
  Wire.write(0);                       //Puts MPU6050 in power mode
  Wire.endTransmission(true);          //Ends Trasmission
  Serial.begin(9600);
  a = y / 64.0 * 8.0;
}

void loop()
{
  Wire.beginTransmission(MPU_addr); //Begins I2C transmission
  Wire.write(0x3B);                 //Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); //Request 14 Registers from MPU6050

  axis_X = Wire.read() << 8 | Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  axis_Y = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
  axis_Z = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)

  int xAng = map(axis_X, minVal, maxVal, -90, 90);
  int yAng = map(axis_Y, minVal, maxVal, -90, 90);
  int zAng = map(axis_Z, minVal, maxVal, -90, 90);

  y = RAD_TO_DEG * (atan2(-zAng, -xAng) + PI);  //Formula to calculate x values in degree
  int pos = map(y, 0, 180, 0, 180);
  Serial.println(pos);
  Serial.println(a);
}

what is "proc"? i don't see it in the posted code

thank you it already works,I've tried it now and it works :slight_smile:

I'm also asking how to set the tm1637 to work and display the number because it keeps flashing, what about that?

#include <Wire.h>                  //Include WIre library for using I2C 

#include <TM1637.h>

const int MPU_addr = 0x68;       //I2C MPU6050 Address

//myservo object for class servo

int16_t axis_X, axis_Y, axis_Z;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;

int pos = 0;
float a;


int CLK = 2;
int DIO = 3;

TM1637 tm(CLK, DIO);

void setup()
{
  tm.init();

  //set brightness; 0-7
  tm.set(5);
 
  Wire.begin();                        //Begins I2C communication
  Wire.beginTransmission(MPU_addr);    //Begins Transmission with MPU6050
  Wire.write(0x6B);                    //Puts MPU6050 in Sleep Mode
  Wire.write(0);                       //Puts MPU6050 in power mode
  Wire.endTransmission(true);          //Ends Trasmission
  Serial.begin(9600);
  delay(1000);
 
}

void loop()
{
 a = y / 64.0 * 8.0;
  
  Wire.beginTransmission(MPU_addr); //Begins I2C transmission
  Wire.write(0x3B);                 //Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); //Request 14 Registers from MPU6050

  axis_X = Wire.read() << 8 | Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  axis_Y = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
  axis_Z = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)

  int xAng = map(axis_X, minVal, maxVal, -90, 90);
  int yAng = map(axis_Y, minVal, maxVal, -90, 90);
  int zAng = map(axis_Z, minVal, maxVal, -90, 90);

  y = RAD_TO_DEG * (atan2(-zAng, -xAng) + PI);  //Formula to calculate x values in degree
  int pos = map(y, 180, 0, 180, 0);
  Serial.println(pos);
  delay(500);
  Serial.println(a);

    displayNumber((a));
    
}
  void displayNumber(int num) {
  tm.display(3, num % 10);
  tm.display(2, num / 10 % 10);
  tm.point(1);
  tm.display(1, num / 100 % 10);
  tm.display(0, num / 1000 % 10);
}

perhaps someone else is familiar with that display module. otherwise try google

ok but thank you :slight_smile:

I still need help, how can I set the accelerometer to work from 90 to 150 degrees?

#include <Wire.h>                  //Include WIre library for using I2C 

#include <TM1637.h>

const int MPU_addr = 0x68;       //I2C MPU6050 Address

//myservo object for class servo

int16_t axis_X, axis_Y, axis_Z;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;

int pos = 0;
float result;


int CLK = 2;
int DIO = 3;

TM1637 tm(CLK, DIO);

void setup()
{
  tm.init();

  //set brightness; 0-7
  tm.set(5);
 
  Wire.begin();                        //Begins I2C communication
  Wire.beginTransmission(MPU_addr);    //Begins Transmission with MPU6050
  Wire.write(0x6B);                    //Puts MPU6050 in Sleep Mode
  Wire.write(0);                       //Puts MPU6050 in power mode
  Wire.endTransmission(true);          //Ends Trasmission
  Serial.begin(9600);
  delay(1000);
 
}

void loop()
{
  
 result = 63.0 / 90.0 * y;
 
  
  Wire.beginTransmission(MPU_addr); //Begins I2C transmission
  Wire.write(0x3B);                 //Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); //Request 14 Registers from MPU6050

  axis_X = Wire.read() << 8 | Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  axis_Y = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
  axis_Z = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)

  int xAng = map(axis_X, minVal, maxVal, -90, 90);
  int yAng = map(axis_Y, minVal, maxVal, -90, 90);
  int zAng = map(axis_Z, minVal, maxVal, -90, 90);

  y = RAD_TO_DEG * (atan2(-zAng, -xAng) + PI);  //Formula to calculate x values in degree
  int pos = map(y, 180, 0, 180, 0);
  
 
   Serial.println(pos);
   Serial.println(result);

  
    displayNumber((result));
    delay(500);
}
  void displayNumber(int num) {
  tm.display(3, num % 10);
  tm.display(2, num / 10 % 10);
  tm.point(1);
  tm.display(1, num / 100 % 10);
  tm.display(0, num / 1000 % 10);
}

arc tangent, atan2() of ax and ay. then convert from radians to degrees, * 180 / Pi

like this?

atan2(150, 180 / PI);

deg = atan2(ay, ax) * 180 / Pi

I'm sorry to ask again, but something like that?

#include <Wire.h>                  //Include WIre library for using I2C 

#include <TM1637.h>

const int MPU_addr = 0x68;       //I2C MPU6050 Address

//myservo object for class servo

int16_t axis_X, axis_Y, axis_Z;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;

int pos = 0;
float result;


int CLK = 2;
int DIO = 3;

TM1637 tm(CLK, DIO);

void setup()
{
  tm.init();

  //set brightness; 0-7
  tm.set(5);

  Wire.begin();                        //Begins I2C communication
  Wire.beginTransmission(MPU_addr);    //Begins Transmission with MPU6050
  Wire.write(0x6B);                    //Puts MPU6050 in Sleep Mode
  Wire.write(0);                       //Puts MPU6050 in power mode
  Wire.endTransmission(true);          //Ends Trasmission
  Serial.begin(9600);
  delay(1000);

}

void loop()
{

  result = 63.0 / 90.0 * y;


  Wire.beginTransmission(MPU_addr); //Begins I2C transmission
  Wire.write(0x3B);                 //Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); //Request 14 Registers from MPU6050

  axis_X = Wire.read() << 8 | Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  axis_Y = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
  axis_Z = Wire.read() << 8 | Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)

  int xAng = map(axis_X, minVal, maxVal, -90, 90);
  int yAng = map(axis_Y, minVal, maxVal, -90, 90);
  int zAng = map(axis_Z, minVal, maxVal, -90, 90);

  y = RAD_TO_DEG * (atan2(-zAng, -xAng) + PI);  //Formula to calculate x values in degree
  int pos = map(y, 180, 0, 180, 0);

pos = atan2(xAng, zAng ) * 180 / PI;


  Serial.println(pos);
  Serial.println(result);


  displayNumber((result));
  delay(500);
}
void displayNumber(int num) {
  tm.display(3, num % 10);
  tm.display(2, num / 10 % 10);
  tm.point(1);
  tm.display(1, num / 100 % 10);
  tm.display(0, num / 1000 % 10);
}

not sure what this is doing. adding PI is like addint 180 deg

    y = RAD_TO_DEG * (atan2(-zAng, -xAng) + PI);

this is what i suggested, except it's an angle, not a position

    pos = atan2(xAng, zAng ) * 180 / PI;

thank you but i don't understand how you think i always calculate one angle (y) but not two i need from 90 to 150 degrees, i have to set it to work and only count from 90 to 150 degrees

it makes sense that you need 2 angles.
the result from atan2() is an angle, not position
the arguments to atan2() are 2 dimensions (??) not angles
two slightly different methods are being used: RAD_TO_DEG and 180/PI
don't understand why you determine an angle (xAng) using map() and axis_X

thank you , but i was thinking of another option not to stop the accelerometer, but turn off the counting, so it doesn't count below 90 and above 150 degrees, it also doesn't count, so it doesn't write me the results, but 90-100-110-120-130-140- 150 writes the result :slight_smile:

i don't understand what you're trying to do
what are you trying to measure/control with your accelerometer?

stromecek_555:
(I apologize for my English I don't speak English well)

try using google translate

I make a prototype, which I named ballistic_cpu, I will calculate the range of the airsoft rifle according to the angle (I have already tried the bows and it worked, but there was another example) :slight_smile:

it makes sense that you're measuring the acceleration of some projectile toward some target and you'd like to determine the angles of the projectile both vertically and horizontally.

it's not clear which axis is toward the target. if ax is toward and ay is the horizontal then atan2(ay,ax) is the horizontal angle and atan2(az, ax) is the vertical angle

is this correct?