void compass_scalled_reading(){
  
  compass_read_XYZdata();
  
  compass_x_scalled=compass_x*compass_gain_fact*compass_x_gainError+compass_x_offset;
  compass_y_scalled=compass_y*compass_gain_fact*compass_y_gainError+compass_y_offset;
  compass_z_scalled=compass_z*compass_gain_fact*compass_z_gainError+compass_z_offset;


}
// --------------------------------------------------------------------------
// This Function calculates the offset in the Magnetometer
// using Positive and Negative bias Self test capability
// This function updates X_offset Y_offset and Z_offset Global variables
// Call Initialize before 
void compass_offset_calibration(int select){
  // ***********************************************************
  // offset_calibration() function performs two taskes
  // 1. It calculates the diffrence in the gain of the each axis magnetometer axis, using 
  //    inbuilt self excitation function of HMC5883L (Which is useless if it is used as a compass
  //    unless you are very unlucy and got a crapy sensor or live at very High or low temperature)
  // 2. It calculates the mean of each axes magnetic field, when the Magnetometer is rotated 360 degree
  // 3. Do Both
  // ***********************************************************    
  
  
  // *****************************************************************************************
  // Gain offset estimation
  // ***************************************************************************************** 
  if (select == 1 | select == 3){ // User input in the function
 // Configuring the Control register for Positive Bais mode
  Serial.println("Calibrating the Magnetometer ....... Gain");
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01110001); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
   1   0   0   =   15 (Default)
   1   0   1   =   30
   1   1   0   =   75
   1   1   1   =   -
   */
  Wire.endTransmission();
  
  compass_read_XYZdata(); // Disregarding the first data

  // Reading the Positive baised Data
  while(compass_x<200 | compass_y<200 | compass_z<200){   // Making sure the data is with Positive baised
     compass_read_XYZdata();
  }
  
  compass_x_scalled=compass_x*compass_gain_fact;
  compass_y_scalled=compass_y*compass_gain_fact;
  compass_z_scalled=compass_z*compass_gain_fact;
  
  
  // Offset = 1160 - Data_positive
  compass_x_gainError = (float)compass_XY_excitation/compass_x_scalled;
  compass_y_gainError = (float)compass_XY_excitation/compass_y_scalled;
  compass_z_gainError = (float)compass_Z_excitation/compass_z_scalled;


  // Configuring the Control register for Negative Bais mode
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01110010); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
                               1   0   0   =   15 (Default)
                               1   0   1   =   30
                               1   1   0   =   75
                               1   1   1   =   -
   */
  Wire.endTransmission();
  
  
  compass_read_XYZdata(); // Disregarding the first data
  // Reading the Negative baised Data
  while(compass_x>-200 | compass_y>-200 | compass_z>-200){   // Making sure the data is with negative baised
     compass_read_XYZdata();
  }
  
  compass_x_scalled=compass_x*compass_gain_fact;
  compass_y_scalled=compass_y*compass_gain_fact;
  compass_z_scalled=compass_z*compass_gain_fact;
  

  // Taking the average of the offsets
  compass_x_gainError = (float)((compass_XY_excitation/abs(compass_x_scalled))+compass_x_gainError)/2;
  compass_y_gainError = (float)((compass_XY_excitation/abs(compass_y_scalled))+compass_y_gainError)/2;
  compass_z_gainError = (float)((compass_Z_excitation/abs(compass_z_scalled))+compass_z_gainError)/2;
  
  
  Serial.print("x_gain_offset = ");
  Serial.println(compass_x_gainError);
  Serial.print("y_gain_offset = ");
  Serial.println(compass_y_gainError);
  Serial.print("z_gain_offset = ");
  Serial.println(compass_z_gainError);
  
  }
  
   // Configuring the Control register for normal mode
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01111000); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
                               1   0   0   =   15 (Default)
                               1   0   1   =   30
                               1   1   0   =   75
                               1   1   1   =   -
   */
  Wire.endTransmission();
  
  // *****************************************************************************************
  // Offset estimation
  // *****************************************************************************************
   if (select == 2 | select == 3){// User input in the function
   Serial.println("Calibrating the Magnetometer ....... Offset");
    Serial.println("Please rotate the magnetometer 2 or 3 times in complete circules with in one minute ............. ");
    
    for(byte i=0;i<10;i++){   // Disregarding first few data
         compass_read_XYZdata();
     }
    
    float x_max=-4000,y_max=-4000,z_max=-4000; 
    float x_min=4000,y_min=4000,z_min=4000;
    
    /*
    Debug code ------------------------------
    */
    if (compass_debug == 1){
      Serial.println("Starting Debug data in ");
      delay(1000);
      Serial.println("3");
      delay(1000);
      Serial.println("2");
      delay(1000);
      Serial.println("1");
      delay(1000);
      Serial.println("0");
      Serial.println();
      for(byte i=0;i<10;i++){   
         Serial.print("*");
      }
      Serial.println("*");
      Serial.println("Debug -- (Offset Calibration)");
      for(byte i=0;i<10;i++){  
         Serial.print("*");
      }
      Serial.println("*");
    }
    // End Debug code
  
    
    unsigned long t = millis();
    while(millis()-t <= 30000){
      
      compass_read_XYZdata();
      
      compass_x_scalled=(float)compass_x*compass_gain_fact*compass_x_gainError;
      compass_y_scalled=(float)compass_y*compass_gain_fact*compass_y_gainError;
      compass_z_scalled=(float)compass_z*compass_gain_fact*compass_z_gainError;
      
      if (compass_debug == 1){  //------------------ Debug Data
        Serial.print(compass_x_scalled);
        Serial.print("\t");
        Serial.print(compass_y_scalled);
        Serial.print("\t");
        Serial.println(compass_z_scalled);
        }//--------------------------------- End Debug Data
  
      x_max = max(x_max,compass_x_scalled);
      y_max = max(y_max,compass_y_scalled);
      z_max = max(z_max,compass_z_scalled);
  
      
      x_min = min(x_min,compass_x_scalled);
      y_min = min(y_min,compass_y_scalled);
      z_min = min(z_min,compass_z_scalled);
   
  
    }
    
        /*
    Debug code ------------------------------
    */
    if (compass_debug == 1){
      Serial.println();
      for(byte i=0;i<10;i++){   
         Serial.print("*");
      }
      Serial.println("*");
      Serial.println("End Debug -- (Offset Calibration)");
      for(byte i=0;i<10;i++){   
         Serial.print("*");
      }
      Serial.println("*");
    }
    // End Debug code
  
    compass_x_offset = ((x_max-x_min)/2)-x_max;
    compass_y_offset = ((y_max-y_min)/2)-y_max;
    compass_z_offset = ((z_max-z_min)/2)-z_max;
    
    
    Serial.print("Offset x  = ");
    Serial.print(compass_x_offset);
    Serial.println(" mG");
    Serial.print("Offset y  = ");
    Serial.print(compass_y_offset);
    Serial.println(" mG");
    Serial.print("Offset z  = ");
    Serial.print(compass_z_offset);
    Serial.println(" mG");
    
  } 
 
}
// --------------------------------------------------------------------------
// This Function calculates the offset in the Magnetometer
// using Positive and Negative bias Self test capability
// This function updates X_offset Y_offset and Z_offset Global variables
// Call Initialize before 
void compass_calibration(int select){
  // ***********************************************************
  // offset_calibration() function performs two taskes
  // 1. It calculates the diffrence in the gain of the each axis magnetometer axis, using 
  //    inbuilt self excitation function of HMC5883L (Which is useless if it is used as a compass
  //    unless you are very unlucy and got a crapy sensor or live at very High or low temperature)
  // 2. It calculates the mean of each axes magnetic field, when the Magnetometer is rotated 360 degree
  // 3. Do Both
  // ***********************************************************    
  
  
  // *****************************************************************************************
  // Gain offset estimation
  // ***************************************************************************************** 
  if (select == 1 | select == 3){ // User input in the function
 // Configuring the Control register for Positive Bais mode
  Serial.println("Calibrating the Magnetometer ....... Gain");
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01110001); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
   1   0   0   =   15 (Default)
   1   0   1   =   30
   1   1   0   =   75
   1   1   1   =   -
   */
  Wire.endTransmission();
  
  compass_read_XYZdata(); // Disregarding the first data

  // Reading the Positive baised Data
  while(compass_x<200 | compass_y<200 | compass_z<200){   // Making sure the data is with Positive biased
     compass_read_XYZdata();
  }
  
  compass_x_scalled=compass_x*compass_gain_fact;
  compass_y_scalled=compass_y*compass_gain_fact;
  compass_z_scalled=compass_z*compass_gain_fact;
  
  
  // Offset = 1160 - Data_positive
  compass_x_gainError = (float)compass_XY_excitation/compass_x_scalled;
  compass_y_gainError = (float)compass_XY_excitation/compass_y_scalled;
  compass_z_gainError = (float)compass_Z_excitation/compass_z_scalled;


  // Configuring the Control register for Negative Bais mode
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01110010); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
                               1   0   0   =   15 (Default)
                               1   0   1   =   30
                               1   1   0   =   75
                               1   1   1   =   -
   */
  Wire.endTransmission();
  
  
  compass_read_XYZdata(); // Disregarding the first data
  // Reading the Negative baised Data
  while(compass_x>-200 | compass_y>-200 | compass_z>-200){   // Making sure the data is with negative baised
     compass_read_XYZdata();
  }
  
  compass_x_scalled=compass_x*compass_gain_fact;
  compass_y_scalled=compass_y*compass_gain_fact;
  compass_z_scalled=compass_z*compass_gain_fact;
  

  // Taking the average of the offsets
  compass_x_gainError = (float)((compass_XY_excitation/abs(compass_x_scalled))+compass_x_gainError)/2;
  compass_y_gainError = (float)((compass_XY_excitation/abs(compass_y_scalled))+compass_y_gainError)/2;
  compass_z_gainError = (float)((compass_Z_excitation/abs(compass_z_scalled))+compass_z_gainError)/2;
  
  
  Serial.print("x_gain_offset = ");
  Serial.println(compass_x_gainError);
  Serial.print("y_gain_offset = ");
  Serial.println(compass_y_gainError);
  Serial.print("z_gain_offset = ");
  Serial.println(compass_z_gainError);
  
  }
  
   // Configuring the Control register for normal mode
  Wire.beginTransmission(compass_address);
  Wire.write(0x00);
  Wire.write(0b01111000); // bit configuration = 0 A A DO2 DO1 DO0 MS1 MS2

  /*
  A A                        DO2 DO1 DO0      Sample Rate [Hz]      MS1 MS0    Measurment Mode
   0 0 = No Average            0   0   0   =   0.75                   0   0   = Normal  
   0 1 = 2 Sample average      0   0   1   =   1.5                    0   1   = Positive Bias
   1 0 = 4 Sample Average      0   1   0   =   3                      1   0   = Negative Bais
   1 1 = 8 Sample Average      0   1   1   =   7.5                    1   1   = -
                               1   0   0   =   15 (Default)
                               1   0   1   =   30
                               1   1   0   =   75
                               1   1   1   =   -
   */
  Wire.endTransmission();

}