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,94 +1,96 @@
/**************************************************************************/
/*!
@file Adafruit_APDS9960.cpp
@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.cpp
*
* @mainpage Adafruit APDS9960 Proximity, Light, RGB, and Gesture Sensor
*
* @section author Author
*
* Ladyada, Dean Miller (Adafruit Industries)
*
* @section license 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.
*/
#ifdef __AVR
#include <avr/pgmspace.h>
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#include <pgmspace.h>
#endif
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include "Adafruit_APDS9960.h"
/*========================================================================*/
/* PRIVATE FUNCTIONS */
/*========================================================================*/
/**************************************************************************/
/*!
@brief Implements missing powf function
*/
/**************************************************************************/
float powf(const float x, const float y)
{
* @brief Implements missing powf function
* @param x
* Base number
* @param y
* Exponent
* @return x raised to the power of y
*/
float powf(const float x, const float y) {
return (float)(pow((double)x, (double)y));
}
/**************************************************************************/
/*!
Enables the device
Disables the device (putting it in lower power sleep mode)
*/
/**************************************************************************/
void Adafruit_APDS9960::enable(boolean en)
{
* @brief Enables the device
* Disables the device (putting it in lower power sleep mode)
* @param en
* Enable (True/False)
*/
void Adafruit_APDS9960::enable(boolean en) {
_enable.PON = en;
this->write8(APDS9960_ENABLE, _enable.get());
}
/*========================================================================*/
/* PUBLIC FUNCTIONS */
/*========================================================================*/
/**************************************************************************/
/*!
Initializes I2C and configures the sensor (call this function before
doing anything else)
*/
/**************************************************************************/
boolean Adafruit_APDS9960::begin(uint16_t iTimeMS, apds9960AGain_t aGain, uint8_t addr)
{
* @brief Initializes I2C and configures the sensor
* @param iTimeMS
* Integration time
* @param aGain
* Gain
* @param addr
* I2C address
* @param *theWire
* Wire object
* @return True if initialization was successful, otherwise false.
*/
boolean Adafruit_APDS9960::begin(uint16_t iTimeMS, apds9960AGain_t aGain,
uint8_t addr, TwoWire *theWire) {
_wire = theWire;
_i2c_init();
_i2caddr = addr;
/* Make sure we're actually connected */
uint8_t x = read8(APDS9960_ID);
if (x != 0xAB)
{
if (x != 0xAB) {
return false;
}
@ -111,7 +113,7 @@ boolean Adafruit_APDS9960::begin(uint16_t iTimeMS, apds9960AGain_t aGain, uint8_
enable(true);
delay(10);
//default to all gesture dimensions
// default to all gesture dimensions
setGestureDimensions(APDS9960_DIMENSIONS_ALL);
setGestureFIFOThreshold(APDS9960_GFIFO_4);
setGestureGain(APDS9960_GGAIN_4);
@ -119,34 +121,38 @@ boolean Adafruit_APDS9960::begin(uint16_t iTimeMS, apds9960AGain_t aGain, uint8_
resetCounts();
_gpulse.GPLEN = APDS9960_GPULSE_32US;
_gpulse.GPULSE = 9; //10 pulses
_gpulse.GPULSE = 9; // 10 pulses
this->write8(APDS9960_GPULSE, _gpulse.get());
return true;
}
/**************************************************************************/
/*!
Sets the integration time for the ADC of the APDS9960, in millis
*/
/**************************************************************************/
void Adafruit_APDS9960::setADCIntegrationTime(uint16_t iTimeMS)
{
* @brief Sets the integration time for the ADC of the APDS9960, in millis
* @param iTimeMS
* Integration time
*/
void Adafruit_APDS9960::setADCIntegrationTime(uint16_t iTimeMS) {
float temp;
// convert ms into 2.78ms increments
temp = iTimeMS;
temp /= 2.78;
temp = 256 - temp;
if (temp > 255) temp = 255;
if (temp < 0) temp = 0;
if (temp > 255)
temp = 255;
if (temp < 0)
temp = 0;
/* Update the timing register */
write8(APDS9960_ATIME, (uint8_t)temp);
}
float Adafruit_APDS9960::getADCIntegrationTime(void)
{
/*!
* @brief Returns the integration time for the ADC of the APDS9960, in millis
* @return Integration time
*/
float Adafruit_APDS9960::getADCIntegrationTime() {
float temp;
temp = read8(APDS9960_ATIME);
@ -157,46 +163,59 @@ float Adafruit_APDS9960::getADCIntegrationTime(void)
return temp;
}
/**************************************************************************/
/*!
Adjusts the color/ALS gain on the APDS9960 (adjusts the sensitivity to light)
*/
/**************************************************************************/
void Adafruit_APDS9960::setADCGain(apds9960AGain_t aGain)
{
* @brief Adjusts the color/ALS gain on the APDS9960 (adjusts the sensitivity
* to light)
* @param aGain
* Gain
*/
void Adafruit_APDS9960::setADCGain(apds9960AGain_t aGain) {
_control.AGAIN = aGain;
/* Update the timing register */
write8(APDS9960_CONTROL, _control.get());
}
apds9960AGain_t Adafruit_APDS9960::getADCGain(void)
{
return (apds9960AGain_t) ( read8(APDS9960_CONTROL) & 0x03 );
/*!
* @brief Returns the ADC gain
* @return ADC gain
*/
apds9960AGain_t Adafruit_APDS9960::getADCGain() {
return (apds9960AGain_t)(read8(APDS9960_CONTROL) & 0x03);
}
/**************************************************************************/
/*!
Adjusts the Proximity gain on the APDS9960
*/
/**************************************************************************/
void Adafruit_APDS9960::setProxGain(apds9960PGain_t pGain)
{
* @brief Adjusts the Proximity gain on the APDS9960
* @param pGain
* Gain
*/
void Adafruit_APDS9960::setProxGain(apds9960PGain_t pGain) {
_control.PGAIN = pGain;
/* Update the timing register */
write8(APDS9960_CONTROL, _control.get());
}
apds9960PGain_t Adafruit_APDS9960::getProxGain(void)
{
return (apds9960PGain_t) ( read8(APDS9960_CONTROL) & 0x0C );
/*!
* @brief Returns the Proximity gain on the APDS9960
* @return Proxmity gain
*/
apds9960PGain_t Adafruit_APDS9960::getProxGain() {
return (apds9960PGain_t)(read8(APDS9960_CONTROL) & 0x0C);
}
/*!
* @brief Sets number of proxmity pulses
* @param pLen
* Pulse Length
* @param pulses
* Number of pulses
*/
void Adafruit_APDS9960::setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses) {
if (pulses < 1) pulses = 1;
if (pulses > 64) pulses = 64;
if (pulses < 1)
pulses = 1;
if (pulses > 64)
pulses = 64;
pulses--;
_ppulse.PPLEN = pLen;
@ -205,100 +224,148 @@ void Adafruit_APDS9960::setProxPulse(apds9960PPulseLen_t pLen, uint8_t pulses) {
write8(APDS9960_PPULSE, _ppulse.get());
}
/**************************************************************************/
/*!
Enable proximity readings on APDS9960
*/
/**************************************************************************/
void Adafruit_APDS9960::enableProximity(boolean en)
{
* @brief Enable proximity readings on APDS9960
* @param en
* Enable (True/False)
*/
void Adafruit_APDS9960::enableProximity(boolean en) {
_enable.PEN = en;
write8(APDS9960_ENABLE, _enable.get());
}
/*!
* @brief Enable proximity interrupts
*/
void Adafruit_APDS9960::enableProximityInterrupt() {
_enable.PIEN = 1;
write8(APDS9960_ENABLE, _enable.get());
clearInterrupt();
}
/*!
* @brief Disable proximity interrupts
*/
void Adafruit_APDS9960::disableProximityInterrupt() {
_enable.PIEN = 0;
write8(APDS9960_ENABLE, _enable.get());
}
void Adafruit_APDS9960::setProximityInterruptThreshold(uint8_t low, uint8_t high, uint8_t persistance){
/*!
* @brief Set proxmity interrupt thresholds
* @param low
* Low threshold
* @param high
* High threshold
* @param persistance
* Persistance
*/
void Adafruit_APDS9960::setProximityInterruptThreshold(uint8_t low,
uint8_t high,
uint8_t persistance) {
write8(APDS9960_PILT, low);
write8(APDS9960_PIHT, high);
if (persistance > 7) persistance = 7;
if (persistance > 7)
persistance = 7;
_pers.PPERS = persistance;
write8(APDS9960_PERS,_pers.get());
write8(APDS9960_PERS, _pers.get());
}
bool Adafruit_APDS9960::getProximityInterrupt()
{
/*!
* @brief Returns proxmity interrupt status
* @return True if enabled, false otherwise.
*/
bool Adafruit_APDS9960::getProximityInterrupt() {
_status.set(this->read8(APDS9960_STATUS));
return _status.PINT;
};
/**************************************************************************/
/*!
Read proximity data
*/
/**************************************************************************/
uint8_t Adafruit_APDS9960::readProximity(void)
{
return read8(APDS9960_PDATA);
}
* @brief Read proximity data
* @return Proximity
*/
uint8_t Adafruit_APDS9960::readProximity() { return read8(APDS9960_PDATA); }
bool Adafruit_APDS9960::gestureValid()
{
/*!
* @brief Returns validity status of a gesture
* @return Status (True/False)
*/
bool Adafruit_APDS9960::gestureValid() {
_gstatus.set(this->read8(APDS9960_GSTATUS));
return _gstatus.GVALID;
}
void Adafruit_APDS9960::setGestureDimensions(uint8_t dims)
{
/*!
* @brief Sets gesture dimensions
* @param dims
* Dimensions (APDS9960_DIMENSIONS_ALL, APDS9960_DIMENSIONS_UP_DOWM,
* APDS9960_DIMENSIONS_UP_DOWN, APGS9960_DIMENSIONS_LEFT_RIGHT)
*/
void Adafruit_APDS9960::setGestureDimensions(uint8_t dims) {
_gconf3.GDIMS = dims;
this->write8(APDS9960_GCONF3, _gconf3.get());
}
void Adafruit_APDS9960::setGestureFIFOThreshold(uint8_t thresh)
{
/*!
* @brief Sets gesture FIFO Threshold
* @param thresh
* Threshold (APDS9960_GFIFO_1, APDS9960_GFIFO_4, APDS9960_GFIFO_8,
* APDS9960_GFIFO_16)
*/
void Adafruit_APDS9960::setGestureFIFOThreshold(uint8_t thresh) {
_gconf1.GFIFOTH = thresh;
this->write8(APDS9960_GCONF1, _gconf1.get());
}
void Adafruit_APDS9960::setGestureGain(uint8_t gain)
{
/*!
* @brief Sets gesture sensor gain
* @param gain
* Gain (APDS9960_GAIN_1, APDS9960_GAIN_2, APDS9960_GAIN_4,
* APDS9960_GAIN_8)
*/
void Adafruit_APDS9960::setGestureGain(uint8_t gain) {
_gconf2.GGAIN = gain;
this->write8(APDS9960_GCONF2, _gconf2.get());
}
void Adafruit_APDS9960::setGestureProximityThreshold(uint8_t thresh)
{
/*!
* @brief Sets gesture sensor threshold
* @param thresh
* Threshold
*/
void Adafruit_APDS9960::setGestureProximityThreshold(uint8_t thresh) {
this->write8(APDS9960_GPENTH, thresh);
}
void Adafruit_APDS9960::setGestureOffset(uint8_t offset_up, uint8_t offset_down, uint8_t offset_left, uint8_t offset_right)
{
/*!
* @brief Sets gesture sensor offset
* @param offset_up
* Up offset
* @param offset_down
* Down offset
* @param offset_left
* Left offset
* @param offset_right
* Right offset
*/
void Adafruit_APDS9960::setGestureOffset(uint8_t offset_up, uint8_t offset_down,
uint8_t offset_left,
uint8_t offset_right) {
this->write8(APDS9960_GOFFSET_U, offset_up);
this->write8(APDS9960_GOFFSET_D, offset_down);
this->write8(APDS9960_GOFFSET_L, offset_left);
this->write8(APDS9960_GOFFSET_R, offset_right);
}
/**************************************************************************/
/*!
Enable gesture readings on APDS9960
*/
/**************************************************************************/
void Adafruit_APDS9960::enableGesture(boolean en)
{
if(!en){
* @brief Enable gesture readings on APDS9960
* @param en
* Enable (True/False)
*/
void Adafruit_APDS9960::enableGesture(boolean en) {
if (!en) {
_gconf4.GMODE = 0;
write8(APDS9960_GCONF4, _gconf4.get());
}
@ -307,8 +374,10 @@ void Adafruit_APDS9960::enableGesture(boolean en)
resetCounts();
}
void Adafruit_APDS9960::resetCounts()
{
/*!
* @brief Resets gesture counts
*/
void Adafruit_APDS9960::resetCounts() {
gestCnt = 0;
UCount = 0;
DCount = 0;
@ -316,74 +385,82 @@ void Adafruit_APDS9960::resetCounts()
RCount = 0;
}
uint8_t Adafruit_APDS9960::readGesture(void)
{
/*!
* @brief Reads gesture
* @return Received gesture (APDS9960_DOWN APDS9960_UP, APDS9960_LEFT
* APDS9960_RIGHT)
*/
uint8_t Adafruit_APDS9960::readGesture() {
uint8_t toRead, bytesRead;
uint8_t buf[256];
unsigned long t;
unsigned long t = 0;
uint8_t gestureReceived;
while(1){
while (1) {
int up_down_diff = 0;
int left_right_diff = 0;
gestureReceived = 0;
if(!gestureValid()) return 0;
if (!gestureValid())
return 0;
delay(30);
toRead = this->read8(APDS9960_GFLVL);
// bytesRead is unused but produces sideffects needed for readGesture to work
bytesRead = this->read(APDS9960_GFIFO_U, buf, toRead);
if(abs((int)buf[0] - (int)buf[1]) > 13)
if (abs((int)buf[0] - (int)buf[1]) > 13)
up_down_diff += (int)buf[0] - (int)buf[1];
if(abs((int)buf[2] - (int)buf[3]) > 13)
if (abs((int)buf[2] - (int)buf[3]) > 13)
left_right_diff += (int)buf[2] - (int)buf[3];
if(up_down_diff != 0){
if(up_down_diff < 0){
if( DCount > 0){
if (up_down_diff != 0) {
if (up_down_diff < 0) {
if (DCount > 0) {
gestureReceived = APDS9960_UP;
}
else UCount++;
}
else if(up_down_diff > 0){
if( UCount > 0){
} else
UCount++;
} else if (up_down_diff > 0) {
if (UCount > 0) {
gestureReceived = APDS9960_DOWN;
}
else DCount++;
} else
DCount++;
}
}
if(left_right_diff != 0){
if(left_right_diff < 0){
if( RCount > 0){
if (left_right_diff != 0) {
if (left_right_diff < 0) {
if (RCount > 0) {
gestureReceived = APDS9960_LEFT;
}
else LCount++;
}
else if(left_right_diff > 0){
if( LCount > 0){
} else
LCount++;
} else if (left_right_diff > 0) {
if (LCount > 0) {
gestureReceived = APDS9960_RIGHT;
}
else RCount++;
} else
RCount++;
}
}
if(up_down_diff != 0 || left_right_diff != 0) t = millis();
if (up_down_diff != 0 || left_right_diff != 0)
t = millis();
if(gestureReceived || millis() - t > 300){
if (gestureReceived || millis() - t > 300) {
resetCounts();
return gestureReceived;
}
}
}
/**************************************************************************/
/*!
Set LED brightness for proximity/gesture
*/
/**************************************************************************/
void Adafruit_APDS9960::setLED(apds9960LedDrive_t drive, apds9960LedBoost_t boost) {
* @brief Set LED brightness for proximity/gesture
* @param drive
* LED Drive
* @param boost
* LED Boost
*/
void Adafruit_APDS9960::setLED(apds9960LedDrive_t drive,
apds9960LedBoost_t boost) {
// set BOOST
_config2.LED_BOOST = boost;
write8(APDS9960_CONFIG2, _config2.get());
@ -392,46 +469,57 @@ void Adafruit_APDS9960::setLED(apds9960LedDrive_t drive, apds9960LedBoost_t boos
write8(APDS9960_CONTROL, _control.get());
}
/**************************************************************************/
/*!
Enable proximity readings on APDS9960
*/
/**************************************************************************/
void Adafruit_APDS9960::enableColor(boolean en)
{
* @brief Enable proximity readings on APDS9960
* @param en
* Enable (True/False)
*/
void Adafruit_APDS9960::enableColor(boolean en) {
_enable.AEN = en;
write8(APDS9960_ENABLE, _enable.get());
}
bool Adafruit_APDS9960::colorDataReady()
{
/*!
* @brief Returns status of color data
* @return True if color data ready, False otherwise
*/
bool Adafruit_APDS9960::colorDataReady() {
_status.set(this->read8(APDS9960_STATUS));
return _status.AVALID;
}
/**************************************************************************/
/*!
@brief Reads the raw red, green, blue and clear channel values
*/
/**************************************************************************/
void Adafruit_APDS9960::getColorData (uint16_t *r, uint16_t *g, uint16_t *b, uint16_t *c)
{
* @brief Reads the raw red, green, blue and clear channel values
* @param *r
* Red value
* @param *g
* Green value
* @param *b
* Blue value
* @param *c
* Clear channel value
*/
void Adafruit_APDS9960::getColorData(uint16_t *r, uint16_t *g, uint16_t *b,
uint16_t *c) {
*c = read16R(APDS9960_CDATAL);
*r = read16R(APDS9960_RDATAL);
*g = read16R(APDS9960_GDATAL);
*b = read16R(APDS9960_BDATAL);
}
/**************************************************************************/
/*!
@brief Converts the raw R/G/B values to color temperature in degrees
Kelvin
*/
/**************************************************************************/
uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g, uint16_t b)
{
* @brief Converts the raw R/G/B values to color temperature in degrees Kelvin
* @param r
* Red value
* @param g
* Green value
* @param b
* Blue value
* @return Color temperature
*/
uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g,
uint16_t b) {
float X, Y, Z; /* RGB to XYZ correlation */
float xc, yc; /* Chromaticity co-ordinates */
float n; /* McCamy's formula */
@ -443,7 +531,7 @@ uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g, ui
/* Note: Y = Illuminance or lux */
X = (-0.14282F * r) + (1.54924F * g) + (-0.95641F * b);
Y = (-0.32466F * r) + (1.57837F * g) + (-0.73191F * b);
Z = (-0.68202F * r) + (0.77073F * g) + ( 0.56332F * b);
Z = (-0.68202F * r) + (0.77073F * g) + (0.56332F * b);
/* 2. Calculate the chromaticity co-ordinates */
xc = (X) / (X + Y + Z);
@ -453,20 +541,24 @@ uint16_t Adafruit_APDS9960::calculateColorTemperature(uint16_t r, uint16_t g, ui
n = (xc - 0.3320F) / (0.1858F - yc);
/* Calculate the final CCT */
cct = (449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
cct =
(449.0F * powf(n, 3)) + (3525.0F * powf(n, 2)) + (6823.3F * n) + 5520.33F;
/* Return the results in degrees Kelvin */
return (uint16_t)cct;
}
/**************************************************************************/
/*!
@brief Calculate ambient light values
*/
/**************************************************************************/
uint16_t Adafruit_APDS9960::calculateLux(uint16_t r, uint16_t g, uint16_t b)
{
* @brief Calculate ambient light values
* @param r
* Red value
* @param g
* Green value
* @param b
* Blue value
* @return LUX value
*/
uint16_t Adafruit_APDS9960::calculateLux(uint16_t r, uint16_t g, uint16_t b) {
float illuminance;
/* This only uses RGB ... how can we integrate clear or calculate lux */
@ -476,21 +568,36 @@ uint16_t Adafruit_APDS9960::calculateLux(uint16_t r, uint16_t g, uint16_t b)
return (uint16_t)illuminance;
}
/*!
* @brief Enables color interrupt
*/
void Adafruit_APDS9960::enableColorInterrupt() {
_enable.AIEN = 1;
write8(APDS9960_ENABLE, _enable.get());
}
/*!
* @brief Disables color interrupt
*/
void Adafruit_APDS9960::disableColorInterrupt() {
_enable.AIEN = 0;
write8(APDS9960_ENABLE, _enable.get());
}
void Adafruit_APDS9960::clearInterrupt(void) {
/*!
* @brief Clears interrupt
*/
void Adafruit_APDS9960::clearInterrupt() {
this->write(APDS9960_AICLEAR, NULL, 0);
}
/*!
* @brief Sets interrupt limits
* @param low
* Low limit
* @param high
* High limit
*/
void Adafruit_APDS9960::setIntLimits(uint16_t low, uint16_t high) {
write8(APDS9960_AILTIL, low & 0xFF);
write8(APDS9960_AILTH, low >> 8);
@ -498,80 +605,122 @@ void Adafruit_APDS9960::setIntLimits(uint16_t low, uint16_t high) {
write8(APDS9960_AIHTH, high >> 8);
}
void Adafruit_APDS9960::write8(byte reg, byte value)
{
/*!
* @brief Writes specified value to given register
* @param reg
* Register to write to
* @param value
* Value to write
*/
void Adafruit_APDS9960::write8(byte reg, byte value) {
this->write(reg, &value, 1);
}
uint8_t Adafruit_APDS9960::read8(byte reg)
{
/*!
* @brief Reads 8 bits from specified register
* @param reg
* Register to write to
* @return Value in register
*/
uint8_t Adafruit_APDS9960::read8(byte reg) {
uint8_t ret;
this->read(reg, &ret, 1);
return ret;
}
uint32_t Adafruit_APDS9960::read32(uint8_t reg)
{
/*!
* @brief Reads 32 bits from specified register
* @param reg
* Register to write to
* @return Value in register
*/
uint32_t Adafruit_APDS9960::read32(uint8_t reg) {
uint8_t ret[4];
this->read(reg, ret, 4);
return (ret[0] << 24) | (ret[1] << 16) | (ret[2] << 8) | ret[3];
}
uint16_t Adafruit_APDS9960::read16(uint8_t reg)
{
/*!
* @brief Reads 16 bites from specified register
* @param reg
* Register to write to
* @return Value in register
*/
uint16_t Adafruit_APDS9960::read16(uint8_t reg) {
uint8_t ret[2];
this->read(reg, ret, 2);
return (ret[0] << 8) | ret[1];
}
uint16_t Adafruit_APDS9960::read16R(uint8_t reg)
{
/*!
* @brief Reads 16 bites from specified register
* @param reg
* Register to write to
* @return Value in register
*/
uint16_t Adafruit_APDS9960::read16R(uint8_t reg) {
uint8_t ret[2];
this->read(reg, ret, 2);
return (ret[1] << 8) | ret[0];
}
void Adafruit_APDS9960::_i2c_init()
{
Wire.begin();
}
/*!
* @brief Begins I2C communication
*/
void Adafruit_APDS9960::_i2c_init() { _wire->begin(); }
uint8_t Adafruit_APDS9960::read(uint8_t reg, uint8_t *buf, uint8_t num)
{
uint8_t value;
/*!
* @brief Reads num bytes from specified register into a given buffer
* @param reg
* Register
* @param *buf
* Buffer
* @param num
* Number of bytes
* @return Position after reading
*/
uint8_t Adafruit_APDS9960::read(uint8_t reg, uint8_t *buf, uint8_t num) {
uint8_t pos = 0;
bool eof = false;
//on arduino we need to read in 32 byte chunks
while(pos < num && !eof){
// on arduino we need to read in 32 byte chunks
while (pos < num && !eof) {
uint8_t read_now = min(32, num - pos);
Wire.beginTransmission((uint8_t)_i2caddr);
Wire.write((uint8_t)reg + pos);
Wire.endTransmission();
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg + pos);
_wire->endTransmission();
Wire.requestFrom((uint8_t)_i2caddr, read_now);
_wire->requestFrom((uint8_t)_i2caddr, read_now);
for(int i=0; i<read_now; i++){
if(!Wire.available()){
for (int i = 0; i < read_now; i++) {
if (!_wire->available()) {
eof = true;
break;
}
buf[pos] = Wire.read();
buf[pos] = _wire->read();
pos++;
}
}
return pos;
}
void Adafruit_APDS9960::write(uint8_t reg, uint8_t *buf, uint8_t num)
{
Wire.beginTransmission((uint8_t)_i2caddr);
Wire.write((uint8_t)reg);
Wire.write((uint8_t *)buf, num);
Wire.endTransmission();
/*!
* @brief Writes num bytes from specified buffer into a given register
* @param reg
* Register
* @param *buf
* Buffer
* @param num
* Number of bytes
*/
void Adafruit_APDS9960::write(uint8_t reg, uint8_t *buf, uint8_t num) {
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->write((uint8_t *)buf, num);
_wire->endTransmission();
}

View file

@ -1,58 +1,43 @@
/**************************************************************************/
/*!
@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
{
/** I2C Registers */
enum {
APDS9960_RAM = 0x00,
APDS9960_ENABLE = 0x80,
APDS9960_ATIME = 0x81,
@ -103,119 +88,111 @@
APDS9960_GFIFO_D = 0xFD,
APDS9960_GFIFO_L = 0xFE,
APDS9960_GFIFO_R = 0xFF,
};
};
/*=========================================================================*/
typedef enum
{
/** 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;
} apds9960AGain_t;
typedef enum
{
/** 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;
} apds9960PGain_t;
typedef enum
{
/** 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;
} apds9960PPulseLen_t;
typedef enum
{
/** 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;
} apds9960LedDrive_t;
typedef enum
{
/** 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;
} apds9960LedBoost_t;
enum
{
APDS9960_DIMENSIONS_ALL = 0x00,
APDS9960_DIMENSIONS_UP_DOWM = 0x01,
APGS9960_DIMENSIONS_LEFT_RIGHT = 0x02,
/** 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_GFIFO_1 = 0x00,
APDS9960_GFIFO_4 = 0x01,
APDS9960_GFIFO_8 = 0x02,
APDS9960_GFIFO_16 = 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_GGAIN_1 = 0x00,
APDS9960_GGAIN_2 = 0x01,
APDS9960_GGAIN_4 = 0x02,
APDS9960_GGAIN_8 = 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
};
enum
{
APDS9960_GPULSE_4US = 0x00,
APDS9960_GPULSE_8US = 0x01,
APDS9960_GPULSE_16US = 0x02,
APDS9960_GPULSE_32US = 0x03,
/** 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_TIME_MULT 2.78 //millisec
#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);
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);
float getADCIntegrationTime();
void setADCGain(apds9960AGain_t gain);
apds9960AGain_t getADCGain(void);
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);
apds9960PGain_t getProxGain();
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);
uint8_t readProximity();
void setProximityInterruptThreshold(uint8_t low, uint8_t high,
uint8_t persistance = 4);
bool getProximityInterrupt();
// gesture
@ -225,8 +202,9 @@ class Adafruit_APDS9960 {
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 setGestureOffset(uint8_t offset_up, uint8_t offset_down,
uint8_t offset_left, uint8_t offset_right);
uint8_t readGesture();
void resetCounts();
// light & color
@ -237,15 +215,15 @@ class Adafruit_APDS9960 {
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);
private:
private:
uint8_t _i2caddr;
TwoWire *_wire;
uint32_t read32(uint8_t reg);
uint16_t read16(uint8_t reg);
@ -268,142 +246,141 @@ class Adafruit_APDS9960 {
struct enable {
//power on
// power on
uint8_t PON : 1;
//ALS enable
// ALS enable
uint8_t AEN : 1;
//Proximity detect enable
// Proximity detect enable
uint8_t PEN : 1;
//wait timer enable
// wait timer enable
uint8_t WEN : 1;
//ALS interrupt enable
// ALS interrupt enable
uint8_t AIEN : 1;
//proximity interrupt enable
// proximity interrupt enable
uint8_t PIEN : 1;
//gesture enable
// gesture enable
uint8_t GEN : 1;
uint8_t get() {
return (GEN << 6) | (PIEN << 5) | (AIEN << 4) | (WEN << 3) | (PEN << 2) | (AEN << 1) | PON;
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
// 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
// proximity interrupt persistence, controls rate of prox interrupt to host
// processor
uint8_t PPERS : 4;
uint8_t get(){
return (PPERS << 4) | APERS;
};
uint8_t get() { return (PPERS << 4) | APERS; };
};
pers _pers;
struct config1 {
uint8_t WLONG : 1;
uint8_t get(){
return WLONG << 1;
};
uint8_t get() { return WLONG << 1; };
};
config1 _config1;
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.
/*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.
// 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;
}
uint8_t get() { return (PPLEN << 6) | PPULSE; }
};
ppulse _ppulse;
struct control {
//ALS and Color gain control
// ALS and Color gain control
uint8_t AGAIN : 2;
//proximity gain control
// proximity gain control
uint8_t PGAIN : 2;
//led drive strength
// led drive strength
uint8_t LDRIVE : 2;
uint8_t get(){
return (LDRIVE << 6) | (PGAIN << 2) | AGAIN;
}
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.
/* 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
// clear photodiode saturation int enable
uint8_t CPSIEN : 1;
//proximity saturation interrupt enable
// proximity saturation interrupt enable
uint8_t PSIEN : 1;
uint8_t get(){
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.
/* 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.
/* 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).
/* 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.
// 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.
// 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.
/* 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.
/* 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){
void set(uint8_t data) {
AVALID = data & 0x01;
PVALID = (data >> 1) & 0x01;
GINT = (data >> 2) & 0x01;
@ -416,118 +393,115 @@ class Adafruit_APDS9960 {
status _status;
struct config3 {
//proximity mask
// 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.
/* 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.
/* 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;
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.
/* 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.
/* 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).
/* 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;
}
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.
/* 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.
// 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.
// 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;
}
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.
/* 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.
// 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;
}
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.
/* Gesture Dimension Select. Selects which gesture photodiode pairs are
enabled to gather results during gesture.
*/
uint8_t GDIMS : 2;
uint8_t get(){
return GDIMS;
}
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).
/* 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.
/* 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){
uint8_t get() { return (GIEN << 1) | GMODE; }
void set(uint8_t data) {
GIEN = (data >> 1) & 0x01;
GMODE = data & 0x01;
}
@ -535,24 +509,23 @@ class Adafruit_APDS9960 {
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).
/* 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.
/* 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){
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,85 +1,131 @@
/***************************************************************************
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)
{
* @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;
}
/*!
* @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)
{
/*!
* @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(uint8_t addr, TwoWire *theWire)
{
/*!
* @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::begin(void)
{
/*!
* @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;
return init();
status = init();
if (!status) {
_i2caddr = BME280_ADDRESS_ALTERNATE;
status = init();
}
return status;
}
bool Adafruit_BME280::init()
{
/*!
* @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();
_wire->begin();
} else {
digitalWrite(_cs, HIGH);
pinMode(_cs, OUTPUT);
if (_sck == -1) {
// hardware SPI
SPI.begin();
_spi->begin();
} else {
// software SPI
pinMode(_sck, OUTPUT);
@ -89,7 +135,8 @@ bool Adafruit_BME280::init()
}
// check if sensor, i.e. the chip ID is correct
if (read8(BME280_REGISTER_CHIPID) != 0x60)
_sensorID = read8(BME280_REGISTER_CHIPID);
if (_sensorID != 0x60)
return false;
// reset the device using soft-reset
@ -112,16 +159,18 @@ bool Adafruit_BME280::init()
return true;
}
/**************************************************************************/
/*!
@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.
*/
/**************************************************************************/
* @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,
@ -132,36 +181,35 @@ void Adafruit_BME280::setSampling(sensor_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)
// 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);
return _spi->transfer(x);
// software SPI
uint8_t reply = 0;
for (int i=7; i>=0; i--) {
for (int i = 7; i >= 0; i--) {
reply <<= 1;
digitalWrite(_sck, LOW);
digitalWrite(_mosi, x & (1<<i));
digitalWrite(_mosi, x & (1 << i));
digitalWrite(_sck, HIGH);
if (digitalRead(_miso))
reply |= 1;
@ -169,145 +217,132 @@ uint8_t Adafruit_BME280::spixfer(uint8_t x) {
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();
_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));
_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
_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;
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();
_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));
_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
_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)
{
* @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();
_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));
_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
_spi->endTransaction(); // release the SPI bus
}
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);
}
/**************************************************************************/
/*!
@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); }
/**************************************************************************/
/*!
*/
/**************************************************************************/
int16_t Adafruit_BME280::readS16_LE(byte 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
*/
/**************************************************************************/
uint32_t Adafruit_BME280::read24(byte 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;
if (_cs == -1) {
_wire -> beginTransmission((uint8_t)_i2caddr);
_wire -> write((uint8_t)reg);
_wire -> endTransmission();
_wire -> requestFrom((uint8_t)_i2caddr, (byte)3);
_wire->beginTransmission((uint8_t)_i2caddr);
_wire->write((uint8_t)reg);
_wire->endTransmission();
_wire->requestFrom((uint8_t)_i2caddr, (byte)3);
value = _wire -> read();
value = _wire->read();
value <<= 8;
value |= _wire -> read();
value |= _wire->read();
value <<= 8;
value |= _wire -> read();
value |= _wire->read();
} else {
if (_sck == -1)
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
_spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
digitalWrite(_cs, LOW);
spixfer(reg | 0x80); // read, bit 7 high
@ -319,20 +354,16 @@ uint32_t Adafruit_BME280::read24(byte reg)
digitalWrite(_cs, HIGH);
if (_sck == -1)
SPI.endTransaction(); // release the SPI bus
_spi->endTransaction(); // release the SPI bus
}
return value;
}
/**************************************************************************/
/*!
@brief Take a new measurement (only possible in forced mode)
*/
/**************************************************************************/
void Adafruit_BME280::takeForcedMeasurement()
{
* @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.
@ -347,14 +378,10 @@ void Adafruit_BME280::takeForcedMeasurement()
}
}
/**************************************************************************/
/*!
@brief Reads the factory-set coefficients
*/
/**************************************************************************/
void Adafruit_BME280::readCoefficients(void)
{
* @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);
@ -372,31 +399,28 @@ void Adafruit_BME280::readCoefficients(void)
_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_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)
{
* @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);
@ -404,25 +428,26 @@ float Adafruit_BME280::readTemperature(void)
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;
float T = (t_fine * 5 + 128) >> 8;
return T/100;
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;
@ -435,30 +460,29 @@ float Adafruit_BME280::readPressure(void) {
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;
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;
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
@ -471,32 +495,35 @@ float Adafruit_BME280::readHumidity(void) {
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) *
(((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 * ((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));
((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);
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).
@param seaLevel Sea-level pressure in hPa
@param atmospheric Atmospheric pressure in hPa
*/
/**************************************************************************/
float Adafruit_BME280::readAltitude(float seaLevel)
{
* 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
@ -508,17 +535,14 @@ float Adafruit_BME280::readAltitude(float seaLevel)
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)
{
* 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
@ -526,5 +550,11 @@ float Adafruit_BME280::seaLevelForAltitude(float altitude, float atmospheric)
// 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,42 +1,45 @@
/***************************************************************************
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
{
/*!
* @brief Register addresses
*/
enum {
BME280_REGISTER_DIG_T1 = 0x88,
BME280_REGISTER_DIG_T2 = 0x8A,
BME280_REGISTER_DIG_T3 = 0x8C,
@ -71,36 +74,35 @@
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,8 +126,18 @@ class Adafruit_BME280_Unified : public Adafruit_Sensor
*/
/**************************************************************************/
/*!
@brief Class that stores state and functions for interacting with BME280 IC
*/
/**************************************************************************/
class Adafruit_BME280 {
public:
public:
/**************************************************************************/
/*!
@brief sampling rates
*/
/**************************************************************************/
enum sensor_sampling {
SAMPLING_NONE = 0b000,
SAMPLING_X1 = 0b001,
@ -135,12 +147,22 @@ class Adafruit_BME280 {
SAMPLING_X16 = 0b101
};
/**************************************************************************/
/*!
@brief power modes
*/
/**************************************************************************/
enum sensor_mode {
MODE_SLEEP = 0b00,
MODE_FORCED = 0b01,
MODE_NORMAL = 0b11
};
/**************************************************************************/
/*!
@brief filter values
*/
/**************************************************************************/
enum sensor_filter {
FILTER_OFF = 0b000,
FILTER_X2 = 0b001,
@ -149,7 +171,11 @@ class Adafruit_BME280 {
FILTER_X16 = 0b100
};
// standby durations in ms
/**************************************************************************/
/*!
@brief standby duration in ms
*/
/**************************************************************************/
enum standby_duration {
STANDBY_MS_0_5 = 0b000,
STANDBY_MS_10 = 0b110,
@ -162,11 +188,12 @@ class Adafruit_BME280 {
};
// constructors
Adafruit_BME280(void);
Adafruit_BME280(int8_t cspin);
Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin);
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();
bool begin(TwoWire *theWire);
bool begin(uint8_t addr);
bool begin(uint8_t addr, TwoWire *theWire);
@ -177,8 +204,7 @@ class Adafruit_BME280 {
sensor_sampling pressSampling = SAMPLING_X16,
sensor_sampling humSampling = SAMPLING_X16,
sensor_filter filter = FILTER_OFF,
standby_duration duration = STANDBY_MS_0_5
);
standby_duration duration = STANDBY_MS_0_5);
void takeForcedMeasurement();
float readTemperature(void);
@ -187,10 +213,11 @@ class Adafruit_BME280 {
float readAltitude(float seaLevel);
float seaLevelForAltitude(float altitude, float pressure);
uint32_t sensorID(void);
private:
TwoWire *_wire;
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);
@ -203,15 +230,24 @@ class Adafruit_BME280 {
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;
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
int8_t _cs, _mosi, _miso, _sck;
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
bme280_calib_data _bme280_calib;
bme280_calib_data _bme280_calib; //!< here calibration data is stored
// The config register
/**************************************************************************/
/*!
@brief config register
*/
/**************************************************************************/
struct config {
// inactive duration (standby time) in normal mode
// 000 = 0.5 ms
@ -222,7 +258,7 @@ class Adafruit_BME280 {
// 101 = 1000 ms
// 110 = 10 ms
// 111 = 20 ms
unsigned int t_sb : 3;
unsigned int t_sb : 3; ///< inactive duration (standby time) in normal mode
// filter settings
// 000 = filter off
@ -230,20 +266,22 @@ class Adafruit_BME280 {
// 010 = 4x filter
// 011 = 8x filter
// 100 and above = 16x filter
unsigned int filter : 3;
unsigned int filter : 3; ///< filter settings
// unused - don't set
unsigned int none : 1;
unsigned int spi3w_en : 1;
unsigned int none : 1; ///< unused - don't set
unsigned int spi3w_en : 1; ///< unused - don't set
unsigned int get() {
return (t_sb << 5) | (filter << 3) | spi3w_en;
}
/// @return combined config register
unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; }
};
config _configReg;
config _configReg; //!< config register object
// The ctrl_meas register
/**************************************************************************/
/*!
@brief ctrl_meas register
*/
/**************************************************************************/
struct ctrl_meas {
// temperature oversampling
// 000 = skipped
@ -252,7 +290,7 @@ class Adafruit_BME280 {
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_t : 3;
unsigned int osrs_t : 3; ///< temperature oversampling
// pressure oversampling
// 000 = skipped
@ -261,24 +299,26 @@ class Adafruit_BME280 {
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_p : 3;
unsigned int osrs_p : 3; ///< pressure oversampling
// device mode
// 00 = sleep
// 01 or 10 = forced
// 11 = normal
unsigned int mode : 2;
unsigned int mode : 2; ///< device mode
unsigned int get() {
return (osrs_t << 5) | (osrs_p << 3) | mode;
}
/// @return combined ctrl register
unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; }
};
ctrl_meas _measReg;
ctrl_meas _measReg; //!< measurement register object
// The ctrl_hum register
/**************************************************************************/
/*!
@brief ctrl_hum register
*/
/**************************************************************************/
struct ctrl_hum {
// unused - don't set
/// unused - don't set
unsigned int none : 5;
// pressure oversampling
@ -288,13 +328,12 @@ class Adafruit_BME280 {
// 011 = x4
// 100 = x8
// 101 and above = x16
unsigned int osrs_h : 3;
unsigned int osrs_h : 3; ///< pressure oversampling
unsigned int get() {
return (osrs_h);
}
/// @return combined ctrl hum register
unsigned int get() { return (osrs_h); }
};
ctrl_hum _humReg;
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