Created
March 26, 2014 05:04
-
-
Save murilopontes/9777189 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//i2c lib | |
#include <Wire.h> | |
TwoWire i2c_port(2); | |
#include <stdarg.h> | |
void debug(char *fmt, ... ){ | |
char buf[128]; // resulting string limited to 128 chars | |
va_list args; | |
va_start (args, fmt ); | |
vsnprintf(buf, 128, fmt, args); | |
va_end (args); | |
Serial.print(buf); | |
} | |
//uncomment to test bmp085 with reference values of datasheet | |
//remember to use overslamping = 0 | |
//#define BMP085_REFERENCE 1 | |
// From the datasheet the BMP module address LSB distinguishes | |
// between read (1) and write (0) operations, corresponding to | |
// address 0xEF (read) and 0xEE (write). | |
// shift the address 1 bit right (0xEF or 0xEE), the Wire library only needs the 7 | |
// most significant bits for the address 0xEF >> 1 = 0x77 | |
// 0xEE >> 1 = 0x77 | |
int I2C_ADDRESS = 0x77; // sensor address | |
// oversampling setting | |
// 0 = ultra low power | |
// 1 = standard | |
// 2 = high | |
// 3 = ultra high resolution | |
const unsigned char oversampling_setting = 3; //oversampling for measurement | |
const unsigned char pressure_conversiontime[4] = { | |
5, 8, 14, 26 }; // delays for oversampling settings 0, 1, 2 and 3 | |
// sensor registers from the BOSCH BMP085 datasheet | |
int16_t ac1; | |
int16_t ac2; | |
int16_t ac3; | |
uint16_t ac4; | |
uint16_t ac5; | |
uint16_t ac6; | |
int16_t b1; | |
int16_t b2; | |
int16_t mb; | |
int16_t mc; | |
int16_t md; | |
// variables to keep the values | |
int32_t temperature = 0; | |
int32_t pressure = 0; | |
double hpa_current=0; | |
double hpa_baseline=0; | |
double temperature_c=0; | |
void setup() | |
{ | |
Serial.begin(115200); | |
debug("ok\r\n"); | |
i2c_port.begin(); | |
delay(10); | |
getCalibrationData(); | |
/////////////////////////////////////////// | |
readSensor(); | |
hpa_baseline=pressure*0.01; | |
debug("hpa_baseline=%.2f\r\n",hpa_baseline); | |
///////////////////////////////////////////// | |
} | |
void loop() | |
{ | |
readSensor(); | |
hpa_current=pressure*0.01; | |
temperature_c=temperature/10.0; | |
debug("Temperature: %d (150 temp in 0.1C) %.2f C\r\n",temperature,temperature_c); | |
debug("Pressure: %d (69964 press in Pa) %.2f hPa\r\n",pressure,hpa_current); | |
#define hpa_sea 1013.25 | |
debug("altitude: %.2f meters (relative to sea)\r\n",calculate_altitude(hpa_current,hpa_sea)); | |
debug("altitude: %.2f meters (relative to baseline)\r\n",calculate_altitude(hpa_current,hpa_baseline)); | |
delay(1000); | |
} | |
double calculate_altitude(double p,double p0){ | |
return 44330.0*(1.0-pow((p/p0),1.0/5.255)); | |
} | |
double calculate_sea_level(double p,double alt){ | |
return p / pow( ( 1.0 - (alt/44330.0)) , 5.255); | |
} | |
// read temperature and pressure from sensor | |
void readSensor() { | |
int ut= readUT(); | |
long up = readUdebug(); | |
#ifdef BMP085_REFERENCE | |
ut=27898; | |
up=23843; | |
#endif | |
debug("--------------READ UT and UP----\r\n"); | |
debug("ut=%d (27898)\r\n",ut); | |
debug("up=%d (23843)\r\n",up); | |
int32_t x1, x2, x3, b3, b5, b6, p; | |
uint32_t b4, b7; | |
//calculate true temperature | |
x1 = (ut - ac6) * ac5 >> 15; | |
x2 = (mc << 11) / (x1 + md); | |
b5 = x1 + x2; | |
temperature = (b5 + 8) >> 4; | |
debug("--------------CALCULATE TRUE TEMPERATURE----\r\n"); | |
debug("x1=%d (4743)\r\n",x1); | |
debug("x2=%d (-2344)\r\n",x2); | |
debug("b5=%d (2399)\r\n",b5); | |
debug("T=%d (150)\r\n",temperature); | |
debug("--------------CALCULATE TRUE PRESSURE----\r\n"); | |
//calculate true pressure | |
b6 = b5 - 4000; | |
x1 = (b2 * (b6 * b6 >> 12)) >> 11; | |
x2 = ac2 * b6 >> 11; | |
x3 = x1 + x2; | |
b3 = (((ac1 * 4 + x3)<<oversampling_setting)+2) >> 2; | |
debug("b6=%d (-1601)\r\n",b6); | |
debug("x1=%d (1)\r\n",x1); | |
debug("x2=%d (56)\r\n",x2); | |
debug("x3=%d (57)\r\n",x3); | |
debug("b3=%d (422)\r\n",b3); | |
x1 = ac3 * b6 >> 13; | |
x2 = (b1 * (b6 * b6 >> 12)) >> 16; | |
x3 = ((x1 + x2) + 2) >> 2; | |
b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15; | |
b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting); | |
if(b7 < 0x80000000){ | |
p= (b7 * 2) / b4; | |
} | |
else { | |
p= (b7 / b4) * 2; | |
} | |
debug("x1=%d (2810)\r\n",x1); | |
debug("x2=%d (59)\r\n",x2); | |
debug("x3=%d (717)\r\n",x3); | |
debug("b4=%d (33457)\r\n",b4); | |
debug("b7=%d (11711050000)\r\n",b7); | |
debug("p=%d (70003)\r\n",p); | |
x1 = (p >> 8) * (p >> 8); | |
debug("x1=%d (74529)\r\n",x1); | |
x1 = (x1 * 3038) >> 16; | |
x2 = (-7357 * p) >> 16; | |
pressure = p + ((x1 + x2 + 3791) >> 4); | |
debug("x1=%d (3454)\r\n",x1); | |
debug("x2=%d (-7859)\r\n",x2); | |
debug("p=%d (69964)\r\n",p); | |
} | |
// read uncompensated temperature value | |
int32_t readUT() { | |
writeRegister(0xf4,0x2e); | |
delay(5); // the datasheet suggests 4.5 ms | |
return read_uint16_Register(0xf6); | |
} | |
// read uncompensated pressure value | |
int32_t readUdebug() { | |
writeRegister(0xf4,0x34+(oversampling_setting<<6)); | |
delay(pressure_conversiontime[oversampling_setting]); | |
i2c_port.beginTransmission(I2C_ADDRESS); | |
i2c_port.write(0xf6); // register to read | |
i2c_port.endTransmission(false); | |
i2c_port.requestFrom(I2C_ADDRESS, 3,true); // request three bytes | |
while(i2c_port.available()!=3); // wait until data available | |
return ( (i2c_port.read()<<16) | (i2c_port.read()<<8) | i2c_port.read() ) >>(8-oversampling_setting); | |
} | |
void getCalibrationData() { | |
Serial.println("Reading Calibration Data"); | |
ac1 = read_uint16_Register(0xAA); | |
ac2 = read_uint16_Register(0xAC); | |
ac3 = read_uint16_Register(0xAE); | |
ac4 = read_uint16_Register(0xB0); | |
ac5 = read_uint16_Register(0xB2); | |
ac6 = read_uint16_Register(0xB4); | |
b1 = read_uint16_Register(0xB6); | |
b2 = read_uint16_Register(0xB8); | |
mb = read_uint16_Register(0xBA); | |
mc = read_uint16_Register(0xBC); | |
md = read_uint16_Register(0xBE); | |
#ifdef BMP085_REFERENCE | |
ac1=408; | |
ac2=-72; | |
ac3=-14383; | |
ac4=32741; | |
ac5=32757; | |
ac6=23153; | |
b1=6190; | |
b2=4; | |
mb=-32768; | |
mc=-8711; | |
md=2868; | |
#endif | |
debug("--------------READ CALIBRATION DATA----\r\n"); | |
debug("ac1=%d (408)\r\n",ac1); | |
debug("ac2=%d (-72)\r\n",ac2); | |
debug("ac3=%d (-14383)\r\n",ac3); | |
debug("ac4=%d (32741)\r\n",ac4); | |
debug("ac5=%d (32757)\r\n",ac5); | |
debug("ac6=%d (23153)\r\n",ac6); | |
debug("b1=%d (6190)\r\n",b1); | |
debug("b2=%d (4)\r\n",b2); | |
debug("mb=%d (-32768)\r\n",mb); | |
debug("mc=%d (-8711)\r\n",mc); | |
debug("md=%d (2868)\r\n",md); | |
} | |
void writeRegister(unsigned char r, unsigned char v) | |
{ | |
i2c_port.beginTransmission(I2C_ADDRESS); | |
i2c_port.write(r); | |
i2c_port.write(v); | |
i2c_port.endTransmission(); | |
} | |
uint16_t read_uint16_Register(unsigned char r) | |
{ | |
i2c_port.beginTransmission(I2C_ADDRESS); | |
i2c_port.write(r); // register to read | |
i2c_port.endTransmission(false); | |
i2c_port.requestFrom(I2C_ADDRESS, 2); // request two bytes | |
while(i2c_port.available()!=2); // wait until data available | |
return (i2c_port.read()<<8) | i2c_port.read(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment