#include <Wire.h>

const int MPU = 0x68; //MPU address
float AccX_Raw, AccY_Raw, AccZ_Raw;
float AccX, AccY, AccZ;
float AccX_SI, AccY_SI, AccZ_SI;


void setup() {
Serial.begin (9600);    //inisiasi serial komunikasi 
Wire.begin ();          //inisiasi komunikasi I2C
Wire.beginTransmission (MPU);     //mulai komunikasi I2C dengan MPU
Wire.write (0x6B);       //Panggil register address 107 atau 0x6B (Register pengaturan power management)
Wire.write (0x00);       //Write bit data pada register 0x6B dengan nilai 0000000 - reset register power management
Wire.endTransmission (true);    //Akhiri transmisi data

//Setting sensitivitas accelerometer
Wire.beginTransmission (MPU);
Wire.write (0x1C);      //Panggil register address 28 atau 0x1C (Register pengaturan akselerometer)
Wire.write (0x10);      //Write bit data pada register 0x1C dengan bit 00010000, setting ini adalah pengaturan sensitifitas sensor acc menjadi +/- 8g. 
                        //bit 4 dan bit 3 (AFS_SEL) pada register di write dengan biner 2bit bernilai  10 (dalam desimal nilainya equivalen dengan nilai 2) lihat tabel ACC_CONFIG di datasheet
Wire.endTransmission (true);    //Akhiri transmisi data

delay (20);
}

void loop() {
  // Pembacaan data accelerometer //
Wire.beginTransmission (MPU);   //mulai komunikasi dengan MPU6050
Wire.write (0x3B);               //panggil register address 59 atau 0x3B ACCEL_XOUT
Wire.endTransmission (false);   //tetap terhubung ke i2c bus 
Wire.requestFrom (MPU,6,true);  //request data dari address "MPU" sebanyak 6 byte, data yang diambil dimulai dari address 0,3B 
                                //artinya semua data pada register akan di ambil oleh master (lihat datasheet), kemudian lepaskan bus dengan mengirim stop massage

AccX_Raw = Wire.read()<<8|Wire.read();  //simpan hasil request data dari dua register 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L) ke variabel AccX_Raw, 
                                        //sekarang, variabel AccX_Raw menyimpan 16 bit data. variabel AccY_Raw dan AccZ_Raw pun sama menyimpan 16 bit data
AccY_Raw = Wire.read()<<8|Wire.read();  //simpan hasil request data dari dua register 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L) ke variabel AccY_Raw
AccZ_Raw = Wire.read()<<8|Wire.read();  //simpan hasil request data dari dua register 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L) ke variabel AccZ_Raw

//sensitivitas akleserometer di atur pada nilai +/- 8g, sehingga nilai pembacaan data register perlu dibagi 4096 untuk mengkonversi Raw data ke satuan g-force (lihat datasheet)
AccX = AccX_Raw/4096;     
AccY = AccY_Raw/4096;
AccZ = AccZ_Raw/4096;

//biasanya kita tidak familiar dengan satuan g-force, kita bisa mengkonversinya menjadi m/s2 dengan gravitasi bumi 9,8 m/s2
AccX_SI = AccX * 9.8;
AccY_SI = AccY * 9.8;
AccZ_SI = AccZ * 9.8;

//tampilkan hasil pengukuran di serial monitor
Serial.print ("Akselerasi Sb X = ");
Serial.println (AccX_SI);
Serial.print ("Akselerasi Sb Y = ");
Serial.println (AccY_SI);
Serial.print ("Akselerasi Sb Z = ");
Serial.println (AccZ_SI);
delay (500);
}