Tahoma working with dropdown

This commit is contained in:
2025-11-16 09:52:56 +01:00
parent d11f49a43d
commit 4240db93d5
1778 changed files with 839466 additions and 1118 deletions
@@ -0,0 +1,431 @@
/*
BME280.cpp
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include <Wire.h>
#include "BME280.h"
/****************************************************************/
BME280::BME280
(
const Settings& settings
):m_settings(settings),
m_initialized(false)
{
}
/****************************************************************/
bool BME280::Initialize()
{
bool success(true);
success &= ReadChipID();
if(success)
{
success &= ReadTrim();
if(m_settings.filter != Filter_Off)
{
InitializeFilter();
}
WriteSettings();
}
m_initialized = success;
return m_initialized;
}
/****************************************************************/
void BME280::InitializeFilter()
{
// Force an unfiltered measurement to populate the filter buffer.
// This fixes a bug that causes the first read to always be 28.82 °C 81732.34 hPa.
Filter filter = m_settings.filter;
m_settings.filter = Filter_Off;
WriteSettings();
float dummy;
read(dummy, dummy, dummy);
m_settings.filter = filter;
}
/****************************************************************/
bool BME280::ReadChipID()
{
uint8_t id[1];
ReadRegister(ID_ADDR, &id[0], 1);
switch(id[0])
{
case ChipModel_BME280:
m_chip_model = ChipModel_BME280;
break;
case ChipModel_BMP280:
m_chip_model = ChipModel_BMP280;
break;
default:
m_chip_model = ChipModel_UNKNOWN;
return false;
}
return true;
}
/****************************************************************/
void BME280::WriteSettings()
{
uint8_t ctrlHum, ctrlMeas, config;
CalculateRegisters(ctrlHum, ctrlMeas, config);
WriteRegister(CTRL_HUM_ADDR, ctrlHum);
WriteRegister(CTRL_MEAS_ADDR, ctrlMeas);
WriteRegister(CONFIG_ADDR, config);
}
/****************************************************************/
void BME280::setSettings
(
const Settings& settings
)
{
m_settings = settings;
WriteSettings();
}
/****************************************************************/
const BME280::Settings& BME280::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280::begin
(
)
{
bool success = Initialize();
success &= m_initialized;
return success;
}
/****************************************************************/
void BME280::CalculateRegisters
(
uint8_t& ctrlHum,
uint8_t& ctrlMeas,
uint8_t& config
)
{
// ctrl_hum register. (ctrl_hum[2:0] = Humidity oversampling rate.)
ctrlHum = (uint8_t)m_settings.humOSR;
// ctrl_meas register. (ctrl_meas[7:5] = temperature oversampling rate, ctrl_meas[4:2] = pressure oversampling rate, ctrl_meas[1:0] = mode.)
ctrlMeas = ((uint8_t)m_settings.tempOSR << 5) | ((uint8_t)m_settings.presOSR << 2) | (uint8_t)m_settings.mode;
// config register. (config[7:5] = standby time, config[4:2] = filter, ctrl_meas[0] = spi enable.)
config = ((uint8_t)m_settings.standbyTime << 5) | ((uint8_t)m_settings.filter << 2) | (uint8_t)m_settings.spiEnable;
}
/****************************************************************/
bool BME280::ReadTrim()
{
uint8_t ord(0);
bool success = true;
// Temp. Dig
success &= ReadRegister(TEMP_DIG_ADDR, &m_dig[ord], TEMP_DIG_LENGTH);
ord += TEMP_DIG_LENGTH;
// Pressure Dig
success &= ReadRegister(PRESS_DIG_ADDR, &m_dig[ord], PRESS_DIG_LENGTH);
ord += PRESS_DIG_LENGTH;
// Humidity Dig 1
success &= ReadRegister(HUM_DIG_ADDR1, &m_dig[ord], HUM_DIG_ADDR1_LENGTH);
ord += HUM_DIG_ADDR1_LENGTH;
// Humidity Dig 2
success &= ReadRegister(HUM_DIG_ADDR2, &m_dig[ord], HUM_DIG_ADDR2_LENGTH);
ord += HUM_DIG_ADDR2_LENGTH;
#ifdef DEBUG_ON
Serial.print("Dig: ");
for(int i = 0; i < 32; ++i)
{
Serial.print(m_dig[i], HEX);
Serial.print(" ");
}
Serial.println();
#endif
return success && ord == DIG_LENGTH;
}
/****************************************************************/
bool BME280::ReadData
(
int32_t data[SENSOR_DATA_LENGTH]
)
{
bool success;
uint8_t buffer[SENSOR_DATA_LENGTH];
// For forced mode we need to write the mode to BME280 register before reading
if (m_settings.mode == Mode_Forced)
{
WriteSettings();
}
// Registers are in order. So we can start at the pressure register and read 8 bytes.
success = ReadRegister(PRESS_ADDR, buffer, SENSOR_DATA_LENGTH);
for(int i = 0; i < SENSOR_DATA_LENGTH; ++i)
{
data[i] = static_cast<int32_t>(buffer[i]);
}
#ifdef DEBUG_ON
Serial.print("Data: ");
for(int i = 0; i < 8; ++i)
{
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.println();
#endif
return success;
}
/****************************************************************/
float BME280::CalculateTemperature
(
int32_t raw,
int32_t& t_fine,
TempUnit unit
)
{
// Code based on calibration algorthim provided by Bosch.
int32_t var1, var2, final;
uint16_t dig_T1 = (m_dig[1] << 8) | m_dig[0];
int16_t dig_T2 = (m_dig[3] << 8) | m_dig[2];
int16_t dig_T3 = (m_dig[5] << 8) | m_dig[4];
var1 = ((((raw >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((raw >> 4) - ((int32_t)dig_T1)) * ((raw >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
final = (t_fine * 5 + 128) >> 8;
return unit == TempUnit_Celsius ? final/100.0 : final/100.0*9.0/5.0 + 32.0;
}
/****************************************************************/
float BME280::CalculateHumidity
(
int32_t raw,
int32_t t_fine
)
{
// Code based on calibration algorthim provided by Bosch.
int32_t var1;
uint8_t dig_H1 = m_dig[24];
int16_t dig_H2 = (m_dig[26] << 8) | m_dig[25];
uint8_t dig_H3 = m_dig[27];
int16_t dig_H4 = (m_dig[28] << 4) | (0x0F & m_dig[29]);
int16_t dig_H5 = (m_dig[30] << 4) | ((m_dig[29] >> 4) & 0x0F);
int8_t dig_H6 = m_dig[31];
var1 = (t_fine - ((int32_t)76800));
var1 = (((((raw << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * var1)) +
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)dig_H6)) >> 10) * (((var1 *
((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)dig_H2) + 8192) >> 14));
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
var1 = (var1 < 0 ? 0 : var1);
var1 = (var1 > 419430400 ? 419430400 : var1);
return ((uint32_t)(var1 >> 12))/1024.0;
}
/****************************************************************/
float BME280::CalculatePressure
(
int32_t raw,
int32_t t_fine,
PresUnit unit
)
{
// Code based on calibration algorthim provided by Bosch.
int64_t var1, var2, pressure;
float final;
uint16_t dig_P1 = (m_dig[7] << 8) | m_dig[6];
int16_t dig_P2 = (m_dig[9] << 8) | m_dig[8];
int16_t dig_P3 = (m_dig[11] << 8) | m_dig[10];
int16_t dig_P4 = (m_dig[13] << 8) | m_dig[12];
int16_t dig_P5 = (m_dig[15] << 8) | m_dig[14];
int16_t dig_P6 = (m_dig[17] << 8) | m_dig[16];
int16_t dig_P7 = (m_dig[19] << 8) | m_dig[18];
int16_t dig_P8 = (m_dig[21] << 8) | m_dig[20];
int16_t dig_P9 = (m_dig[23] << 8) | m_dig[22];
var1 = (int64_t)t_fine - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0) { return NAN; } // Don't divide by zero.
pressure = 1048576 - raw;
pressure = (((pressure << 31) - var2) * 3125)/var1;
var1 = (((int64_t)dig_P9) * (pressure >> 13) * (pressure >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * pressure) >> 19;
pressure = ((pressure + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
final = ((uint32_t)pressure)/256.0;
// Conversion units courtesy of www.endmemo.com.
switch(unit){
case PresUnit_hPa: /* hPa */
final /= 100.0;
break;
case PresUnit_inHg: /* inHg */
final /= 3386.3752577878; /* final pa * 1inHg/3386.3752577878Pa */
break;
case PresUnit_atm: /* atm */
final /= 101324.99766353; /* final pa * 1 atm/101324.99766353Pa */
break;
case PresUnit_bar: /* bar */
final /= 100000.0; /* final pa * 1 bar/100kPa */
break;
case PresUnit_torr: /* torr */
final /= 133.32236534674; /* final pa * 1 torr/133.32236534674Pa */
break;
case PresUnit_psi: /* psi */
final /= 6894.744825494; /* final pa * 1psi/6894.744825494Pa */
break;
default: /* Pa (case: 0) */
break;
}
return final;
}
/****************************************************************/
float BME280::temp
(
TempUnit unit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
return CalculateTemperature(rawTemp, t_fine, unit);
}
/****************************************************************/
float BME280::pres
(
PresUnit unit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
CalculateTemperature(rawTemp, t_fine);
return CalculatePressure(rawPressure, t_fine, unit);
}
/****************************************************************/
float BME280::hum()
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawHumidity = (data[6] << 8) | data[7];
CalculateTemperature(rawTemp, t_fine);
return CalculateHumidity(rawHumidity, t_fine);
}
/****************************************************************/
void BME280::read
(
float& pressure,
float& temp,
float& humidity,
TempUnit tempUnit,
PresUnit presUnit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){
pressure = temp = humidity = NAN;
return;
}
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawHumidity = (data[6] << 8) | data[7];
temp = CalculateTemperature(rawTemp, t_fine, tempUnit);
pressure = CalculatePressure(rawPressure, t_fine, presUnit);
humidity = CalculateHumidity(rawHumidity, t_fine);
}
/****************************************************************/
BME280::ChipModel BME280::chipModel
(
)
{
return m_chip_model;
}
@@ -0,0 +1,344 @@
/*
BME280.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
*/
#ifndef TG_BME_280_H
#define TG_BME_280_H
#include "Arduino.h"
//////////////////////////////////////////////////////////////////
/// BME280 - Driver class for Bosch Bme280 sensor
///
/// Based on the data sheet provided by Bosch for
/// the Bme280 environmental sensor.
///
class BME280
{
public:
/*****************************************************************/
/* ENUMERATIONS */
/*****************************************************************/
enum TempUnit
{
TempUnit_Celsius,
TempUnit_Fahrenheit
};
enum PresUnit
{
PresUnit_Pa,
PresUnit_hPa,
PresUnit_inHg,
PresUnit_atm,
PresUnit_bar,
PresUnit_torr,
PresUnit_psi
};
enum OSR
{
OSR_Off = 0,
OSR_X1 = 1,
OSR_X2 = 2,
OSR_X4 = 3,
OSR_X8 = 4,
OSR_X16 = 5
};
enum Mode
{
Mode_Sleep = 0,
Mode_Forced = 1,
Mode_Normal = 3
};
enum StandbyTime
{
StandbyTime_500us = 0,
StandbyTime_62500us = 1,
StandbyTime_125ms = 2,
StandbyTime_250ms = 3,
StandbyTime_50ms = 4,
StandbyTime_1000ms = 5,
StandbyTime_10ms = 6,
StandbyTime_20ms = 7
};
enum Filter
{
Filter_Off = 0,
Filter_2 = 1,
Filter_4 = 2,
Filter_8 = 3,
Filter_16 = 4
};
enum SpiEnable
{
SpiEnable_False = 0,
SpiEnable_True = 1
};
enum ChipModel
{
ChipModel_UNKNOWN = 0,
ChipModel_BMP280 = 0x58,
ChipModel_BME280 = 0x60
};
/*****************************************************************/
/* STRUCTURES */
/*****************************************************************/
struct Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): tempOSR(_tosr),
humOSR(_hosr),
presOSR(_posr),
mode(_mode),
standbyTime(_st),
filter(_filter),
spiEnable(_se) {}
OSR tempOSR;
OSR humOSR;
OSR presOSR;
Mode mode;
StandbyTime standbyTime;
Filter filter;
SpiEnable spiEnable;
};
/*****************************************************************/
/* INIT FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Constructor used to create the class.
/// All parameters have default values.
BME280(
const Settings& settings);
/////////////////////////////////////////////////////////////////
/// Method used to initialize the class.
bool begin();
/*****************************************************************/
/* ENVIRONMENTAL FUNCTIONS */
/*****************************************************************/
//////////////////////////////////////////////////
/// Read the temperature from the BME280 and return a float.
float temp(
TempUnit unit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Read the pressure from the BME280 and return a float with the
/// specified unit.
float pres(
PresUnit unit = PresUnit_hPa);
/////////////////////////////////////////////////////////////////
/// Read the humidity from the BME280 and return a percentage
/// as a float.
float hum();
/////////////////////////////////////////////////////////////////
/// Read the data from the BME280 in the specified unit.
void read(
float& pressure,
float& temperature,
float& humidity,
TempUnit tempUnit = TempUnit_Celsius,
PresUnit presUnit = PresUnit_hPa);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
////////////////////////////////////////////////////////////////
/// Method used to return ChipModel.
ChipModel chipModel();
protected:
/*****************************************************************/
/* CONSTRUCTOR INIT FUNCTIONS */
/*****************************************************************/
///////////////////////////////////////////////////////////////
/// Write configuration to BME280, return true if successful.
/// Must be called from any child classes.
virtual bool Initialize();
///////////////////////////////////////////////////////////////
/// Force a unfiltered measurement to populate the filter
/// buffer.
void InitializeFilter();
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
virtual const Settings& getSettings() const;
private:
/*****************************************************************/
/* CONSTANTS */
/*****************************************************************/
static const uint8_t CTRL_HUM_ADDR = 0xF2;
static const uint8_t CTRL_MEAS_ADDR = 0xF4;
static const uint8_t CONFIG_ADDR = 0xF5;
static const uint8_t PRESS_ADDR = 0xF7;
static const uint8_t TEMP_ADDR = 0xFA;
static const uint8_t HUM_ADDR = 0xFD;
static const uint8_t TEMP_DIG_ADDR = 0x88;
static const uint8_t PRESS_DIG_ADDR = 0x8E;
static const uint8_t HUM_DIG_ADDR1 = 0xA1;
static const uint8_t HUM_DIG_ADDR2 = 0xE1;
static const uint8_t ID_ADDR = 0xD0;
static const uint8_t TEMP_DIG_LENGTH = 6;
static const uint8_t PRESS_DIG_LENGTH = 18;
static const uint8_t HUM_DIG_ADDR1_LENGTH = 1;
static const uint8_t HUM_DIG_ADDR2_LENGTH = 7;
static const uint8_t DIG_LENGTH = 32;
static const uint8_t SENSOR_DATA_LENGTH = 8;
/*****************************************************************/
/* VARIABLES */
/*****************************************************************/
Settings m_settings;
uint8_t m_dig[32];
ChipModel m_chip_model;
bool m_initialized;
/*****************************************************************/
/* ABSTRACT FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data)=0;
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length)=0;
/*****************************************************************/
/* WORKER FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Calculates registers based on settings.
void CalculateRegisters(
uint8_t& ctrlHum,
uint8_t& ctrlMeas,
uint8_t& config);
/////////////////////////////////////////////////////////////////
/// Write the settings to the chip.
void WriteSettings();
/////////////////////////////////////////////////////////////////
/// Read the the chip id data from the BME280, return true if
/// successful and the id matches a known value.
bool ReadChipID();
/////////////////////////////////////////////////////////////////
/// Read the the trim data from the BME280, return true if
/// successful.
bool ReadTrim();
/////////////////////////////////////////////////////////////////
/// Read the raw data from the BME280 into an array and return
/// true if successful.
bool ReadData(
int32_t data[8]);
/////////////////////////////////////////////////////////////////
/// Calculate the temperature from the BME280 raw data and
/// BME280 trim, return a float.
float CalculateTemperature(
int32_t raw,
int32_t& t_fine,
TempUnit unit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the humidity from the BME280 raw data and BME280
/// trim, return a float.
float CalculateHumidity(
int32_t raw,
int32_t t_fine);
/////////////////////////////////////////////////////////////////
/// Calculate the pressure from the BME280 raw data and BME280
/// trim, return a float.
float CalculatePressure(
int32_t raw,
int32_t t_fine,
PresUnit unit = PresUnit_hPa);
};
#endif // TG_BME_280_H
@@ -0,0 +1,102 @@
/*
BME280I2CI2C.cpp
This code records data from the BME280I2C sensor and provides an API.
This file is part of the Arduino BME280I2C library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Jan 1 2016. - Happy New year!
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280I2C environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include <Wire.h>
#include "BME280I2C.h"
/****************************************************************/
BME280I2C::BME280I2C
(
const Settings& settings
):BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
void BME280I2C::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280I2C::Settings& BME280I2C::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280I2C::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
Wire.beginTransmission(m_settings.bme280Addr);
Wire.write(addr);
Wire.write(data);
Wire.endTransmission();
return true; // TODO: Check return values from wire calls.
}
/****************************************************************/
bool BME280I2C::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
uint8_t ord(0);
Wire.beginTransmission(m_settings.bme280Addr);
Wire.write(addr);
Wire.endTransmission();
Wire.requestFrom(static_cast<uint8_t>(m_settings.bme280Addr), length);
while(Wire.available())
{
data[ord++] = Wire.read();
}
return ord == length;
}
@@ -0,0 +1,105 @@
/*
BME280I2C.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Sep 19 2016.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_I2C_H
#define TG_BME_280_I2C_H
#include "BME280.h"
//////////////////////////////////////////////////////////////////
/// BME280I2C - I2C Implementation of BME280.
class BME280I2C: public BME280
{
public:
enum I2CAddr
{
I2CAddr_0x76 = 0x76,
I2CAddr_0x77 = 0x77
};
struct Settings : public BME280::Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_16,
SpiEnable _se = SpiEnable_False,
I2CAddr _addr = I2CAddr_0x76
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
bme280Addr(_addr) {}
I2CAddr bme280Addr;
};
///////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280I2C(
const Settings& settings = Settings());
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
private:
Settings m_settings;
//////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
};
#endif // TG_BME_280_I2C_H
@@ -0,0 +1,97 @@
/*
BME280I2C_BRZO.cpp
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
Forked by Alex Shavlovsky
to support https://github.com/pasko-zh/brzo_i2c library on ESP8266.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280I2C_BRZO environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "BME280I2C_BRZO.h"
#ifdef USING_BRZO
#include "brzo_i2c.h"
/****************************************************************/
BME280I2C_BRZO::BME280I2C_BRZO
(
const Settings& settings
):BME280I2C(settings),
m_settings(settings)
{
}
/****************************************************************/
void BME280I2C_BRZO::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280I2C_BRZO::Settings& BME280I2C_BRZO::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280I2C_BRZO::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
uint8_t bf[2];
bf[0] = addr;
bf[1] = data;
brzo_i2c_start_transaction(m_settings.bme280Addr, m_settings.i2cClockRate);
brzo_i2c_write(bf, 2, false);
return (brzo_i2c_end_transaction()==0);
}
/****************************************************************/
bool BME280I2C_BRZO::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
brzo_i2c_start_transaction(m_settings.bme280Addr, m_settings.i2cClockRate);
brzo_i2c_write(&addr, 1, true);
brzo_i2c_read(data, length, false);
brzo_i2c_end_transaction();
return (brzo_i2c_end_transaction()==0);
}
#endif
@@ -0,0 +1,101 @@
/*
BME280I2C_BRZO.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
Forked by Alex Shavlovsky
to support https://github.com/pasko-zh/brzo_i2c library on ESP8266.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Sep 19 2016.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef BME280I2C_BRZO_H
#define BME280I2C_BRZO_H
#include "BME280I2C.h"
//////////////////////////////////////////////////////////////////
/// BME280I2C_BRZO - I2C Implementation of BME280.
class BME280I2C_BRZO : public BME280I2C
{
public:
struct Settings : public BME280I2C::Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False,
uint16_t _cr = 400
): BME280I2C::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
i2cClockRate(_cr) {}
uint16_t i2cClockRate;
};
///////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280I2C_BRZO(
const Settings& settings = Settings());
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
private:
Settings m_settings;
//////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
};
#endif // BME280I2C_BRZO_H
@@ -0,0 +1,134 @@
/*
BME280Spi.cpp
This code records data from the BME280Spi sensor and provides an API.
This file is part of the Arduino BME280Spi library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280Spi environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "Arduino.h"
#include "BME280Spi.h"
#include <SPI.h>
/****************************************************************/
BME280Spi::BME280Spi
(
const Settings& settings
)
:BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
bool BME280Spi::Initialize()
{
pinMode(m_settings.spiCsPin, OUTPUT);
digitalWrite(m_settings.spiCsPin, HIGH);
return BME280::Initialize();
}
/****************************************************************/
void BME280Spi::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280Spi::Settings& BME280Spi::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280Spi::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t len
)
{
SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE0));
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t readAddr = addr | BME280_SPI_READ;
//select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr
SPI.transfer(readAddr);
// read the data
for(int i = 0; i < len; ++i)
{
// transfer 0x00 to get the data
data[i] = SPI.transfer(0);
}
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
SPI.endTransaction();
return true;
}
/****************************************************************/
bool BME280Spi::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE0));
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t writeAddr = addr & ~0x80;
// select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr and then the data to spi device
SPI.transfer(writeAddr);
SPI.transfer(data);
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
SPI.endTransaction();
return true;
}
@@ -0,0 +1,104 @@
/*
BME280Spi.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_SPI_H
#define TG_BME_280_SPI_H
#include "BME280.h"
class BME280Spi: public BME280
{
public:
struct Settings : public BME280::Settings
{
Settings(
uint8_t _cspin,
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
spiCsPin(_cspin) {}
uint8_t spiCsPin;
};
////////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280Spi(
const Settings& settings);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
////////////////////////////////////////////////////////////////
/// Method used at start up to initialize the class. Starts the
/// I2C interface.
virtual bool Initialize();
private:
static const uint8_t BME280_SPI_WRITE = 0x7F;
static const uint8_t BME280_SPI_READ = 0x80;
Settings m_settings;
////////////////////////////////////////////////////////////////
/// Read the data from the BME280 addr into an array and
/// return true if successful.
virtual bool ReadRegister(
uint8_t addr,
uint8_t array[],
uint8_t len);
////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
};
#endif // TG_BME_280_SPI_H
@@ -0,0 +1,152 @@
/*
BME280SpiSw.cpp
This code records data from the BME280SpiSw sensor and provides an API.
This file is part of the Arduino BME280SpiSw library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Dec 18 2016. - Happy Holidays!
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280SpiSw environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "Arduino.h"
#include "BME280SpiSw.h"
/****************************************************************/
BME280SpiSw::BME280SpiSw
(
const Settings& settings
)
:BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
bool BME280SpiSw::Initialize(){
digitalWrite(m_settings.spiCsPin, HIGH);
pinMode(m_settings.spiCsPin, OUTPUT);
pinMode(m_settings.spiSckPin, OUTPUT);
pinMode(m_settings.spiMosiPin, OUTPUT);
pinMode(m_settings.spiMisoPin, INPUT);
return BME280::Initialize();
}
/****************************************************************/
void BME280SpiSw::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280SpiSw::Settings& BME280SpiSw::getSettings() const
{
return m_settings;
}
/****************************************************************/
uint8_t BME280SpiSw::SpiTransferSw
(
uint8_t data
)
{
uint8_t resp = 0;
for (int bit = 7; bit >= 0; --bit) {
resp <<= 1;
digitalWrite(m_settings.spiSckPin, LOW);
digitalWrite(m_settings.spiMosiPin, data & (1 << bit));
digitalWrite(m_settings.spiSckPin, HIGH);
resp |= digitalRead(m_settings.spiMisoPin);
}
return resp;
}
/****************************************************************/
bool BME280SpiSw::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t readAddr = addr | BME280_SPI_READ;
//select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr
SpiTransferSw(readAddr);
// read the data
for(int i = 0; i < length; ++i)
{
// transfer 0x00 to get the data
data[i] = SpiTransferSw(0);
}
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
return true;
}
/****************************************************************/
bool BME280SpiSw::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t writeAddr = addr & ~0x80;
// select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr and then the data to spi device
SpiTransferSw(writeAddr);
SpiTransferSw(data);
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
return true;
}
@@ -0,0 +1,115 @@
/*
BME280SpiSw.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_SPI_H
#define TG_BME_280_SPI_H
#include "BME280.h"
class BME280SpiSw: public BME280{
public:
struct Settings : public BME280::Settings
{
Settings(
uint8_t _cs,
uint8_t _mosi,
uint8_t _miso,
uint8_t _sck,
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
spiCsPin(_cs),
spiMosiPin(_mosi),
spiMisoPin(_miso),
spiSckPin(_sck) {}
uint8_t spiCsPin;
uint8_t spiMosiPin;
uint8_t spiMisoPin;
uint8_t spiSckPin;
};
////////////////////////////////////////////////////////////////
/// Constructor for software spi
BME280SpiSw(
const Settings& settings);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
////////////////////////////////////////////////////////////////
/// Method used at start up to initialize the class. Starts the
/// software SPI interface.
virtual bool Initialize();
private:
static const uint8_t BME280_SPI_WRITE = 0x7F;
static const uint8_t BME280_SPI_READ = 0x80;
Settings m_settings;
////////////////////////////////////////////////////////////////
/// Does a sw spi transfer.
uint8_t SpiTransferSw(
uint8_t data);
////////////////////////////////////////////////////////////////
/// Read the data from the BME280 addr into an array and return
/// true if successful.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
};
#endif // TG_BME_280_SPI_H
@@ -0,0 +1,217 @@
/*
EnvironmentCalculations.cpp
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Dec 23 2017.
This header must be included in any derived code or copies of the code.
*/
#include "EnvironmentCalculations.h"
#include <Arduino.h>
#include <math.h>
#define hi_coeff1 -42.379
#define hi_coeff2 2.04901523
#define hi_coeff3 10.14333127
#define hi_coeff4 -0.22475541
#define hi_coeff5 -0.00683783
#define hi_coeff6 -0.05481717
#define hi_coeff7 0.00122874
#define hi_coeff8 0.00085282
#define hi_coeff9 -0.00000199
/****************************************************************/
float EnvironmentCalculations::Altitude
(
float pressure,
AltitudeUnit altUnit,
float referencePressure,
float outdoorTemp,
TempUnit tempUnit
)
{
// Equation inverse to EquivalentSeaLevelPressure calculation.
float altitude = NAN;
if (!isnan(pressure) && !isnan(referencePressure) && !isnan(outdoorTemp))
{
if(tempUnit != TempUnit_Celsius)
outdoorTemp = (outdoorTemp - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
altitude = pow(referencePressure / pressure, 0.190234) - 1;
altitude *= ((outdoorTemp + 273.15) / 0.0065);
if(altUnit != AltitudeUnit_Meters) altitude *= 3.28084;
}
return altitude;
}
/****************************************************************/
float EnvironmentCalculations::AbsoluteHumidity
(
float temperature,
float humidity,
TempUnit tempUnit
)
{
//taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
//precision is about 0.1°C in range -30 to 35°C
//August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04)
//Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97)
//reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html
float temp = NAN;
const float mw = 18.01534; // molar mass of water g/mol
const float r = 8.31447215; // Universal gas constant J/mol/K
if (isnan(temperature) || isnan(humidity) )
{
return NAN;
}
if(tempUnit != TempUnit_Celsius)
{
temperature = (temperature - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
}
temp = pow(2.718281828, (17.67 * temperature) / (temperature + 243.5));
//return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version
return (6.112 * temp * humidity * mw) / ((273.15 + temperature) * r); //long version
}
/****************************************************************/
//FYI: https://ehp.niehs.nih.gov/1206273/ in detail this flow graph: https://ehp.niehs.nih.gov/wp-content/uploads/2013/10/ehp.1206273.g003.png
float EnvironmentCalculations::HeatIndex
(
float temperature,
float humidity,
TempUnit tempUnit
)
{
float heatIndex(NAN);
if ( isnan(temperature) || isnan(humidity) )
{
return heatIndex;
}
if (tempUnit == TempUnit_Celsius)
{
temperature = (temperature * (9.0 / 5.0) + 32.0); /*conversion to [°F]*/
}
// Using both Rothfusz and Steadman's equations
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
if (temperature <= 40)
{
heatIndex = temperature; //first red block
}
else
{
heatIndex = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (humidity * 0.094)); //calculate A -- from the official site, not the flow graph
if (heatIndex >= 79)
{
/*
* calculate B
* the following calculation is optimized. Simply spoken, reduzed cpu-operations to minimize used ram and runtime.
* Check the correctness with the following link:
* http://www.wolframalpha.com/input/?source=nav&i=b%3D+x1+%2B+x2*T+%2B+x3*H+%2B+x4*T*H+%2B+x5*T*T+%2B+x6*H*H+%2B+x7*T*T*H+%2B+x8*T*H*H+%2B+x9*T*T*H*H
*/
heatIndex = hi_coeff1
+ (hi_coeff2 + hi_coeff4 * humidity + temperature * (hi_coeff5 + hi_coeff7 * humidity)) * temperature
+ (hi_coeff3 + humidity * (hi_coeff6 + temperature * (hi_coeff8 + hi_coeff9 * temperature))) * humidity;
//third red block
if ((humidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
{
heatIndex -= ((13.0 - humidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
} //fourth red block
else if ((humidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
{
heatIndex += (0.02 * (humidity - 85.0) * (87.0 - temperature));
}
}
}
if (tempUnit == TempUnit_Celsius)
{
return (heatIndex - 32.0) * (5.0 / 9.0); /*conversion back to [°C]*/
}
else
{
return heatIndex; //fifth red block
}
}
/****************************************************************/
float EnvironmentCalculations::EquivalentSeaLevelPressure
(
float altitude,
float temp,
float pres,
AltitudeUnit altUnit,
TempUnit tempUnit
)
{
float seaPress = NAN;
if(!isnan(altitude) && !isnan(temp) && !isnan(pres))
{
if(tempUnit != TempUnit_Celsius)
temp = (temp - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
if(altUnit != AltitudeUnit_Meters)
altitude *= 0.3048; /*conversion to meters*/
seaPress = (pres / pow(1 - ((0.0065 *altitude) / (temp + (0.0065 *altitude) + 273.15)), 5.257));
}
return seaPress;
}
/****************************************************************/
float EnvironmentCalculations::DewPoint
(
float temp,
float hum,
TempUnit tempUnit
)
{
// Equations courtesy of Brian McNoldy from http://andrew.rsmas.miami.edu;
float dewPoint = NAN;
if(!isnan(temp) && !isnan(hum))
{
if (tempUnit == TempUnit_Celsius)
{
dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * temp)/(243.04 + temp)))
/(17.625 - log(hum/100.0) - ((17.625 * temp)/(243.04 + temp)));
}
else
{
float ctemp = (temp - 32.0) * 5.0/9.0;
dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * ctemp)/(243.04 + ctemp)))
/(17.625 - log(hum/100.0) - ((17.625 * ctemp)/(243.04 + ctemp)));
dewPoint = dewPoint * 9.0/5.0 + 32.0;
}
}
return dewPoint;
}
@@ -0,0 +1,129 @@
/*
EnvironmentCalculations.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Oct 7 2017.
Last Updated: Dec 11 2017.
This code is licensed under the GNU LGPL and is open for distrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
*/
#ifndef TG_ENVIRONMENT_CALCULATIONS_H
#define TG_ENVIRONMENT_CALCULATIONS_H
namespace EnvironmentCalculations
{
/////////////////////////////////////////////////////////////////
/// Temperature unit enumeration.
enum TempUnit
{
TempUnit_Celsius,
TempUnit_Fahrenheit
};
/////////////////////////////////////////////////////////////////
/// Altitude unit enumeration.
enum AltitudeUnit
{
AltitudeUnit_Meters,
AltitudeUnit_Feet
};
/////////////////////////////////////////////////////////////////
/// Calculate the altitude based on the pressure and temperature
/// in temptUnit.
/// @param pressure at the station in any units.
/// @param altUnit meters or feet. default=AltitudeUnit_Meters
/// @param referencePressure (usually pressure on MSL)
/// in the same units as pressure. default=1013.25hPa (ISA)
/// @param outdoorTemp temperature at the station in tempUnit
/// default=15°C (ISA)
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
/// @return Calculated Altitude in altUnit.
float Altitude(
float pressure,
AltitudeUnit altUnit = AltitudeUnit_Meters,
float referencePressure = 1013.25, // [hPa] ....ISA value
float outdoorTemp = 15, // [°C] .... ISA value
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the heatindex based on the humidity and temperature
/// in tempUnit.
/// The formula based on the Heat Index Equation of the US National Weather Service
/// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
/// @param temperature in tempUnit
/// @param humidity in percentage
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
/// @return Calculated heatindex as float in TempUnit
float HeatIndex(
float temperature,
float humidity,
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the absolute humidity based on the relative humidity and temperature
/// in tempUnit.
/// the formula does work for values between -30°C and 35°C with 0.1°C precision
/// @param temperature in tempUnit
/// @param humidity in percentage
/// @param tempUnit in °C. default=TempUnit_Celsius
/// @return Calculated absolute humidity in grams/m³
float AbsoluteHumidity
(
float temperature,
float humidity,
TempUnit tempUnit
);
/////////////////////////////////////////////////////////////////
/// Convert current pressure to equivalent sea-level pressure.
/// @param altitude in altUnit.
/// @param temp in tempUnit.
/// @param pressure at the station in any units.
/// @param altUnit meters or feet. default=AltitudeUnit_Meters
/// @param tempUnit in °C or °F. default=TempUnit_Celsius
/// @return Equivalent pressure at sea level. The input pressure
/// unit will determine the output
/// pressure unit.
float EquivalentSeaLevelPressure(
float altitude,
float temp,
float pres,
AltitudeUnit altUnit = AltitudeUnit_Meters,
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the dew point based on the temperature in tempUnit
/// and humidity.
/// @param temp in tempUnit.
/// @param hum in %.
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
float DewPoint(
float temp,
float hum,
TempUnit tempUnit = TempUnit_Celsius);
}
#endif // TG_ENVIRONMENT_CALCULATIONS_H