Skip to content

Instantly share code, notes, and snippets.

@afcruz
Created July 22, 2014 03:45
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save afcruz/0715a35f53f7cfcc979e to your computer and use it in GitHub Desktop.
Tutorial de introducción al modulo BMP180
/*
BMP180.h - Header file for the BMP180 Barometric Pressure Sensor Arduino Library.
Copyright (C) 2012 Love Electronics Ltd (loveelectronics.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Datasheet for BMP180:
http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP180-DS000-07.pdf
Edited by Silvan, 2013-08-31: Fixes for CompensatePressure()
Fixed loop for additional oversampling in GetUncompensatedPressure()
*/
#include "BMP180.h"
#include "Arduino.h"
BMP180::BMP180()
{
ConversionWaitTimeMs = 5;
OversamplingSetting = 0;
Oversample = false;
LastTemperatureTime = -1000;
LastTemperatureData = 0;
AcceptableTemperatureLatencyForPressure = 1000;
SetResolution(BMP180_Mode_Standard, false);
//SetResolution(BMP180_Mode_UltraHighResolution, false); // Use the maximum internal oversampling for less noise.
}
uint8_t BMP180::EnsureConnected()
{
uint8_t data = Read(Reg_ChipId, 1)[0];
if(data == ChipIdData)
IsConnected = 1;
else
IsConnected = 0;
return IsConnected;
}
void BMP180::Initialize()
{
uint8_t* buffer = Read(Reg_CalibrationStart, Reg_CalibrationEnd - Reg_CalibrationStart + 2);
// This data is in Big Endian format from the BMP180.
Calibration_AC1 = (buffer[0] << 8) | buffer[1];
Calibration_AC2 = (buffer[2] << 8) | buffer[3];
Calibration_AC3 = (buffer[4] << 8) | buffer[5];
Calibration_AC4 = (buffer[6] << 8) | buffer[7];
Calibration_AC5 = (buffer[8] << 8) | buffer[9];
Calibration_AC6 = (buffer[10] << 8) | buffer[11];
Calibration_B1 = (buffer[12] << 8) | buffer[13];
Calibration_B2 = (buffer[14] << 8) | buffer[15];
Calibration_MB = (buffer[16] << 8) | buffer[17];
Calibration_MC = (buffer[18] << 8) | buffer[19];
Calibration_MD = (buffer[20] << 8) | buffer[21];
}
void BMP180::PrintCalibrationData()
{
Serial.print("AC1:\t"); Serial.println(Calibration_AC1);
Serial.print("AC2:\t"); Serial.println(Calibration_AC2);
Serial.print("AC3:\t"); Serial.println(Calibration_AC3);
Serial.print("AC4:\t"); Serial.println(Calibration_AC4);
Serial.print("AC5:\t"); Serial.println(Calibration_AC5);
Serial.print("AC6:\t"); Serial.println(Calibration_AC6);
Serial.print("B1:\t"); Serial.println(Calibration_B1);
Serial.print("B2:\t"); Serial.println(Calibration_B2);
Serial.print("MB:\t"); Serial.println(Calibration_MB);
Serial.print("MC:\t"); Serial.println(Calibration_MC);
Serial.print("MD:\t"); Serial.println(Calibration_MD);
}
int BMP180::GetUncompensatedTemperature()
{
// Instruct device to perform a conversion.
Write(Reg_Control, ControlInstruction_MeasureTemperature);
// Wait for the conversion to complete.
delay(5);
uint8_t* data = Read(Reg_AnalogConverterOutMSB, 2);
int value = (data[0] << 8) | data[1];
return value;
}
long BMP180::GetUncompensatedPressure()
{
long pressure = 0;
long pressuresum = 0;
int loops = Oversample ? 3 : 1;
for (int i = 0; i < loops; i++)
{
// Instruct device to perform a conversion, including the oversampling data.
uint8_t CtrlByte = ControlInstruction_MeasurePressure + (OversamplingSetting << 6);
Write(Reg_Control, CtrlByte);
// Wait for the conversion
delay(ConversionWaitTimeMs);
// Read the conversion data.
uint8_t buffer[3];
Read2(Reg_AnalogConverterOutMSB, 3, buffer);
// Collect the data (and push back the LSB if we are not sampling them).
pressure = ((((long)buffer[0] <<16) | ((long)buffer[1] <<8) | ((long)buffer[2])) >> (8-OversamplingSetting));
pressuresum = pressuresum + pressure;
}
return pressuresum / loops;
}
float BMP180::CompensateTemperature(int uncompensatedTemperature)
{
int temperature;
int x2;
long x1;
x1 = (((long)uncompensatedTemperature - (long)Calibration_AC6) * (long)Calibration_AC5) >> 15;
x2 = ((long)Calibration_MC << 11) / (x1 + Calibration_MD);
int param_b5 = x1 + x2;
temperature = (int)((param_b5 + 8) >> 4); /* temperature in 0.1 deg C*/
float fTemperature = temperature;
fTemperature /= 10.0;
// Record this data because it is required by the pressure algorithem.
LastTemperatureData = param_b5;
LastTemperatureTime = millis();
return fTemperature;
}
long BMP180::CompensatePressure(long uncompensatedPressure)
{
int msSinceLastTempReading = millis() - LastTemperatureTime;
// Check to see if we have old temperature data.
if (msSinceLastTempReading > AcceptableTemperatureLatencyForPressure)
GetTemperature(); // Refresh the temperature.
// Data from the BMP180 datasheet to test algorithm.
/*OversamplingSetting = 0;
uncompensatedPressure = 23843;
LastTemperatureData = 2399;
Calibration_AC1 = 408;
Calibration_AC2 = -72;
Calibration_AC3 = -14383;
Calibration_AC4 = 32741;
Calibration_AC5 = 32757;
Calibration_AC6 = 23153;
Calibration_B1 = 6190;
Calibration_B2 = 4;
Calibration_MB = -32767;
Calibration_MC = -8711;
Calibration_MD = 2868;*/
// Algorithm taken from BMP180 datasheet.
long b6 = LastTemperatureData - 4000;
long x1 = (Calibration_B2 * (b6 * b6 >> 12)) >> 11;
long x2 = (Calibration_AC2 * b6) >> 11;
long x3 = x1 + x2;
long b3 = (((long)Calibration_AC1 * 4 + x3) << OversamplingSetting) + 2;
b3 = b3 >> 2;
x1 = (Calibration_AC3 * b6) >> 13;
x2 = (Calibration_B1 * ((b6 * b6) >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
unsigned long b4 = (Calibration_AC4 * (unsigned long)(x3 + 32768)) >> 15;
unsigned long b7 = ((((unsigned long)(uncompensatedPressure - b3))) * (50000 >> OversamplingSetting));
long p;
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 = p + ((x1 + x2 + 3791) >> 4);
return p;
}
void BMP180::SoftReset()
{
Write(Reg_SoftReset, SoftResetInstruction);
delay(100);
}
float BMP180::GetTemperature()
{
return CompensateTemperature(GetUncompensatedTemperature());
}
long BMP180::GetPressure()
{
return CompensatePressure(GetUncompensatedPressure());
}
float BMP180::GetAltitude(float currentSeaLevelPressureInPa)
{
// Get pressure in Pascals (Pa).
float pressure = GetPressure();
// Calculate altitude from sea level.
float altitude = 44330.0 * (1.0 - pow(pressure / currentSeaLevelPressureInPa, 0.1902949571836346));
return altitude;
}
uint8_t BMP180::SetResolution(uint8_t sampleResolution, bool oversample)
{
OversamplingSetting = sampleResolution;
Oversample = oversample;
switch (sampleResolution)
{
case 0:
ConversionWaitTimeMs = 5;
break;
case 1:
ConversionWaitTimeMs = 8;
break;
case 2:
ConversionWaitTimeMs = 14;
break;
case 3:
ConversionWaitTimeMs = 26;
break;
default:
return ErrorCode_1_Num;
}
}
void BMP180::Write(int address, int data)
{
Wire.beginTransmission(BMP180_Address);
Wire.write(address);
Wire.write(data);
Wire.endTransmission();
}
uint8_t* BMP180::Read(int address, int length)
{
Wire.beginTransmission(BMP180_Address);
Wire.write(address);
Wire.endTransmission();
Wire.beginTransmission(BMP180_Address);
Wire.requestFrom(BMP180_Address, length);
uint8_t buffer[length];
while(Wire.available())
{
for(uint8_t i = 0; i < length; i++)
{
buffer[i] = Wire.read();
}
}
Wire.endTransmission();
return buffer;
}
void BMP180::Read2(int address, int length, uint8_t buffer[])
{
Wire.beginTransmission(BMP180_Address);
Wire.write(address);
Wire.endTransmission();
Wire.beginTransmission(BMP180_Address);
Wire.requestFrom(BMP180_Address, length);
while(Wire.available())
{
for(uint8_t i = 0; i < length; i++)
{
buffer[i] = Wire.read();
}
}
Wire.endTransmission();
}
char* BMP180::GetErrorText(int errorCode)
{
if(ErrorCode_1_Num == 1)
return ErrorCode_1;
return "Error not defined.";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment