Pages: 1 2 3 [4] 5   Go Down
Author Topic: Barometric Presure sensor BMP180  (Read 2357 times)
0 Members and 2 Guests are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley last thing you want is a "Don't worry I fixed it" post with no follow up. The scourge of the internet search...
Logged

Germany
Offline Offline
Jr. Member
**
Karma: 3
Posts: 83
I'm a newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, the problem I got myself into is that I neglected to consider that we might all be using different OSS settings.
e.g. I'm using setting "3", the data sheet example uses setting "0". That is why I couldn't understand why I wasn't getting anything useful from your examples.

I've updated the code and would ask that you use this for further analysis:

Code:
/**********************************************************
  Bosch Pressure Sensor BMP085 / BMP180 readout routine
  for the Arduino platform.

  Version 1.1
  7/2014            
    
  Compiled by Leo Nutz
  www.ALTDuino.de
 **********************************************************/

#include <Wire.h>

#define ADDRESS_SENSOR 0x77                 // Sensor address

int16_t  ac1, ac2, ac3, b1, b2, mb, mc, md; // Store sensor PROM values from BMP180
uint16_t ac4, ac5, ac6;                     // Store sensor PROM values from BMP180

// Ultra Low Power       OSS = 0, OSD =  5ms
// Standard              OSS = 1, OSD =  8ms
// High                  OSS = 2, OSD = 14ms
// Ultra High Resolution OSS = 3, OSD = 26ms
const uint8_t oss = 3;                      // Set oversampling setting
      uint8_t osd;                          // Corresponding oversampling delay

float T, P;                                 // Set global variables for temperature and pressure

void setup()
{
  Wire.begin();                             // Activate I2C
  
  Serial.begin(9600);                       // Set up serial port

  Serial.println("");
  Serial.print("Oversampling setting (oss) = "); Serial.println(oss);

       if(oss == 0 ) osd =  5;
  else if(oss == 1 ) osd =  8;
  else if(oss == 2 ) osd = 14;
  else if(oss == 3 ) osd = 26;
  else { Serial.print("Incorrect OSS value defined!"); while(1){} }

  init_SENSOR();                            // Initialize baro sensor variables

  delay(100);
}

void loop()
{
  int32_t b5;
 
  b5 = temperature();                       // Read and calculate temperature (T)

  Serial.print("Temperature: ");
  Serial.print(T, 2);
  Serial.print(" C, ");
  Serial.print(1.8 * T + 32.0, 2);
  Serial.println(" F");

  P = pressure(b5);                         // Read and calculate pressure (P)

  Serial.print("Pressure: ");
  Serial.print(P, 2);
  Serial.print(" mbar, ");
  Serial.print(P * 0.0295299830714, 2);
  Serial.println(" inHg");
  if(P < 300 || P > 1100) Serial.println("Pressure sensor reading out of range!!!!"); // Pressure range according to the data sheet

  float alt = (pow(1013.25 / P, 0.190223f) - 1.0f) * 44330.08f;                       // Use static SI standard temperature (15°C)
  
  Serial.print("Altitude: "); Serial.print(alt); Serial.print(" m, "); Serial.print(alt * 3.28084); Serial.println(" ft");
  Serial.println("-----------------------------------------");

  delay(500);                               // Delay between each readout
  
}

/**********************************************
  Initialize sensor variables
 **********************************************/
void init_SENSOR()
{
  ac1 = read_2_bytes(0xAA);
  ac2 = read_2_bytes(0xAC);
  ac3 = read_2_bytes(0xAE);
  ac4 = read_2_bytes(0xB0);
  ac5 = read_2_bytes(0xB2);
  ac6 = read_2_bytes(0xB4);
  b1  = read_2_bytes(0xB6);
  b2  = read_2_bytes(0xB8);
  mb  = read_2_bytes(0xBA);
  mc  = read_2_bytes(0xBC);
  md  = read_2_bytes(0xBE);

  Serial.println("");
  Serial.println("Sensor calibration data:");
  Serial.print(F("ac1 = ")); Serial.print(ac1); Serial.println(F(";"));
  Serial.print(F("ac2 = ")); Serial.print(ac2); Serial.println(F(";"));
  Serial.print(F("ac3 = ")); Serial.print(ac3); Serial.println(F(";"));
  Serial.print(F("ac4 = ")); Serial.print(ac4); Serial.println(F(";"));
  Serial.print(F("ac5 = ")); Serial.print(ac5); Serial.println(F(";"));
  Serial.print(F("ac6 = ")); Serial.print(ac6); Serial.println(F(";"));
  Serial.print(F(" b1 = ")); Serial.print(b1);  Serial.println(F(";"));
  Serial.print(F(" b2 = ")); Serial.print(b2);  Serial.println(F(";"));
  Serial.print(F(" mb = ")); Serial.print(mb);  Serial.println(F(";"));
  Serial.print(F(" mc = ")); Serial.print(mc);  Serial.println(F(";"));
  Serial.print(F(" md = ")); Serial.print(md);  Serial.println(F(";"));
  Serial.println("----------------");
}

/**********************************************
  Calcualte pressure readings
 **********************************************/
float pressure(int32_t b5)
{
  int32_t x1, x2, x3, b3, b6, p, UP;
  uint32_t b4, b7;

  UP = read_pressure();                         // Read raw pressure
  Serial.print(F("UP = ")); Serial.print(UP); Serial.println(F(";"));

  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  x2 = ac2 * b6 >> 11;
  x3 = x1 + x2;
  b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2;
  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 >> oss);
  if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // or p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Return pressure in mbar
}

/**********************************************
  Read uncompensated temperature
 **********************************************/
int32_t temperature()
{
  int32_t x1, x2, b5, UT;

  Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
  Wire.write(0xf4);                       // Sends register address
  Wire.write(0x2e);                       // Write data
  Wire.endTransmission();                 // End transmission
  delay(5);                               // Datasheet suggests 4.5 ms
  
  UT = read_2_bytes(0xf6);                // Read uncompensated TEMPERATURE value
  Serial.print(F("UT = ")); Serial.print(UT); Serial.println(F(";"));

  // Calculate true temperature
  x1 = (UT - (int32_t)ac6) * (int32_t)ac5 >> 15;
  x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md);
  b5 = x1 + x2;
  T  = (b5 + 8) >> 4;
  T = T / 10.0;                           // Temperature in celsius
  return b5;  
}

/**********************************************
  Read uncompensated pressure value
 **********************************************/
int32_t read_pressure()
{
  int32_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);   // Start transmission to device
  Wire.write(0xf4);                         // Sends register address to read from
  Wire.write(0x34 + (oss << 6));            // Write data
  Wire.endTransmission();                   // SEd transmission
  delay(osd);                               // Oversampling setting delay
  Wire.beginTransmission(ADDRESS_SENSOR);
  Wire.write(0xf6);                         // Register to read
  Wire.endTransmission();
  Wire.requestFrom(ADDRESS_SENSOR, 3);      // Request three bytes
  if(Wire.available() >= 3)
  {
    value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 - oss);
  }
  return value;                             // Return value
}

/**********************************************
  Read 1 byte from the BMP sensor
 **********************************************/
uint8_t read_1_byte(uint8_t code)
{
  uint8_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);         // Start transmission to device
  Wire.write(code);                               // Sends register address to read from
  Wire.endTransmission();                         // End transmission
  Wire.requestFrom(ADDRESS_SENSOR, 1);            // Request data for 1 byte to be read
  if(Wire.available() >= 1)
  {
    value = Wire.read();                          // Get 1 byte of data
  }
  return value;                                   // Return value
}

/**********************************************
  Read 2 bytes from the BMP sensor
 **********************************************/
uint16_t read_2_bytes(uint8_t code)
{
  uint16_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);         // Start transmission to device
  Wire.write(code);                               // Sends register address to read from
  Wire.endTransmission();                         // End transmission
  Wire.requestFrom(ADDRESS_SENSOR, 2);            // Request 2 bytes from device
  if(Wire.available() >= 2)
  {
    value = (Wire.read() << 8) | Wire.read();     // Get 2 bytes of data
  }
  return value;                                   // Return value
}

Here is an example of my test using a UNO R3 and BMP180:

Oversampling setting (oss) = 3

Sensor calibration data:
ac1 = 6759;
ac2 = -1131;
ac3 = -14633;
ac4 = 33667;
ac5 = 24876;
ac6 = 20348;
 b1 = 6515;
 b2 = 42;
 mb = -32768;
 mc = -11786;
 md = 2895;
----------------
UT = 28666;
Temperature: 23.10 C, 73.58 F
UP = 317365;
Pressure: 971.93 mbar, 28.70 inHg
Altitude: 352.49 m, 1156.45 ft
-----------------------------------------

I practically get the same readings using oss 0 thru 3.
« Last Edit: July 29, 2014, 03:47:42 am by _Leo_ » Logged

Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de


Offline Offline
Full Member
***
Karma: 12
Posts: 209
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Out of range!:

Code:

Oversampling setting (oss) = 3

Sensor calibration data:
ac1 = 9060;
ac2 = -1244;
ac3 = -14867;
ac4 = 33491;
ac5 = 25092;
ac6 = 15143;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2764;
----------------
UT = 24706;
Temperature: 30.80 C, 87.44 F
UP = 339901;
Pressure: 1512.55 mbar, 44.67 inHg
Pressure sensor reading out of range!!!!
Altitude: -3252.86 m, -10672.13 ft
-----------------------------------------
  smiley-roll-sweat
Logged

Germany
Offline Offline
Jr. Member
**
Karma: 3
Posts: 83
I'm a newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Please also try oss = 0, 1 and 2 by changing this line:

const uint8_t oss = 3;                      // Set oversampling setting

Logged

Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de


Offline Offline
Full Member
***
Karma: 12
Posts: 209
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

case 3:

Code:
Oversampling setting (oss) = 3

Sensor calibration data:
ac1 = 9060;
ac2 = -1244;
ac3 = -14867;
ac4 = 33491;
ac5 = 25092;
ac6 = 15143;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2764;
----------------
UT = 24691;
Temperature: 30.70 C, 87.26 F
UP = 339951;
Pressure: 1512.45 mbar, 44.66 inHg
Pressure sensor reading out of range!!!!
Altitude: -3252.35 m, -10670.43 ft
-----------------------------------------

case 2:

Code:
Oversampling setting (oss) = 2

Sensor calibration data:
ac1 = 9060;
ac2 = -1244;
ac3 = -14867;
ac4 = 33491;
ac5 = 25092;
ac6 = 15143;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2764;
----------------
UT = 24738;
Temperature: 31.00 C, 87.80 F
UP = 169871;
Pressure: 1512.73 mbar, 44.67 inHg
Pressure sensor reading out of range!!!!
Altitude: -3253.79 m, -10675.18 ft
-----------------------------------------

case 1:

Code:
Oversampling setting (oss) = 1

Sensor calibration data:
ac1 = 9060;
ac2 = -1244;
ac3 = -14867;
ac4 = 33491;
ac5 = 25092;
ac6 = 15143;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2764;
----------------
UT = 24690;
Temperature: 30.70 C, 87.26 F
UP = 84990;
Pressure: 1512.43 mbar, 44.66 inHg
Pressure sensor reading out of range!!!!
Altitude: -3252.24 m, -10670.09 ft
-----------------------------------------

case 0:

Code:

Oversampling setting (oss) = 0

Sensor calibration data:
ac1 = 9060;
ac2 = -1244;
ac3 = -14867;
ac4 = 33491;
ac5 = 25092;
ac6 = 15143;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2764;
----------------
UT = 24696;
Temperature: 30.80 C, 87.44 F
UP = 42494;
Pressure: 1512.57 mbar, 44.67 inHg
Pressure sensor reading out of range!!!!
Altitude: -3252.97 m, -10672.46 ft
-----------------------------------------
Logged

Germany
Offline Offline
Jr. Member
**
Karma: 3
Posts: 83
I'm a newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, all show the same results.

Please try this by replacing

Code:
b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2; // as per data sheet

with

Code:
// b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2; // as per data sheet
int32_t b3_tmp = ac1; // Split up the equation...
b3_tmp = (b3_tmp * 4 + x3) << oss;
b3     = (b3_tmp + 2) / 4;

and run all 4 oss values.
Logged

Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de


Offline Offline
Full Member
***
Karma: 12
Posts: 209
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK

case 0:
Code:
-----------------------------------------
UT = 24677;
Temperature: 30.60 C, 87.08 F
UP = 42502;
Pressure: 1014.90 mbar, 29.97 inHg
Altitude: -13.72 m, -45.01 ft
-----------------------------------------

case 1:
Code:
-----------------------------------------
UT = 24740;
Temperature: 31.00 C, 87.80 F
UP = 84929;
Pressure: 1014.88 mbar, 29.97 inHg
Altitude: -13.55 m, -44.47 ft
-----------------------------------------

case 2:
Code:
-----------------------------------------
UT = 24760;
Temperature: 31.10 C, 87.98 F
UP = 169818;
Pressure: 1014.92 mbar, 29.97 inHg
Altitude: -13.89 m, -45.56 ft
-----------------------------------------

case 3:
Code:
-----------------------------------------
UT = 24776;
Temperature: 31.20 C, 88.16 F
UP = 339559;
Pressure: 1014.91 mbar, 29.97 inHg
Altitude: -13.80 m, -45.29 ft
-----------------------------------------
smiley-lol
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3077
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That looks OK.

Didn't you figure out yesterday,   you need to correct the type casting in that line of the program ?
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3077
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your problem is,  -14657 x 4 + x3 << 3

will be evaluated on the arduino as a 16 bit number,   and it will overflow.   That is your problem,  right there.   You need to force that calculation to be done as a 32 bit int,   before you get to the bit where it overflows,   not afterwards.
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3077
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can see right there on the Bosch datasheet,   where they refer to all their 16 bit numbers as "shorts".

Nobody discussing the arduino ever mentions "short".    Ints on the arduino are "short".

The only people who ever explicitly talk about "short" ints,   are the people who are thinking that an int is 4 bytes,  because that's the devices they use.

Logged

Germany
Offline Offline
Jr. Member
**
Karma: 3
Posts: 83
I'm a newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Jakob, would nice if you could do the same tests  smiley
Logged

Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de


Germany
Offline Offline
Jr. Member
**
Karma: 3
Posts: 83
I'm a newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

After taking into account the pointers given by "michinyon" and doing numerous tests here the latest version:

Code:
/**********************************************************
  Bosch Pressure Sensor BMP085 / BMP180 library free
  readout routine for the Arduino platform.

  Version 1.2  7/2014             
     
  Compiled by Leo Nutz
  www.ALTDuino.de
 **********************************************************/

#include <Wire.h>

#define ADDRESS_SENSOR 0x77                 // Sensor address

int16_t  ac1, ac2, ac3, b1, b2, mb, mc, md; // Store sensor PROM values from BMP180
uint16_t ac4, ac5, ac6;                     // Store sensor PROM values from BMP180
float T, P;                                 // Set global variables for temperature and pressure

uint8_t osd;                                // Oversampling delay

// Hardware pressure sampling accuracy modes:
// Ultra Low Power       OSS = 0
// Standard              OSS = 1
// High                  OSS = 2
// Ultra High Resolution OSS = 3
const uint8_t oss = 3;                      // Set oversampling accuracy mode here

void setup()
{
  Wire.begin();                             // Activate I2C
 
  Serial.begin(9600);                       // Set up serial port

  Serial.println("");
  Serial.print("Oversampling setting (oss) = "); Serial.println(oss);

       if(oss == 0 ) osd =  5; // Ultra Low Power       OSD =  5ms
  else if(oss == 1 ) osd =  8; // Standard              OSD =  8ms
  else if(oss == 2 ) osd = 14; // High                  OSD = 14ms
  else if(oss == 3 ) osd = 26; // Ultra High Resolution OSD = 26ms
  else { Serial.print("Incorrect OSS value defined!"); while(1){} }

  init_SENSOR();                            // Initialize baro sensor variables

  delay(100);
}

void loop()
{
  int32_t b5;
 
  b5 = temperature();                       // Read and calculate temperature (T)

  Serial.print("Temperature: ");
  Serial.print(T, 2);
  Serial.print(" C, ");
  Serial.print(1.8 * T + 32.0, 2);
  Serial.println(" F");

  P = pressure(b5);                         // Read and calculate pressure (P)

  Serial.print("Pressure: ");
  Serial.print(P, 2);
  Serial.print(" mbar, ");
  Serial.print(P * 0.0295299830714, 2);
  Serial.println(" inHg");
  if(P < 300 || P > 1100) Serial.println("Pressure sensor reading out of range!!!!"); // Pressure range according to the data sheet

  float alt = (pow(1013.25 / P, 0.190223f) - 1.0f) * 44330.08f;                       // Use static SI standard temperature (15°C)
 
  Serial.print("Altitude: "); Serial.print(alt); Serial.print(" m, "); Serial.print(alt * 3.28084); Serial.println(" ft");
  Serial.println("-----------------------------------------");

  delay(500);                               // Delay between each readout
 
}

/**********************************************
  Initialize sensor variables
 **********************************************/
void init_SENSOR()
{
  ac1 = read_2_bytes(0xAA);
  ac2 = read_2_bytes(0xAC);
  ac3 = read_2_bytes(0xAE);
  ac4 = read_2_bytes(0xB0);
  ac5 = read_2_bytes(0xB2);
  ac6 = read_2_bytes(0xB4);
   b1 = read_2_bytes(0xB6);
   b2 = read_2_bytes(0xB8);
   mb = read_2_bytes(0xBA);
   mc = read_2_bytes(0xBC);
   md = read_2_bytes(0xBE);

  Serial.println("");
  Serial.println("Sensor calibration data:");
  Serial.print(F("ac1 = ")); Serial.print(ac1); Serial.println(F(";"));
  Serial.print(F("ac2 = ")); Serial.print(ac2); Serial.println(F(";"));
  Serial.print(F("ac3 = ")); Serial.print(ac3); Serial.println(F(";"));
  Serial.print(F("ac4 = ")); Serial.print(ac4); Serial.println(F(";"));
  Serial.print(F("ac5 = ")); Serial.print(ac5); Serial.println(F(";"));
  Serial.print(F("ac6 = ")); Serial.print(ac6); Serial.println(F(";"));
  Serial.print(F(" b1 = ")); Serial.print(b1);  Serial.println(F(";"));
  Serial.print(F(" b2 = ")); Serial.print(b2);  Serial.println(F(";"));
  Serial.print(F(" mb = ")); Serial.print(mb);  Serial.println(F(";"));
  Serial.print(F(" mc = ")); Serial.print(mc);  Serial.println(F(";"));
  Serial.print(F(" md = ")); Serial.print(md);  Serial.println(F(";"));
  Serial.println("----------------");
}

/**********************************************
  Calcualte pressure readings
 **********************************************/
float pressure(int32_t b5)
{
  int32_t x1, x2, x3, b3, b6, p, UP;
  uint32_t b4, b7;

  UP = read_pressure();                          // Read raw pressure
  Serial.print(F("UP = ")); Serial.print(UP); Serial.println(F(";"));

  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6 >> 12)) >> 11;
  x2 = ac2 * b6 >> 11;
  x3 = x1 + x2;
  int32_t b3_tmp = ac1;                          // Improved b3 calculation which also uses less program code.
  b3_tmp = (b3_tmp * 4 + x3) << oss;
  b3     = (b3_tmp + 2) >> 2;
  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 >> oss);
  if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // or p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
  x1 = (p >> 8) * (p >> 8);
  x1 = (x1 * 3038) >> 16;
  x2 = (-7357 * p) >> 16;
  return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Return pressure in mbar
}

/**********************************************
  Read uncompensated temperature
 **********************************************/
int32_t temperature()
{
  int32_t x1, x2, b5, UT;

  Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
  Wire.write(0xf4);                       // Sends register address
  Wire.write(0x2e);                       // Write data
  Wire.endTransmission();                 // End transmission
  delay(5);                               // Datasheet suggests 4.5 ms
  UT = read_2_bytes(0xf6);                // Read uncompensated TEMPERATURE value
  Serial.print(F("UT = ")); Serial.print(UT); Serial.println(F(";"));

  // Calculate true temperature
  x1 = (UT - ac6) * ac5 >> 15;
  x2 = ((int32_t)mc << 11) / (x1 + md);
  b5 = x1 + x2;
  T  = (b5 + 8) >> 4;
  T = T / 10.0;                           // Temperature in celsius
  return b5; 
}

