Added .readAltitude function

This commit is contained in:
Kevin Townsend 2015-09-01 07:23:33 +02:00
parent 59079b6d37
commit 11ad05a034
3 changed files with 74 additions and 48 deletions

View File

@ -1,17 +1,17 @@
/*************************************************************************** /***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor This is a library for the BME280 humidity, temperature & pressure sensor
Designed specifically to work with the Adafruit BME280 Breakout Designed specifically to work with the Adafruit BME280 Breakout
----> http://www.adafruit.com/products/2650 ----> http://www.adafruit.com/products/2650
These sensors use I2C or SPI to communicate, 2 or 4 pins are required These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface. to interface.
Adafruit invests time and resources providing this open source code, Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products please support Adafruit andopen-source hardware by purchasing products
from Adafruit! from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries. Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution BSD license, all text above must be included in any redistribution
***************************************************************************/ ***************************************************************************/
#include "Arduino.h" #include "Arduino.h"
@ -19,23 +19,23 @@
#include <SPI.h> #include <SPI.h>
#include "Adafruit_BME280.h" #include "Adafruit_BME280.h"
static bme280_calib_data bme280_calib; static bme280_calib_data bme280_calib;
/*************************************************************************** /***************************************************************************
PRIVATE FUNCTIONS PRIVATE FUNCTIONS
***************************************************************************/ ***************************************************************************/
Adafruit_BME280::Adafruit_BME280() Adafruit_BME280::Adafruit_BME280()
: _cs(-1), _mosi(-1), _miso(-1), _sck(-1) : _cs(-1), _mosi(-1), _miso(-1), _sck(-1)
{ } { }
Adafruit_BME280::Adafruit_BME280(int8_t cspin) Adafruit_BME280::Adafruit_BME280(int8_t cspin)
: _cs(cspin), _mosi(-1), _miso(-1), _sck(-1) : _cs(cspin), _mosi(-1), _miso(-1), _sck(-1)
{ } { }
Adafruit_BME280::Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin) Adafruit_BME280::Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin)
: _cs(cspin), _mosi(mosipin), _miso(misopin), _sck(sckpin) : _cs(cspin), _mosi(mosipin), _miso(misopin), _sck(sckpin)
{ } { }
@ -70,9 +70,9 @@ bool Adafruit_BME280::begin(uint8_t a) {
} }
uint8_t Adafruit_BME280::spixfer(uint8_t x) { uint8_t Adafruit_BME280::spixfer(uint8_t x) {
if (_sck == -1) if (_sck == -1)
return SPI.transfer(x); return SPI.transfer(x);
// software spi // software spi
//Serial.println("Software SPI"); //Serial.println("Software SPI");
uint8_t reply = 0; uint8_t reply = 0;
@ -81,7 +81,7 @@ uint8_t Adafruit_BME280::spixfer(uint8_t x) {
digitalWrite(_sck, LOW); digitalWrite(_sck, LOW);
digitalWrite(_mosi, x & (1<<i)); digitalWrite(_mosi, x & (1<<i));
digitalWrite(_sck, HIGH); digitalWrite(_sck, HIGH);
if (digitalRead(_miso)) if (digitalRead(_miso))
reply |= 1; reply |= 1;
} }
return reply; return reply;
@ -119,7 +119,7 @@ void Adafruit_BME280::write8(byte reg, byte value)
uint8_t Adafruit_BME280::read8(byte reg) uint8_t Adafruit_BME280::read8(byte reg)
{ {
uint8_t value; uint8_t value;
if (_cs == -1) { if (_cs == -1) {
Wire.beginTransmission((uint8_t)_i2caddr); Wire.beginTransmission((uint8_t)_i2caddr);
Wire.write((uint8_t)reg); Wire.write((uint8_t)reg);
@ -173,7 +173,7 @@ uint16_t Adafruit_BME280::read16(byte reg)
uint16_t Adafruit_BME280::read16_LE(byte reg) { uint16_t Adafruit_BME280::read16_LE(byte reg) {
uint16_t temp = read16(reg); uint16_t temp = read16(reg);
return (temp >> 8) | (temp << 8); return (temp >> 8) | (temp << 8);
} }
/**************************************************************************/ /**************************************************************************/
@ -217,8 +217,8 @@ void Adafruit_BME280::readCoefficients(void)
bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1); bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1);
bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2); bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2);
bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3); bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3);
bme280_calib.dig_H4 = (read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4+1) & 0xF); bme280_calib.dig_H4 = (read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4+1) & 0xF);
bme280_calib.dig_H5 = (read8(BME280_REGISTER_DIG_H5+1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4); bme280_calib.dig_H5 = (read8(BME280_REGISTER_DIG_H5+1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4);
bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6); bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6);
} }
@ -230,17 +230,17 @@ void Adafruit_BME280::readCoefficients(void)
float Adafruit_BME280::readTemperature(void) float Adafruit_BME280::readTemperature(void)
{ {
int32_t var1, var2; int32_t var1, var2;
int32_t adc_T = read16(BME280_REGISTER_TEMPDATA); int32_t adc_T = read16(BME280_REGISTER_TEMPDATA);
adc_T <<= 8; adc_T <<= 8;
adc_T |= read8(BME280_REGISTER_TEMPDATA+2); adc_T |= read8(BME280_REGISTER_TEMPDATA+2);
adc_T >>= 4; adc_T >>= 4;
var1 = ((((adc_T>>3) - ((int32_t)bme280_calib.dig_T1 <<1))) * var1 = ((((adc_T>>3) - ((int32_t)bme280_calib.dig_T1 <<1))) *
((int32_t)bme280_calib.dig_T2)) >> 11; ((int32_t)bme280_calib.dig_T2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)bme280_calib.dig_T1)) * var2 = (((((adc_T>>4) - ((int32_t)bme280_calib.dig_T1)) *
((adc_T>>4) - ((int32_t)bme280_calib.dig_T1))) >> 12) * ((adc_T>>4) - ((int32_t)bme280_calib.dig_T1))) >> 12) *
((int32_t)bme280_calib.dig_T3)) >> 14; ((int32_t)bme280_calib.dig_T3)) >> 14;
t_fine = var1 + var2; t_fine = var1 + var2;
@ -256,7 +256,7 @@ float Adafruit_BME280::readTemperature(void)
/**************************************************************************/ /**************************************************************************/
float Adafruit_BME280::readPressure(void) { float Adafruit_BME280::readPressure(void) {
int64_t var1, var2, p; int64_t var1, var2, p;
int32_t adc_P = read16(BME280_REGISTER_PRESSUREDATA); int32_t adc_P = read16(BME280_REGISTER_PRESSUREDATA);
adc_P <<= 8; adc_P <<= 8;
adc_P |= read8(BME280_REGISTER_PRESSUREDATA+2); adc_P |= read8(BME280_REGISTER_PRESSUREDATA+2);
@ -269,7 +269,7 @@ float Adafruit_BME280::readPressure(void) {
var1 = ((var1 * var1 * (int64_t)bme280_calib.dig_P3)>>8) + var1 = ((var1 * var1 * (int64_t)bme280_calib.dig_P3)>>8) +
((var1 * (int64_t)bme280_calib.dig_P2)<<12); ((var1 * (int64_t)bme280_calib.dig_P2)<<12);
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bme280_calib.dig_P1)>>33; var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bme280_calib.dig_P1)>>33;
if (var1 == 0) { if (var1 == 0) {
return 0; // avoid exception caused by division by zero return 0; // avoid exception caused by division by zero
} }
@ -295,17 +295,39 @@ float Adafruit_BME280::readHumidity(void) {
v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)bme280_calib.dig_H4) << 20) - v_x1_u32r = (((((adc_H << 14) - (((int32_t)bme280_calib.dig_H4) << 20) -
(((int32_t)bme280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((int32_t)bme280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
(((((((v_x1_u32r * ((int32_t)bme280_calib.dig_H6)) >> 10) * (((((((v_x1_u32r * ((int32_t)bme280_calib.dig_H6)) >> 10) *
(((v_x1_u32r * ((int32_t)bme280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + (((v_x1_u32r * ((int32_t)bme280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) +
((int32_t)2097152)) * ((int32_t)bme280_calib.dig_H2) + 8192) >> 14)); ((int32_t)2097152)) * ((int32_t)bme280_calib.dig_H2) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
((int32_t)bme280_calib.dig_H1)) >> 4)); ((int32_t)bme280_calib.dig_H1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
float h = (v_x1_u32r>>12); float h = (v_x1_u32r>>12);
return h / 1024.0; return h / 1024.0;
} }
/**************************************************************************/
/*!
Calculates the altitude (in meters) from the specified atmospheric
pressure (in hPa), and sea-level pressure (in hPa).
@param seaLevel Sea-level pressure in hPa
@param atmospheric Atmospheric pressure in hPa
*/
/**************************************************************************/
float Adafruit_BME280::readAltitude(float seaLevel)
{
// Equation taken from BMP180 datasheet (page 16):
// http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
// Note that using the equation from wikipedia can give bad results
// at high altitude. See this thread for more information:
// http://forums.adafruit.com/viewtopic.php?f=22&t=58064
float atmospheric = readPressure() / 100.0F;
return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
}

View File

@ -1,17 +1,17 @@
/*************************************************************************** /***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor This is a library for the BME280 humidity, temperature & pressure sensor
Designed specifically to work with the Adafruit BME280 Breakout Designed specifically to work with the Adafruit BME280 Breakout
----> http://www.adafruit.com/products/2650 ----> http://www.adafruit.com/products/2650
These sensors use I2C or SPI to communicate, 2 or 4 pins are required These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface. to interface.
Adafruit invests time and resources providing this open source code, Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products please support Adafruit andopen-source hardware by purchasing products
from Adafruit! from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries. Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution BSD license, all text above must be included in any redistribution
***************************************************************************/ ***************************************************************************/
#ifndef __BME280_H__ #ifndef __BME280_H__
@ -113,7 +113,7 @@ class Adafruit_BME280_Unified : public Adafruit_Sensor
{ {
public: public:
Adafruit_BME280_Unified(int32_t sensorID = -1); Adafruit_BME280_Unified(int32_t sensorID = -1);
bool begin(uint8_t addr = BME280_ADDRESS); bool begin(uint8_t addr = BME280_ADDRESS);
void getTemperature(float *temp); void getTemperature(float *temp);
void getPressure(float *pressure); void getPressure(float *pressure);
@ -140,9 +140,7 @@ class Adafruit_BME280
float readTemperature(void); float readTemperature(void);
float readPressure(void); float readPressure(void);
float readHumidity(void); float readHumidity(void);
float readAltitude(float seaLevel);
// float pressureToAltitude(float seaLevel, float atmospheric, float temp);
// float seaLevelForAltitude(float altitude, float atmospheric, float temp);
private: private:

View File

@ -1,17 +1,17 @@
/*************************************************************************** /***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor This is a library for the BME280 humidity, temperature & pressure sensor
Designed specifically to work with the Adafruit BME280 Breakout Designed specifically to work with the Adafruit BME280 Breakout
----> http://www.adafruit.com/products/2650 ----> http://www.adafruit.com/products/2650
These sensors use I2C or SPI to communicate, 2 or 4 pins are required These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface. to interface.
Adafruit invests time and resources providing this open source code, Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products please support Adafruit andopen-source hardware by purchasing products
from Adafruit! from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries. Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution BSD license, all text above must be included in any redistribution
***************************************************************************/ ***************************************************************************/
@ -22,36 +22,42 @@
#define BME_SCK 13 #define BME_SCK 13
#define BME_MISO 12 #define BME_MISO 12
#define BME_MOSI 11 #define BME_MOSI 11
#define BME_CS 10 #define BME_CS 10
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI //Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); //Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
Serial.println(F("BME280 test")); Serial.println(F("BME280 test"));
if (!bme.begin()) { if (!bme.begin()) {
Serial.println("Could not find a valid BME280 sensor, check wiring!"); Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1); while (1);
} }
} }
void loop() { void loop() {
Serial.print("Temperature = "); Serial.print("Temperature = ");
Serial.print(bme.readTemperature()); Serial.print(bme.readTemperature());
Serial.println(" *C"); Serial.println(" *C");
Serial.print("Pressure = "); Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F); Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa"); Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = "); Serial.print("Humidity = ");
Serial.print(bme.readHumidity()); Serial.print(bme.readHumidity());
Serial.println(" %"); Serial.println(" %");
Serial.println(); Serial.println();
delay(500); delay(500);
} }