Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 3:96075bee19f0, committed 2016-04-22
- Comitter:
- loopsva
- Date:
- Fri Apr 22 14:25:55 2016 +0000
- Parent:
- 1:d8d62aee6d5b
- Commit message:
- Trying again to delete VEML60xx remenants
Changed in this revision
diff -r d8d62aee6d5b -r 96075bee19f0 bme280.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bme280.cpp Fri Apr 22 14:25:55 2016 +0000
@@ -0,0 +1,425 @@
+// Borch BME280 Barometer, Humidity and Temperature sensor IC
+
+#include "bme280.h"
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Constructor, to allow for user to select i2c address based on CSB pin
+
+bme280::bme280(PinName sda, PinName scl, CSBpolarity CSBpin) : _i2c(sda, scl) {
+ _i2c.frequency(400000);
+ i2cWAddr = BME280_WADDR;
+ i2cRAddr = BME280_RADDR;
+ if(CSBpin == CSBpin_1) {
+ i2cWAddr++;
+ i2cWAddr++;
+ i2cRAddr++;
+ i2cRAddr++;
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// deconstructor
+
+bme280::~bme280() {
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// I2C start. Returns "ack" from slave
+
+int bme280::_i2c_start(uint8_t i2c_addr) {
+ int ack;
+ _i2c.start();
+ ack = _i2c_write(i2c_addr);
+ return(ack);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// I2C stop
+
+void bme280::_i2c_stop() {
+ _i2c.stop();
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// I2C write a byte. Returns "ack" from slave
+
+uint8_t bme280::_i2c_write(uint8_t data) {
+ int ack = _i2c.write(data);
+ return(ack);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// I2C read byte and sending ACK. Returns data byte.
+
+uint8_t bme280::_i2c_readACK() {
+ uint8_t rdata = _i2c.read(1);
+ return(rdata);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// I2C read byte and sending NACK. Returns data byte.
+
+uint8_t bme280::_i2c_readNACK() {
+ uint8_t rdata = _i2c.read(0);
+ return(rdata);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Get BME280 ID register
+
+uint8_t bme280::getBmeID() {
+#if defined BMEi2cLOWLEVEL
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CHIP_ID_REG);
+ _i2c_start(i2cRAddr);
+ uint8_t rdata = _i2c_readNACK();
+ _i2c_stop();
+ return(rdata);
+#else
+ bme280Buffer[0] = BME280_CHIP_ID_REG;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 1, false);
+ uint8_t rdata = bme280Buffer[0];
+ return(bme280Buffer[0]);
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Soft reset the chip
+
+uint8_t bme280::resetBme() {
+#if defined BMEi2cLOWLEVEL
+ uint8_t rdata = _i2c_start(i2cWAddr);
+ if(rdata) return(rdata);
+ _i2c_write(BME280_RST_REG);
+ _i2c_write(BME280_RESET_VALUE);
+ _i2c_stop();
+#else
+ bme280Buffer[0] = BME280_RST_REG;
+ bme280Buffer[1] = BME280_RESET_VALUE;
+ uint8_t rdata = _i2c.write(i2cWAddr, bme280Buffer, 2, false);
+#endif
+ return(rdata);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Get BME280 status register. Returns register value
+
+uint8_t bme280::getBmeStatus() {
+#if defined BMEi2cLOWLEVEL
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_STAT_REG);
+ _i2c_start(i2cRAddr);
+ uint8_t rdata = _i2c_readNACK();
+ _i2c_stop();
+ return(rdata);
+#else
+ bme280Buffer[0] = BME280_STAT_REG;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 1, false);
+ return(bme280Buffer[0]);
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Get BME280 PTH values. Saves raw data is data structure. Returns 0 if successful, !0 if status was busy - pass thru from getBmeStatus();
+
+uint8_t bme280::getBmeRawData(bme_data& bmed) {
+ uint8_t rdata = getBmeStatus();
+ if(rdata) return(rdata);
+ bmed.raw_hum = 0;
+#if defined BMEi2cLOWLEVEL
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_PRESSURE_MSB_REG);
+ _i2c_start(i2cRAddr);
+
+ // MSB first LSB second XLSB third
+ bmed.raw_baro = ((_i2c_readACK() << 12) | (_i2c_readACK() << 4) | (_i2c_readACK()));
+ bmed.raw_temp = ((_i2c_readACK() << 12) | (_i2c_readACK() << 4) | (_i2c_readACK()));
+ bmed.raw_hum = ((_i2c_readACK() << 8) | (_i2c_readNACK()));
+ _i2c_stop();
+#else
+ bme280Buffer[0] = BME280_PRESSURE_MSB_REG;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 8, false);
+ // MSB first LSB second XLSB third
+ bmed.raw_baro = ((bme280Buffer[0] << 12) | (bme280Buffer[1] << 4) | (bme280Buffer[2]));
+ bmed.raw_temp = ((bme280Buffer[3] << 12) | (bme280Buffer[4] << 4) | (bme280Buffer[5]));
+ bmed.raw_hum = ((bme280Buffer[6] << 8) | (bme280Buffer[7]));
+#endif
+ return(0);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Convert BME280 PTH values. Takes raw data from data structure and applies calibration values to it.
+
+void bme280::convertBmeRawData(bme_data& bmed, bme_cal& bmec) {
+
+ //Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
+ //t_fine carries fine temperature as global value
+ int var1t = ((((bmed.raw_temp >> 3) - ((int)bmec.dig_T1 << 1))) * ((int)bmec.dig_T2)) >> 11;
+ int var2t = (((((bmed.raw_temp >> 4) - ((int)bmec.dig_T1)) * ((bmed.raw_temp >> 4) - ((int)bmec.dig_T1))) >> 12) *
+ ((int)bmec.dig_T3)) >> 14;
+ bmec.t_fine = var1t + var2t;
+ bmed.corr_temp = (bmec.t_fine * 5 + 128) >> 8;
+ bmed.bme_temp = (double)bmed.corr_temp / 100.0;
+
+ //Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
+ //Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
+ int64_t var1p, var2p, p;
+ var1p = ((int64_t)bmec.t_fine) - 128000;
+ var2p = var1p * var1p * (int64_t)bmec.dig_P6;
+ var2p = var2p + ((var1p * (int64_t)bmec.dig_P5) << 17);
+ var2p = var2p + (((int64_t)bmec.dig_P4) << 35);
+ var1p = ((var1p * var1p * (int64_t)bmec.dig_P3 )>> 8) + ((var1p * (int64_t)bmec.dig_P2) << 12);
+ var1p = (((((int64_t)1) << 47) + var1p)) * ((int64_t)bmec.dig_P1) >> 33;
+ if (var1p == 0) return; // avoid exception caused by division by zero
+ p = 1048576 - bmed.raw_baro;
+ p = (((p << 31) - var2p) * 3125)/var1p;
+ var1p = (((int64_t)bmec.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
+ var2p = (((int64_t)bmec.dig_P8) * p) >> 19;
+ p = ((p + var1p + var2p) >> 8) + (((int64_t)bmec.dig_P7) << 4);
+ bmed.corr_baro = p >> 8;
+ bmed.bme_baro = (double)bmed.corr_baro / 100.0;
+
+ //Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
+ //Output value of “47445” represents 47445/1024 = 46.333 %RH
+ int v_x1_u32r = (bmec.t_fine - ((int)76800));
+ v_x1_u32r = (((((bmed.raw_hum << 14) - (((int)bmec.dig_H4) << 20) - (((int)bmec.dig_H5) * v_x1_u32r)) +
+ ((int)16384)) >> 15) * (((((((v_x1_u32r * ((int)bmec.dig_H6)) >> 10) * (((v_x1_u32r *
+ ((int)bmec.dig_H3)) >> 11) + ((int)32768))) >> 10) + ((int)2097152)) *
+ ((int)bmec.dig_H2) + 8192) >> 14));
+ v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int)bmec.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);
+ bmed.corr_hum = (uint32_t)(v_x1_u32r >> 12);
+ bmed.bme_hum = (double)bmed.corr_hum / 1024.0; //was: / 1000.0
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//Convert BME280 PTH values. Takes raw data from data structure and applies calibration values to it.
+//Note: This is the floating point version.
+
+void bme280::convertBmeRawDataFloat(bme_data& bmed, bme_cal& bmec) {
+
+ //Returns temperature in DegC, double precision. Output value of “51.23” equals 51.23 DegC.
+ //t_fine carries fine temperature as global value
+ double var1, var2;
+ var1 = (((double)bmed.raw_temp) / 16384.0 - ((double)bmec.dig_T1) / 1024.0) * ((double)bmec.dig_T2);
+ var2 = ((((double)bmed.raw_temp) / 131072.0 - ((double)bmec.dig_T1) / 8192.0) *
+ (((double)bmed.raw_temp) / 131072.0 - ((double)bmec.dig_T1) / 8192.0)) * ((double)bmec.dig_T3);
+ bmec.t_fine = (int)(var1 + var2);
+ bmed.corr_temp = 0;
+ bmed.bme_temp = (var1 + var2) / 5120.0;
+
+ //Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
+ double p;
+ var1 = ((double)bmec.t_fine / 2.0) - 64000.0;
+ var2 = var1 * var1 * ((double)bmec.dig_P6) / 32768.0;
+ var2 = var2 + var1 * ((double)bmec.dig_P5) * 2.0;
+ var2 = (var2 / 4.0)+(((double)bmec.dig_P4) * 65536.0);
+ var1 = (((double)bmec.dig_P3) * var1 * var1 / 524288.0 + ((double)bmec.dig_P2) * var1) / 524288.0;
+ var1 = (1.0 + var1 / 32768.0)*((double)bmec.dig_P1);
+ if (var1 == 0.0) {
+ bmed.corr_baro = 0;
+ bmed.bme_baro = 0.0;
+ return; //avoid exception caused by division by zero
+ }
+ p = 1048576.0 - (double)bmed.raw_baro;
+ p = (p - (var2 / 4096.0)) * 6250.0 / var1;
+ var1 = ((double)bmec.dig_P9) * p * p / 2147483648.0;
+ var2 = p * ((double)bmec.dig_P8) / 32768.0;
+ p = p + (var1 + var2 + ((double)bmec.dig_P7)) / 16.0;
+ bmed.corr_baro = 0;
+ bmed.bme_baro = p / 100.0;
+
+ //Returns humidity in %rH as as double. Output value of “46.332” represents 46.332 %rH
+ double var_H;
+ var_H = (((double)bmec.t_fine) - 76800.0);
+ var_H = (bmed.raw_hum - (((double)bmec.dig_H4) * 64.0 + ((double)bmec.dig_H5) / 16384.0 * var_H)) *
+ (((double)bmec.dig_H2) / 65536.0 * (1.0 + ((double)bmec.dig_H6) / 67108864.0 * var_H *
+ (1.0 + ((double)bmec.dig_H3) / 67108864.0 * var_H)));
+ var_H = var_H * (1.0 - ((double)bmec.dig_H1) * var_H / 524288.0);
+ if (var_H > 100.0) {
+ var_H = 100.0;
+ } else if (var_H < 0.0) {
+ var_H = 0.0;
+ }
+ bmed.corr_hum = 0;
+ bmed.bme_hum = var_H;
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Initialize the chip
+
+uint8_t bme280::initBme(bme_cal& bmec) {
+#if defined BMEi2cLOWLEVEL
+ //initialize the chip
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CTRL_HUMIDITY_REG);
+ _i2c_write(BME280_CTRL_HUMIDITY_REG_DATA);
+ _i2c_stop();
+
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CTRL_MEAS_REG);
+ _i2c_write(BME280_CTRL_MEAS_REG_DATA);
+ _i2c_stop();
+
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CONFIG_REG);
+ _i2c_write(BME280_CONFIG_REG_DATA);
+ _i2c_stop();
+
+ //read back config registers
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CTRL_HUMIDITY_REG);
+ _i2c_start(i2cRAddr);
+ bmec.ctrl_hum_reg = _i2c_readACK();
+ uint8_t status = _i2c_readACK();
+ bmec.ctrl_meas_reg = _i2c_readACK();
+ bmec.config_reg = _i2c_readNACK();
+ _i2c_stop();
+
+ //now get the calibration registers
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CAL_DATA_START_1);
+ _i2c_start(i2cRAddr);
+ // LSB first MSB second
+ bmec.dig_T1 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_T2 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_T3 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P1 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P2 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P3 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P4 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P5 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P6 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P7 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P8 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_P9 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ uint8_t rdata = (_i2c_readACK()); //dummy read of address 0xa0
+ bmec.dig_H1 = (_i2c_readNACK());
+ _i2c_stop();
+
+ //finally, get the Humid calibration registers
+ _i2c_start(i2cWAddr);
+ _i2c_write(BME280_CAL_DATA_START_2);
+ _i2c_start(i2cRAddr);
+ bmec.dig_H2 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_H3 = (_i2c_readACK());
+ bmec.dig_H4 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_H5 = (_i2c_readACK() + (_i2c_readACK() << 8));
+ bmec.dig_H6 = (_i2c_readNACK());
+ _i2c_stop();
+
+#else
+ //initialize the chip
+ bme280Buffer[0] = BME280_CTRL_HUMIDITY_REG;
+ bme280Buffer[1] = BME280_CTRL_HUMIDITY_REG_DATA;
+ _i2c.write(i2cWAddr, bme280Buffer, 2, false);
+
+ bme280Buffer[0] = BME280_CTRL_MEAS_REG;
+ bme280Buffer[1] = BME280_CTRL_MEAS_REG_DATA;
+ _i2c.write(i2cWAddr, bme280Buffer, 2, false);
+
+ bme280Buffer[0] = BME280_CONFIG_REG;
+ bme280Buffer[1] = BME280_CONFIG_REG_DATA;
+ _i2c.write(i2cWAddr, bme280Buffer, 2, false);
+
+ //read back config registers
+ bme280Buffer[0] = BME280_CTRL_HUMIDITY_REG;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 4, false);
+ bmec.ctrl_hum_reg = bme280Buffer[0];
+// uint8_t status = bme280Buffer[1];
+ bmec.ctrl_meas_reg = bme280Buffer[2];
+ bmec.config_reg = bme280Buffer[3];
+
+ //now get the calibration registers, Temp and Press first
+ bme280Buffer[0] = BME280_CAL_DATA_START_1;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 26, false);
+ // LSB first MSB second
+ bmec.dig_T1 = (bme280Buffer[0] | (bme280Buffer[1] << 8));
+ bmec.dig_T2 = (bme280Buffer[2] | (bme280Buffer[3] << 8));
+ bmec.dig_T3 = (bme280Buffer[4] | (bme280Buffer[5] << 8));
+ bmec.dig_P1 = (bme280Buffer[6] | (bme280Buffer[7] << 8));
+ bmec.dig_P2 = (bme280Buffer[8] | (bme280Buffer[9] << 8));
+ bmec.dig_P3 = (bme280Buffer[10] | (bme280Buffer[11] << 8));
+ bmec.dig_P4 = (bme280Buffer[12] | (bme280Buffer[13] << 8));
+ bmec.dig_P5 = (bme280Buffer[14] | (bme280Buffer[15] << 8));
+ bmec.dig_P6 = (bme280Buffer[16] | (bme280Buffer[17] << 8));
+ bmec.dig_P7 = (bme280Buffer[18] | (bme280Buffer[19] << 8));
+ bmec.dig_P8 = (bme280Buffer[20] | (bme280Buffer[21] << 8));
+ bmec.dig_P9 = (bme280Buffer[22] | (bme280Buffer[23] << 8));
+// uint8_t rdata = (bme280Buffer[24]); //dummy read of address 0xa0
+ bmec.dig_H1 = (bme280Buffer[25]);
+
+ //finally, get the Humid calibration registers
+ bme280Buffer[0] = BME280_CAL_DATA_START_2;
+ _i2c.write(i2cWAddr, bme280Buffer, 1, true);
+ _i2c.read(i2cRAddr, bme280Buffer, 8, false);
+ bmec.dig_H2 = (bme280Buffer[0] | (bme280Buffer[1] << 8));
+ bmec.dig_H3 = (bme280Buffer[2]);
+ bmec.dig_H4 = ((bme280Buffer[4] & 15) | (bme280Buffer[3] << 4));
+ bmec.dig_H5 = (((bme280Buffer[4] >> 4) & 15) | (bme280Buffer[5] << 4));
+ bmec.dig_H6 = (bme280Buffer[6]);
+
+#endif
+ return(0);
+ }
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Return corrected altitude (in feet) from barometer at sea level (in mB)
+
+float bme280::getAltitudeFT(bme_data& bmed, float sea_pressure) {
+ return(float)((1 - (pow((bmed.bme_baro / (double)sea_pressure), 0.190284))) * 145366.45);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Return corrected barometer, based on altitude (in feet)
+
+float bme280::getSeaLevelBaroFT(bme_data& bmed, float known_alt) {
+ return(pow(pow((bmed.bme_baro * MB_INHG_DOUBLE), 0.190284) + 0.00001313 * (double)known_alt , 5.2553026) * INHG_MB_DOUBLE);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Return corrected barometer, based on altitude (in meters)
+
+float bme280::getSeaLevelBaroM(bme_data& bmed, float known_alt) {
+ return(pow(pow((bmed.bme_baro * MB_INHG_DOUBLE), 0.190284) + 0.00001313 * (double)known_alt * FEET_METERS , 5.2553026) * INHG_MB_DOUBLE);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Return dew point. More accurate, slower
+
+float bme280::getDewPt(bme_data& bmed) {
+ // dewPoint function NOAA
+ // reference: http://wahiduddin.net/calc/density_algorithms.htm
+ double A0= 373.15 / (273.15 + (double)bmed.bme_temp);
+ double SUM = -7.90298 * (A0 -1);
+ SUM += 5.02808 * log10(A0);
+ SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/A0))) -1) ;
+ SUM += 8.1328e-3 * (pow(10,(-3.49149 * (A0 -1))) -1) ;
+ SUM += log10(1013.246);
+ double VP = pow(10, SUM -3) * bmed.bme_hum;
+ double T = log(VP / 0.61078); // temp var
+ return (241.88 * T) / (17.558 - T);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Return dew point. Less accurate, faster
+
+float bme280::getDewPtFast(bme_data& bmed) {
+ // delta max = 0.6544 wrt dewPoint()
+ // 5x faster than dewPoint()
+ // reference: http://en.wikipedia.org/wiki/Dew_point
+ double bmeDtzA = 17.271;
+ double bmeDtzB = 237.7;
+ double bmeDtzC = (bmeDtzA * bmed.bme_temp) / (bmeDtzB + bmed.bme_temp) + log(bmed.bme_hum / 100.0);
+ double bmeDtzD = (bmeDtzB * bmeDtzC) / (bmeDtzA - bmeDtzC);
+ return (bmeDtzD);
+}
+
+
+
diff -r d8d62aee6d5b -r 96075bee19f0 bme280.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bme280.h Fri Apr 22 14:25:55 2016 +0000
@@ -0,0 +1,331 @@
+#ifndef BME280_H
+#define BME280_H
+
+#include "mbed.h"
+
+#if(defined(TARGET_KL25Z) || defined(TARGET_K64F))
+
+// #define BME280i2cLOWLEVEL 1 //if the use of low-level I2C routines is needed
+// #warning "BME280 using low level I2C routines"
+
+#endif
+
+
+#define SEA_PRESS 1013.25 //default sea level pressure level in mb
+//#define KNOWNALT 327.0 //default known altitude in feet
+#define METERS_FEET 3.2808399
+#define FEET_METERS 0.3048006
+#define MB_INHG_DOUBLE 0.02952998751
+#define INHG_MB_DOUBLE 33.8638815767
+#define DEGC_DEGF_FLOAT 9.0 / 5.0 + 32.0
+#define DEGC_DEGF_INT 9 / 5 + 32
+
+#define BME280_WADDR 0xEC //i2c address write mode (CSBpin = 0);
+#define BME280_RADDR 0xED //i2c address read mode
+
+#define BME280_CHIP_ID_REG 0xD0 //Chip ID Register
+#define BME280_CAL_DATA_START_1 0x88 //Calibration data parameters
+#define BME280_CAL_DATA_START_2 0xE1 //More calibration data parameters
+#define BME280_RST_REG 0xE0 //Softreset Register
+#define BME280_STAT_REG 0xF3 //Status Register
+#define BME280_CTRL_MEAS_REG 0xF4 //Ctrl Measure Register
+#define BME280_CTRL_HUMIDITY_REG 0xF2 //Ctrl Humidity Register
+#define BME280_CONFIG_REG 0xF5 //Configuration Register
+#define BME280_PRESSURE_MSB_REG 0xF7 //Pressure MSB Register
+#define BME280_PRESSURE_LSB_REG 0xF8 //Pressure LSB Register
+#define BME280_PRESSURE_XLSB_REG 0xF9 //Pressure XLSB Register
+#define BME280_TEMPERATURE_MSB_REG 0xFA //Temperature MSB Reg
+#define BME280_TEMPERATURE_LSB_REG 0xFB //Temperature LSB Reg
+#define BME280_TEMPERATURE_XLSB_REG 0xFC //Temperature XLSB Reg
+#define BME280_HUMIDITY_MSB_REG 0xFD //Humidity MSB Reg
+#define BME280_HUMIDITY_LSB_REG 0xFE //Humidity LSB Reg
+
+// Status register bits
+#define BME280_STATUS_BUSY 0x08
+#define BME280_STATUS_UNKNOWN 0x04
+#define BME280_STATUS_IMUPDATE 0x01
+
+#define BME280_RESET_VALUE 0xB6
+
+// Config register equates
+#define BME280_OVERSAMPLE_SKIP 0
+#define BME280_OVERSAMPLE_x1 1
+#define BME280_OVERSAMPLE_x2 2
+#define BME280_OVERSAMPLE_x4 3
+#define BME280_OVERSAMPLE_x8 4
+#define BME280_OVERSAMPLE_x16 5
+
+#define BME280_TEMP_OVERSAMPLE BME280_OVERSAMPLE_x1 //was x2
+#define BME280_PRESS_OVERSAMPLE BME280_OVERSAMPLE_x1 //was x4
+#define BME280_HUM_OVERSAMPLE BME280_OVERSAMPLE_x1 //was x2
+
+#define BME280_MODE_SLEEP 0
+#define BME280_MODE_FORCED 1
+#define BME280_MODE_NORMAL 3
+
+#define BME280_STANDBY_0m5 0
+#define BME280_STANDBY_62m5 1
+#define BME280_STANDBY_125m 2
+#define BME280_STANDBY_250m 3
+#define BME280_STANDBY_500m 4
+#define BME280_STANDBY_1000m 5
+#define BME280_STANDBY_10m 6
+#define BME280_STANDBY_20m 7
+
+#define BME280_FILTER_OFF 0
+#define BME280_FILTER_2 1
+#define BME280_FILTER_4 2
+#define BME280_FILTER_8 3
+#define BME280_FILTER_16 4
+
+//osrs_t(7..5), osrs_p(4..2), mode(1..0)
+#define BME280_CTRL_MEAS_REG_DATA ((BME280_TEMP_OVERSAMPLE << 5) | (BME280_PRESS_OVERSAMPLE << 2) | BME280_MODE_NORMAL)
+//0(7..3), osrs_h(2..0)
+#define BME280_CTRL_HUMIDITY_REG_DATA ((BME280_HUM_OVERSAMPLE))
+//sb(7..5), filter(4..2), 0(1), spl3w_en(0)
+#define BME280_CONFIG_REG_DATA ((BME280_STANDBY_1000m << 5) | (BME280_FILTER_OFF << 2)) //was FILTER_4
+
+//Until it is understood why data cannot be raed out of BME280 right after BUSY goes false, the
+//defines below introduce a variable delay in main(), based on sb bits used.
+// example: wait_ms(BME280_MAIN_WAIT); must be put between pth.getBmeRawData(bmed_struct); accesses
+#if ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_0m5)
+#define BME280_MAIN_WAIT 100
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_62m5)
+#define BME280_MAIN_WAIT 60
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_125m)
+#define BME280_MAIN_WAIT 120
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_250m)
+#define BME280_MAIN_WAIT 240
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_500m)
+#define BME280_MAIN_WAIT 100
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_1000m)
+#define BME280_MAIN_WAIT 500
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_10m)
+#define BME280_MAIN_WAIT 50
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_20m)
+#define BME280_MAIN_WAIT 59
+#endif
+
+
+ /**
+ * Create bme280 controller class
+ *
+ * @param bme280 class
+ *
+ */
+class bme280 {
+
+public:
+
+ /**
+ * Public data structure for CME280 correction values.
+ *
+ **/
+ typedef struct {
+ uint16_t dig_T1; /*!< calibration parameter -> Temp T1 */
+ int16_t dig_T2; /*!< calibration parameter -> Temp T2 */
+ int16_t dig_T3; /*!< calibration parameter -> Temp T3 */
+
+ uint16_t dig_P1; /*!< calibration parameter -> Press P1 */
+ int16_t dig_P2; /*!< calibration parameter -> Press P2 */
+ int16_t dig_P3; /*!< calibration parameter -> Press P3 */
+ int16_t dig_P4; /*!< calibration parameter -> Press P4 */
+ int16_t dig_P5; /*!< calibration parameter -> Press P5 */
+ int16_t dig_P6; /*!< calibration parameter -> Press P6 */
+ int16_t dig_P7; /*!< calibration parameter -> Press P7 */
+ int16_t dig_P8; /*!< calibration parameter -> Press P8 */
+ int16_t dig_P9; /*!< calibration parameter -> Press P9 */
+
+ uint8_t dig_H1; /*!< calibration parameter -> Hum H1 */
+ int16_t dig_H2; /*!< calibration parameter -> Hum H2 */
+ uint8_t dig_H3; /*!< calibration parameter -> Hum H3 */
+ int16_t dig_H4; /*!< calibration parameter -> Hum H4 */
+ int16_t dig_H5; /*!< calibration parameter -> Hum H5 */
+ int8_t dig_H6; /*!< calibration parameter -> Hum H6 */
+
+ uint32_t t_fine; /*!< scratch T_FINE */
+
+ uint8_t ctrl_hum_reg; /*!< config -> hum */
+ uint8_t ctrl_meas_reg; /*!< config -> temp press mode */
+ uint8_t config_reg; /*!< config -> delay filter spi3w */
+ } bme_cal;
+
+ /**
+ * Public data structure to obtain CME280 data.
+ *
+ **/
+ typedef struct {
+ int raw_temp; /*!< raw temperature reading, 20 bits */
+ int raw_baro; /*!< raw pressure reading, 20 bits */
+ int raw_hum; /*!< raw humidity reading, 16 bits */
+ int corr_temp; /*!< corrected temperature as integer*/
+ int64_t corr_baro; /*!< corrected pressure as integer */
+ uint32_t corr_hum; /*!< corrected humidity as integer */
+ double bme_temp; /*!< corrected temperature as a float */
+ double bme_baro; /*!< corrected pressure as a float */
+ double bme_hum; /*!< corrected humidity as a float */
+ } bme_data;
+
+ /**
+ * Public enum for selecting polarity of I2C address pin.
+ *
+ * - CSB pin = 0, user set I2C address to 0xEC
+ * - CSB pin = 1, user set I2C address to 0xEE
+ *
+ **/
+ enum CSBpolarity {
+ CSBpin_0, //CSB pin is grounded, I2C address is 0xEC and 0xED
+ CSBpin_1, //CSB pin is tied to Vdd, I2C address is 0xEE and 0xEF
+ };
+
+ /**
+ * Create a BME280 object using the specified I2C object
+ * - User defined use of the CSB pin
+ * - CSB pin = 0, user set I2C address to 0xEC
+ * - CSB pin = 1, user set I2C address to 0xEE
+ * @param sda - mbed I2C interface pin
+ * @param scl - mbed I2C interface pin
+ * @param bme280::CSBpin_0 - CSB pin tied to ground
+ * @param bme280::CSBpin_1 - CSB pin tied to VDD
+ */
+ bme280(PinName sda, PinName scl, CSBpolarity CSBpin);
+
+ /**
+ * Destructor
+ *
+ * @param --none--
+ */
+ ~bme280();
+
+ /**
+ * Get BME280 ID Register
+ *
+ * @param --none--
+ *
+ * @return ID Register value
+ */
+ uint8_t getBmeID();
+
+ /**
+ * Soft Reset the BME280
+ *
+ * @param --none--
+ *
+ * @return ACK/NACK status
+ */
+ uint8_t resetBme();
+
+ /**
+ * Get BME280 Status Register
+ *
+ * @param --none--
+ *
+ * @return Status Register value
+ */
+ uint8_t getBmeStatus();
+
+ /**
+ * Get BME280 Raw Data
+ *
+ * @param pointer to struct bme_data
+ *
+ * @return Status Register value. Pass-thru from getBmeStatus()
+ * @return raw data put into struct bme_data
+ */
+ uint8_t getBmeRawData(bme_data& bmed);
+
+ /**
+ * Convert BME280 Raw Data using integer based routines
+ *
+ * @param pointer to struct bme_data
+ * @param pointer to struct bme_cal
+ *
+ * @return converted data put into struct bme_data
+ */
+ void convertBmeRawData(bme_data& bmed, bme_cal& bmec);
+
+ /**
+ * Convert BME280 Raw Data using all floating routines
+ *
+ * @param pointer to struct bme_data
+ * @param pointer to struct bme_cal
+ *
+ * @return converted data put into struct bme_data
+ */
+ void convertBmeRawDataFloat(bme_data& bmed, bme_cal& bmec);
+
+ /**
+ * Initialize the BME280.
+ * - Sets up the command registers
+ * - Loads up the calibration data
+ *
+ * @param pointer to struct bme_data
+ *
+ * @return 0
+ */
+ uint8_t initBme(bme_cal& bmec);
+
+ /**
+ * Corrected altitude (feet) from barometer at seal level (mB)
+ *
+ * @param pointer to struct bme_data
+ * @param pressure at sea level (in mB)
+ *
+ * @return corrected altimeter (in feet)
+ */
+ float getAltitudeFT(bme_data& bmed, float sea_pressure);
+
+ /**
+ * Altitude corrected barometer (feet)
+ *
+ * @param pointer to struct bme_data
+ * @param known_alt in feet
+ *
+ * @return corrected barometer
+ */
+ float getSeaLevelBaroFT(bme_data& bmed, float known_alt);
+
+ /**
+ * Altitude corrected barometer (meters)
+ *
+ * @param pointer to struct bme_data
+ * @param known_alt in meters
+ *
+ * @return corrected barometer
+ */
+ float getSeaLevelBaroM(bme_data& bmed, float known_alt);
+
+ /**
+ * Return the dew point based on T & H. Slower but more accurate.
+ *
+ * @param pointer to struct bme_data
+ *
+ * @return dew point in degrees C
+ */
+ float getDewPt(bme_data& bmed);
+
+ /**
+ * Return the dew point based on T & H. Faster but less accurate.
+ *
+ * @param pointer to struct bme_data
+ *
+ * @return dew point in degrees C
+ */
+ float getDewPtFast(bme_data& bmed);
+
+private:
+#if not defined BMEi2cLOWLEVEL
+ char bme280Buffer[32];
+#endif
+ char i2cWAddr;
+ char i2cRAddr;
+ int _i2c_start(uint8_t i2c_addr);
+ void _i2c_stop();
+ uint8_t _i2c_write(uint8_t data);
+ uint8_t _i2c_readACK();
+ uint8_t _i2c_readNACK();
+
+protected:
+ I2C _i2c;
+};
+#endif
\ No newline at end of file
diff -r d8d62aee6d5b -r 96075bee19f0 veml60xx.cpp
--- a/veml60xx.cpp Thu Apr 21 23:32:50 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-// Vishay veml6040 RGBW and veml6075 UVA + UVB optical sensors
-
-#include "veml60xx.h"
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Constructor, to allow for user to select i2c frequency
-
-veml60xx::veml60xx(PinName sda, PinName scl, int i2cFrequency) {
- _i2c_ = new I2C(sda, scl);
- _i2c_->frequency(i2cFrequency);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// deconstructor
-
-veml60xx::~veml60xx() {
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Set/initialize the veml60xx config register.
-
-void veml60xx::setConfig(veml60xx_struct& Pntr, uint16_t val) {
- vemlBuffer[0] = VEML60xx_CONF_REG;
- vemlBuffer[1] = val;
- //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | val;
- //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | VEML6075_CONF_BITS_HD;
- //vemlBuffer[1] = VEML60xx_CONF_BITS_IT_400m320m | VEML6075_CONF_BITS_HD | VEML60xx_CONF_BITS_AF;
- vemlBuffer[2] = 0;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 3, false);
- Pntr.conf_reg = (vemlBuffer[2] << 8) | vemlBuffer[1];
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Get veml60xx ID register. Returns register value
-// Note: the veml6040 does hvae a device ID, but is not in datasheet
-
-uint16_t veml60xx::getID(veml60xx_struct& Pntr) {
- vemlBuffer[0] = VEML6075_CHIP_ID_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- uint16_t rdata = (vemlBuffer[1] << 8) | vemlBuffer[0];
- if((rdata & VEML6075_DEVICE_ID) == VEML6075_DEVICE_ID) {
- Pntr.is6075 = true;
- Pntr.is6040 = false;
- } else
- if((rdata & VEML6040_DEVICE_ID) == VEML6040_DEVICE_ID) {
- Pntr.is6075 = false;
- Pntr.is6040 = true;
- } else {
- Pntr.is6075 = false;
- Pntr.is6040 = false;
- }
- return(rdata);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Get veml60xx config register. Returns register value
-
-uint16_t veml60xx::getConfig(veml60xx_struct& Pntr) {
- vemlBuffer[0] = VEML60xx_CONF_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- uint16_t rdata = (vemlBuffer[1] << 8) | vemlBuffer[0];
- if(Pntr.is6040) {
- uint16_t c = rdata & VEML60xx_CONF_BITS_IT;
- switch (c) {
- case VEML60xx_CONF_BITS_IT_50m40m:
- Pntr.lux_step = VEML6040_LUX_STEP_000;
- break;
- case VEML60xx_CONF_BITS_IT_100m80m:
- Pntr.lux_step = VEML6040_LUX_STEP_001;
- break;
- case VEML60xx_CONF_BITS_IT_200m160m:
- Pntr.lux_step = VEML6040_LUX_STEP_010;
- break;
- case VEML60xx_CONF_BITS_IT_400m320m:
- Pntr.lux_step = VEML6040_LUX_STEP_011;
- break;
- case VEML60xx_CONF_BITS_IT_800m640m:
- Pntr.lux_step = VEML6040_LUX_STEP_100;
- break;
- case VEML6040_CONF_BITS_IT_1280m:
- Pntr.lux_step = VEML6040_LUX_STEP_101;
- break;
- default:
- Pntr.lux_step = 0.0;
- break;
- }
- }
- return(rdata);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// If AF set to trigger mode, start a conversion process trigger
-// Returns: 0=trigger set, 1=already triggered, 2=no AF bit - cannot set trigger
-
-uint16_t veml60xx::startAccess(veml60xx_struct& Pntr) {
- uint16_t val = getConfig(Pntr);
- if((val & VEML60xx_CONF_BITS_AF) == VEML60xx_CONF_BITS_AF) {
- if((val & VEML60xx_CONF_BITS_TRIG) == VEML60xx_CONF_BITS_TRIG) return(1);
- val |= VEML60xx_CONF_BITS_TRIG;
- setConfig(Pntr, val);
- return(0);
- }
- return(2);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Get VEML60xx values. Saves raw data is data structure. Returns 0 if successful, !0 if status is (something else);
-// mode: false = VEML6075, true = VEML6040
-
-uint16_t veml60xx::getRawData(veml60xx_struct& Pntr) {
- Pntr.conf_reg = getConfig(Pntr);
- Pntr.id = getID(Pntr);
-
- if(Pntr.is6075) {
- vemlBuffer[0] = VEML6075_UVA_DATA_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- Pntr.uva_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- }
-
- vemlBuffer[0] = VEML6075_DUMMY_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- if(Pntr.is6075) {
- Pntr.dummy_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- } else
- if(Pntr.is6040) {
- Pntr.r_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- }
-
- vemlBuffer[0] = VEML6075_UVB_DATA_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- if(Pntr.is6075) {
- Pntr.uvb_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- } else
- if(Pntr.is6040) {
- Pntr.g_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- }
-
- vemlBuffer[0] = VEML6075_UV_COMP1_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- if(Pntr.is6075) {
- Pntr.uv_c1 = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- } else
- if(Pntr.is6040) {
- Pntr.b_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- }
-
- vemlBuffer[0] = VEML6075_UV_COMP2_REG;
- _i2c_->write(VEML60_WADDR, vemlBuffer, 1, true);
- _i2c_->read(VEML60_RADDR, vemlBuffer, 2, false);
- if(Pntr.is6075) {
- Pntr.uv_c1 = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- } else
- if(Pntr.is6040) {
- Pntr.w_d = ((vemlBuffer[1] << 8) | vemlBuffer[0]);
- }
-
- return(0);
-}
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// Convert raw data into real UVA, UVB and UVI numbers
-
-void veml60xx::convertRawData(veml60xx_struct& Pntr) {
- getRawData(Pntr);
-
- //Eq (1)
- Pntr.uva_comp = (double)(Pntr.uva_d - Pntr.dummy_d) -
- VEML6075_UVA_COEF_A * (double)(Pntr.uv_c1 - Pntr.dummy_d) -
- VEML6075_UVA_COEF_B * (double)(Pntr.uv_c2 - Pntr.dummy_d);
-
- //Eq (2)
- Pntr.uvb_comp = (double)(Pntr.uvb_d - Pntr.dummy_d) -
- VEML6075_UVB_COEF_C * (double)(Pntr.uv_c1 - Pntr.dummy_d) -
- VEML6075_UVB_COEF_D * (double)(Pntr.uv_c2 - Pntr.dummy_d);
- //Eq (3)
- Pntr.uv_index = ((Pntr.uva_comp * VEML6075_UVA_RESP) + (Pntr.uvb_comp * VEML6075_UVB_RESP))/2.0;
-}
-
-
-//--------------------------------------------------------------------------------------------------------------------------------------//
-// If there is a lux over/underflow, automatically adjust the CONF_BITS_IT by +-1 to compensate accordingly
-// if returns true, the Lux level was changed.
-
-bool veml60xx::autoAdjustLux(veml60xx_struct& Pntr) {
- getRawData(Pntr);
- uint16_t rdata = Pntr.conf_reg;
- uint16_t lux = rdata & VEML60xx_CONF_BITS_IT;
- if(Pntr.is6040) {
- if((Pntr.r_d < 255) && (Pntr.g_d < 255) && (Pntr.b_d < 255) && (Pntr.w_d < 255)) {
- if(lux == VEML6040_CONF_BITS_IT_1280m) return false;
- lux += VEML60xx_CONF_BITS_IT_100m80m;
- rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
- setConfig(Pntr, rdata);
- return true;
- } else
- if((Pntr.r_d == 65535) || (Pntr.g_d == 65535) || (Pntr.b_d == 65535) || (Pntr.w_d == 65535)) {
- if(lux == VEML60xx_CONF_BITS_IT_50m40m) return false;
- lux -= VEML60xx_CONF_BITS_IT_100m80m;
- rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
- setConfig(Pntr, rdata);
- return true;
- }
- } else
- if(Pntr.is6075) {
- if((Pntr.uva_d < 255) && (Pntr.uvb_d < 255)) {
- if(lux == VEML60xx_CONF_BITS_IT_800m640m) return false;
- lux += VEML60xx_CONF_BITS_IT_100m80m;
- rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
- setConfig(Pntr, rdata);
- return true;
- } else
- if((Pntr.uva_d == 65535) || (Pntr.uvb_d == 65535)) {
- if(lux == VEML60xx_CONF_BITS_IT_50m40m) return false;
- lux -= VEML60xx_CONF_BITS_IT_100m80m;
- rdata = (rdata & ~VEML60xx_CONF_BITS_IT) | lux;
- setConfig(Pntr, rdata);
- return true;
- }
- }
- return false;
-}
-
-
\ No newline at end of file
diff -r d8d62aee6d5b -r 96075bee19f0 veml60xx.h
--- a/veml60xx.h Thu Apr 21 23:32:50 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-#ifndef VEML60XX_H
-#define VEML60XX_H
-
-#include "mbed.h"
-
-// I2C address
-#define VEML60_WADDR 0x20 //i2c address write mode
-#define VEML60_RADDR 0x21 //i2c address read mode
-
-
-// VEMP6040 and VEML6075 common register set
-#define VEML60xx_CONF_REG 0x00 //rw Config Register
-
-// VEML6075-only register set
-#define VEML6075_UVA_DATA_REG 0x07 //ro 16 bit UVA data Register
-#define VEML6075_DUMMY_REG 0x08 //ro 16 bit dummy Register
-#define VEML6075_UVB_DATA_REG 0x09 //ro 16 bit UVB data Register
-#define VEML6075_UV_COMP1_REG 0x0A //ro 16 bit UV compensation Register 1
-#define VEML6075_UV_COMP2_REG 0x0B //ro 16 bit UV compensation Register 2
-#define VEML6075_CHIP_ID_REG 0x0C //ro 16 bit Chip ID Register
-
-// VEML6040-only register set
-#define VEML6040_R_DATA_REG 0x08 //ro 16 bit RED data
-#define VEML6040_G_DATA_REG 0x09 //ro 16 bit GREEN data
-#define VEML6040_B_DATA_REG 0x0A //ro 16 bit BLUE data
-#define VEML6040_W_DATA_REG 0x0B //ro 16 bit WHITE data
-
-// VEML6040 and VEML6075 common config register bits
-#define VEML60xx_CONF_BITS_IT 0x70 //VEML6075 -> 0x00 = 50mS, 0x10 = 100mS, 0x20 = 200mS, 0x30 = 400mS, 0x40 = 800mS, 0x50-0x70 = reserved
- //VEML6040 -> 0x00 = 40mS, 0x10 = 80mS, 0x20 = 160mS, 0x30 = 320mS, 0x40 = 640mS, 0x50 = 1280mS, 0x60-0x70 = reserved
-#define VEML60xx_CONF_BITS_IT_50m40m 0x00
-#define VEML60xx_CONF_BITS_IT_100m80m 0x10
-#define VEML60xx_CONF_BITS_IT_200m160m 0x20
-#define VEML60xx_CONF_BITS_IT_400m320m 0x30
-#define VEML60xx_CONF_BITS_IT_800m640m 0x40
-
-#define VEML60xx_CONF_BITS_TRIG 0x04 //0x00 = idle, 0x04 = trigger (measurement), auto returns to 0x00 note: AF == 1
-#define VEML60xx_CONF_BITS_AF 0x02 //0x00 = auto, 0x02 = force (mode)
-#define VEML60xx_CONF_BITS_SD 0x01 //0x00 = run, 0x01 = shut down
-
-// VEML6075-only config register bits
-#define VEML6075_CONF_BITS_HD 0x08 //0x00 = normal, 0x08 = high (dynamic setting)
-
-// VEML6040-only config register bits
-#define VEML6040_CONF_BITS_IT_1280m 0x50
-
-// VEML6075-only ID contents
-#define VEML6075_DEVICE_ID 0x0026 //expected device ID
-
-// VEML6040-only ID contents
-#define VEML6040_DEVICE_ID 0x0123 //expected device ID
-
-// VEML6075-only conversion coefficients
-#define VEML6075_UVA_COEF_A 3.33
-#define VEML6075_UVA_COEF_B 2.50
-#define VEML6075_UVB_COEF_C 3.67
-#define VEML6075_UVB_COEF_D 2.75
-
-// VEML6040-only conversion coefficients
-#define VEML6040_LUX_STEP_000 0.18
-#define VEML6040_LUX_STEP_001 0.09
-#define VEML6040_LUX_STEP_010 0.045
-#define VEML6040_LUX_STEP_011 0.0225
-#define VEML6040_LUX_STEP_100 0.01125
-#define VEML6040_LUX_STEP_101 0.005625
-
-// VEML6075-only conversion coefficients
-#define VEML6075_UVA_RESP 0.0011
-#define VEML6075_UVB_RESP 0.00125
-
-
- /**
- * Create VEML60 controller class
- *
- * @param VEML class
- *
- */
-class veml60xx {
-
-public:
-
- /**
- * Public data structure for VEML60xx data values.
- *
- **/
- typedef struct {
- uint16_t conf_reg; /*!< VEML60xx config register mirror */
-
- uint16_t uva_d; /*!< VEML6075 UVA data */
- uint16_t dummy_d; /*!< VEML6075 Dummy data */
- uint16_t uvb_d; /*!< VEML6075 UVB data */
- uint16_t uv_c1; /*!< VEML6075 UV comp1 data */
- uint16_t uv_c2; /*!< VEML6075 UV comp2 data */
- uint16_t id; /*!< VEML6075 Device ID*/
- double uva_comp; /*!< VEML6075 UVA compensated data */
- double uvb_comp; /*!< VEML6075 UVB compensated data */
- double uv_index; /*!< VEML6075 UV Index */
-
- uint16_t r_d; /*!< VEML6040 RED data */
- uint16_t g_d; /*!< VEML6040 GREEN data */
- uint16_t b_d; /*!< VEML6040 BLUE data */
- uint16_t w_d; /*!< VEML6040 WHITE data */
- double lux_step; /*!< VEML6040 Lux value per step */
-
- bool is6075; /*!< connected device is a VEML6075 */
- bool is6040; /*!< connected device is a VEML6040 */
- } veml60xx_struct;
-
- /**
- * Create a VME60xx object using the specified I2C object
- *
- * @param sda - mbed I2C interface pin
- *
- * @param scl - mbed I2C interface pin
- *
- * @param set_I2C_frequency
- */
- veml60xx(PinName sda, PinName scl, int i2cFrequency);
-
- /**
- * Destructor
- *
- * @param --none--
- */
- ~veml60xx();
-
- /**
- * Get VEMP6075 ID Register
- *
- * Note: the VEMP6040 seems to have an ID register. It's not published
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return ID Register value
- */
- uint16_t getID(veml60xx_struct& Pntr);
-
- /**
- * Get VEMPxx Config Register
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return Config Register value
- */
- uint16_t getConfig(veml60xx_struct& Pntr);
-
- /**
- * Get VEMP60xx Raw Data
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return raw data put into struct vemp60xx_struct
- */
- uint16_t getRawData(veml60xx_struct& Pntr);
-
- /**
- * Convert the VEMP6075 Raw Data
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return converted data put into struct vemp60xx_struct
- */
- void convertRawData(veml60xx_struct& Pntr);
-
- /**
- * Initialize the VEMP60xx
- *
- * Sets up the command register to proper operating mode
- *
- * @param pointer to struct veml60xx_struct
- *
- * @param val any value to be or'd into the config register
- *
- * @return 0
- */
- void setConfig(veml60xx_struct& Pntr, uint16_t val);
-
- /**
- * Trigger a VEMP60xx conversion cycle
- *
- * Must be in manual trigger mode (AF == 1)
- *
- * Example: uv.setConfig(struct_ptr, VEML60xx_CONF_BITS_AF);
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return 0 TRIG properly set
- * @return 1 TRIG has been previously set
- * @return 2 AF bit not set (in AUTO mode)
- */
- uint16_t startAccess(veml60xx_struct& Pntr);
-
- /**
- * Automatically adjust Lux scaling level
- *
- * Change CONF_BITS_IT by +-1 if count bits saturated or too low
- *
- * @param pointer to struct veml60xx_struct
- *
- * @return true = IT scale value has changed
- * @return false = IT scale value not changed, could be at its limit
- */
- bool autoAdjustLux(veml60xx_struct& Pntr);
-
-private:
- char vemlBuffer[4];
-
-protected:
- I2C* _i2c_;
-
-};
-#endif
\ No newline at end of file