Skip to main content

Day 24: BMP180 | C++ Skills Development

Hardware: BMP180

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
// b5 is calculated in bmp180GetTemperature(...), this variable is also used in bmp180GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;
// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
const unsigned char OSS = 2; // Oversampling Setting
short bmp180GetTemperature(unsigned int ut)
{
 long x1, x2;

 x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
 x2 = ((long)mc << 11)/(x1 + md);
 b5 = x1 + x2;
 return ((b5 + 8)>>4);
}
// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp180GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp180GetPressure(unsigned long up)
{
 long x1, x2, x3, b3, b6, p;
 unsigned long b4, b7;
 b6 = b5 - 4000;
 // Calculate B3
 x1 = (b2 * (b6 * b6)>>12)>>11;
 x2 = (ac2 * b6)>>11;
 x3 = x1 + x2;
 b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

 // Calculate B4
 x1 = (ac3 * b6)>>13;
 x2 = (b1 * ((b6 * b6)>>12))>>16;
 x3 = ((x1 + x2) + 2)>>2;
 b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

 b7 = ((unsigned long)(up - b3) * (50000>>OSS));
 if (b7 < 0x80000000)
 p = (b7<<1)/b4;
 else
 p = (b7/b4)<<1;
 x1 = (p>>8) * (p>>8);
 x1 = (x1 * 3038)>>16;
 x2 = (-7357 * p)>>16;
 p += (x1 + x2 + 3791)>>4;
 return p;
}


#include <Wire.h>
#include <SD.h>
//#include<SoftwareSerial.h>
#include "BMP180Lib.c"
#define BMP180_ADDRESS 0x77
const int CS_PIN=10;
const float p0 = 101325; // Pressure at sea level (Pa)
float altitude;
short temperature;
long pressure;
// Use these for altitude conversions
//SoftwareSerial BT(12,13);

void setup()
{
 Serial.begin(9600);
 //BT.begin(115200);
 Wire.begin();
 Serial.println("Initializing Card");
 pinMode(CS_PIN,OUTPUT);
 bmp180Calibration();
 if(!SD.begin(CS_PIN)) //Print error message if SD.begin fails
  {
    Serial.println("Card Failure");
    return;
  }
  Serial.println("Card Ready");
}
// Stores all of the bmp180's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
char bmp180Read(unsigned char address)
{
 unsigned char data;
 Wire.beginTransmission(BMP180_ADDRESS);
 Wire.write(address);
 Wire.endTransmission();
 Wire.requestFrom(BMP180_ADDRESS, 1);
 while(!Wire.available());
 return Wire.read();
}
// Read 2 bytes from the BMP180
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp180ReadInt(unsigned char address)
{
 unsigned char msb, lsb;
 Wire.beginTransmission(BMP180_ADDRESS);
 Wire.write(address);
 Wire.endTransmission();

 Wire.requestFrom(BMP180_ADDRESS, 2);
 while(Wire.available()<2)
 ;
 msb = Wire.read();
 lsb = Wire.read();

 return (int) msb<<8 | lsb;
}
void bmp180Calibration()
{
 ac1 = bmp180ReadInt(0xAA);
 ac2 = bmp180ReadInt(0xAC);
 ac3 = bmp180ReadInt(0xAE);
 ac4 = bmp180ReadInt(0xB0);
 ac5 = bmp180ReadInt(0xB2);
 ac6 = bmp180ReadInt(0xB4);
 b1 = bmp180ReadInt(0xB6);
 b2 = bmp180ReadInt(0xB8);
 mb = bmp180ReadInt(0xBA);
 mc = bmp180ReadInt(0xBC);
 md = bmp180ReadInt(0xBE);
}
// Read the uncompensated temperature value
unsigned int bmp180ReadUT()
{
 unsigned int ut;
 // Write 0x2E into Register 0xF4
 // This requests a temperature reading
 Wire.beginTransmission(BMP180_ADDRESS);
 Wire.write(0xF4);
 Wire.write(0x2E);
 Wire.endTransmission();
 // Wait at least 4.5ms
 delay(5);
 // Read two bytes from registers 0xF6 and 0xF7
 ut = bmp180ReadInt(0xF6);
 return ut;
}
// Read the uncompensated pressure value
unsigned long bmp180ReadUP()
{
 unsigned char msb, lsb, xlsb;
 unsigned long up = 0;
 // Write 0x34+(OSS<<6) into register 0xF4
 // Request a pressure reading w/ oversampling setting
 Wire.beginTransmission(BMP180_ADDRESS);
 Wire.write(0xF4);
 Wire.write(0x34 + (OSS<<6));
 Wire.endTransmission();
 // Wait for conversion, delay time dependent on OSS
 delay(2 + (3<<OSS));
 // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 Wire.beginTransmission(BMP180_ADDRESS);
 Wire.write(0xF6);
 Wire.endTransmission();
 Wire.requestFrom(BMP180_ADDRESS, 3);
 // Wait for data to become available
 while(Wire.available() < 3)
 ;
 msb = Wire.read();
 lsb = Wire.read();
 xlsb = Wire.read();
 up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
 return up;
}

void loop()
{
 temperature = bmp180GetTemperature(bmp180ReadUT());
 pressure = bmp180GetPressure(bmp180ReadUP());
 altitude = (float)44330 * (1 - pow(((float) pressure/p0), 0.190295));
 File dataFile=SD.open("BMP.csv",FILE_WRITE);
 if(dataFile)
 {
  dataFile.print(millis());
  dataFile.print(",");
  dataFile.print(altitude);
  dataFile.print(",");
  dataFile.print(temperature);
  dataFile.print(",");
  dataFile.println(pressure);
  dataFile.close();

  
  //Serial.print("Altitude: ");
   Serial.print(altitude, 2);
   Serial.print(",");
   //Serial.println(" m");
  
   //Serial.print("Temperature: ");
   Serial.print(temperature, DEC);
   Serial.print(",");
   //Serial.println(" *0.1 deg C");
   //Serial.print("Pressure: ");
   Serial.print(pressure, DEC);
   //Serial.println(" Pa");
   Serial.println();
 }
 else
 {
  Serial.println("Couldn't open file");
 }

Comments

Popular posts from this blog

Day 20: Structures, Programming with Pointers

Lecture Structures Structure defines set of data, but individual parts do not have to be the same type. Example 1.1 struct hurricane {  char name[10];  int year,category; }; Within a structure, variables and even arrays can be defined. Structures are also known as aggregate data types since multiple data values can be collected into a single data type. Individual values within a structure are called data members, and each member is given a name. In Example 1.1, the names of the data members are name, year, and category. To refer to a data member, the structure variable name followed by a period and a data member name is used.  Definition and Initialization Define structure. Keyword struct used to define name of structure (aka structure tag) and data members that are included in structure After structure defined, structure variables can be defined using declaration statements. Semicolon required after structure definition. Statements can appear before m...

Day 4: RGB Nightlight | Algorithm Development, Conditional Expressions, Selection Statements

Hardware: RGB Nightlight const int red=11; const int green=10; const int blue=9; const int button=4; boolean lastbutton=LOW; boolean currentbutton=LOW; int ledMode=0; void setup() {   // put your setup code here, to run once:   pinMode(button,INPUT);   pinMode(red,OUTPUT);   pinMode(green,OUTPUT);   pinMode(blue,OUTPUT); } boolean debounce(boolean last) {   boolean current=digitalRead(button);   if(last!=current)   {     delay(5);     current=digitalRead(button);   }   return current; } void setMode(int mode) {   //RED   if(mode==1)   {     digitalWrite(red,HIGH);     digitalWrite(green,LOW);     digitalWrite(blue,LOW);   }   if(mode==2)   {     //orange     digitalWrite(red,HIGH);     analogWrite(green,40);     digitalWrite(blue,LOW);...