/**********************************************
  Read uncompensated pressure value
 **********************************************/
int32_t read_pressure()
{
  int32_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);   // Start transmission to device
  Wire.write(0xf4);                         // Sends register address to read from
  Wire.write(0x34 + (oss << 6));            // Write data
  Wire.endTransmission();                   // SEd transmission
  delay(osd);                               // Oversampling setting delay
  Wire.beginTransmission(ADDRESS_SENSOR);
  Wire.write(0xf6);                         // Register to read
  Wire.endTransmission();
  Wire.requestFrom(ADDRESS_SENSOR, 3);      // Request three bytes
  if(Wire.available() >= 3)
  {
    value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 - oss);
  }
  return value;                             // Return value
}

/**********************************************
  Read 1 byte from the BMP sensor
 **********************************************/
uint8_t read_1_byte(uint8_t code)
{
  uint8_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);         // Start transmission to device
  Wire.write(code);                               // Sends register address to read from
  Wire.endTransmission();                         // End transmission
  Wire.requestFrom(ADDRESS_SENSOR, 1);            // Request data for 1 byte to be read
  if(Wire.available() >= 1)
  {
    value = Wire.read();                          // Get 1 byte of data
  }
  return value;                                   // Return value
}

/**********************************************
  Read 2 bytes from the BMP sensor
 **********************************************/
uint16_t read_2_bytes(uint8_t code)
{
  uint16_t value;
  Wire.beginTransmission(ADDRESS_SENSOR);         // Start transmission to device
  Wire.write(code);                               // Sends register address to read from
  Wire.endTransmission();                         // End transmission
  Wire.requestFrom(ADDRESS_SENSOR, 2);            // Request 2 bytes from device
  if(Wire.available() >= 2)
  {
    value = (Wire.read() << 8) | Wire.read();     // Get 2 bytes of data
  }
  return value;                                   // Return value
}
Logged

Leo

Project "ALTDuino" - A homemade altimeter for model rockets.
http://www.altduino.de


Offline Offline
Faraday Member
**
Karma: 62
Posts: 3077
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks good.
Logged

Italy
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hallo.
first I have to say thankyou to all of you for so nice and accurate code.
now...
I'm using Arduino Due with "your" code, the last posted by Jacob, I think I have some calibration problem here.
Todays local pressure is 1021 but the sensor is reading 1018mb.
Altiture is about +40m above sea level but sensor giving me -41m.
Same result regardless OSS (0,1,2,3).

here the result I have:
Oversampling setting (oss) = 0

Sensor calibration data:
ac1 = 8180;
ac2 = -1252;
ac3 = -14376;
ac4 = 33262;
ac5 = 25253;
ac6 = 19971;
 b1 = 6515;
 b2 = 52;
 mb = -32768;
 mc = -11786;
 md = 2666;
----------------
UT = 28643;
Temperature: 25.60 C, 78.08 F
UP = 41993;
Pressure: 1018.23 mbar, 30.07 inHg
Altitude: -41.32 m, -135.58 ft
-----------------------------------------
UT = 28642;
Temperature: 25.60 C, 78.08 F
UP = 41996;
Pressure: 1018.26 mbar, 30.07 inHg
Altitude: -41.57 m, -136.39 ft
-----------------------------------------
UT = 28644;
Temperature: 25.60 C, 78.08 F
UP = 41995;
Pressure: 1018.29 mbar, 30.07 inHg
Altitude: -41.82 m, -137.21 ft
-----------------------------------------



Any suggestion please?

thankyou
diego
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 222
Posts: 13870
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


I suspect the math in the code overflows due to intermediate results, resulting in incorrect sign.
not checked

Change the integer types from int to long or float   (16 bit to 32 bit)

give it a try

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: 1 2 3 [4] 5   Go Up
Jump to: