Update firmware libraries

This commit is contained in:
Florian Eitel 2019-08-03 20:34:17 +02:00
parent 92908452fc
commit f4139b27c8
No known key found for this signature in database
GPG key ID: 9987EAFEF6F686BB
19 changed files with 1968 additions and 1585 deletions

View file

@ -1,258 +1,236 @@
/**************************************************************************/
/*!
@file Adafruit_APDS9960.h
@author Ladyada, Dean Miller (Adafruit Industries)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2017, Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
* @file Adafruit_APDS9960.h
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2017, Adafruit Industries
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _APDS9960_H_
#define _APDS9960_H_
#include <Arduino.h>
#include <Wire.h>
#define I2CDEBUG
#define APDS9960_ADDRESS (0x39) /**< I2C Address */
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define APDS9960_ADDRESS (0x39)
/*=========================================================================*/
/*=========================================================================
REGISTERS
-----------------------------------------------------------------------*/
enum
{
APDS9960_RAM = 0x00,
APDS9960_ENABLE = 0x80,
APDS9960_ATIME = 0x81,
APDS9960_WTIME = 0x83,
APDS9960_AILTIL = 0x84,
APDS9960_AILTH = 0x85,
APDS9960_AIHTL = 0x86,
APDS9960_AIHTH = 0x87,
APDS9960_PILT = 0x89,
APDS9960_PIHT = 0x8B,
APDS9960_PERS = 0x8C,
APDS9960_CONFIG1 = 0x8D,
APDS9960_PPULSE = 0x8E,
APDS9960_CONTROL = 0x8F,
APDS9960_CONFIG2 = 0x90,
APDS9960_ID = 0x92,
APDS9960_STATUS = 0x93,
APDS9960_CDATAL = 0x94,
APDS9960_CDATAH = 0x95,
APDS9960_RDATAL = 0x96,
APDS9960_RDATAH = 0x97,
APDS9960_GDATAL = 0x98,
APDS9960_GDATAH = 0x99,
APDS9960_BDATAL = 0x9A,
APDS9960_BDATAH = 0x9B,
APDS9960_PDATA = 0x9C,
APDS9960_POFFSET_UR = 0x9D,
APDS9960_POFFSET_DL = 0x9E,
APDS9960_CONFIG3 = 0x9F,
APDS9960_GPENTH = 0xA0,
APDS9960_GEXTH = 0xA1,
APDS9960_GCONF1 = 0xA2,
APDS9960_GCONF2 = 0xA3,
APDS9960_GOFFSET_U = 0xA4,
APDS9960_GOFFSET_D = 0xA5,
APDS9960_GOFFSET_L = 0xA7,
APDS9960_GOFFSET_R = 0xA9,
APDS9960_GPULSE = 0xA6,
APDS9960_GCONF3 = 0xAA,
APDS9960_GCONF4 = 0xAB,
APDS9960_GFLVL = 0xAE,
APDS9960_GSTATUS = 0xAF,
APDS9960_IFORCE = 0xE4,
APDS9960_PICLEAR = 0xE5,
APDS9960_CICLEAR = 0xE6,
APDS9960_AICLEAR = 0xE7,
APDS9960_GFIFO_U = 0xFC,
APDS9960_GFIFO_D = 0xFD,
APDS9960_GFIFO_L = 0xFE,
APDS9960_GFIFO_R = 0xFF,
};
/*=========================================================================*/
typedef enum
{
APDS9960_AGAIN_1X = 0x00, /**< No gain */
APDS9960_AGAIN_4X = 0x01, /**< 2x gain */
APDS9960_AGAIN_16X = 0x02, /**< 16x gain */
APDS9960_AGAIN_64X = 0x03 /**< 64x gain */
}
apds9960AGain_t;
typedef enum
{
APDS9960_PGAIN_1X = 0x00, /**< 1x gain */
APDS9960_PGAIN_2X = 0x04, /**< 2x gain */
APDS9960_PGAIN_4X = 0x08, /**< 4x gain */
APDS9960_PGAIN_8X = 0x0C /**< 8x gain */
}
apds9960PGain_t;
typedef enum
{
APDS9960_PPULSELEN_4US = 0x00, /**< 4uS */
APDS9960_PPULSELEN_8US = 0x40, /**< 8uS */
APDS9960_PPULSELEN_16US = 0x80, /**< 16uS */
APDS9960_PPULSELEN_32US = 0xC0 /**< 32uS */
}
apds9960PPulseLen_t;
typedef enum
{
APDS9960_LEDDRIVE_100MA = 0x00, /**< 100mA */
APDS9960_LEDDRIVE_50MA = 0x40, /**< 50mA */
APDS9960_LEDDRIVE_25MA = 0x80, /**< 25mA */
APDS9960_LEDDRIVE_12MA = 0xC0 /**< 12.5mA */
}
apds9960LedDrive_t;
typedef enum
{
APDS9960_LEDBOOST_100PCNT = 0x00, /**< 100% */
APDS9960_LEDBOOST_150PCNT = 0x10, /**< 150% */
APDS9960_LEDBOOST_200PCNT = 0x20, /**< 200% */
APDS9960_LEDBOOST_300PCNT = 0x30 /**< 300% */
}
apds9960LedBoost_t;
enum
{
APDS9960_DIMENSIONS_ALL = 0x00,
APDS9960_DIMENSIONS_UP_DOWM = 0x01,
APGS9960_DIMENSIONS_LEFT_RIGHT = 0x02,
/** I2C Registers */
enum {
APDS9960_RAM = 0x00,
APDS9960_ENABLE = 0x80,
APDS9960_ATIME = 0x81,
APDS9960_WTIME = 0x83,
APDS9960_AILTIL = 0x84,
APDS9960_AILTH = 0x85,
APDS9960_AIHTL = 0x86,
APDS9960_AIHTH = 0x87,
APDS9960_PILT = 0x89,
APDS9960_PIHT = 0x8B,
APDS9960_PERS = 0x8C,
APDS9960_CONFIG1 = 0x8D,
APDS9960_PPULSE = 0x8E,
APDS9960_CONTROL = 0x8F,
APDS9960_CONFIG2 = 0x90,
APDS9960_ID = 0x92,
APDS9960_STATUS = 0x93,
APDS9960_CDATAL = 0x94,
APDS9960_CDATAH = 0x95,
APDS9960_RDATAL = 0x96,
APDS9960_RDATAH = 0x97,
APDS9960_GDATAL = 0x98,
APDS9960_GDATAH = 0x99,
APDS9960_BDATAL = 0x9A,
APDS9960_BDATAH = 0x9B,
APDS9960_PDATA = 0x9C,
APDS9960_POFFSET_UR = 0x9D,
APDS9960_POFFSET_DL = 0x9E,
APDS9960_CONFIG3 = 0x9F,
APDS9960_GPENTH = 0xA0,
APDS9960_GEXTH = 0xA1,
APDS9960_GCONF1 = 0xA2,
APDS9960_GCONF2 = 0xA3,
APDS9960_GOFFSET_U = 0xA4,
APDS9960_GOFFSET_D = 0xA5,
APDS9960_GOFFSET_L = 0xA7,
APDS9960_GOFFSET_R = 0xA9,
APDS9960_GPULSE = 0xA6,
APDS9960_GCONF3 = 0xAA,
APDS9960_GCONF4 = 0xAB,
APDS9960_GFLVL = 0xAE,
APDS9960_GSTATUS = 0xAF,
APDS9960_IFORCE = 0xE4,
APDS9960_PICLEAR = 0xE5,
APDS9960_CICLEAR = 0xE6,
APDS9960_AICLEAR = 0xE7,
APDS9960_GFIFO_U = 0xFC,
APDS9960_GFIFO_D = 0xFD,
APDS9960_GFIFO_L = 0xFE,
APDS9960_GFIFO_R = 0xFF,
};
enum
{
APDS9960_GFIFO_1 = 0x00,
APDS9960_GFIFO_4 = 0x01,
APDS9960_GFIFO_8 = 0x02,
APDS9960_GFIFO_16 = 0x03,
/** ADC gain settings */
typedef enum {
APDS9960_AGAIN_1X = 0x00, /**< No gain */
APDS9960_AGAIN_4X = 0x01, /**< 2x gain */
APDS9960_AGAIN_16X = 0x02, /**< 16x gain */
APDS9960_AGAIN_64X = 0x03 /**< 64x gain */
} apds9960AGain_t;
/** Proxmity gain settings */
typedef enum {
APDS9960_PGAIN_1X = 0x00, /**< 1x gain */
APDS9960_PGAIN_2X = 0x04, /**< 2x gain */
APDS9960_PGAIN_4X = 0x08, /**< 4x gain */
APDS9960_PGAIN_8X = 0x0C /**< 8x gain */
} apds9960PGain_t;
/** Pulse length settings */
typedef enum {
APDS9960_PPULSELEN_4US = 0x00, /**< 4uS */
APDS9960_PPULSELEN_8US = 0x40, /**< 8uS */
APDS9960_PPULSELEN_16US = 0x80, /**< 16uS */
APDS9960_PPULSELEN_32US = 0xC0 /**< 32uS */
} apds9960PPulseLen_t;
/** LED drive settings */
typedef enum {
APDS9960_LEDDRIVE_100MA = 0x00, /**< 100mA */
APDS9960_LEDDRIVE_50MA = 0x40, /**< 50mA */
APDS9960_LEDDRIVE_25MA = 0x80, /**< 25mA */
APDS9960_LEDDRIVE_12MA = 0xC0 /**< 12.5mA */
} apds9960LedDrive_t;
/** LED boost settings */
typedef enum {
APDS9960_LEDBOOST_100PCNT = 0x00, /**< 100% */
APDS9960_LEDBOOST_150PCNT = 0x10, /**< 150% */
APDS9960_LEDBOOST_200PCNT = 0x20, /**< 200% */
APDS9960_LEDBOOST_300PCNT = 0x30 /**< 300% */
} apds9960LedBoost_t;
/** Dimensions */
enum {
APDS9960_DIMENSIONS_ALL = 0x00, // All dimensions
APDS9960_DIMENSIONS_UP_DOWN = 0x01, // Up/Down dimensions
APGS9960_DIMENSIONS_LEFT_RIGHT = 0x02, // Left/Right dimensions
};
enum
{
APDS9960_GGAIN_1 = 0x00,
APDS9960_GGAIN_2 = 0x01,
APDS9960_GGAIN_4 = 0x02,
APDS9960_GGAIN_8 = 0x03,
/** FIFO Interrupts */
enum {
APDS9960_GFIFO_1 = 0x00, // Generate interrupt after 1 dataset in FIFO
APDS9960_GFIFO_4 = 0x01, // Generate interrupt after 2 datasets in FIFO
APDS9960_GFIFO_8 = 0x02, // Generate interrupt after 3 datasets in FIFO
APDS9960_GFIFO_16 = 0x03, // Generate interrupt after 4 datasets in FIFO
};
enum
{
APDS9960_GPULSE_4US = 0x00,
APDS9960_GPULSE_8US = 0x01,
APDS9960_GPULSE_16US = 0x02,
APDS9960_GPULSE_32US = 0x03,
/** Gesture Gain */
enum {
APDS9960_GGAIN_1 = 0x00, // Gain 1x
APDS9960_GGAIN_2 = 0x01, // Gain 2x
APDS9960_GGAIN_4 = 0x02, // Gain 4x
APDS9960_GGAIN_8 = 0x03, // Gain 8x
};
#define APDS9960_TIME_MULT 2.78 //millisec
/** Pulse Lenghts */
enum {
APDS9960_GPULSE_4US = 0x00, // Pulse 4us
APDS9960_GPULSE_8US = 0x01, // Pulse 8us
APDS9960_GPULSE_16US = 0x02, // Pulse 16us
APDS9960_GPULSE_32US = 0x03, // Pulse 32us
};
#define APDS9960_UP 0x01
#define APDS9960_DOWN 0x02
#define APDS9960_LEFT 0x03
#define APDS9960_RIGHT 0x04
#define APDS9960_UP 0x01 /**< Gesture Up */
#define APDS9960_DOWN 0x02 /**< Gesture Down */
#define APDS9960_LEFT 0x03 /**< Gesture Left */
#define APDS9960_RIGHT 0x04 /**< Gesture Right */
/*!
* @brief Class that stores state and functions for interacting with
* APDS9960 Sensor
*/
class Adafruit_APDS9960 {
public:
Adafruit_APDS9960(void) {};
~Adafruit_APDS9960(void) {};
public:
Adafruit_APDS9960(){};
~Adafruit_APDS9960(){};
boolean begin(uint16_t iTimeMS = 10, apds9960AGain_t = APDS9960_AGAIN_4X, uint8_t addr = APDS9960_ADDRESS);
void setADCIntegrationTime(uint16_t iTimeMS);
float getADCIntegrationTime(void);
void setADCGain(apds9960AGain_t gain);
apds9960AGain_t getADCGain(void);
void setLED(apds9960LedDrive_t drive, apds9960LedBoost_t boost);
boolean begin(uint16_t iTimeMS = 10, apds9960AGain_t = APDS9960_AGAIN_4X,
uint8_t addr = APDS9960_ADDRESS, TwoWire *theWire = &Wire);
void setADCIntegrationTime(uint16_t iTimeMS);
float getADCIntegrationTime();
void setADCGain(apds9960AGain_t gain);
apds9960AGain_t getADCGain();
void setLED(apds9960LedDrive_t drive, apds9960LedBoost_t boost);
// proximity
void enableProximity(boolean en = true);
void setProxGain(apds9960PGain_t gain);
apds9960PGain_t getProxGain(void);
void setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses);
void enableProximityInterrupt();
void disableProximityInterrupt();
uint8_t readProximity(void);
void setProximityInterruptThreshold(uint8_t low, uint8_t high, uint8_t persistance = 4);
bool getProximityInterrupt();
void enableProximity(boolean en = true);
void setProxGain(apds9960PGain_t gain);
apds9960PGain_t getProxGain();
void setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses);
void enableProximityInterrupt();
void disableProximityInterrupt();
uint8_t readProximity();
void setProximityInterruptThreshold(uint8_t low, uint8_t high,
uint8_t persistance = 4);
bool getProximityInterrupt();
// gesture
void enableGesture(boolean en = true);
bool gestureValid();
void setGestureDimensions(uint8_t dims);
void setGestureFIFOThreshold(uint8_t thresh);
void setGestureGain(uint8_t gain);
void setGestureProximityThreshold(uint8_t thresh);
void setGestureOffset(uint8_t offset_up, uint8_t offset_down, uint8_t offset_left, uint8_t offset_right);
uint8_t readGesture(void);
void resetCounts();
void enableGesture(boolean en = true);
bool gestureValid();
void setGestureDimensions(uint8_t dims);
void setGestureFIFOThreshold(uint8_t thresh);
void setGestureGain(uint8_t gain);
void setGestureProximityThreshold(uint8_t thresh);
void setGestureOffset(uint8_t offset_up, uint8_t offset_down,
uint8_t offset_left, uint8_t offset_right);
uint8_t readGesture();
void resetCounts();
// light & color
void enableColor(boolean en = true);
bool colorDataReady();
void getColorData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
void enableColor(boolean en = true);
bool colorDataReady();
void getColorData(uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c);
uint16_t calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b);
uint16_t calculateLux(uint16_t r, uint16_t g, uint16_t b);
void enableColorInterrupt();
void disableColorInterrupt();
void clearInterrupt(void);
void clearInterrupt();
void setIntLimits(uint16_t l, uint16_t h);
// turn on/off elements
void enable(boolean en = true);
void enable(boolean en = true);
private:
private:
uint8_t _i2caddr;
TwoWire *_wire;
uint32_t read32(uint8_t reg);
uint16_t read16(uint8_t reg);
uint16_t read16R(uint8_t reg);
void write8(byte reg, byte value);
uint8_t read8(byte reg);
void write8(byte reg, byte value);
uint8_t read8(byte reg);
uint8_t gestCnt;
@ -268,291 +246,286 @@ class Adafruit_APDS9960 {
struct enable {
//power on
uint8_t PON : 1;
// power on
uint8_t PON : 1;
//ALS enable
uint8_t AEN : 1;
// ALS enable
uint8_t AEN : 1;
//Proximity detect enable
uint8_t PEN : 1;
// Proximity detect enable
uint8_t PEN : 1;
//wait timer enable
uint8_t WEN : 1;
// wait timer enable
uint8_t WEN : 1;
//ALS interrupt enable
uint8_t AIEN : 1;
// ALS interrupt enable
uint8_t AIEN : 1;
//proximity interrupt enable
uint8_t PIEN : 1;
// proximity interrupt enable
uint8_t PIEN : 1;
//gesture enable
uint8_t GEN : 1;
// gesture enable
uint8_t GEN : 1;
uint8_t get() {
return (GEN << 6) | (PIEN << 5) | (AIEN << 4) | (WEN << 3) | (PEN << 2) | (AEN << 1) | PON;
};
};
struct enable _enable;
uint8_t get() {
return (GEN << 6) | (PIEN << 5) | (AIEN << 4) | (WEN << 3) | (PEN << 2) |
(AEN << 1) | PON;
};
};
struct enable _enable;
struct pers {
//ALS Interrupt Persistence. Controls rate of Clear channel interrupt to the host processor
uint8_t APERS : 4;
struct pers {
// ALS Interrupt Persistence. Controls rate of Clear channel interrupt to
// the host processor
uint8_t APERS : 4;
//proximity interrupt persistence, controls rate of prox interrupt to host processor
uint8_t PPERS : 4;
// proximity interrupt persistence, controls rate of prox interrupt to host
// processor
uint8_t PPERS : 4;
uint8_t get(){
return (PPERS << 4) | APERS;
};
};
pers _pers;
uint8_t get() { return (PPERS << 4) | APERS; };
};
pers _pers;
struct config1 {
uint8_t WLONG : 1;
struct config1 {
uint8_t WLONG : 1;
uint8_t get(){
return WLONG << 1;
};
};
config1 _config1;
uint8_t get() { return WLONG << 1; };
};
config1 _config1;
struct ppulse {
struct ppulse {
/*Proximity Pulse Count. Specifies the number of proximity pulses to be generated on LDR.
Number of pulses is set by PPULSE value plus 1.
*/
uint8_t PPULSE : 6;
/*Proximity Pulse Count. Specifies the number of proximity pulses to be
generated on LDR. Number of pulses is set by PPULSE value plus 1.
*/
uint8_t PPULSE : 6;
//Proximity Pulse Length. Sets the LED-ON pulse width during a proximity LDR pulse.
uint8_t PPLEN : 2;
// Proximity Pulse Length. Sets the LED-ON pulse width during a proximity
// LDR pulse.
uint8_t PPLEN : 2;
uint8_t get(){
return (PPLEN << 6) | PPULSE;
}
};
ppulse _ppulse;
uint8_t get() { return (PPLEN << 6) | PPULSE; }
};
ppulse _ppulse;
struct control {
//ALS and Color gain control
uint8_t AGAIN : 2;
struct control {
// ALS and Color gain control
uint8_t AGAIN : 2;
//proximity gain control
uint8_t PGAIN : 2;
// proximity gain control
uint8_t PGAIN : 2;
//led drive strength
uint8_t LDRIVE : 2;
// led drive strength
uint8_t LDRIVE : 2;
uint8_t get(){
return (LDRIVE << 6) | (PGAIN << 2) | AGAIN;
}
};
control _control;
uint8_t get() { return (LDRIVE << 6) | (PGAIN << 2) | AGAIN; }
};
control _control;
struct config2 {
/* Additional LDR current during proximity and gesture LED pulses. Current value, set by LDRIVE,
is increased by the percentage of LED_BOOST.
*/
uint8_t LED_BOOST : 2;
struct config2 {
/* Additional LDR current during proximity and gesture LED pulses. Current
value, set by LDRIVE, is increased by the percentage of LED_BOOST.
*/
uint8_t LED_BOOST : 2;
//clear photodiode saturation int enable
uint8_t CPSIEN : 1;
// clear photodiode saturation int enable
uint8_t CPSIEN : 1;
//proximity saturation interrupt enable
uint8_t PSIEN : 1;
// proximity saturation interrupt enable
uint8_t PSIEN : 1;
uint8_t get(){
return (PSIEN << 7) | (CPSIEN << 6) | (LED_BOOST << 4) | 1;
}
};
config2 _config2;
uint8_t get() {
return (PSIEN << 7) | (CPSIEN << 6) | (LED_BOOST << 4) | 1;
}
};
config2 _config2;
struct status {
/* ALS Valid. Indicates that an ALS cycle has completed since AEN was asserted or since a read
from any of the ALS/Color data registers.
*/
uint8_t AVALID : 1;
struct status {
/* ALS Valid. Indicates that an ALS cycle has completed since AEN was
asserted or since a read from any of the ALS/Color data registers.
*/
uint8_t AVALID : 1;
/* Proximity Valid. Indicates that a proximity cycle has completed since PEN was asserted or since
PDATA was last read. A read of PDATA automatically clears PVALID.
*/
uint8_t PVALID : 1;
/* Proximity Valid. Indicates that a proximity cycle has completed since PEN
was asserted or since PDATA was last read. A read of PDATA automatically
clears PVALID.
*/
uint8_t PVALID : 1;
/* Gesture Interrupt. GINT is asserted when GFVLV becomes greater than GFIFOTH or if GVALID
has become asserted when GMODE transitioned to zero. The bit is reset when FIFO is
completely emptied (read).
*/
uint8_t GINT : 1;
/* Gesture Interrupt. GINT is asserted when GFVLV becomes greater than
GFIFOTH or if GVALID has become asserted when GMODE transitioned to zero.
The bit is reset when FIFO is completely emptied (read).
*/
uint8_t GINT : 1;
//ALS Interrupt. This bit triggers an interrupt if AIEN in ENABLE is set.
uint8_t AINT : 1;
// ALS Interrupt. This bit triggers an interrupt if AIEN in ENABLE is set.
uint8_t AINT : 1;
//Proximity Interrupt. This bit triggers an interrupt if PIEN in ENABLE is set.
uint8_t PINT : 1;
// Proximity Interrupt. This bit triggers an interrupt if PIEN in ENABLE is
// set.
uint8_t PINT : 1;
/* Indicates that an analog saturation event occurred during a previous proximity or gesture
cycle. Once set, this bit remains set until cleared by clear proximity interrupt special function
command (0xE5 PICLEAR) or by disabling Prox (PEN=0). This bit triggers an interrupt if PSIEN
is set.
*/
uint8_t PGSAT : 1;
/* Indicates that an analog saturation event occurred during a previous
proximity or gesture cycle. Once set, this bit remains set until cleared by
clear proximity interrupt special function command (0xE5 PICLEAR) or by
disabling Prox (PEN=0). This bit triggers an interrupt if PSIEN is set.
*/
uint8_t PGSAT : 1;
/* Clear Photodiode Saturation. When asserted, the analog sensor was at the upper end of its
dynamic range. The bit can be de-asserted by sending a Clear channel interrupt command
(0xE6 CICLEAR) or by disabling the ADC (AEN=0). This bit triggers an interrupt if CPSIEN is set.
*/
uint8_t CPSAT : 1;
/* Clear Photodiode Saturation. When asserted, the analog sensor was at the
upper end of its dynamic range. The bit can be de-asserted by sending a
Clear channel interrupt command (0xE6 CICLEAR) or by disabling the ADC
(AEN=0). This bit triggers an interrupt if CPSIEN is set.
*/
uint8_t CPSAT : 1;
void set(uint8_t data){
AVALID = data & 0x01;
PVALID = (data >> 1) & 0x01;
GINT = (data >> 2) & 0x01;
AINT = (data >> 4) & 0x01;
PINT = (data >> 5) & 0x01;
PGSAT = (data >> 6) & 0x01;
CPSAT = (data >> 7) & 0x01;
}
};
status _status;
void set(uint8_t data) {
AVALID = data & 0x01;
PVALID = (data >> 1) & 0x01;
GINT = (data >> 2) & 0x01;
AINT = (data >> 4) & 0x01;
PINT = (data >> 5) & 0x01;
PGSAT = (data >> 6) & 0x01;
CPSAT = (data >> 7) & 0x01;
}
};
status _status;
struct config3 {
//proximity mask
uint8_t PMASK_R : 1;
uint8_t PMASK_L : 1;
uint8_t PMASK_D : 1;
uint8_t PMASK_U : 1;
struct config3 {
// proximity mask
uint8_t PMASK_R : 1;
uint8_t PMASK_L : 1;
uint8_t PMASK_D : 1;
uint8_t PMASK_U : 1;
/* Sleep After Interrupt. When enabled, the device will automatically enter low power mode
when the INT pin is asserted and the state machine has progressed to the SAI decision block.
Normal operation is resumed when INT pin is cleared over I2C.
*/
uint8_t SAI : 1;
/* Sleep After Interrupt. When enabled, the device will automatically enter
low power mode when the INT pin is asserted and the state machine has
progressed to the SAI decision block. Normal operation is resumed when INT
pin is cleared over I2C.
*/
uint8_t SAI : 1;
/* Proximity Gain Compensation Enable. This bit provides gain compensation when proximity
photodiode signal is reduced as a result of sensor masking. If only one diode of the diode pair
is contributing, then only half of the signal is available at the ADC; this results in a maximum
ADC value of 127. Enabling PCMP enables an additional gain of 2X, resulting in a maximum
ADC value of 255.
*/
uint8_t PCMP : 1;
/* Proximity Gain Compensation Enable. This bit provides gain compensation
when proximity photodiode signal is reduced as a result of sensor masking.
If only one diode of the diode pair is contributing, then only half of the
signal is available at the ADC; this results in a maximum ADC value of 127.
Enabling PCMP enables an additional gain of 2X, resulting in a maximum ADC
value of 255.
*/
uint8_t PCMP : 1;
uint8_t get(){
return (PCMP << 5) | (SAI << 4) | (PMASK_U << 3) | (PMASK_D << 2) | (PMASK_L << 1) | PMASK_R;
}
};
config3 _config3;
uint8_t get() {
return (PCMP << 5) | (SAI << 4) | (PMASK_U << 3) | (PMASK_D << 2) |
(PMASK_L << 1) | PMASK_R;
}
};
config3 _config3;
struct gconf1 {
/* Gesture Exit Persistence. When a number of consecutive “gesture end” occurrences become
equal or greater to the GEPERS value, the Gesture state machine is exited.
*/
uint8_t GEXPERS : 2;
struct gconf1 {
/* Gesture Exit Persistence. When a number of consecutive “gesture end”
occurrences become equal or greater to the GEPERS value, the Gesture state
machine is exited.
*/
uint8_t GEXPERS : 2;
/* Gesture Exit Mask. Controls which of the gesture detector photodiodes (UDLR) will be included
to determine a gesture end and subsequent exit of the gesture state machine. Unmasked
UDLR data will be compared with the value in GTHR_OUT. Field value bits correspond to UDLR
detectors.
*/
uint8_t GEXMSK : 4;
/* Gesture Exit Mask. Controls which of the gesture detector photodiodes
(UDLR) will be included to determine a “gesture end” and subsequent exit
of the gesture state machine. Unmasked UDLR data will be compared with the
value in GTHR_OUT. Field value bits correspond to UDLR detectors.
*/
uint8_t GEXMSK : 4;
/* Gesture FIFO Threshold. This value is compared with the FIFO Level (i.e. the number of UDLR
datasets) to generate an interrupt (if enabled).
*/
uint8_t GFIFOTH : 2;
/* Gesture FIFO Threshold. This value is compared with the FIFO Level (i.e.
the number of UDLR datasets) to generate an interrupt (if enabled).
*/
uint8_t GFIFOTH : 2;
uint8_t get(){
return (GFIFOTH << 6) | (GEXMSK << 2) | GEXPERS;
}
};
gconf1 _gconf1;
uint8_t get() { return (GFIFOTH << 6) | (GEXMSK << 2) | GEXPERS; }
};
gconf1 _gconf1;
struct gconf2 {
/* Gesture Wait Time. The GWTIME controls the amount of time in a low power mode between
gesture detection cycles.
*/
uint8_t GWTIME : 3;
struct gconf2 {
/* Gesture Wait Time. The GWTIME controls the amount of time in a low power
mode between gesture detection cycles.
*/
uint8_t GWTIME : 3;
//Gesture LED Drive Strength. Sets LED Drive Strength in gesture mode.
uint8_t GLDRIVE : 2;
// Gesture LED Drive Strength. Sets LED Drive Strength in gesture mode.
uint8_t GLDRIVE : 2;
//Gesture Gain Control. Sets the gain of the proximity receiver in gesture mode.
uint8_t GGAIN : 2;
// Gesture Gain Control. Sets the gain of the proximity receiver in gesture
// mode.
uint8_t GGAIN : 2;
uint8_t get(){
return (GGAIN << 5) | (GLDRIVE << 3) | GWTIME;
}
};
gconf2 _gconf2;
uint8_t get() { return (GGAIN << 5) | (GLDRIVE << 3) | GWTIME; }
};
gconf2 _gconf2;
struct gpulse {
/* Number of Gesture Pulses. Specifies the number of pulses to be generated on LDR.
Number of pulses is set by GPULSE value plus 1.
*/
uint8_t GPULSE : 6;
struct gpulse {
/* Number of Gesture Pulses. Specifies the number of pulses to be generated
on LDR. Number of pulses is set by GPULSE value plus 1.
*/
uint8_t GPULSE : 6;
//Gesture Pulse Length. Sets the LED_ON pulse width during a Gesture LDR Pulse.
uint8_t GPLEN : 2;
// Gesture Pulse Length. Sets the LED_ON pulse width during a Gesture LDR
// Pulse.
uint8_t GPLEN : 2;
uint8_t get(){
return (GPLEN << 6) | GPULSE;
}
};
gpulse _gpulse;
uint8_t get() { return (GPLEN << 6) | GPULSE; }
};
gpulse _gpulse;
struct gconf3 {
/* Gesture Dimension Select. Selects which gesture photodiode pairs are enabled to gather
results during gesture.
*/
uint8_t GDIMS : 2;
struct gconf3 {
/* Gesture Dimension Select. Selects which gesture photodiode pairs are
enabled to gather results during gesture.
*/
uint8_t GDIMS : 2;
uint8_t get(){
return GDIMS;
}
};
gconf3 _gconf3;
uint8_t get() { return GDIMS; }
};
gconf3 _gconf3;
struct gconf4 {
/* Gesture Mode. Reading this bit reports if the gesture state machine is actively running, 1
= Gesture, 0= ALS, Proximity, Color. Writing a 1 to this bit causes immediate entry in to the
gesture state machine (as if GPENTH had been exceeded). Writing a 0 to this bit causes exit of
gesture when current analog conversion has finished (as if GEXTH had been exceeded).
*/
uint8_t GMODE : 1;
struct gconf4 {
/* Gesture Mode. Reading this bit reports if the gesture state machine is
actively running, 1 = Gesture, 0= ALS, Proximity, Color. Writing a 1 to this
bit causes immediate entry in to the gesture state machine (as if GPENTH had
been exceeded). Writing a 0 to this bit causes exit of gesture when current
analog conversion has finished (as if GEXTH had been exceeded).
*/
uint8_t GMODE : 1;
/* Gesture interrupt enable. Gesture Interrupt Enable. When asserted, all gesture related
interrupts are unmasked.
*/
uint8_t GIEN : 2;
/* Gesture interrupt enable. Gesture Interrupt Enable. When asserted, all
gesture related interrupts are unmasked.
*/
uint8_t GIEN : 2;
uint8_t get(){
return (GIEN << 1) | GMODE;
}
void set(uint8_t data){
GIEN = (data >> 1) & 0x01;
GMODE = data & 0x01;
}
};
gconf4 _gconf4;
uint8_t get() { return (GIEN << 1) | GMODE; }
void set(uint8_t data) {
GIEN = (data >> 1) & 0x01;
GMODE = data & 0x01;
}
};
gconf4 _gconf4;
struct gstatus {
/* Gesture FIFO Data. GVALID bit is sent when GFLVL becomes greater than GFIFOTH (i.e. FIFO has
enough data to set GINT). GFIFOD is reset when GMODE = 0 and the GFLVL=0 (i.e. All FIFO data
has been read).
*/
uint8_t GVALID : 1;
struct gstatus {
/* Gesture FIFO Data. GVALID bit is sent when GFLVL becomes greater than
GFIFOTH (i.e. FIFO has enough data to set GINT). GFIFOD is reset when GMODE
= 0 and the GFLVL=0 (i.e. All FIFO data has been read).
*/
uint8_t GVALID : 1;
/* Gesture FIFO Overflow. A setting of 1 indicates that the FIFO has filled to capacity and that new
gesture detector data has been lost.
*/
uint8_t GFOV : 1;
void set(uint8_t data){
GFOV = (data >> 1) & 0x01;
GVALID = data & 0x01;
}
};
gstatus _gstatus;
/* Gesture FIFO Overflow. A setting of 1 indicates that the FIFO has filled
to capacity and that new gesture detector data has been lost.
*/
uint8_t GFOV : 1;
void set(uint8_t data) {
GFOV = (data >> 1) & 0x01;
GVALID = data & 0x01;
}
};
gstatus _gstatus;
};
#endif

View file

@ -0,0 +1,18 @@
# Adafruit APDS9960 Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_APDS9960.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_APDS9960)
<a href="https://www.adafruit.com/product/3595"><img src="assets/board.jpg?raw=true" width="500px"></a>
This is the Adafruit APDS9960 Proximity, Light, RGB, and Gesture sensor Library
Tested and works great with the Adafruit APDS9960 Board
* http://www.adafruit.com/products/3595
This chip uses I2C to communicate, 2 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!
Written by Dean Miller, Limor Fried for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution
To install, use the Arduino Library Manager and search for "Adafruit APDS9960 Library" and install the library.

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

View file

@ -0,0 +1,127 @@
# Adafruit Community Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and leaders pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level or type of
experience, education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
## Our Standards
We are committed to providing a friendly, safe and welcoming environment for
all.
Examples of behavior that contributes to creating a positive environment
include:
* Be kind and courteous to others
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Collaborating with other community members
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and sexual attention or advances
* The use of inappropriate images, including in a community member's avatar
* The use of inappropriate language, including in a community member's nickname
* Any spamming, flaming, baiting or other attention-stealing behavior
* Excessive or unwelcome helping; answering outside the scope of the question
asked
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate
The goal of the standards and moderation guidelines outlined here is to build
and maintain a respectful community. We ask that you dont just aim to be
"technically unimpeachable", but rather try to be your best self.
We value many things beyond technical expertise, including collaboration and
supporting others within our community. Providing a positive experience for
other community members can have a much more significant impact than simply
providing the correct answer.
## Our Responsibilities
Project leaders are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project leaders have the right and responsibility to remove, edit, or
reject messages, comments, commits, code, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any community member for other behaviors that they deem
inappropriate, threatening, offensive, or harmful.
## Moderation
Instances of behaviors that violate the Adafruit Community Code of Conduct
may be reported by any member of the community. Community members are
encouraged to report these situations, including situations they witness
involving other community members.
You may report in the following ways:
In any situation, you may send an email to <support@adafruit.com>.
On the Adafruit Discord, you may send an open message from any channel
to all Community Helpers by tagging @community helpers. You may also send an
open message from any channel, or a direct message to @kattni#1507,
@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or
@Andon#8175.
Email and direct message reports will be kept confidential.
In situations on Discord where the issue is particularly egregious, possibly
illegal, requires immediate action, or violates the Discord terms of service,
you should also report the message directly to Discord.
These are the steps for upholding our communitys standards of conduct.
1. Any member of the community may report any situation that violates the
Adafruit Community Code of Conduct. All reports will be reviewed and
investigated.
2. If the behavior is an egregious violation, the community member who
committed the violation may be banned immediately, without warning.
3. Otherwise, moderators will first respond to such behavior with a warning.
4. Moderators follow a soft "three strikes" policy - the community member may
be given another chance, if they are receptive to the warning and change their
behavior.
5. If the community member is unreceptive or unreasonable when warned by a
moderator, or the warning goes unheeded, they may be banned for a first or
second offense. Repeated offenses will result in the community member being
banned.
## Scope
This Code of Conduct and the enforcement policies listed above apply to all
Adafruit Community venues. This includes but is not limited to any community
spaces (both public and private), the entire Adafruit Discord server, and
Adafruit GitHub repositories. Examples of Adafruit Community spaces include
but are not limited to meet-ups, audio chats on the Adafruit Discord, or
interaction at a conference.
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. As a community
member, you are representing our community, and are expected to behave
accordingly.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>,
and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html).
For other projects adopting the Adafruit Community Code of
Conduct, please contact the maintainers of those projects for enforcement.
If you wish to use this code of conduct for your own project, consider
explicitly mentioning your moderation policy or making a copy with your
own moderation policy so as to avoid confusion.

View file

@ -1,5 +1,5 @@
name=Adafruit APDS9960 Library
version=1.0.5
version=1.1.1
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=This is a library for the Adafruit APDS9960 gesture/proximity/color/light sensor.

View file

@ -0,0 +1,26 @@
Software License Agreement (BSD License)
Copyright (c) 2012, Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,530 +1,560 @@
/***************************************************************************
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 <Wire.h>
#include <SPI.h>
#include "Adafruit_BME280.h"
/***************************************************************************
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)
{ }
/**************************************************************************/
/*!
@brief Initialise sensor with given parameters / settings
*/
/**************************************************************************/
bool Adafruit_BME280::begin(TwoWire *theWire)
{
_wire = theWire;
_i2caddr = BME280_ADDRESS;
return init();
* @file Adafruit_BME280.cpp
*
* @mainpage Adafruit BME280 humidity, temperature & pressure sensor
*
* @section intro_sec Introduction
*
* Driver for the BME280 humidity, temperature & pressure sensor
*
* These sensors use I2C or SPI to communicate, 2 or 4 pins are required
* to interface.
*
* Designed specifically to work with the Adafruit BME280 Breakout
* ----> http://www.adafruit.com/products/2652
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* @section author Author
*
* Written by Kevin "KTOWN" Townsend for Adafruit Industries.
*
* @section license License
*
* BSD license, all text here must be included in any redistribution.
* See the LICENSE file for details.
*
*/
#include "Adafruit_BME280.h"
#include "Arduino.h"
#include <SPI.h>
#include <Wire.h>
/*!
* @brief class constructor
*/
Adafruit_BME280::Adafruit_BME280() : _cs(-1), _mosi(-1), _miso(-1), _sck(-1) {}
/*!
* @brief class constructor if using hardware SPI
* @param cspin the chip select pin to use
* @param *theSPI
* optional SPI object
*/
Adafruit_BME280::Adafruit_BME280(int8_t cspin, SPIClass *theSPI) {
_cs = cspin;
_mosi = _miso = _sck = -1;
_spi = theSPI;
}
bool Adafruit_BME280::begin(uint8_t addr)
{
_i2caddr = addr;
_wire = &Wire;
return init();
/*!
* @brief class constructor if using software SPI
* @param cspin the chip select pin to use
* @param mosipin the MOSI pin to use
* @param misopin the MISO pin to use
* @param sckpin the SCK pin to use
*/
Adafruit_BME280::Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin,
int8_t sckpin)
: _cs(cspin), _mosi(mosipin), _miso(misopin), _sck(sckpin) {}
/*!
* @brief Initialise sensor with given parameters / settings
* @param theWire the I2C object to use
* @returns true on success, false otherwise
*/
bool Adafruit_BME280::begin(TwoWire *theWire) {
_wire = theWire;
_i2caddr = BME280_ADDRESS;
return init();
}
bool Adafruit_BME280::begin(uint8_t addr, TwoWire *theWire)
{
_i2caddr = addr;
_wire = theWire;
return init();
/*!
* @brief Initialise sensor with given parameters / settings
* @param addr the I2C address the device can be found on
* @returns true on success, false otherwise
*/
bool Adafruit_BME280::begin(uint8_t addr) {
_i2caddr = addr;
_wire = &Wire;
return init();
}
bool Adafruit_BME280::begin(void)
{
_i2caddr = BME280_ADDRESS;
_wire = &Wire;
return init();
/*!
* @brief Initialise sensor with given parameters / settings
* @param addr the I2C address the device can be found on
* @param theWire the I2C object to use
* @returns true on success, false otherwise
*/
bool Adafruit_BME280::begin(uint8_t addr, TwoWire *theWire) {
_i2caddr = addr;
_wire = theWire;
return init();
}
bool Adafruit_BME280::init()
{
// init I2C or SPI sensor interface
if (_cs == -1) {
// I2C
_wire -> begin();
/*!
* @brief Initialise sensor with given parameters / settings
* @returns true on success, false otherwise
*/
bool Adafruit_BME280::begin(void) {
bool status = false;
_i2caddr = BME280_ADDRESS;
_wire = &Wire;
status = init();
if (!status) {
_i2caddr = BME280_ADDRESS_ALTERNATE;
status = init();
}
return status;
}
/*!
* @brief Initialise sensor with given parameters / settings
* @returns true on success, false otherwise
*/
bool Adafruit_BME280::init() {
// init I2C or SPI sensor interface
if (_cs == -1) {
// I2C
_wire->begin();
} else {
digitalWrite(_cs, HIGH);
pinMode(_cs, OUTPUT);
if (_sck == -1) {
// hardware SPI
_spi->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);
}
// software SPI
pinMode(_sck, OUTPUT);
pinMode(_mosi, OUTPUT);
pinMode(_miso, INPUT);
}
}
// check if sensor, i.e. the chip ID is correct
if (read8(BME280_REGISTER_CHIPID) != 0x60)
return false;
// check if sensor, i.e. the chip ID is correct
_sensorID = read8(BME280_REGISTER_CHIPID);
if (_sensorID != 0x60)
return false;
// reset the device using soft-reset
// this makes sure the IIR is off, etc.
write8(BME280_REGISTER_SOFTRESET, 0xB6);
// reset the device using soft-reset
// this makes sure the IIR is off, etc.
write8(BME280_REGISTER_SOFTRESET, 0xB6);
// wait for chip to wake up.
delay(300);
// if chip is still reading calibration, delay
while (isReadingCalibration())
delay(100);
readCoefficients(); // read trimming parameters, see DS 4.2.2
setSampling(); // use defaults
// wait for chip to wake up.
delay(300);
// if chip is still reading calibration, delay
while (isReadingCalibration())
delay(100);
return true;
readCoefficients(); // read trimming parameters, see DS 4.2.2
setSampling(); // use defaults
delay(100);
return true;
}
/**************************************************************************/
/*!
@brief setup sensor with given parameters / settings
* @brief setup sensor with given parameters / settings
*
* This is simply a overload to the normal begin()-function, so SPI users
* don't get confused about the library requiring an address.
* @param mode the power mode to use for the sensor
* @param tempSampling the temp samping rate to use
* @param pressSampling the pressure sampling rate to use
* @param humSampling the humidity sampling rate to use
* @param filter the filter mode to use
* @param duration the standby duration to use
*/
void Adafruit_BME280::setSampling(sensor_mode mode,
sensor_sampling tempSampling,
sensor_sampling pressSampling,
sensor_sampling humSampling,
sensor_filter filter,
standby_duration duration) {
_measReg.mode = mode;
_measReg.osrs_t = tempSampling;
_measReg.osrs_p = pressSampling;
This is simply a overload to the normal begin()-function, so SPI users
don't get confused about the library requiring an address.
*/
/**************************************************************************/
_humReg.osrs_h = humSampling;
_configReg.filter = filter;
_configReg.t_sb = duration;
void Adafruit_BME280::setSampling(sensor_mode mode,
sensor_sampling tempSampling,
sensor_sampling pressSampling,
sensor_sampling humSampling,
sensor_filter filter,
standby_duration duration) {
_measReg.mode = mode;
_measReg.osrs_t = tempSampling;
_measReg.osrs_p = pressSampling;
_humReg.osrs_h = humSampling;
_configReg.filter = filter;
_configReg.t_sb = duration;
// you must make sure to also set REGISTER_CONTROL after setting the
// CONTROLHUMID register, otherwise the values won't be applied (see DS 5.4.3)
write8(BME280_REGISTER_CONTROLHUMID, _humReg.get());
write8(BME280_REGISTER_CONFIG, _configReg.get());
write8(BME280_REGISTER_CONTROL, _measReg.get());
// you must make sure to also set REGISTER_CONTROL after setting the
// CONTROLHUMID register, otherwise the values won't be applied (see
// DS 5.4.3)
write8(BME280_REGISTER_CONTROLHUMID, _humReg.get());
write8(BME280_REGISTER_CONFIG, _configReg.get());
write8(BME280_REGISTER_CONTROL, _measReg.get());
}
/**************************************************************************/
/*!
@brief Encapsulate hardware and software SPI transfer into one function
*/
/**************************************************************************/
* @brief Encapsulate hardware and software SPI transfer into one
* function
* @param x the data byte to transfer
* @returns the data byte read from the device
*/
uint8_t Adafruit_BME280::spixfer(uint8_t x) {
// hardware SPI
if (_sck == -1)
return SPI.transfer(x);
// hardware SPI
if (_sck == -1)
return _spi->transfer(x);
// software SPI
uint8_t reply = 0;
for (int i=7; i>=0; i--) {
reply <<= 1;
digitalWrite(_sck, LOW);
digitalWrite(_mosi, x & (1<<i));
digitalWrite(_sck, HIGH);
if (digitalRead(_miso))
reply |= 1;
}
return reply;
// software SPI
uint8_t reply = 0;
for (int i = 7; i >= 0; i--) {
reply <<= 1;
digitalWrite(_sck, LOW);
digitalWrite(_mosi, x & (1 << i));
digitalWrite(_sck, HIGH);
if (digitalRead(_miso))
reply |= 1;
}
return reply;
}
/**************************************************************************/
/*!
@brief Writes an 8 bit value over I2C or SPI
*/
/**************************************************************************/
* @brief Writes an 8 bit value over I2C or SPI
* @param reg the register address to write to
* @param value the value to write to the register
*/
void Adafruit_BME280::write8(byte reg, byte value) {
if (_cs == -1) {
_wire -> beginTransmission((uint8_t)_i2caddr);
_wire -> write((uint8_t)reg);
_wire -> write((uint8_t)value);
_wire -> endTransmission();
} else {
if (_sck == -1)
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg & ~0x80); // write, bit 7 low
spixfer(value);
digitalWrite(_cs, HIGH);
if (_cs == -1) {
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->write((uint8_t)value);
_wire->endTransmission();
} else {
if (_sck == -1)
SPI.endTransaction(); // release the SPI bus
}
_spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg & ~0x80); // write, bit 7 low
spixfer(value);
digitalWrite(_cs, HIGH);
if (_sck == -1)
_spi->endTransaction(); // release the SPI bus
}
}
/**************************************************************************/
/*!
@brief Reads an 8 bit value over I2C or SPI
*/
/**************************************************************************/
* @brief Reads an 8 bit value over I2C or SPI
* @param reg the register address to read from
* @returns the data byte read from the device
*/
uint8_t Adafruit_BME280::read8(byte reg) {
uint8_t value;
uint8_t value;
if (_cs == -1) {
_wire -> beginTransmission((uint8_t)_i2caddr);
_wire -> write((uint8_t)reg);
_wire -> endTransmission();
_wire -> requestFrom((uint8_t)_i2caddr, (byte)1);
value = _wire -> read();
} else {
if (_sck == -1)
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
SPI.endTransaction(); // release the SPI bus
}
return value;
if (_cs == -1) {
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->endTransmission();
_wire->requestFrom((uint8_t)_i2caddr, (byte)1);
value = _wire->read();
} else {
if (_sck == -1)
_spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
_spi->endTransaction(); // release the SPI bus
}
return value;
}
/**************************************************************************/
/*!
@brief Reads a 16 bit value over I2C or SPI
*/
/**************************************************************************/
uint16_t Adafruit_BME280::read16(byte reg)
{
uint16_t value;
* @brief Reads a 16 bit value over I2C or SPI
* @param reg the register address to read from
* @returns the 16 bit data value read from the device
*/
uint16_t Adafruit_BME280::read16(byte reg) {
uint16_t value;
if (_cs == -1) {
_wire -> beginTransmission((uint8_t)_i2caddr);
_wire -> write((uint8_t)reg);
_wire -> endTransmission();
_wire -> requestFrom((uint8_t)_i2caddr, (byte)2);
value = (_wire -> read() << 8) | _wire -> read();
} else {
if (_sck == -1)
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = (spixfer(0) << 8) | spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
SPI.endTransaction(); // release the SPI bus
}
if (_cs == -1) {
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->endTransmission();
_wire->requestFrom((uint8_t)_i2caddr, (byte)2);
value = (_wire->read() << 8) | _wire->read();
} else {
if (_sck == -1)
_spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = (spixfer(0) << 8) | spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
_spi->endTransaction(); // release the SPI bus
}
return value;
return value;
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
* @brief Reads a signed 16 bit little endian value over I2C or SPI
* @param reg the register address to read from
* @returns the 16 bit data value read from the device
*/
uint16_t Adafruit_BME280::read16_LE(byte reg) {
uint16_t temp = read16(reg);
return (temp >> 8) | (temp << 8);
uint16_t temp = read16(reg);
return (temp >> 8) | (temp << 8);
}
/**************************************************************************/
/*!
@brief Reads a signed 16 bit value over I2C or SPI
*/
/**************************************************************************/
int16_t Adafruit_BME280::readS16(byte reg)
{
return (int16_t)read16(reg);
* @brief Reads a signed 16 bit value over I2C or SPI
* @param reg the register address to read from
* @returns the 16 bit data value read from the device
*/
int16_t Adafruit_BME280::readS16(byte reg) { return (int16_t)read16(reg); }
/*!
* @brief Reads a signed little endian 16 bit value over I2C or SPI
* @param reg the register address to read from
* @returns the 16 bit data value read from the device
*/
int16_t Adafruit_BME280::readS16_LE(byte reg) {
return (int16_t)read16_LE(reg);
}
/**************************************************************************/
/*!
* @brief Reads a 24 bit value over I2C
* @param reg the register address to read from
* @returns the 24 bit data value read from the device
*/
uint32_t Adafruit_BME280::read24(byte reg) {
uint32_t value;
*/
/**************************************************************************/
int16_t Adafruit_BME280::readS16_LE(byte reg)
{
return (int16_t)read16_LE(reg);
if (_cs == -1) {
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->endTransmission();
_wire->requestFrom((uint8_t)_i2caddr, (byte)3);
value = _wire->read();
value <<= 8;
value |= _wire->read();
value <<= 8;
value |= _wire->read();
} else {
if (_sck == -1)
_spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = spixfer(0);
value <<= 8;
value |= spixfer(0);
value <<= 8;
value |= spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
_spi->endTransaction(); // release the SPI bus
}
return value;
}
/**************************************************************************/
/*!
@brief Reads a 24 bit value over I2C
*/
/**************************************************************************/
uint32_t Adafruit_BME280::read24(byte reg)
{
uint32_t value;
if (_cs == -1) {
_wire -> beginTransmission((uint8_t)_i2caddr);
_wire -> write((uint8_t)reg);
_wire -> endTransmission();
_wire -> requestFrom((uint8_t)_i2caddr, (byte)3);
value = _wire -> read();
value <<= 8;
value |= _wire -> read();
value <<= 8;
value |= _wire -> read();
} else {
if (_sck == -1)
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
value = spixfer(0);
value <<= 8;
value |= spixfer(0);
value <<= 8;
value |= spixfer(0);
digitalWrite(_cs, HIGH);
if (_sck == -1)
SPI.endTransaction(); // release the SPI bus
}
return value;
* @brief Take a new measurement (only possible in forced mode)
*/
void Adafruit_BME280::takeForcedMeasurement() {
// If we are in forced mode, the BME sensor goes back to sleep after each
// measurement and we need to set it to forced mode once at this point, so
// it will take the next measurement and then return to sleep again.
// In normal mode simply does new measurements periodically.
if (_measReg.mode == MODE_FORCED) {
// set to forced mode, i.e. "take next measurement"
write8(BME280_REGISTER_CONTROL, _measReg.get());
// wait until measurement has been completed, otherwise we would read
// the values from the last measurement
while (read8(BME280_REGISTER_STATUS) & 0x08)
delay(1);
}
}
/**************************************************************************/
/*!
@brief Take a new measurement (only possible in forced mode)
*/
/**************************************************************************/
void Adafruit_BME280::takeForcedMeasurement()
{
// If we are in forced mode, the BME sensor goes back to sleep after each
// measurement and we need to set it to forced mode once at this point, so
// it will take the next measurement and then return to sleep again.
// In normal mode simply does new measurements periodically.
if (_measReg.mode == MODE_FORCED) {
// set to forced mode, i.e. "take next measurement"
write8(BME280_REGISTER_CONTROL, _measReg.get());
// wait until measurement has been completed, otherwise we would read
// the values from the last measurement
while (read8(BME280_REGISTER_STATUS) & 0x08)
delay(1);
}
* @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);
}
/**************************************************************************/
/*!
@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);
}
/**************************************************************************/
/*!
@brief return true if chip is busy reading cal data
*/
/**************************************************************************/
bool Adafruit_BME280::isReadingCalibration(void)
{
* @brief return true if chip is busy reading cal data
* @returns true if reading calibration, false otherwise
*/
bool Adafruit_BME280::isReadingCalibration(void) {
uint8_t const rStatus = read8(BME280_REGISTER_STATUS);
return (rStatus & (1 << 0)) != 0;
}
/**************************************************************************/
/*!
@brief Returns the temperature from the sensor
*/
/**************************************************************************/
float Adafruit_BME280::readTemperature(void)
{
int32_t var1, var2;
* @brief Returns the temperature from the sensor
* @returns the temperature read from the device
*/
float Adafruit_BME280::readTemperature(void) {
int32_t var1, var2;
int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
if (adc_T == 0x800000) // value in case temp measurement was disabled
return NAN;
adc_T >>= 4;
int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
if (adc_T == 0x800000) // value in case temp measurement was disabled
return NAN;
adc_T >>= 4;
var1 = ((((adc_T>>3) - ((int32_t)_bme280_calib.dig_T1 <<1))) *
((int32_t)_bme280_calib.dig_T2)) >> 11;
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;
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;
t_fine = var1 + var2;
float T = (t_fine * 5 + 128) >> 8;
return T/100;
float T = (t_fine * 5 + 128) >> 8;
return T / 100;
}
/**************************************************************************/
/*!
@brief Returns the temperature from the sensor
*/
/**************************************************************************/
* @brief Returns the pressure from the sensor
* @returns the pressure value (in Pascal) read from the device
*/
float Adafruit_BME280::readPressure(void) {
int64_t var1, var2, p;
int64_t var1, var2, p;
readTemperature(); // must be done first to get t_fine
readTemperature(); // must be done first to get t_fine
int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA);
if (adc_P == 0x800000) // value in case pressure measurement was disabled
return NAN;
adc_P >>= 4;
int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA);
if (adc_P == 0x800000) // value in case pressure measurement was disabled
return NAN;
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;
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;
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;
p = ((p + var1 + var2) >> 8) + (((int64_t)_bme280_calib.dig_P7) << 4);
return (float)p / 256;
}
/**************************************************************************/
/*!
@brief Returns the humidity from the sensor
*/
/**************************************************************************/
* @brief Returns the humidity from the sensor
* @returns the humidity value read from the device
*/
float Adafruit_BME280::readHumidity(void) {
readTemperature(); // must be done first to get t_fine
readTemperature(); // must be done first to get t_fine
int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA);
if (adc_H == 0x8000) // value in case humidity measurement was disabled
return NAN;
int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA);
if (adc_H == 0x8000) // value in case humidity measurement was disabled
return NAN;
int32_t v_x1_u32r;
int32_t v_x1_u32r;
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) -
(((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 = (((((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 - (((((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;
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;
}
/**************************************************************************/
/*!
Calculates the altitude (in meters) from the specified atmospheric
pressure (in hPa), and sea-level pressure (in hPa).
* 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
* @returns the altitude value read from the device
*/
float Adafruit_BME280::readAltitude(float seaLevel) {
// Equation taken from BMP180 datasheet (page 16):
// http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
@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
// 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));
float atmospheric = readPressure() / 100.0F;
return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
}
/**************************************************************************/
/*!
Calculates the pressure at sea level (in hPa) from the specified altitude
(in meters), and atmospheric pressure (in hPa).
@param altitude Altitude in meters
@param atmospheric Atmospheric pressure in hPa
*/
/**************************************************************************/
float Adafruit_BME280::seaLevelForAltitude(float altitude, float atmospheric)
{
// Equation taken from BMP180 datasheet (page 17):
// http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
* Calculates the pressure at sea level (in hPa) from the specified
* altitude (in meters), and atmospheric pressure (in hPa).
* @param altitude Altitude in meters
* @param atmospheric Atmospheric pressure in hPa
* @returns the pressure at sea level (in hPa) from the specified altitude
*/
float Adafruit_BME280::seaLevelForAltitude(float altitude, float atmospheric) {
// Equation taken from BMP180 datasheet (page 17):
// 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
// 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
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
return atmospheric / pow(1.0 - (altitude / 44330.0), 5.255);
}
/*!
* Returns Sensor ID found by init() for diagnostics
* @returns Sensor ID 0x60 for BME280, 0x56, 0x57, 0x58 BMP280
*/
uint32_t Adafruit_BME280::sensorID(void) { return _sensorID; }

View file

@ -1,106 +1,108 @@
/***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor
/*!
* @file Adafruit_BME280.h
*
* 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 and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Kevin "KTOWN" Townsend for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
* See the LICENSE file for details.
*
*/
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 "Arduino.h"
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <Wire.h>
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define BME280_ADDRESS (0x77)
/*=========================================================================*/
/*!
* @brief default I2C address
*/
#define BME280_ADDRESS (0x77) // Primary I2C Address
/*!
* @brief alternate I2C address
*/
#define BME280_ADDRESS_ALTERNATE (0x76) // Alternate Address
/*=========================================================================
REGISTERS
-----------------------------------------------------------------------*/
enum
{
BME280_REGISTER_DIG_T1 = 0x88,
BME280_REGISTER_DIG_T2 = 0x8A,
BME280_REGISTER_DIG_T3 = 0x8C,
/*!
* @brief Register addresses
*/
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_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_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_CHIPID = 0xD0,
BME280_REGISTER_VERSION = 0xD1,
BME280_REGISTER_SOFTRESET = 0xE0,
BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0
BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0
BME280_REGISTER_CONTROLHUMID = 0xF2,
BME280_REGISTER_STATUS = 0XF3,
BME280_REGISTER_CONTROL = 0xF4,
BME280_REGISTER_CONFIG = 0xF5,
BME280_REGISTER_PRESSUREDATA = 0xF7,
BME280_REGISTER_TEMPDATA = 0xFA,
BME280_REGISTER_HUMIDDATA = 0xFD
};
BME280_REGISTER_CONTROLHUMID = 0xF2,
BME280_REGISTER_STATUS = 0XF3,
BME280_REGISTER_CONTROL = 0xF4,
BME280_REGISTER_CONFIG = 0xF5,
BME280_REGISTER_PRESSUREDATA = 0xF7,
BME280_REGISTER_TEMPDATA = 0xFA,
BME280_REGISTER_HUMIDDATA = 0xFD
};
/*=========================================================================*/
/**************************************************************************/
/*!
@brief calibration data
*/
/**************************************************************************/
typedef struct {
uint16_t dig_T1; ///< temperature compensation value
int16_t dig_T2; ///< temperature compensation value
int16_t dig_T3; ///< temperature compensation value
/*=========================================================================
CALIBRATION DATA
-----------------------------------------------------------------------*/
typedef struct
{
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1; ///< pressure compensation value
int16_t dig_P2; ///< pressure compensation value
int16_t dig_P3; ///< pressure compensation value
int16_t dig_P4; ///< pressure compensation value
int16_t dig_P5; ///< pressure compensation value
int16_t dig_P6; ///< pressure compensation value
int16_t dig_P7; ///< pressure compensation value
int16_t dig_P8; ///< pressure compensation value
int16_t dig_P9; ///< pressure compensation value
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;
uint8_t dig_H1; ///< humidity compensation value
int16_t dig_H2; ///< humidity compensation value
uint8_t dig_H3; ///< humidity compensation value
int16_t dig_H4; ///< humidity compensation value
int16_t dig_H5; ///< humidity compensation value
int8_t dig_H6; ///< humidity compensation value
} bme280_calib_data;
/*=========================================================================*/
/*
@ -124,177 +126,214 @@ class Adafruit_BME280_Unified : public Adafruit_Sensor
*/
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with BME280 IC
*/
/**************************************************************************/
class Adafruit_BME280 {
public:
enum sensor_sampling {
SAMPLING_NONE = 0b000,
SAMPLING_X1 = 0b001,
SAMPLING_X2 = 0b010,
SAMPLING_X4 = 0b011,
SAMPLING_X8 = 0b100,
SAMPLING_X16 = 0b101
};
public:
/**************************************************************************/
/*!
@brief sampling rates
*/
/**************************************************************************/
enum sensor_sampling {
SAMPLING_NONE = 0b000,
SAMPLING_X1 = 0b001,
SAMPLING_X2 = 0b010,
SAMPLING_X4 = 0b011,
SAMPLING_X8 = 0b100,
SAMPLING_X16 = 0b101
};
enum sensor_mode {
MODE_SLEEP = 0b00,
MODE_FORCED = 0b01,
MODE_NORMAL = 0b11
};
/**************************************************************************/
/*!
@brief power modes
*/
/**************************************************************************/
enum sensor_mode {
MODE_SLEEP = 0b00,
MODE_FORCED = 0b01,
MODE_NORMAL = 0b11
};
enum sensor_filter {
FILTER_OFF = 0b000,
FILTER_X2 = 0b001,
FILTER_X4 = 0b010,
FILTER_X8 = 0b011,
FILTER_X16 = 0b100
};
/**************************************************************************/
/*!
@brief filter values
*/
/**************************************************************************/
enum sensor_filter {
FILTER_OFF = 0b000,
FILTER_X2 = 0b001,
FILTER_X4 = 0b010,
FILTER_X8 = 0b011,
FILTER_X16 = 0b100
};
// standby durations in ms
enum standby_duration {
STANDBY_MS_0_5 = 0b000,
STANDBY_MS_10 = 0b110,
STANDBY_MS_20 = 0b111,
STANDBY_MS_62_5 = 0b001,
STANDBY_MS_125 = 0b010,
STANDBY_MS_250 = 0b011,
STANDBY_MS_500 = 0b100,
STANDBY_MS_1000 = 0b101
};
/**************************************************************************/
/*!
@brief standby duration in ms
*/
/**************************************************************************/
enum standby_duration {
STANDBY_MS_0_5 = 0b000,
STANDBY_MS_10 = 0b110,
STANDBY_MS_20 = 0b111,
STANDBY_MS_62_5 = 0b001,
STANDBY_MS_125 = 0b010,
STANDBY_MS_250 = 0b011,
STANDBY_MS_500 = 0b100,
STANDBY_MS_1000 = 0b101
};
// constructors
Adafruit_BME280(void);
Adafruit_BME280(int8_t cspin);
Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin);
// constructors
Adafruit_BME280();
Adafruit_BME280(int8_t cspin, SPIClass *theSPI = &SPI);
Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin,
int8_t sckpin);
bool begin(void);
bool begin(TwoWire *theWire);
bool begin(uint8_t addr);
bool begin(uint8_t addr, TwoWire *theWire);
bool init();
bool begin();
bool begin(TwoWire *theWire);
bool begin(uint8_t addr);
bool begin(uint8_t addr, TwoWire *theWire);
bool init();
void setSampling(sensor_mode mode = MODE_NORMAL,
sensor_sampling tempSampling = SAMPLING_X16,
sensor_sampling pressSampling = SAMPLING_X16,
sensor_sampling humSampling = SAMPLING_X16,
sensor_filter filter = FILTER_OFF,
standby_duration duration = STANDBY_MS_0_5
);
void setSampling(sensor_mode mode = MODE_NORMAL,
sensor_sampling tempSampling = SAMPLING_X16,
sensor_sampling pressSampling = SAMPLING_X16,
sensor_sampling humSampling = SAMPLING_X16,
sensor_filter filter = FILTER_OFF,
standby_duration duration = STANDBY_MS_0_5);
void takeForcedMeasurement();
float readTemperature(void);
float readPressure(void);
float readHumidity(void);
void takeForcedMeasurement();
float readTemperature(void);
float readPressure(void);
float readHumidity(void);
float readAltitude(float seaLevel);
float seaLevelForAltitude(float altitude, float pressure);
float readAltitude(float seaLevel);
float seaLevelForAltitude(float altitude, float pressure);
uint32_t sensorID(void);
protected:
TwoWire *_wire; //!< pointer to a TwoWire object
SPIClass *_spi; //!< pointer to SPI object
void readCoefficients(void);
bool isReadingCalibration(void);
uint8_t spixfer(uint8_t x);
private:
TwoWire *_wire;
void readCoefficients(void);
bool isReadingCalibration(void);
uint8_t spixfer(uint8_t x);
void write8(byte reg, byte value);
uint8_t read8(byte reg);
uint16_t read16(byte reg);
uint32_t read24(byte reg);
int16_t readS16(byte reg);
uint16_t read16_LE(byte reg); // little endian
int16_t readS16_LE(byte reg); // little endian
void write8(byte reg, byte value);
uint8_t read8(byte reg);
uint16_t read16(byte reg);
uint32_t read24(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; //!< I2C addr for the TwoWire interface
int32_t _sensorID; //!< ID of the BME Sensor
int32_t t_fine; //!< temperature with high resolution, stored as an attribute
//!< as this is used for temperature compensation reading
//!< humidity and pressure
uint8_t _i2caddr;
int32_t _sensorID;
int32_t t_fine;
int8_t _cs; //!< for the SPI interface
int8_t _mosi; //!< for the SPI interface
int8_t _miso; //!< for the SPI interface
int8_t _sck; //!< for the SPI interface
int8_t _cs, _mosi, _miso, _sck;
bme280_calib_data _bme280_calib; //!< here calibration data is stored
bme280_calib_data _bme280_calib;
/**************************************************************************/
/*!
@brief config register
*/
/**************************************************************************/
struct config {
// inactive duration (standby time) in normal mode
// 000 = 0.5 ms
// 001 = 62.5 ms
// 010 = 125 ms
// 011 = 250 ms
// 100 = 500 ms
// 101 = 1000 ms
// 110 = 10 ms
// 111 = 20 ms
unsigned int t_sb : 3; ///< inactive duration (standby time) in normal mode
// The config register
struct config {
// inactive duration (standby time) in normal mode
// 000 = 0.5 ms
// 001 = 62.5 ms
// 010 = 125 ms
// 011 = 250 ms
// 100 = 500 ms
// 101 = 1000 ms
// 110 = 10 ms
// 111 = 20 ms
unsigned int t_sb : 3;
// filter settings
// 000 = filter off
// 001 = 2x filter
// 010 = 4x filter
// 011 = 8x filter
// 100 and above = 16x filter
unsigned int filter : 3; ///< filter settings
// filter settings
// 000 = filter off
// 001 = 2x filter
// 010 = 4x filter
// 011 = 8x filter
// 100 and above = 16x filter
unsigned int filter : 3;
// unused - don't set
unsigned int none : 1; ///< unused - don't set
unsigned int spi3w_en : 1; ///< unused - don't set
// unused - don't set
unsigned int none : 1;
unsigned int spi3w_en : 1;
/// @return combined config register
unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; }
};
config _configReg; //!< config register object
unsigned int get() {
return (t_sb << 5) | (filter << 3) | spi3w_en;
}
};
config _configReg;
/**************************************************************************/
/*!
@brief ctrl_meas register
*/
/**************************************************************************/
struct ctrl_meas {
// temperature oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_t : 3; ///< temperature oversampling
// pressure oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_p : 3; ///< pressure oversampling
// The ctrl_meas register
struct ctrl_meas {
// temperature oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_t : 3;
// device mode
// 00 = sleep
// 01 or 10 = forced
// 11 = normal
unsigned int mode : 2; ///< device mode
// pressure oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_p : 3;
/// @return combined ctrl register
unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; }
};
ctrl_meas _measReg; //!< measurement register object
// device mode
// 00 = sleep
// 01 or 10 = forced
// 11 = normal
unsigned int mode : 2;
/**************************************************************************/
/*!
@brief ctrl_hum register
*/
/**************************************************************************/
struct ctrl_hum {
/// unused - don't set
unsigned int none : 5;
unsigned int get() {
return (osrs_t << 5) | (osrs_p << 3) | mode;
}
};
ctrl_meas _measReg;
// pressure oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_h : 3; ///< pressure oversampling
// The ctrl_hum register
struct ctrl_hum {
// unused - don't set
unsigned int none : 5;
// pressure oversampling
// 000 = skipped
// 001 = x1
// 010 = x2
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_h : 3;
unsigned int get() {
return (osrs_h);
}
};
ctrl_hum _humReg;
/// @return combined ctrl hum register
unsigned int get() { return (osrs_h); }
};
ctrl_hum _humReg; //!< hum register object
};
#endif

View file

@ -0,0 +1,27 @@
Copyright (c) 2015, Limor Fried & Kevin Townsend for Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Adafruit Industries nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,3 +1,7 @@
# Adafruit BME280 Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_BME280_Library.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_BME280_Library)
<a href="http://www.adafruit.com/products/2652"><img src="./assets/board.jpg" width="500"/></a>
This is a library for the Adafruit BME280 Humidity, Barometric Pressure + Temp sensor
Designed specifically to work with the Adafruit BME280 Breakout
@ -25,35 +29,3 @@ You may need to create the libraries subfolder if its your first library. Restar
We also have a great tutorial on Arduino library installation at:
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
<!-- START COMPATIBILITY TABLE -->
## Compatibility
MCU | Tested Works | Doesn't Work | Not Tested | Notes
------------------ | :----------: | :----------: | :---------: | -----
Atmega328 @ 16MHz | X | | |
Atmega328 @ 12MHz | X | | |
Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D2 &amp; D3
Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D2 &amp; D3
ESP8266 | X | | | I2C: just works, SPI: SDA/SCL default to pins 4 &amp; 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL)
ESP32 | X | | | I2C: just works, SPI: SDA/SCL default to pins 4 &amp; 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL)
Atmega2560 @ 16MHz | X | | | Use SDA/SCL on pins 20 &amp; 21
ATSAM3X8E | X | | | Use SDA/SCL on pins 20 &amp; 21
ATSAM21D | X | | |
ATtiny85 @ 16MHz | | X | |
ATtiny85 @ 8MHz | | X | |
Intel Curie @ 32MHz | | | X |
STM32F2 | | | X |
* ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
* ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
* ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
* ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
* ESP8266 : Adafruit Huzzah
* ATmega2560 @ 16MHz : Arduino Mega
* ATSAM3X8E : Arduino Due
* ATSAM21D : Arduino Zero, M0 Pro
* ATtiny85 @ 16MHz : Adafruit Trinket 5V
* ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
<!-- END COMPATIBILITY TABLE -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

View file

@ -13,6 +13,7 @@
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
See the LICENSE file for details.
***************************************************************************/
#include <Wire.h>
@ -37,7 +38,7 @@ void setup() {
Serial.begin(9600);
Serial.println(F("BME280 test"));
if (! bme.begin(&Wire1)) {
if (! bme.begin(&Wire)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
@ -101,6 +102,7 @@ void setup() {
// = 40ms (25Hz)
// with standby time that should really be 24.16913... Hz
delayTime = 41;
*/
/*
// gaming

View file

@ -13,6 +13,7 @@
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
See the LICENSE file for details.
***************************************************************************/
#include <Wire.h>
@ -35,15 +36,21 @@ unsigned long delayTime;
void setup() {
Serial.begin(9600);
while(!Serial); // time to get serial running
Serial.println(F("BME280 test"));
bool status;
unsigned status;
// default settings
// (you can also pass in a Wire library object like &Wire2)
status = bme.begin();
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1);
}

View file

@ -1,5 +1,5 @@
name=Adafruit BME280 Library
version=1.0.7
version=1.0.9
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Arduino library for BME280 sensors.

View file

@ -20,7 +20,9 @@
#ifndef _ADAFRUIT_SENSOR_H
#define _ADAFRUIT_SENSOR_H
#if ARDUINO >= 100
#ifndef ARDUINO
#include <stdint.h>
#elif ARDUINO >= 100
#include "Arduino.h"
#include "Print.h"
#else
@ -72,9 +74,9 @@ typedef struct {
};
/* Orientation sensors */
struct {
float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90°<=roll<=90° */
float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90°<=roll<=90° */
float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180°<=pitch<=180°) */
float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359° */
};
};
int8_t status;
@ -143,7 +145,7 @@ class Adafruit_Sensor {
virtual ~Adafruit_Sensor() {}
// These must be defined by the subclass
/// NOT USED virtual void enableAutoRange(bool enabled) {};
virtual void enableAutoRange(bool enabled) { (void)enabled; /* suppress unused warning */ };
virtual bool getEvent(sensors_event_t*) = 0;
virtual void getSensor(sensor_t*) = 0;

View file

@ -35,7 +35,18 @@ The following drivers are based on the Adafruit Unified Sensor Driver:
- [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
**Humidity & Temperature**
- [Adafruit\_DHT\_Unified](https://github.com/adafruit/Adafruit_DHT_Unified)
- [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library)
**Humidity, Temperature, & Barometric Pressure**
- [Adafruit_BME280_Library](https://github.com/adafruit/Adafruit_BME280_Library/)
**Orientation**
- [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
**All in one device**
- [Adafruit_LSM9DS0](https://github.com/adafruit/Adafruit_LSM9DS0_Library) (accelerometer, gyroscope, magnetometer)
- [Adafruit_LSM9DS1](https://github.com/adafruit/Adafruit_LSM9DS1/) (accelerometer, gyroscope, magnetometer)
## How Does it Work? ##

View file

@ -1,5 +1,5 @@
name=Adafruit Unified Sensor
version=1.0.2
version=1.0.3
author=Adafruit <info@adafruit.com>
maintainer=Adafruit <info@adafruit.com>
sentence=Required for all Adafruit Unified Sensor based libraries.
@ -7,3 +7,4 @@ paragraph=A unified sensor abstraction layer used by many Adafruit sensor librar
category=Sensors
url=https://github.com/adafruit/Adafruit_Sensor
architectures=*
includes=Adafruit_Sensor.h

3
firmware/sensors.ino Executable file → Normal file
View file

@ -31,7 +31,7 @@ float fetchLight() {
return lux * LIGHT_FACTOR;
}
void _anemometerInterrupt() {
ICACHE_RAM_ATTR void _anemometerInterrupt() {
anemometerRotations++;
#ifdef DEBUG
Serial.print("*");
@ -75,4 +75,3 @@ float isBatCharging() {
}
#endif