From 60bb88f25720a3a9bcf470db856e82ebace1ca3c Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 24 Jul 2015 16:44:43 -0400 Subject: [PATCH] init --- Adafruit_BME280.cpp | 311 +++++++++++++++++++++++++++++ Adafruit_BME280.h | 167 ++++++++++++++++ README.md | 24 +++ examples/bme280test/bme280test.ino | 57 ++++++ 4 files changed, 559 insertions(+) create mode 100644 Adafruit_BME280.cpp create mode 100644 Adafruit_BME280.h create mode 100644 README.md create mode 100644 examples/bme280test/bme280test.ino diff --git a/Adafruit_BME280.cpp b/Adafruit_BME280.cpp new file mode 100644 index 0000000..2610dcd --- /dev/null +++ b/Adafruit_BME280.cpp @@ -0,0 +1,311 @@ +/*************************************************************************** + This is a library for the BME280 humidity, temperature & pressure sensor + + Designed specifically to work with the Adafruit BME280 Breakout + ----> http://www.adafruit.com/products/2650 + + These sensors use I2C or SPI to communicate, 2 or 4 pins are required + to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit andopen-source hardware by purchasing products + from Adafruit! + + Written by Limor Fried & Kevin Townsend for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ***************************************************************************/ +#include "Arduino.h" +#include +#include +#include "Adafruit_BME280.h" + +static bme280_calib_data bme280_calib; + +/*************************************************************************** + PRIVATE FUNCTIONS + ***************************************************************************/ + + +Adafruit_BME280::Adafruit_BME280() + : _cs(-1), _mosi(-1), _miso(-1), _sck(-1) +{ } + +Adafruit_BME280::Adafruit_BME280(int8_t cspin) + : _cs(cspin), _mosi(-1), _miso(-1), _sck(-1) +{ } + +Adafruit_BME280::Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin) + : _cs(cspin), _mosi(mosipin), _miso(misopin), _sck(sckpin) +{ } + + +bool Adafruit_BME280::begin(uint8_t a) { + _i2caddr = a; + + if (_cs == -1) { + // i2c + Wire.begin(); + } else { + digitalWrite(_cs, HIGH); + pinMode(_cs, OUTPUT); + + if (_sck == -1) { + // hardware SPI + SPI.begin(); + } else { + // software SPI + pinMode(_sck, OUTPUT); + pinMode(_mosi, OUTPUT); + pinMode(_miso, INPUT); + } + } + + if (read8(BME280_REGISTER_CHIPID) != 0x60) + return false; + + readCoefficients(); + write8(BME280_REGISTER_CONTROL, 0x3F); + write8(BME280_REGISTER_CONTROLHUMID, 0x03); + return true; +} + +uint8_t Adafruit_BME280::spixfer(uint8_t x) { + if (_sck == -1) + return SPI.transfer(x); + + // software spi + //Serial.println("Software SPI"); + uint8_t reply = 0; + for (int i=7; i>=0; i--) { + reply <<= 1; + digitalWrite(_sck, LOW); + digitalWrite(_mosi, x & (1<> 8) | (temp << 8); + +} + +/**************************************************************************/ +/*! + @brief Reads a signed 16 bit value over I2C +*/ +/**************************************************************************/ +int16_t Adafruit_BME280::readS16(byte reg) +{ + return (int16_t)read16(reg); + +} + +int16_t Adafruit_BME280::readS16_LE(byte reg) +{ + return (int16_t)read16_LE(reg); + +} + +/**************************************************************************/ +/*! + @brief Reads the factory-set coefficients +*/ +/**************************************************************************/ +void Adafruit_BME280::readCoefficients(void) +{ + bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1); + bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2); + bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3); + + bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1); + bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2); + bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3); + bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4); + bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5); + bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6); + bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7); + bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8); + bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9); + + bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1); + bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2); + 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_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); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +float Adafruit_BME280::readTemperature(void) +{ + int32_t var1, var2; + + int32_t adc_T = read16(BME280_REGISTER_TEMPDATA); + adc_T <<= 8; + adc_T |= read8(BME280_REGISTER_TEMPDATA+2); + adc_T >>= 4; + + var1 = ((((adc_T>>3) - ((int32_t)bme280_calib.dig_T1 <<1))) * + ((int32_t)bme280_calib.dig_T2)) >> 11; + + var2 = (((((adc_T>>4) - ((int32_t)bme280_calib.dig_T1)) * + ((adc_T>>4) - ((int32_t)bme280_calib.dig_T1))) >> 12) * + ((int32_t)bme280_calib.dig_T3)) >> 14; + + t_fine = var1 + var2; + + float T = (t_fine * 5 + 128) >> 8; + return T/100; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +float Adafruit_BME280::readPressure(void) { + int64_t var1, var2, p; + + int32_t adc_P = read16(BME280_REGISTER_PRESSUREDATA); + adc_P <<= 8; + adc_P |= read8(BME280_REGISTER_PRESSUREDATA+2); + adc_P >>= 4; + + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)bme280_calib.dig_P6; + var2 = var2 + ((var1*(int64_t)bme280_calib.dig_P5)<<17); + var2 = var2 + (((int64_t)bme280_calib.dig_P4)<<35); + var1 = ((var1 * var1 * (int64_t)bme280_calib.dig_P3)>>8) + + ((var1 * (int64_t)bme280_calib.dig_P2)<<12); + var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bme280_calib.dig_P1)>>33; + + if (var1 == 0) { + return 0; // avoid exception caused by division by zero + } + p = 1048576 - adc_P; + p = (((p<<31) - var2)*3125) / var1; + var1 = (((int64_t)bme280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25; + var2 = (((int64_t)bme280_calib.dig_P8) * p) >> 19; + + p = ((p + var1 + var2) >> 8) + (((int64_t)bme280_calib.dig_P7)<<4); + return (float)p/256; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +float Adafruit_BME280::readHumidity(void) { + + int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA); + + int32_t v_x1_u32r; + + v_x1_u32r = (t_fine - ((int32_t)76800)); + + 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) * + (((((((v_x1_u32r * ((int32_t)bme280_calib.dig_H6)) >> 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)); + + v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * + ((int32_t)bme280_calib.dig_H1)) >> 4)); + + v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; + v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; + float h = (v_x1_u32r>>12); + return h / 1024.0; +} diff --git a/Adafruit_BME280.h b/Adafruit_BME280.h new file mode 100644 index 0000000..5c94e37 --- /dev/null +++ b/Adafruit_BME280.h @@ -0,0 +1,167 @@ +/*************************************************************************** + This is a library for the BME280 humidity, temperature & pressure sensor + + Designed specifically to work with the Adafruit BME280 Breakout + ----> http://www.adafruit.com/products/2650 + + These sensors use I2C or SPI to communicate, 2 or 4 pins are required + to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit andopen-source hardware by purchasing products + from Adafruit! + + Written by Limor Fried & Kevin Townsend for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ***************************************************************************/ +#ifndef __BME280_H__ +#define __BME280_H__ + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include + +#ifdef __AVR_ATtiny85__ + #include "TinyWireM.h" + #define Wire TinyWireM +#else + #include +#endif + +/*========================================================================= + I2C ADDRESS/BITS + -----------------------------------------------------------------------*/ + #define BME280_ADDRESS (0x77) +/*=========================================================================*/ + +/*========================================================================= + REGISTERS + -----------------------------------------------------------------------*/ + enum + { + BME280_REGISTER_DIG_T1 = 0x88, + BME280_REGISTER_DIG_T2 = 0x8A, + BME280_REGISTER_DIG_T3 = 0x8C, + + BME280_REGISTER_DIG_P1 = 0x8E, + BME280_REGISTER_DIG_P2 = 0x90, + BME280_REGISTER_DIG_P3 = 0x92, + BME280_REGISTER_DIG_P4 = 0x94, + BME280_REGISTER_DIG_P5 = 0x96, + BME280_REGISTER_DIG_P6 = 0x98, + BME280_REGISTER_DIG_P7 = 0x9A, + BME280_REGISTER_DIG_P8 = 0x9C, + BME280_REGISTER_DIG_P9 = 0x9E, + + BME280_REGISTER_DIG_H1 = 0xA1, + BME280_REGISTER_DIG_H2 = 0xE1, + BME280_REGISTER_DIG_H3 = 0xE3, + BME280_REGISTER_DIG_H4 = 0xE4, + BME280_REGISTER_DIG_H5 = 0xE5, + BME280_REGISTER_DIG_H6 = 0xE7, + + BME280_REGISTER_CHIPID = 0xD0, + BME280_REGISTER_VERSION = 0xD1, + BME280_REGISTER_SOFTRESET = 0xE0, + + BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0 + + BME280_REGISTER_CONTROLHUMID = 0xF2, + BME280_REGISTER_CONTROL = 0xF4, + BME280_REGISTER_CONFIG = 0xF5, + BME280_REGISTER_PRESSUREDATA = 0xF7, + BME280_REGISTER_TEMPDATA = 0xFA, + BME280_REGISTER_HUMIDDATA = 0xFD, + }; + +/*=========================================================================*/ + +/*========================================================================= + CALIBRATION DATA + -----------------------------------------------------------------------*/ + typedef struct + { + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; + + uint8_t dig_H1; + int16_t dig_H2; + uint8_t dig_H3; + int16_t dig_H4; + int16_t dig_H5; + int8_t dig_H6; + } bme280_calib_data; +/*=========================================================================*/ + +/* +class Adafruit_BME280_Unified : public Adafruit_Sensor +{ + public: + Adafruit_BME280_Unified(int32_t sensorID = -1); + + bool begin(uint8_t addr = BME280_ADDRESS); + void getTemperature(float *temp); + void getPressure(float *pressure); + float pressureToAltitude(float seaLevel, float atmospheric, float temp); + float seaLevelForAltitude(float altitude, float atmospheric, float temp); + void getEvent(sensors_event_t*); + void getSensor(sensor_t*); + + private: + uint8_t _i2c_addr; + int32_t _sensorID; +}; + +*/ + +class Adafruit_BME280 +{ + public: + Adafruit_BME280(void); + Adafruit_BME280(int8_t cspin); + Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin); + + bool begin(uint8_t addr = BME280_ADDRESS); + float readTemperature(void); + float readPressure(void); + float readHumidity(void); + + // float pressureToAltitude(float seaLevel, float atmospheric, float temp); + // float seaLevelForAltitude(float altitude, float atmospheric, float temp); + + private: + + void readCoefficients(void); + uint8_t spixfer(uint8_t x); + + void write8(byte reg, byte value); + uint8_t read8(byte reg); + uint16_t read16(byte reg); + int16_t readS16(byte reg); + uint16_t read16_LE(byte reg); // little endian + int16_t readS16_LE(byte reg); // little endian + + uint8_t _i2caddr; + int32_t _sensorID; + int32_t t_fine; + + int8_t _cs, _mosi, _miso, _sck; + +}; + +#endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ebb003 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +This is a library for the Adafruit BME280 Humidity, Barometric Pressure + Temp sensor + +Designed specifically to work with the Adafruit BME280 Breakout + * http://www.adafruit.com/products/2652 + +These sensors use I2C or SPI to communicate, up to 4 pins are required to interface + +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Check out the links above for our tutorials and wiring diagrams + +Written by Limor Fried/Ladyada for Adafruit Industries. +BSD license, all text above must be included in any redistribution + +To download. click the DOWNLOAD ZIP button, rename the uncompressed folder Adafruit_BME280. +Check that the Adafruit_BME280 folder contains Adafruit_BME280.cpp and Adafruit_BME280.h + +Place the Adafruit_BME280 library folder your arduinosketchfolder/libraries/ folder. +You may need to create the libraries subfolder if its your first library. Restart the IDE. + +We also have a great tutorial on Arduino library installation at: +http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use \ No newline at end of file diff --git a/examples/bme280test/bme280test.ino b/examples/bme280test/bme280test.ino new file mode 100644 index 0000000..1d11da1 --- /dev/null +++ b/examples/bme280test/bme280test.ino @@ -0,0 +1,57 @@ +/*************************************************************************** + This is a library for the BME280 humidity, temperature & pressure sensor + + Designed specifically to work with the Adafruit BME280 Breakout + ----> http://www.adafruit.com/products/2650 + + These sensors use I2C or SPI to communicate, 2 or 4 pins are required + to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit andopen-source hardware by purchasing products + from Adafruit! + + Written by Limor Fried & Kevin Townsend for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ***************************************************************************/ + +#include +#include +#include +#include + +#define BME_SCK 13 +#define BME_MISO 12 +#define BME_MOSI 11 +#define BME_CS 10 + +Adafruit_BME280 bme; // I2C +//Adafruit_BME280 bme(BME_CS); // hardware SPI +//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); + +void setup() { + Serial.begin(9600); + Serial.println(F("BME280 test")); + + if (!bme.begin()) { + Serial.println("Could not find a valid BME280 sensor, check wiring!"); + while (1); + } +} + +void loop() { + Serial.print("Temperature = "); + Serial.print(bme.readTemperature()); + Serial.println(" *C"); + + Serial.print("Pressure = "); + Serial.print(bme.readPressure()); + Serial.println(" Pa"); + + Serial.print("Humidity = "); + Serial.print(bme.readHumidity()); + Serial.println(" %"); + + Serial.println(); + delay(500); +}