Created
May 5, 2014 09:49
-
-
Save sahilshekhawat/67dff74f1fc6e6b96e9f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wire.h> | |
// The name of the sensor is "MPU-6050". | |
// For program code, I omit the '-', | |
// therefor I use the name "MPU6050....". | |
// Register names according to the datasheet. | |
// According to the InvenSense document | |
// "MPU-6000 and MPU-6050 Register Map | |
// and Descriptions Revision 3.2", there are no registers | |
// at 0x02 ... 0x18, but according other information | |
// the registers in that unknown area are for gain | |
// and offsets. | |
// | |
#define MPU6050_PWR_MGMT_1 0x6B // R/W | |
#define MPU6050_WHO_AM_I 0x75 // R | |
#define MPU6050_I2C_ADDRESS 0x68 | |
// Defines for the bits, to be able to change | |
// between bit number and binary definition. | |
// By using the bit number, programming the sensor | |
// is like programming the AVR microcontroller. | |
// But instead of using "(1<<X)", or "_BV(X)", | |
// the Arduino "bit(X)" is used. | |
typedef union accel_t_gyro_union | |
{ | |
struct | |
{ | |
uint8_t x_accel_h; | |
uint8_t x_accel_l; | |
uint8_t y_accel_h; | |
uint8_t y_accel_l; | |
uint8_t z_accel_h; | |
uint8_t z_accel_l; | |
uint8_t t_h; | |
uint8_t t_l; | |
uint8_t x_gyro_h; | |
uint8_t x_gyro_l; | |
uint8_t y_gyro_h; | |
uint8_t y_gyro_l; | |
uint8_t z_gyro_h; | |
uint8_t z_gyro_l; | |
} reg; | |
struct | |
{ | |
int16_t x_accel; | |
int16_t y_accel; | |
int16_t z_accel; | |
int16_t temperature; | |
int16_t x_gyro; | |
int16_t y_gyro; | |
int16_t z_gyro; | |
} value; | |
}; | |
struct { | |
uint8_t buttons; | |
int8_t x; | |
int8_t y; | |
int8_t wheel; /* Not yet implemented */ | |
} mouseReport; | |
uint8_t nullReport[4] = { 0, 0, 0, 0 }; | |
float distx=0,disty=0,sumvelx=0,sumvely=0,sumaccx=0,sumaccy=0,avgvelx=0,avgvely=0,avgdistx=0,avgdisty=0,prevx=0,prevy=0; | |
int i=0,j=0; | |
int LDR = A3; //analog pin to which LDR is connected, here we set it to 0 so it means A0 | |
int LDRValue = 0; //that’s a variable to store LDR values | |
int light_sensitivity = 100; //This is the approx value of light surrounding your LDR | |
void setup() | |
{ | |
int error; | |
uint8_t c; | |
Serial.begin(9600); | |
//Serial.println(F("InvenSense MPU-6050")); | |
//Serial.println(F("June 2012")); | |
// Initialize the 'Wire' class for the I2C-bus. | |
Wire.begin(); | |
// default at power-up: | |
// Gyro at 250 degrees second | |
// Acceleration at 2g | |
// Clock source at internal 8MHz | |
// The device is in sleep mode. | |
// | |
#define MPU6050_ACCEL_XOUT_H 0x3B // R | |
error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1); | |
//Serial.print(F("WHO_AM_I : ")); | |
//Serial.print(c,HEX); | |
//Serial.print(F(", error = ")); | |
//Serial.println(error,DEC); | |
// According to the datasheet, the 'sleep' bit | |
// should read a '1'. | |
// That bit has to be cleared, since the sensor | |
// is in sleep mode at power-up. | |
error = MPU6050_read (MPU6050_PWR_MGMT_1, &c, 1); | |
//Serial.print(F("PWR_MGMT_1 : ")); | |
//Serial.print(c,HEX); | |
//Serial.print(F(", error = ")); | |
//Serial.println(error,DEC); | |
// Clear the 'sleep' bit to start the sensor. | |
MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0); | |
//delay(200); | |
} | |
/* Move the mouse in a clockwise square every 5 seconds */ | |
void loop() | |
{ | |
int ind; | |
int error; | |
double dT; | |
accel_t_gyro_union accel_t_gyro; | |
//delay(100); | |
LDRValue = analogRead(LDR); //reads the ldr’s value through LDR which we have set to Analog input 0 “A0″ | |
//Serial.println(LDRValue); //prints the LDR values to serial monitor | |
//delay(50); | |
if (LDRValue < light_sensitivity) | |
{ | |
mouseReport.buttons=1; | |
} | |
else | |
{ | |
mouseReport.buttons=0; | |
} | |
//mouseReport.buttons = 0; | |
mouseReport.x = 0; | |
mouseReport.y = 0; | |
mouseReport.wheel = 0; | |
error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) &accel_t_gyro, sizeof(accel_t_gyro)); | |
uint8_t swap; | |
#define SWAP(x,y) swap = x; x = y; y = swap | |
SWAP (accel_t_gyro.reg.x_accel_h, accel_t_gyro.reg.x_accel_l); | |
SWAP (accel_t_gyro.reg.y_accel_h, accel_t_gyro.reg.y_accel_l); | |
SWAP (accel_t_gyro.reg.z_accel_h, accel_t_gyro.reg.z_accel_l); | |
SWAP (accel_t_gyro.reg.t_h, accel_t_gyro.reg.t_l); | |
SWAP (accel_t_gyro.reg.x_gyro_h, accel_t_gyro.reg.x_gyro_l); | |
SWAP (accel_t_gyro.reg.y_gyro_h, accel_t_gyro.reg.y_gyro_l); | |
SWAP (accel_t_gyro.reg.z_gyro_h, accel_t_gyro.reg.z_gyro_l); | |
if(i!=3) | |
{ | |
sumaccx=sumaccx+accel_t_gyro.value.x_accel; | |
sumaccy=sumaccy+accel_t_gyro.value.y_accel; | |
i=i+1; | |
} | |
if(i==3) | |
{ | |
avgvelx=sumaccx*(0.003); | |
avgvely=sumaccy*(0.003); | |
sumvelx=sumvelx+avgvelx; | |
sumvely=sumvely+avgvely; | |
j=j+1; | |
i=0; | |
sumaccx=0; | |
sumaccy=0; | |
} | |
if(j==3) | |
{prevx=avgdistx; | |
prevy=avgdisty; | |
avgdistx=sumvelx*(0.009); | |
avgdisty=sumvely*(0.009); | |
distx=avgdistx-prevx; | |
disty=avgdisty-prevy; | |
j=0; | |
sumvelx=0; | |
sumvely=0; | |
mouseReport.x = (-10)*avgdistx; | |
mouseReport.y = 10*avgdisty; | |
//Serial.print(avgdistx); | |
for (ind=0; ind<1; ind++) { | |
Serial.write((uint8_t *)&mouseReport, 4); | |
Serial.write((uint8_t *)&nullReport, 4); | |
}} | |
delay(10); | |
} | |
// -------------------------------------------------------- | |
// MPU6050_read | |
// | |
// This is a common function to read multiple bytes | |
// from an I2C device. | |
// | |
// It uses the boolean parameter for Wire.endTransMission() | |
// to be able to hold or release the I2C-bus. | |
// This is implemented in Arduino 1.0.1. | |
// | |
// Only this function is used to read. | |
// There is no function for a single byte. | |
// | |
int MPU6050_read(int start, uint8_t *buffer, int size) | |
{ | |
int i, n, error; | |
Wire.beginTransmission(MPU6050_I2C_ADDRESS); | |
n = Wire.write(start); | |
if (n != 1) | |
return (-10); | |
n = Wire.endTransmission(false); // hold the I2C-bus | |
if (n != 0) | |
return (n); | |
// Third parameter is true: relase I2C-bus after data is read. | |
Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true); | |
i = 0; | |
while(Wire.available() && i<size) | |
{ | |
buffer[i++]=Wire.read(); | |
} | |
if ( i != size) | |
return (-11); | |
return (0); // return : no error | |
} | |
// -------------------------------------------------------- | |
// MPU6050_write | |
// | |
// This is a common function to write multiple bytes to an I2C device. | |
// | |
// If only a single register is written, | |
// use the function MPU_6050_write_reg(). | |
// | |
// Parameters: | |
// start : Start address, use a define for the register | |
// pData : A pointer to the data to write. | |
// size : The number of bytes to write. | |
// | |
// If only a single register is written, a pointer | |
// to the data has to be used, and the size is | |
// a single byte: | |
// int data = 0; // the data to write | |
// MPU6050_write (MPU6050_PWR_MGMT_1, &c, 1); | |
// | |
int MPU6050_write(int start, const uint8_t *pData, int size) | |
{ | |
int n, error; | |
Wire.beginTransmission(MPU6050_I2C_ADDRESS); | |
n = Wire.write(start); // write the start address | |
if (n != 1) | |
return (-20); | |
n = Wire.write(pData, size); // write data bytes | |
if (n != size) | |
return (-21); | |
error = Wire.endTransmission(true); // release the I2C-bus | |
if (error != 0) | |
return (error); | |
return (0); // return : no error | |
} | |
// -------------------------------------------------------- | |
// MPU6050_write_reg | |
// | |
// An extra function to write a single register. | |
// It is just a wrapper around the MPU_6050_write() | |
// function, and it is only a convenient function | |
// to make it easier to write a single register. | |
// | |
int MPU6050_write_reg(int reg, uint8_t data) | |
{ | |
int error; | |
error = MPU6050_write(reg, &data, 1); | |
return (error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment