Section 4: Flight-Control-Functions.

... Source Code Get Altitude from Barometric Pressure ...

========== File-Name: 17_Get_Altitude_from_Baro.ino ===========


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++ Get Altitude from Barometric Pressure +++++++++++
//                Last Update: 13-09-2022  
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++                                                                                                                                                            //======== Function Read-Altitude with BMP-280 =============

// This code works with the BMP-280 barometric pressure sensor
// Note: right shift >>n is divide by 2**n
// Note: left shift <  21,3316 m afname.
//========================================================

//========= Function get_baro_altitude =============
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Latest Update: 31-07-2022
//
float get_baro_altitude() 
 {
   float _baro_altitude;
//  based onthe assumption: 1 mbar = 8m  valid up to 1000m   
    actual_baropressure = Call_baro_pressure();
    _baro_altitude = (start_baropressure - actual_baropressure)*8; //m 
    
    return _baro_altitude;     
 }

//========= Function Read BMP280 AirPressure =============
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Latest Update: 13-09-2022
//
// Code based on Bosch BMP280 Datasheet
// Note: 1 mbar = 1 hPa, range 0-1000m etwa 1 mbar/8m afname.
// Note: 2mmHg = 2,66645 mbar =>  21,3316 m afname.

//void Call_BMP280AirPressure() 

float Call_baro_pressure() 
 {
   float _pressure;
   
   if (AltitudeFlag==0)
    {  
      Read_BMP280_EPROM_values();
    }

  writeTo(BMP280_Addr, 0xE0, 0x00);  //0xB6 reset register
  delay(3);
  
  writeTo(BMP280_Addr, 0xF4, 0b01101111);  //ctrl-measure register
//  osrs_t | osrs_p | mode => 0b 011 | 011 | 11 See Datasheet
//  I2C.write(0b 011 011 11); // send 0b01101111 to register
   delay(3);

//  uint8_t data[6]; 
    I2C.beginTransmission(BMP280_Addr); // Start I2C Transmission
    I2C.write(0xF7);                    // F7 Select data register
    I2C.endTransmission();              // Stop I2C Transmission
    I2C.requestFrom(BMP280_Addr, 6);    // Request 2 bytes of data

    for (count = 0; count <3; count++)
     {
      delay(10);
      data[count] = I2C.read();     //Read actual Temperature Data
 //     Serial.print("Tdata");
 //     Serial.print(count);
 //     Serial.print("= ");
 //     Serial.print(data[count]);
 //     Serial.print("    ");
     }
//      Serial.println();
     
    for (count = 3; count <6; count++)
     {
      delay(10);
      data[count] = I2C.read();     //Read actual Pressure Data
//      Serial.print("Pdata");
//      Serial.print(count);
//      Serial.print("= ");
//      Serial.print(data[count]);
//      Serial.print("    ");
      }
//      Serial.println();

  int32_t adcTemp = (int32_t)data[3] << 12 | (int32_t)data[4] << 4 | (int32_t)data[5] >> 4;  // Copy the temperature and pressure data into the adc variables
  int32_t adcPres = (int32_t)data[0] << 12 | (int32_t)data[1] << 4 | (int32_t)data[2] >> 4;

//      Serial.print("adcTemp 519888= ");
//      Serial.print(adcTemp);
//      Serial.print("    ");
//      Serial.print("adcPres 415148= ");
//      Serial.print(adcPres);
//      Serial.println(); 
//      delay(5000);      

//  Temperature compensation (function from BMP280 datasheet)
    float temp = bmp280_compensate_T_double(adcTemp);   
    temperature = (float)temp;  // Calculate the temperature in degrees Celsius

//  Pressure compensation (function from BMP280 datasheet)
    double pres = bmp280_compensate_P_double(adcPres);        
    return _pressure = (float)pres;   // pressure in millibar
   }  

// ================= Start Reading BMP280-EPROM ===================
void   Read_BMP280_EPROM_values()
  {
//    uint16_t dig_T1;
//    int16_t  dig_T2, dig_T3;
//    uint16_t dig_P1;
//    int16_t  dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9;
    
    Serial.println();
    Serial.println("Reading calib.coefficients stored in BMP-280 EPROM.");

    for (count = 0; count <12; count++)
     {
      I2C.beginTransmission(BMP280_Addr); // Start I2C Transmission
      I2C.write(0x88 + (2 * count));          // F7 Select data register
      I2C.endTransmission();              // Stop I2C Transmission
      I2C.requestFrom(BMP280_Addr, 2);    // Request 2 bytes of data
    
      if(I2C.available() == 2)            // Read 2 bytes of data dwz Coff msb, Coff lsb
       {
        delay(150);       
        data[0] = I2C.read();     //LSB
//      Serial.print("LSB= ");
//      Serial.print(data[0]);
        delay(150);      
        data[1] = I2C.read();     //MSB
//      Serial.print("   MSB= ");
//      Serial.print(data[1]);
//      Serial.println();
        }  
   
      Coff[count] = ((data[1] * 256) + data[0]);   // Convert the data

//    Serial.print("Test Coff-");
//    Serial.print(count);
//    Serial.print("= ");
//    Serial.print(Coff[count]);
//    Serial.println();
      delay(100);
    }
    
    Serial.println();
    dig_T1 = Coff[0];
    Serial.print("dig_T1 27504= ");
    Serial.println(dig_T1);
    dig_T2 =  Coff[1];
    Serial.print("dig_T2 26435= ");
    Serial.println(dig_T2);
    dig_T3 =  Coff[2];
    Serial.print("dig_T3 -1000= ");
    Serial.println(dig_T3);
    Serial.println();
    dig_P1 = Coff[3];
    Serial.print("dig_P1 36477= ");
    Serial.println(dig_P1);   
    dig_P2 = Coff[4];
    Serial.print("dig_P2 -10685= ");
    Serial.println(dig_P2); 
    dig_P3 = Coff[5];
    Serial.print("dig_P3 3024= ");
    Serial.println(dig_P3); 
    dig_P4 = Coff[6];
    Serial.print("dig_P4 2855= ");
    Serial.println(dig_P4); 
    dig_P5 = Coff[7];
    Serial.print("dig_P5 140= ");
    Serial.println(dig_P5); 
    dig_P6 = Coff[8];
    Serial.print("dig_P6 -7= ");
    Serial.println(dig_P6); 
    dig_P7 = Coff[9];
    Serial.print("dig_P7 15500= ");
    Serial.println(dig_P7); 
    dig_P8 = Coff[10];
    Serial.print("dig_P8 -14600= ");
    Serial.println(dig_P8); 
    dig_P9 = Coff[ 11];
    Serial.print("dig_P9 6000= ");
    Serial.println(dig_P9);
    Serial.println();
    AltitudeFlag=1;
 }
// ================== End Reading BMP280-EPROM ===================


//////////////////////////////////////////////////////////////////
//          Begin Bosch BMP280 Functions from Data-Sheet
//////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
// This Bosch Function Returns Temperature as double. 

// uint16_t dig_T1;
// int16_t  dig_T2, dig_T3;

double bmp280_compensate_T_double(int32_t adc_T)  
  {
   double h1, h2, h3, h4, var1, var2, T;
// var1 = (((double)adc_T)/16384.0 – ((double)dig_T1)/1024.0) * ((double)dig_T2);  //checked en OK
   h1= ((double)adc_T)/16384.0; 
   h2= ((double)dig_T1)/1024.0;
   h3= (double)dig_T2;
   var1 = (h1 - h2)*h3;

//    var2 = ( ( (adc_T)/131072.0 – (dig_T1)/8192.0 ) * ( (adc_T)/131072.0 – ( dig_T1)/8192.0) ) * (dig_T3); //checked en OK
//    var2 = ( (h1 – h2) * (h1 – h2) ) * h3;

   h1= ((double)adc_T)/131072.0;
   h2= ((double)dig_T1)/8192.0;
   h3=  (double)dig_T3;

/*      
      Serial.print("h1= ");
      Serial.print(h1,4);
      Serial.print("    ");
      Serial.print("h2= ");
      Serial.print(h2,4);
      Serial.print("    ");
      Serial.print("h3= ");
      Serial.print(h3,4);
      Serial.println(); 
//      delay(5000);      
*/
      h4= ((double)h1)- ((double)h2);
      var2= ( h4 * h4 ) * h3;
  
      t_fine = (int32_t)(var1 + var2);  //checked en OK
      T = (var1 + var2) / 5120.0;       //Checked en OK

      return T;
  }

//---------------------------------------------------------
///////////////////////////////////////////////////////////
//.........................................................
// This Bosch Function Returns pressure as double in mbar. 
 double bmp280_compensate_P_double(int32_t adc_P)
  {
// Press. Calibration data from barometric BMP280 EEProm
//   uint16_t dig_P1 =0;
//   int16_t  dig_P2 =0;
//   int16_t  dig_P3 =0;
//   int16_t  dig_P4 =0;
//   int16_t  dig_P5 =0;
//   int16_t  dig_P6 =0;
//   int16_t  dig_P7 =0;
//   int16_t  dig_P8 =0;
//   int16_t  dig_P9 =0;
    
   double k1, k2, var1, var2, p;
// var1 = ((double)t_fine/2.0) – 64000.0;   //checked en OK
   k1= ((double)t_fine/2.0);
   var1 = k1 ;  
   var1 -= 64000.0;
 //  Serial.println();
 //  Serial.print("var1 211,1435029= ");
 //  Serial.print(var1,4);

// var2 = var1 * var1 * ((double)dig_P6) / 32768.0;  //checked en OK 
   k2 = ((double)dig_P6) / 32768.0;
   var2 = var1 * var1 * k2;
//   Serial.println();
//   Serial.print("var2 -9.523652701= ");
//   Serial.print(var2,6);
   
   var2 = var2 + var1 * ((double)dig_P5) * 2.0;   //checked en OK 
//   Serial.println();
//   Serial.print("var2 59110.65716= ");
//   Serial.print(var2,4);
   
   var2 = (var2/4.0)+(((double)dig_P4) * 65536.0);  //checked en OK 
//   Serial.println();
//   Serial.print("var2 187120057.7= ");
//   Serial.print(var2,1);
      
   var1 = (((double)dig_P3) * var1 * var1 / 524288.0 + ((double)dig_P2) * var1) / 524288.0;  //checked en OK 
//   Serial.println();
//   Serial.print("var1 -4.302618389= ");
//   Serial.print(var1,6);
   
   var1 = (1.0 + var1 / 32768.0)*((double)dig_P1);  //checked en OK 
//   Serial.println();
//   Serial.print("var1 36472.21037= ");
//   Serial.print(var1,4);

   if (var1 == 0.0)
    {
     return 0; // avoid exception caused by division by zero
    }
//   p = 1048576.0 – (double)adc_P;  //checked en OK
     k1 = ((double)adc_P);
     k2 = 1048576.0; 
     p = k2 - k1;
//     Serial.println();
//     Serial.print("p 33428= ");
//     Serial.print(p,0);
     
//   p = (p – (var2 / 4096.0)) * 6250.0 / var1; //checked en OK
     k1 = (var2 / 4096.0);
     k2 = 6250.0 / var1;
     p = (p - k1) * k2;;
//     Serial.println();
//     Serial.print("p 100717.8456= ");
//     Serial.print(p,4);

     var1 = ((double)dig_P9) * p * p / 2147483648.0; //checked en OK
//     Serial.println();
//     Serial.print("var1 28342.24444= ");
//     Serial.print(var1,5);
     
     var2 = p * ((double)dig_P8) / 32768.0;  //checked en OK
//     Serial.println();
//     Serial.print("var2 -44857.50492= ");
//     Serial.print(var2,5);
     
     p = p + (var1 + var2 + ((double)dig_P7)) / 16.0; //checked en OK
//     Serial.println();
//     Serial.print("p 100653,27= ");
//     Serial.print(p,2);
//     Serial.println();
//   divide p by 99.5 to get mbar values aligned with internet values
     p=p/99.5;     //mbar
     return p;
}

// .............................................................
// /////////////////////////////////////////////////////////////
// End Bosch BMP280 Functions from Data-Sheet
// /////////////////////////////////////////////////////////////

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++ End Source Code Get Altitude from Barometric Pressure +++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Free-Drones Company 2022