Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ===Contact & Support===
- Website: http://eeenthusiast.com/
- Youtube: https://www.youtube.com/EEEnthusiast
- Facebook: https://www.facebook.com/EEEnthusiast/
- Patreon: https://www.patreon.com/EE_Enthusiast
- Revision: 1.0 (July 13th, 2016)
- ===Hardware===
- - Arduino Uno R3
- - MPU-6050 (Available from: http://eeenthusiast.com/product/6dof-mpu-6050-accelerometer-gyroscope-temperature/)
- ===Software===
- - Latest Software: https://github.com/VRomanov89/EEEnthusiast/tree/master/MPU-6050%20Implementation/MPU6050_Implementation
- - Arduino IDE v1.6.9
- - Arduino Wire library
- ===Terms of use===
- The software is provided by EEEnthusiast without warranty of any kind. In no event shall the authors or
- copyright holders be liable for any claim, damages or other liability, whether in an action of contract,
- tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in
- the software.
- */
- // I2Cdev and MPU6050 must be installed as libraries
- #include "I2Cdev.h"
- #include "MPU6050.h"
- #include <Wire.h>
- /////////////////////////////////// CONFIGURATION /////////////////////////////
- //Change this 3 variables if you want to fine tune the skecth to your needs.
- int buffersize=1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000)
- int acel_deadzone=8; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8)
- int giro_deadzone=1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1)
- // default I2C address is 0x68
- // specific I2C addresses may be passed as a parameter here
- // AD0 low = 0x68 (default for InvenSense evaluation board)
- // AD0 high = 0x69
- //MPU6050 accelgyro;
- MPU6050 accelgyro(0x68); // <-- use for AD0 high
- int16_t ax, ay, az,gx, gy, gz;
- int mean_ax,mean_ay,mean_az,mean_gx,mean_gy,mean_gz,state=0;
- int ax_offset,ay_offset,az_offset,gx_offset,gy_offset,gz_offset;
- int ready=0;
- long accelX, accelY, accelZ;
- float gForceX, gForceY, gForceZ;
- long gyroX, gyroY, gyroZ;
- float rotX, rotY, rotZ;
- void setup() {
- // initialize digital pin LED_BUILTIN as an output.
- pinMode(LED_BUILTIN, OUTPUT);
- // initialize serial communication
- Serial.begin(9600);
- // join I2C bus (I2Cdev library doesn't do this automatically)
- Wire.begin();
- // start message
- Serial.println("\nMPU6050 Calibration Sketch");
- delay(2000);
- Serial.println("\nYour MPU6050 should be placed in horizontal position, with package letters facing up. \nDon't touch it until you see a finish message.\n");
- delay(3000);
- // verify connection
- Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
- delay(1000);
- // reset offsets
- accelgyro.setXAccelOffset(0);
- accelgyro.setYAccelOffset(0);
- accelgyro.setZAccelOffset(0);
- accelgyro.setXGyroOffset(0);
- accelgyro.setYGyroOffset(0);
- accelgyro.setZGyroOffset(0);
- setupMPU();
- if (state==0){
- Serial.println("\nReading sensors for first time...");
- meansensors();
- state++;
- delay(1000);
- }
- if (state==1) {
- Serial.println("\nCalculating offsets...");
- calibration();
- state++;
- delay(1000);
- }
- if (state==2) {
- meansensors();
- Serial.println("\nFINISHED!");
- Serial.print("\nSensor readings with offsets:\t");
- Serial.print(mean_ax);
- Serial.print("\t");
- Serial.print(mean_ay);
- Serial.print("\t");
- Serial.print(mean_az);
- Serial.print("\t");
- Serial.print(mean_gx);
- Serial.print("\t");
- Serial.print(mean_gy);
- Serial.print("\t");
- Serial.println(mean_gz);
- Serial.print("Your offsets:\t");
- Serial.print(ax_offset);
- Serial.print("\t");
- Serial.print(ay_offset);
- Serial.print("\t");
- Serial.print(az_offset);
- Serial.print("\t");
- Serial.print(gx_offset);
- Serial.print("\t");
- Serial.print(gy_offset);
- Serial.print("\t");
- Serial.println(gz_offset);
- Serial.println("\nData is printed as: acelX acelY acelZ giroX giroY giroZ");
- Serial.println("Check that your sensor readings are close to 0 0 16384 0 0 0");
- Serial.println(" ");
- }
- }
- void loop() {
- recordAccelRegisters();
- recordGyroRegisters();
- printData();
- delay(100);
- }
- /////////////////////////////////// FUNCTIONS ////////////////////////////////////
- void meansensors(){
- long i=0,buff_ax=0,buff_ay=0,buff_az=0,buff_gx=0,buff_gy=0,buff_gz=0;
- while (i<(buffersize+101)){
- // read raw accel/gyro measurements from device
- accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
- if (i>100 && i<=(buffersize+100)){ //First 100 measures are discarded
- buff_ax=buff_ax+ax;
- buff_ay=buff_ay+ay;
- buff_az=buff_az+az;
- buff_gx=buff_gx+gx;
- buff_gy=buff_gy+gy;
- buff_gz=buff_gz+gz;
- }
- if (i==(buffersize+100)){
- mean_ax=buff_ax/buffersize;
- mean_ay=buff_ay/buffersize;
- mean_az=buff_az/buffersize;
- mean_gx=buff_gx/buffersize;
- mean_gy=buff_gy/buffersize;
- mean_gz=buff_gz/buffersize;
- }
- i++;
- delay(2); //Needed so we don't get repeated measures
- }
- }
- void calibration(){
- ax_offset=-mean_ax/8;
- ay_offset=-mean_ay/8;
- az_offset=(8192-mean_az)/8;
- gx_offset=-mean_gx/4;
- gy_offset=-mean_gy/4;
- gz_offset=-mean_gz/4;
- while (ready<6){
- int ready=0;
- accelgyro.setXAccelOffset(ax_offset);
- accelgyro.setYAccelOffset(ay_offset);
- accelgyro.setZAccelOffset(az_offset);
- accelgyro.setXGyroOffset(gx_offset);
- accelgyro.setYGyroOffset(gy_offset);
- accelgyro.setZGyroOffset(gz_offset);
- meansensors();
- Serial.println("...");
- if (abs(mean_ax)<=acel_deadzone) ready++;
- else ax_offset=ax_offset-mean_ax/acel_deadzone;
- if (abs(mean_ay)<=acel_deadzone) ready++;
- else ay_offset=ay_offset-mean_ay/acel_deadzone;
- if (abs(8192-mean_az)<=acel_deadzone) ready++;
- else az_offset=az_offset+(8192-mean_az)/acel_deadzone;
- if (abs(mean_gx)<=giro_deadzone) ready++;
- else gx_offset=gx_offset-mean_gx/(giro_deadzone+1);
- if (abs(mean_gy)<=giro_deadzone) ready++;
- else gy_offset=gy_offset-mean_gy/(giro_deadzone+1);
- if (abs(mean_gz)<=giro_deadzone) ready++;
- else gz_offset=gz_offset-mean_gz/(giro_deadzone+1);
- if (ready==6) break;
- }
- }
- void setupMPU(){
- Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
- Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
- Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
- Wire.endTransmission();
- Wire.beginTransmission(0b1101000); //I2C address of the MPU
- Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4)
- Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s
- Wire.endTransmission();
- Wire.beginTransmission(0b1101000); //I2C address of the MPU
- Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5)
- Wire.write(0b00001000); //Setting the accel to +/- 4g
- Wire.endTransmission();
- }
- void recordAccelRegisters() {
- Wire.beginTransmission(0b1101000); //I2C address of the MPU
- Wire.write(0x3B); //Starting register for Accel Readings
- Wire.endTransmission();
- Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)
- while(Wire.available() < 6);
- accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
- accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
- accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
- processAccelData();
- }
- void processAccelData(){
- gForceX = accelX / 8192.0;
- gForceY = accelY / 8192.0;
- gForceZ = accelZ / 8192.0;
- }
- void recordGyroRegisters() {
- Wire.beginTransmission(0b1101000); //I2C address of the MPU
- Wire.write(0x43); //Starting register for Gyro Readings
- Wire.endTransmission();
- Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48)
- while(Wire.available() < 6);
- gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
- gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
- gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
- processGyroData();
- }
- void processGyroData() {
- rotX = gyroX / 131.0;
- rotY = gyroY / 131.0;
- rotZ = gyroZ / 131.0;
- }
- void printData() {
- Serial.print("Gyro (deg)");
- Serial.print(" X=");
- Serial.print(rotX);
- if (rotX>=100){
- blinkLED();
- }
- if (rotX<=-90){
- blinkLED();
- }
- Serial.print(" Y=");
- Serial.print(rotY);
- if (rotY>=90){
- blinkLED();
- }
- if (rotY<=-90){
- blinkLED();
- }
- Serial.print(" Z=");
- Serial.print(rotZ);
- Serial.print(" Accel (g)");
- Serial.print(" X=");
- Serial.print(gForceX);
- if (gForceX>=0.75){
- blinkLED();
- }
- if (gForceX<=-0.75){
- blinkLED();
- }
- Serial.print(" Y=");
- Serial.print(gForceY);
- if (gForceY>=0.75){
- blinkLED();
- }
- if (gForceY<=-0.75){
- blinkLED();
- }
- Serial.print(" Z=");
- Serial.println(gForceZ);
- if (gForceZ>=3.5){
- blinkLED();
- }
- }
- void blinkLED(){
- digitalWrite(LED_BUILTIN, HIGH);
- delay(5000);
- digitalWrite(LED_BUILTIN, LOW);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement