ANGLE MAESUREMENT BY MPU6050

angle

#include <avr/interrupt.h>

#include <avr/eeprom.h>

#include “I2Cdev.h”

#include “MPU6050_6Axis_MotionApps20.h”

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

#include “Wire.h”

#endif

MPU6050 mpu;

#define OUTPUT_READABLE_EULER

#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)

bool blinkState = false;

int pinSetting = 4;

#include <IRremote.h>

int RECV_PIN = 5;

IRrecv irrecv(RECV_PIN);

decode_results results;

int addr = 1;

float sudut = 0;

int sudutawal = 0;

// 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

// ================================================================

// === INTERRUPT DETECTION ROUTINE ===

// ================================================================

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high

void dmpDataReady() {

mpuInterrupt = true;

}

// ================================================================

// === INITIAL SETUP ===

// ================================================================

void setup() {

irrecv.enableIRIn();

pinMode(pinSetting, INPUT);

// 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(9600);

while (!Serial); // wait for Leonardo enumeration, others continue immediately

mpu.initialize();

devStatus = mpu.dmpInitialize();

// supply your own gyro offsets here, scaled for min sensitivity

mpu.setXGyroOffset(38);

mpu.setYGyroOffset(-91);

mpu.setZGyroOffset(46);

mpu.setZAccelOffset(1682); // 1688 factory default for my test chip

// make sure it worked (returns 0 if so)

if (devStatus == 0) {

mpu.setDMPEnabled(true);

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() {

// if programming failed, don’t try to do anything

if (!dmpReady) return;

// wait for MPU interrupt or extra packet(s) available

while (!mpuInterrupt && fifoCount < packetSize) {

// other program behavior stuff here

// .

// .

// .

// if you are really paranoid you can frequently test in between other

// stuff to see if mpuInterrupt is true, and if so, “break;” from the

// while() loop to immediately process the MPU data

// .

// .

// .

}

// reset interrupt flag and get INT_STATUS byte

mpuInterrupt = false;

mpuIntStatus = mpu.getIntStatus();

// get current FIFO count

fifoCount = mpu.getFIFOCount();

if(irrecv.decode(&results)){

//————————————————————————

// check for overflow (this should never happen unless our code is too inefficient)

if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

// reset so we can continue cleanly

mpu.resetFIFO();

//Serial.println(F(“FIFO overflow!”));

// otherwise, check for DMP data ready interrupt (this should happen frequently)

} else if (mpuIntStatus & 0x02) {

// wait for correct available data length, should be a VERY short wait

while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO

mpu.getFIFOBytes(fifoBuffer, packetSize);

// track FIFO count here in case there is > 1 packet available

// (this lets us immediately read more without waiting for an interrupt)

fifoCount -= packetSize;

// display Euler angles in degrees

mpu.dmpGetQuaternion(&q, fifoBuffer);

mpu.dmpGetEuler(euler, &q);

//Serial.print(“euler\t”);

sudut = euler[0] * 180/M_PI;

//Serial.print(sudut);

//Serial.print(” “);

// Serial.print(“\t”);

// Serial.print(euler[1] * 180/M_PI);

// Serial.print(“\t”);

// Serial.println(euler[2] * 180/M_PI);

// blink LED to indicate activity

//blinkState = !blinkState;

//digitalWrite(LED_PIN, blinkState);

}

//————————————————————————————–

while (!eeprom_is_ready());

cli();

if(eeprom_read_word((uint16_t*)addr) != sudut) {

eeprom_update_word((uint16_t*)addr, sudut);

}

sei();

while (!eeprom_is_ready());

cli();

sudutawal = eeprom_read_word((uint16_t*)addr); // => sensorValue

sei();

Serial.print(sudut);

Serial.print(” “);

Serial.print(sudutawal);

Serial.print(” “);

hitung();

irrecv.resume();

delay(100);

}else{

//————————————————————————

// check for overflow (this should never happen unless our code is too inefficient)

if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

// reset so we can continue cleanly

mpu.resetFIFO();

//Serial.println(F(“FIFO overflow!”));

// otherwise, check for DMP data ready interrupt (this should happen frequently)

} else if (mpuIntStatus & 0x02) {

// wait for correct available data length, should be a VERY short wait

while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO

mpu.getFIFOBytes(fifoBuffer, packetSize);

// track FIFO count here in case there is > 1 packet available

// (this lets us immediately read more without waiting for an interrupt)

fifoCount -= packetSize;

// display Euler angles in degrees

mpu.dmpGetQuaternion(&q, fifoBuffer);

mpu.dmpGetEuler(euler, &q);

//Serial.print(“euler\t”);

sudut = euler[0] * 180/M_PI;

//Serial.print(sudut);

//Serial.print(” “);

// Serial.print(“\t”);

// Serial.print(euler[1] * 180/M_PI);

// Serial.print(“\t”);

// Serial.println(euler[2] * 180/M_PI);

// blink LED to indicate activity

//blinkState = !blinkState;

//digitalWrite(LED_PIN, blinkState);

}

//————————————————————————————–

//while (!eeprom_is_ready());

//cli();

/*if(eeprom_read_word((uint16_t*)addr) != sudut) {

eeprom_write_word((uint16_t*)addr, sudut);

}

sei();

*/

while (!eeprom_is_ready());

cli();

sudutawal = eeprom_read_word((uint16_t*)addr); // => sensorValue

sei();

Serial.print(sudut);

Serial.print(” “);

Serial.print(sudutawal);

Serial.print(” “);

hitung();

delay(100);

}

}

void hitung(){

if(((sudutawal >= -90) && (sudutawal <= 90)) || ((sudutawal >= -180) && (sudutawal < -90))){

int delta = abs(sudut-sudutawal);

Serial.println(delta);

}

else if((sudutawal > 90) && (sudutawal <= 180) && (sudut >= -180) && (sudut < 0)){

int delta = (360 + sudut-sudutawal);

Serial.println(delta);

}

else if((sudutawal >= -180) && (sudutawal < -90) && (sudut >= 0) && (sudut <= 180)){

int delta = (360 – sudut+sudutawal);

Serial.println(delta);

}

else if((sudutawal > 90) && (sudutawal <= 180) && (sudut >= 0) && (sudut <= 180)){

int delta = abs(sudut-sudutawal);

Serial.println(delta);

}

else{

Serial.println(” “);

}

}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s