diff --git a/README.md b/README.md new file mode 100644 index 0000000..0106cad --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Weather Sensors Library + +### Content + +The **Weather Sensors Library** supports the + +* **TMP007** infra-red thermometer, +* **OPT3001** light sensor, and +* **BME280** thermometer, barometer and hydrometer + +of the [Sensors BoosterPack](http://embeddedcomputing.weebly.com/sensors-boosterpack.html). + +The IMU sensors (Bosch BMI160 and BMM150) are insufficiently documented. + +### External dependencies + +The library requires the Wire library for the I2C bus. + +### Installation + +Place the `SensorWeather_Library` folder on the `Libraries` folder of the sketchbook. + +### Reference + +* [Texas Instruments TMP007](http://www.ti.com/product/tmp007) +* [Texas Instruments OPT3001](http://www.ti.com/product/OPT3001) +* [Bosch BME280](https://www.bosch-sensortec.com/bst/products/all_products/bme280) + +### Licence + +![image](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png) + +This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/). \ No newline at end of file diff --git a/examples/WeatherSensors_demo/WeatherSensors_demo.ino b/examples/WeatherSensors_demo/WeatherSensors_demo.ino new file mode 100644 index 0000000..142c881 --- /dev/null +++ b/examples/WeatherSensors_demo/WeatherSensors_demo.ino @@ -0,0 +1,148 @@ +/// +/// @mainpage WeatherSensors +/// +/// @details Description of the project +/// @n +/// @n +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// @date nov. 12, 2016 19:37 +/// @version <#version#> +/// +/// @copyright (c) Rei Vilo, 2016 +/// @copyright GNU General Public Licence +/// +/// @see ReadMe.txt for references +/// + + +/// +/// @file WeatherSensors.ino +/// @brief Main sketch +/// +/// @details <#details#> +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// @date nov. 12, 2016 19:37 +/// @version <#version#> +/// +/// @copyright (c) Rei Vilo, 2016 +/// @copyright GNU General Public Licence +/// +/// @see ReadMe.txt for references +/// @n +/// + + +// Core library for code-sense - IDE-based +#if defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#else // error +#error Platform not supported +#endif // end IDE + +// Set parameters +#define USE_TMP007 0 +#define USE_OPT3001 1 +#define USE_BME280 1 + +// Include application, user and local libraries +#include "Wire.h" +#include "Sensor_Units.h" + + +// Define variables and constants +#if (USE_TMP007 == 1) +#include "Sensor_TMP007.h" +Sensor_TMP007 myTMP007; +float TMP007_internalTemperature, TMP007_externalTemperature; +#endif + +#if (USE_OPT3001 == 1) +#include "Sensor_OPT3001.h" +Sensor_OPT3001 myOPT3001; +float OPT3001_light; +#endif + +#if (USE_BME280 == 1) +#include "Sensor_BME280.h" +Sensor_BME280 myBME280; +float BME280_pressure, BME280_temperature, BME280_humidity; +#endif + +// Edit period_ms +const uint32_t period_ms = 10000; + + +// Add setup code +void setup() +{ + Serial.begin(9600); + Wire.begin(); + +#if (USE_TMP007 == 1) + myTMP007.begin(TMP007_FOUR_SAMPLES); + myTMP007.get(); +#endif + +#if (USE_OPT3001 == 1) + myOPT3001.begin(); + myOPT3001.get(); +#endif + +#if (USE_BME280 == 1) + myBME280.begin(); + myBME280.get(); +#endif +} + +// Add loop code +void loop() +{ +#if (USE_TMP007 == 1) + myTMP007.get(); + TMP007_internalTemperature = conversion(myTMP007.internalTemperature(), KELVIN, CELSIUS); + TMP007_externalTemperature = conversion(myTMP007.externalTemperature(), KELVIN, CELSIUS)); + Serial.print("TMP007_internalTemperature "); + Serial.print(TMP007_internalTemperature); + Serial.println(CELSIUS.symbol) + + Serial.print("TMP007_externalTemperature "); + Serial.print(TMP007_externalTemperature); + Serial.println(CELSIUS.symbol) +#endif + +#if (USE_OPT3001 == 1) + myOPT3001.get(); + OPT3001_light = myOPT3001.light(); + Serial.print("OPT3001_light "); + Serial.print(OPT3001_light); + Serial.println(LUX.symbol); +#endif + +#if (USE_BME280 == 1) + myBME280.get(); + BME280_pressure = myBME280.pressure(); + BME280_temperature = conversion(myBME280.temperature(), KELVIN, CELSIUS); + BME280_humidity = myBME280.humidity(); + + Serial.print("BME280_pressure "); + Serial.print(BME280_pressure); + Serial.println(HECTOPASCAL.symbol); + + Serial.print("BME280_temperature "); + Serial.print(BME280_temperature); + Serial.println(CELSIUS.symbol); + + Serial.print("BME280_humidity "); + Serial.print(BME280_humidity); + Serial.println("%"); +#endif + + Serial.println(); + delay(period_ms); +} diff --git a/extra/WeatherSensors - Reference Manual.pdf b/extra/WeatherSensors - Reference Manual.pdf new file mode 100644 index 0000000..f875149 Binary files /dev/null and b/extra/WeatherSensors - Reference Manual.pdf differ diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..b47333a --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=Weather Sensors BoosterPack Library +version=1.0.2 +author=Rei Vilo +maintainer=Rei Vilo +sentence=Library for the weather sensors of the Sensors BoosterPack +paragraph=The Weather Sensors Library supports the TMP007 infra-red thermometer, OPT3001 light sensor and BME280 thermometer, barometer and hydrometer of the Sensors BoosterPack. +category=Sensors +url=http://embeddedcomputing.weebly.com/sensors-boosterpack.html +architectures=cc3200emt,msp432,tivac,msp430 diff --git a/src/Sensor_BME280.cpp b/src/Sensor_BME280.cpp new file mode 100644 index 0000000..6357ecf --- /dev/null +++ b/src/Sensor_BME280.cpp @@ -0,0 +1,377 @@ +// +// Sensor_BME280.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode+ +// http://embedXcode.weebly.com +// +// Project SensorsBoosterPack +// +// Created by Rei Vilo, 20/08/2015 13:43 +// http://embeddedcomputing.weebly.com +// +// Copyright (c) Rei Vilo, 2015-2016 +// Licence CC = BY SA NC +// +// See Sensor_BME280.h and ReadMe.txt for references +// + + + +// 0xF7 to 0xFE +#define BME280_SLAVE_ADDRESS 0x77 + +#define BME280_DATA_F7_FE 0xf7 +#define BME280_CONTROL_TEMPERATURE_PRESSURE 0xf4 +#define BME280_CONTROL_HUMIDITY 0xf2 +#define BME280_STATUS 0xf3 +#define BME280_CONFIGURATION 0xf5 +#define BME280_RESET 0xe0 + +#define BME280_VALUE_RESET_EXECUTE 0xb6 + +#define BME280_CALIBRATION_T1 0x88 +#define BME280_CALIBRATION_T2 0x8a +#define BME280_CALIBRATION_T3 0x8c +#define BME280_CALIBRATION_P1 0x8e +#define BME280_CALIBRATION_P2 0x90 +#define BME280_CALIBRATION_P3 0x92 +#define BME280_CALIBRATION_P4 0x94 +#define BME280_CALIBRATION_P5 0x96 +#define BME280_CALIBRATION_P6 0x98 +#define BME280_CALIBRATION_P7 0x9a +#define BME280_CALIBRATION_P8 0x9c +#define BME280_CALIBRATION_P9 0x9e +#define BME280_calibrationH1 0xa1 + +#define BME280_calibrationH2 0xe1 +#define BME280_calibrationH3 0xe3 +#define BME280_calibrationH4 0xe4 +#define BME280_calibrationH5 0xe5 +#define BME280_calibrationH6 0xe7 + +// Library header +#include "Sensor_BME280.h" +#include "Wire_Utilities.h" + +// Code + +Sensor_BME280::Sensor_BME280() +{ + +} + +String Sensor_BME280::WhoAmI() +{ + return "BME280 temperature + humidity + pressure"; +} + +void Sensor_BME280::begin() +{ + writeRegister8(BME280_SLAVE_ADDRESS, BME280_RESET, BME280_VALUE_RESET_EXECUTE); + delay(100); + writeRegister8(BME280_SLAVE_ADDRESS, BME280_CONTROL_TEMPERATURE_PRESSURE, 0x3f); + writeRegister8(BME280_SLAVE_ADDRESS, BME280_CONTROL_HUMIDITY, 0x03); + + // Register Address Register content Data type + // 0x88 / 0x89 dig_T1 [7:0] / [15:8] unsigned short = uint16_t + // 0x8A / 0x8B dig_T2 [7:0] / [15:8] signed short = int16_t + // 0x8C / 0x8D dig_T3 [7:0] / [15:8] signed short + // 0x8E / 0x8F dig_P1 [7:0] / [15:8] unsigned short = uint16_t + // 0x90 / 0x91 dig_P2 [7:0] / [15:8] signed short + // 0x92 / 0x93 dig_P3 [7:0] / [15:8] signed short + // 0x94 / 0x95 dig_P4 [7:0] / [15:8] signed short + // 0x96 / 0x97 dig_P5 [7:0] / [15:8] signed short + // 0x98 / 0x99 dig_P6 [7:0] / [15:8] signed short + // 0x9A / 0x9B dig_P7 [7:0] / [15:8] signed short + // 0x9C / 0x9D dig_P8 [7:0] / [15:8] signed short + // 0x9E / 0x9F dig_P9 [7:0] / [15:8] signed short + // 0xA1 dig_H1 [7:0] unsigned char = uint8_t + // 0xE1 / 0xE2 dig_H2 [7:0] / [15:8] signed short = int16_t + // 0xE3 dig_H3 [7:0] unsigned char = uint8_t + // 0xE4 / 0xE5[3:0] dig_H4 [11:4] / [3:0] signed short = int16_t + // 0xE5[7:4] / 0xE6 dig_H5 [3:0] / [11:4] signed short = int16_t + // 0xE7 dig_H6 signed char = int8_t + + _calibrationT1 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_T1, LSBFIRST); // uint16_t + _calibrationT2 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_T2, LSBFIRST); // int16_t + _calibrationT3 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_T3, LSBFIRST); // int16_t + + _calibrationP1 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P1, LSBFIRST); // uint16_t + _calibrationP2 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P2, LSBFIRST); // int16_t + _calibrationP3 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P3, LSBFIRST); // int16_t + _calibrationP4 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P4, LSBFIRST); // int16_t + _calibrationP5 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P5, LSBFIRST); // int16_t + _calibrationP6 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P6, LSBFIRST); // int16_t + _calibrationP7 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P7, LSBFIRST); // int16_t + _calibrationP8 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P8, LSBFIRST); // int16_t + _calibrationP9 = readRegister16(BME280_SLAVE_ADDRESS, BME280_CALIBRATION_P9, LSBFIRST); // int16_t + + _calibrationH1 = readRegister8(BME280_SLAVE_ADDRESS, BME280_calibrationH1); // uint8_t + _calibrationH2 = readRegister16(BME280_SLAVE_ADDRESS, BME280_calibrationH2, LSBFIRST); // int16_t + _calibrationH3 = readRegister8(BME280_SLAVE_ADDRESS, BME280_calibrationH3); // uint8_t + + // 0xE4 / 0xE5[3:0] dig_H4 [11:4] / [3:0] signed short = int16_t + _calibrationH4 = (readRegister8(BME280_SLAVE_ADDRESS, 0xe4) << 4) + (readRegister8(BME280_SLAVE_ADDRESS, 0xe5) & 0x0f); + // 0xE5[7:4] / 0xE6 dig_H5 [3:0] / [11:4] signed short = int16_t + _calibrationH5 = (readRegister8(BME280_SLAVE_ADDRESS, 0xe5) >> 4) + (readRegister8(BME280_SLAVE_ADDRESS, 0xe6) << 4); + + _calibrationH6 = readRegister8(BME280_SLAVE_ADDRESS, BME280_calibrationH6); // int8_t + + /* + QuickDebugln("calibration T1 ui16: %i", _calibrationT1); + QuickDebugln("calibration T2 i16: %i", _calibrationT2); + QuickDebugln("calibration T3 i16: %i", _calibrationT3); + + QuickDebugln("calibration P1 ui16: %i", _calibrationP1); + QuickDebugln("calibration P2 i16: %i", _calibrationP2); + QuickDebugln("calibration P3 i16: %i", _calibrationP3); + QuickDebugln("calibration P4 i16: %i", _calibrationP4); + QuickDebugln("calibration P5 i16: %i", _calibrationP5); + QuickDebugln("calibration P6 i16: %i", _calibrationP6); + QuickDebugln("calibration P7 i16: %i", _calibrationP7); + QuickDebugln("calibration P8 i16: %i", _calibrationP8); + QuickDebugln("calibration P9 i16: %i", _calibrationP9); + + QuickDebugln("calibration H1 ui8: %i", _calibrationH1); + QuickDebugln("calibration H2 i16: %i", _calibrationH2); + QuickDebugln("calibration H3 ui8: %i", _calibrationH3); + QuickDebugln("calibration H4 i16: %i", _calibrationH4); + QuickDebugln("calibration H5 i16: %i", _calibrationH5); + QuickDebugln("calibration H6 i8: %i", _calibrationH6); + */ + + // Is some delay needed for readiness? + delay(100); + // First dummy reading required? + get(); +} + +uint8_t Sensor_BME280::get() +{ + int32_t _rawPressure, _rawTemperature, _rawHumidity; + int32_t t_fine; + + // while (readRegister8(BME280_SLAVE_ADDRESS, BME280_STATUS) & 0x08); + + Wire.beginTransmission(BME280_SLAVE_ADDRESS); + Wire.write(BME280_DATA_F7_FE); + Wire.endTransmission(); + + // uint8_t data[8]; + // Wire.requestFrom(BME280_SLAVE_ADDRESS, 8); + // while (Wire.available() < 8); + // for (uint8_t i=0; i<8; i++) { + // data[i] = Wire.read(); + // } + // + // _rawPressure = ((uint32_t)data[0] << 12) + ((uint32_t)data[1] << 4) + ((uint32_t)data[2]>> 4); // f7.f8.f9 + // _rawTemperature = ((uint32_t)data[3] << 12) + ((uint32_t)data[4] << 4) + ((uint32_t)data[5]>> 4); // fa.fb.fc + // _rawHumidity = ((uint32_t)data[6] << 8) + ((uint32_t)data[7]); // fd.fe + + Wire.requestFrom(BME280_SLAVE_ADDRESS, 8); + while (Wire.available() < 8); + _rawPressure = ((uint32_t)Wire.read() << 12) + ((uint32_t)Wire.read() << 4) + ((uint32_t)Wire.read() >> 4); // f7.f8.f9 + _rawTemperature = ((uint32_t)Wire.read() << 12) + ((uint32_t)Wire.read() << 4) + ((uint32_t)Wire.read() >> 4); // fa.fb.fc + _rawHumidity = ((uint32_t)Wire.read() << 8) + ((uint32_t)Wire.read()); // fd.fe + + if (_rawPressure == 0x80000) + { + return BM280_ERROR; + // Serial.print("!!! Error"); + } + + // QuickDebugln("_rawPressure %x", _rawPressure); + // QuickDebugln("_rawTemperature %x", _rawTemperature); + // QuickDebugln("_rawHumidity %x", _rawHumidity); + + + /* + // Code from Bosch + // 1. Temperature + int32_t v_x1_u32, v_x2_u32; + int32_t t_fine; + + v_x1_u32 = ((((_rawTemperature>> 3) - ((int32_t)_calibrationT1 << 1))) * ((int32_t)_calibrationT2))>> 11; + v_x2_u32 = (((((_rawTemperature>> 4) - ((int32_t)_calibrationT1)) * ((_rawTemperature>> 4) - ((int32_t)_calibrationT1)))>> 12) * ((int32_t)_calibrationT3))>> 14; + t_fine = v_x1_u32 + v_x2_u32; + + QuickDebugln("v_x1_u32 %i, v_x2_u32 %i \r\n", v_x1_u32, v_x2_u32); + + // _temperature = (float)(t_fine * 5 + 128) * (1.0/256.0); + // _temperature = (float)(t_fine * 10 + 256) * (1.0/512.0); + _temperature = (float)(v_x1_u32 + v_x2_u32) / 5120.0; + + // 2. Pressure + uint32_t pressure32; + + v_x1_u32 = (((int32_t)t_fine)>> 1) - (int32_t)64000; + v_x2_u32 = (((v_x1_u32>> 2) * (v_x1_u32>> 2))>> 11) * ((int32_t)_calibrationP6); + v_x2_u32 = v_x2_u32 + ((v_x1_u32 * ((int32_t)_calibrationP5)) << 1); + v_x2_u32 = (v_x2_u32>> 2) + (((int32_t)_calibrationP4) << 16); + v_x1_u32 = (((_calibrationP3 * (((v_x1_u32>> 2) * (v_x1_u32>> 2))>> 13))>> 3) + ((((int32_t)_calibrationP2) * v_x1_u32)>> 1))>> 18; + v_x1_u32 = ((((32768+v_x1_u32)) * ((int32_t)_calibrationP1))>> 15); + + if (v_x1_u32 != 0) { + // Avoid exception caused by division by zero + pressure32 = (((uint32_t)(((int32_t)1048576) - _rawPressure) - (v_x2_u32>> 12))) * 3125; + if (pressure32 < 0x80000000) pressure32 = (pressure32 << 1) / ((uint32_t)v_x1_u32); + else pressure32 = (pressure32 / (uint32_t)v_x1_u32) * 2; + + v_x1_u32 = (((int32_t)_calibrationP9) * ((int32_t)(((pressure32>> 3) * (pressure32>> 3))>> 13)))>> 12; + v_x2_u32 = (((int32_t)(pressure32>> 2)) * ((int32_t)_calibrationP8))>> 13; + // pressure32 = (float)(uint32_t)((int32_t)pressure32 + ((v_x1_u32 + v_x2_u32 + _calibrationP7)>> 4)); + // pressure32 = pressure32 + (v_x1_u32 + v_x2_u32 + ((float)_calibrationP7)) / 16.0; + _pressure = (float)pressure32 + ((float)(v_x1_u32 + v_x2_u32 + _calibrationP7) / 16.0); + + } + + // 3. Humidity + v_x1_u32 = (t_fine - ((int32_t)76800)); + v_x1_u32 = (((((_rawHumidity << 14) - (((int32_t)_calibrationH4) << 20) - (((int32_t)_calibrationH5) * v_x1_u32)) + ((int32_t)16384))>> 15) * (((((((v_x1_u32 * ((int32_t)_calibrationH6))>> 10) * (((v_x1_u32 * ((int32_t)_calibrationH3))>> 11) + ((int32_t)32768)))>> 10) + ((int32_t)2097152)) * ((int32_t)_calibrationH2) + 8192)>> 14)); + v_x1_u32 = (v_x1_u32 - (((((v_x1_u32>> 15) * (v_x1_u32>> 15))>> 7) * ((int32_t)_calibrationH1))>> 4)); + v_x1_u32 = (v_x1_u32 < 0 ? 0 : v_x1_u32); + v_x1_u32 = (v_x1_u32 > 419430400 ? 419430400 : v_x1_u32); + _humidity = (float)(v_x1_u32>> 12) / 512.0; + */ + + /* + // Code from Bosch, float + float v_x1_u32 = 0.0; + float v_x2_u32 = 0.0; + + // 1. Temperature + v_x1_u32 = (((float)_rawPressure) / 16384.0 - ((float)_calibrationT1) / 1024.0) * ((float)_calibrationT2); + v_x2_u32 = ((((float)_rawTemperature) / 131072.0 - ((float)_calibrationT1) / 8192.0) * (((float)_rawTemperature) / 131072.0 - ((float)_calibrationT1) / 8192.0)) * ((float)_calibrationT3); + t_fine = (int32_t)(v_x1_u32 + v_x2_u32); + _temperature = (v_x1_u32 + v_x2_u32) / 5120.0; + + // 2. Pressure + v_x1_u32 = ((float)t_fine / 2.0) - 64000.0; + v_x2_u32 = v_x1_u32 * v_x1_u32 * ((float)_calibrationP6) / 32768.0; + v_x2_u32 = v_x2_u32 + v_x1_u32 * ((float)_calibrationP5) * 2.0; + v_x2_u32 = (v_x2_u32 / 4.0) + (((float)_calibrationP4) * 65536.0); + v_x1_u32 = (((float)_calibrationP3) * v_x1_u32 * v_x1_u32 / 524288.0 + ((float)_calibrationP2) * v_x1_u32) / 524288.0; + v_x1_u32 = (1.0 + v_x1_u32 / 32768.0) * ((float)_calibrationP1); + + // Avoid exception caused by division by zero + if (v_x1_u32 != 0) + { + _pressure = 1048576.0 - (float)_rawPressure ; + _pressure = (_pressure - (v_x2_u32 / 4096.0)) * 6250.0 / v_x1_u32; + v_x1_u32 = ((float)_calibrationP9) * _pressure * _pressure / 2147483648.0; + v_x2_u32 = _pressure * ((float)_calibrationP8) / 32768.0; + _pressure = _pressure + (v_x1_u32 + v_x2_u32 + ((float)_calibrationP7)) / 16.0; + } + + // 3. Humidity + float var_h = (((float)t_fine) - 76800.0); + // Avoid invalid data + + QuickDebugln("var_h %5.2f", var_h); + if (var_h != 0) + { + _humidity = (_rawHumidity - (((float)_calibrationH4) * 64.0 + ((float)_calibrationH5) / 16384.0 * var_h)) * (((float)_calibrationH2) / 65536.0 * (1.0 + ((float) _calibrationH6) / 67108864.0 * var_h * (1.0 + ((float)_calibrationH3) / 67108864.0 * var_h))); + _humidity = _humidity * (1.0 - ((float)_calibrationH1)*var_h / 524288.0); + + QuickDebugln("_humidity %5.2f", _humidity); + if (_humidity > 100.0) _humidity = 100.0; + else if (_humidity < 0.0) _humidity = 0.0; + } + */ + + // Code from Adafruit + int64_t var1, var2, var3; + + // 1. Temperature + var1 = ((((_rawTemperature >> 3) - ((int32_t)_calibrationT1 << 1))) * ((int32_t)_calibrationT2)) >> 11; + var2 = (((((_rawTemperature >> 4) - ((int32_t)_calibrationT1)) * ((_rawTemperature >> 4) - ((int32_t)_calibrationT1))) >> 12) * ((int32_t)_calibrationT3)) >> 14; + t_fine = var1 + var2; + + // _temperature = (float)(t_fine * 5 + 128) / 25600.0; + _temperature = (float)(t_fine) / 5120.0 + 273.15; // in Kelvin + + // 2. Pressure + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)_calibrationP6; + var2 = var2 + ((var1 * (int64_t)_calibrationP5) << 17); + var2 = var2 + (((int64_t)_calibrationP4) << 35); + var1 = ((var1 * var1 * (int64_t)_calibrationP3) >> 8) + ((var1 * (int64_t)_calibrationP2) << 12); + var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)_calibrationP1) >> 33; + + if (var1 != 0) + { + var3 = 1048576 - _rawPressure; + var3 = (((var3 << 31) - var2) * 3125) / var1; + var1 = (((int64_t)_calibrationP9) * (var3 >> 13) * (var3 >> 13)) >> 25; + var2 = (((int64_t)_calibrationP8) * var3) >> 19; + + var3 = ((var3 + var1 + var2) >> 8) + (((int64_t)_calibrationP7) << 4); + _pressure = (float)var3 / 25600.0; // in hPa + } + + // 3. Humidity + var1 = (t_fine - ((int32_t)76800)); + + var1 = (((((_rawHumidity << 14) - (((int32_t)_calibrationH4) << 20) - (((int32_t)_calibrationH5) * var1)) + ((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)_calibrationH6)) >> 10) * (((var1 * ((int32_t)_calibrationH3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)_calibrationH2) + 8192) >> 14)); + + var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)_calibrationH1)) >> 4)); + + if (var1 < 0) + { + var1 = 0; + } + if (var1 > 419430400) + { + var1 = 419430400; + } + _humidity = (float)(var1 >> 12) / 1024.0; // in % + + return BM280_SUCCESS; +} + +float Sensor_BME280::temperature() +{ + + return _temperature; +} + +float Sensor_BME280::humidity() +{ + return _humidity; +} + +float Sensor_BME280::pressure() +{ + return _pressure; +} + +void Sensor_BME280::setPowerMode(uint8_t mode) +{ + +} + +float Sensor_BME280::absolutePressure(float altitudeMeters) +{ + return _pressure / pow(1 - altitudeMeters / 44330.77, 5.255876); + + // Absolute pressure from read = relative pressure would be + // return seaLevelPressure * pow(1 - altitudeMeters / 44330.77, 5.255876); +} + +float Sensor_BME280::altitude(float seaLevelPressure) +{ + return 44330.77 * (1.0 - pow(_pressure / seaLevelPressure, 0.190263)); +} + +float Sensor_BME280::altitude(float referencePressure, float referenceAltitude) +{ + // Sea level pressure + float seaLevelPressure = referencePressure / pow(1 - referenceAltitude / 44330.77, 5.255876); + // Altitude based on absolute pressure + return 44330.0 * (1.0 - pow(_pressure / seaLevelPressure, 0.1903)); +} + + + + diff --git a/src/Sensor_BME280.h b/src/Sensor_BME280.h new file mode 100644 index 0000000..7c97a91 --- /dev/null +++ b/src/Sensor_BME280.h @@ -0,0 +1,189 @@ +/// +/// @file Sensor_BME280.h +/// @brief Library header for BME280 sensor +/// @details BME280 Combined humidity and pressure sensor +/// @n +/// @n @b Project SensorsBoosterPack +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// +/// @date 20/08/2015 13:43 +/// @version 102 +/// +/// @copyright (c) Rei Vilo, 2015-2016 +/// @copyright CC = BY SA NC +/// +/// @see ReadMe.txt for references +/// * Pressure Altimetry using the MPL3115A2 +/// @n http://cache.freescale.com/files/sensors/doc/app_note/AN4528.pdf +/// + + +// Core library for code-sense - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(ROBOTIS) // Robotis specific +#include "libpandora_types.h" +#include "pandora.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#elif defined(LITTLEROBOTFRIENDS) // LittleRobotFriends specific +#include "LRF.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(REDBEARLAB) // RedBearLab specific +#include "Arduino.h" +#elif defined(RFDUINO) // RFduino specific +#include "Arduino.h" +#elif defined(SPARK) // Spark specific +#include "application.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +# error Platform not defined +#endif // end IDE + +#ifndef Sensor_BME280_RELEASE +/// +/// @brief Release +/// +#define Sensor_BME280_RELEASE 102 + +#define BM280_SUCCESS 0 ///< success +#define BM280_ERROR 1 ///< error + +#include "Wire.h" + +/// +/// @brief Class for sensor BME280 +/// @details Combined humidity and pressure sensor +/// @see http://www.bosch-sensortec.com/de/homepage/products_3/environmental_sensors_1/bme280/bme280_1 +/// +class Sensor_BME280 +{ + public: + /// + /// @brief Constructor + /// + Sensor_BME280(); + + /// + /// @brief Initialisation + /// @todo mode hardware accuracy + /// @param number of reads + /// @note See Table # of the BME280 data-sheet + /// @todo Add options + /// + void begin(); + + /// + /// @brief Who am I? + /// @return Who am I? string + /// + String WhoAmI(); + + /// + /// @brief Acquire data + /// @return 0 if success, error code otherwise + /// @code + /// do + /// { + /// delay(100); + /// result = myBME280.get(); + /// count++; + /// } + /// while ((result > 0) and (count < 8)); + /// @endcode + /// + uint8_t get(); + + /// + /// @brief Return temperature + /// @return temperature, in °K + /// @note Use conversion() for another unit + /// + float temperature(); + + /// + /// @brief Return relative humidity + /// @return relative humidity, in % + /// + float humidity(); + + /// + /// @brief Return pressure, relative to current altitude + /// @return pressure, in hPa + /// @note Use conversion() for another unit + /// + float pressure(); + + /// + /// @brief Return absolute pressure, equivalent at sea level + /// @param altitudeMeters current altitude, in meter + /// @return absolute pressure at sea level, in hPa + /// @note Use conversion() for another unit + /// + float absolutePressure(float altitudeMeters = 50.0); + + /// + /// @brief Return altitude based on pressure + /// @param seaLevelPressure pressure at sea level, in hPa + /// @return altitude, in meter + /// @note Use conversion() for another unit + /// + float altitude(float seaLevelPressure = 1013.250); + + /// + /// @brief Return altitude based on reference pressure and altitude + /// @param referencePressure reference pressure, in hPa + /// @param referenceAltitude reference altitude, in meter + /// @return altitude in meter + /// @note The reference is a measure of the pressure at a known altitude. + /// @note Use conversion() for another unit + /// + float altitude(float referencePressure = 1013.250, float referenceAltitude = 0.0); + + /// + /// @brief Set power mode + /// @param mode default=LOW=sleep, HIGH=activated + /// + void setPowerMode(uint8_t mode = LOW); + + private: + float _temperature; + float _humidity; + float _pressure; + + uint16_t _calibrationT1; + int16_t _calibrationT2; + int16_t _calibrationT3; + + uint16_t _calibrationP1; + int16_t _calibrationP2; + int16_t _calibrationP3; + int16_t _calibrationP4; + int16_t _calibrationP5; + int16_t _calibrationP6; + int16_t _calibrationP7; + int16_t _calibrationP8; + int16_t _calibrationP9; + + uint8_t _calibrationH1; + int16_t _calibrationH2; + uint8_t _calibrationH3; + int16_t _calibrationH4; + int16_t _calibrationH5; + int8_t _calibrationH6; +}; + +#endif diff --git a/src/Sensor_OPT3001.cpp b/src/Sensor_OPT3001.cpp new file mode 100644 index 0000000..576962f --- /dev/null +++ b/src/Sensor_OPT3001.cpp @@ -0,0 +1,128 @@ +// +// Sensor_OPT3001.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode+ +// http://embedXcode.weebly.com +// +// Project SensorsBoosterPack +// +// Created by a0273900 for initial C-library +// Adapted by Rei Vilo, Aug 20, 2015 13:42 +// http://embeddedcomputing.weebly.com +// +// Copyright (c) Rei Vilo, 2015-2016 +// Licence CC = BY SA NC +// +// See Sensor_OPT3001.h and ReadMe.txt for references +// + + +// Library header +#include "Sensor_OPT3001.h" +#include "Wire_Utilities.h" + + +// Constants +#define OPT3001_SLAVE_ADDRESS 0x47 + +#define OPT3001_RESULT_REGISTER 0x00 +#define OPT3001_CONFIGURATION_REGISTER 0x01 +#define OPT3001_LOW_LIMIT_REGISTER 0x02 +#define OPT3001_HIGH_LIMIT_REGISTER 0x03 +#define OPT3001_MANUFACTURE_ID_REGISTER 0x7e +#define OPT3001_DEVICE_ID_REGISTER 0x7f + +#define OPT3001_READY_FLAG 0x80 +#define OPT3001_POWER_UP 0x0400 + + +// Code +Sensor_OPT3001::Sensor_OPT3001() +{ + ; +} + +String Sensor_OPT3001::WhoAmI() +{ + return "OPT3001 luxmeter"; +} + +void Sensor_OPT3001::begin(uint16_t configuration, uint8_t interruptPin) +{ + // Set configuration + writeRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_CONFIGURATION_REGISTER, configuration); + _interruptPin = interruptPin; +} + +/* + uint16_t Sensor_OPT3001::readManufacturerId() + { + return readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_MANUFACTUREID_REGISTER); + } + + uint16_t Sensor_OPT3001::readDeviceId() + { + return readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_DEVICEID_REGISTER); + } + + uint16_t Sensor_OPT3001::readConfigReg() + { + return readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_CONFIGURATION_REGISTER); + } + + uint16_t Sensor_OPT3001::readLowLimitReg() + { + return readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_LOWLIMIT_REGISTER); + } + + uint16_t Sensor_OPT3001::readHighLimitReg() + { + return readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_HIGHLIMIT_REGISTER); + } +*/ + +void Sensor_OPT3001::get() +{ + _rawLux = readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_RESULT_REGISTER); + + // Extract _fraction and _exponent from _rawLux data + uint32_t _fraction = _rawLux & 0x0fff; + uint32_t _exponent = 1 << ((_rawLux >> 12) & 0x000f); // to be /64 = >>6 + + _rawLux = (_fraction * _exponent) >> 6; +} + +//uint32_t Sensor_OPT3001::light() +float Sensor_OPT3001::light() +{ + + // Scale to lux + return 0, 0625 * (float)_rawLux; +} + +void Sensor_OPT3001::setPowerMode(uint8_t mode) +{ + // uint16_t statusMaskRegister = readRegister16(TMP007_SLAVE_ADDRESS, TMP007_STATUS_MASK); + // Serial.print("sm=\t"); + // Serial.print(statusMaskRegister, BIN); + + //#define OPT3001_100_MS 0xc010 // shut-down = clear 0x0400 + //#define OPT3001_100_MS 0xc410 // continous = set 0x0400 + //#define OPT3001_800_MS 0xc810 // shut-down + //#define OPT3001_800_MS 0xcc10 // continuous + uint16_t configurationRegister = readRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_CONFIGURATION_REGISTER); + + if (mode == HIGH) + { + configurationRegister |= OPT3001_POWER_UP; + } + else + { + configurationRegister &= OPT3001_POWER_UP; + } + + writeRegister16(OPT3001_SLAVE_ADDRESS, OPT3001_CONFIGURATION_REGISTER, configurationRegister); +} + + diff --git a/src/Sensor_OPT3001.h b/src/Sensor_OPT3001.h new file mode 100644 index 0000000..3dc02ba --- /dev/null +++ b/src/Sensor_OPT3001.h @@ -0,0 +1,137 @@ +/// +/// @file Sensor_OPT3001.h +/// @brief Library header for OPT3001 sensor +/// @details OPT3001 Digital Ambient Light Sensor (ALS) with High Precision Human Eye Response +/// @n +/// @n @b Project SensorsBoosterPack +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author a0273900 for initial C-library +/// @author Rei Vilo for Energia adapted C++-library +/// @author http://embeddedcomputing.weebly.com +/// +/// @date 20/08/2015 13:42 +/// @version 102 +/// +/// @copyright (c) Rei Vilo, 2015-2016 +/// @copyright CC = BY SA NC +/// +/// @see ReadMe.txt for references +/// + + +// Core library for code-sense - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(ROBOTIS) // Robotis specific +#include "libpandora_types.h" +#include "pandora.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#elif defined(LITTLEROBOTFRIENDS) // LittleRobotFriends specific +#include "LRF.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(REDBEARLAB) // RedBearLab specific +#include "Arduino.h" +#elif defined(RFDUINO) // RFduino specific +#include "Arduino.h" +#elif defined(SPARK) // Spark specific +#include "application.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +# error Platform not defined +#endif // end IDE + +#include "Wire.h" + +#ifndef Sensor_OPT3001_RELEASE +/// +/// @brief Release +/// +#define Sensor_OPT3001_RELEASE 102 + +/// +/// @brief Conversion modes +/// @{ +//#define OPT3001_100_MS 0xc010 // shut-down +#define OPT3001_100_MS 0xc410 ///< continous +//#define OPT3001_800_MS 0xc810 // shut-down +#define OPT3001_800_MS 0xcc10 ///< continuous +#define OPT3001_INTERRUPT_PIN 11 +/// @} + +/// +/// @brief Class for sensor OPT3001 +/// @details Digital Ambient Light Sensor (ALS) with High Precision Human Eye Response +/// @see http://www.ti.com/product/OPT3001 +/// +class Sensor_OPT3001 +{ + public: + /// + /// @brief Constructor + /// + Sensor_OPT3001(); + + /// + /// @brief Initialisation + /// @param configuration default = 100 ms, OPT3001_100_MS or OPT3001_800_MS + /// @param interruptPin default = 11 + /// + void begin(uint16_t configuration = OPT3001_100_MS, + uint8_t interruptPin = OPT3001_INTERRUPT_PIN); + + /// + /// @brief Who Am I? + /// @return name of the sensor, string + /// + String WhoAmI(); + + /// + /// @brief Acquisition + /// + void get(); + + /// + /// @brief Measure + /// @return light in lux + /// + // uint32_t light(); + float light(); + + /// + /// @brief Manage power + /// @param mode LOW=default=off, HIGH=on + /// + void setPowerMode(uint8_t mode = LOW); + + /* + uint16_t readManufacturerId(); + uint16_t readDeviceId(); + uint16_t readConfigReg(); + uint16_t readLowLimitReg(); + uint16_t readHighLimitReg(); + */ + + private: + // uint16_t manu_id;/**< manufacture chip id of the sensor*/ + // uint16_t device_id;/**< device id of the sensor*/ + // uint16_t config_reg;/**< configuration register setting*/ + // uint16_t lowlimit_reg;/**< low limit register value*/ + // uint16_t highlimit_reg;/**< high limit register value*/ + uint8_t _interruptPin; + uint32_t _rawLux; ///< raw lux result register value +}; + + +#endif diff --git a/src/Sensor_TMP007.cpp b/src/Sensor_TMP007.cpp new file mode 100644 index 0000000..4c6681c --- /dev/null +++ b/src/Sensor_TMP007.cpp @@ -0,0 +1,128 @@ +// +// Sensor_TMP007.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode+ +// http://embedXcode.weebly.com +// +// Project SensorsBoosterPack +// +// Created by Rei Vilo, 20/08/2015 13:42 +// http://embeddedcomputing.weebly.com +// +// Copyright (c) Rei Vilo, 2015-2016 +// Licence CC = BY SA NC +// +// See Sensor_TMP007.h and ReadMe.txt for references +// + + +// Library header +#include "Sensor_TMP007.h" +#include "Wire_Utilities.h" + +#define TMP007_SLAVE_ADDRESS 0x40 +#define TMP007_VOLTAGE 0x00 +#define TMP007_INTERNAL_TEMPERATURE 0x01 +#define TMP007_CONFIGURATION 0x02 +#define TMP007_EXTERNAL_TEMPERATURE 0x03 +#define TMP007_STATUS 0x04 +#define TMP007_STATUS_MASK 0x05 +#define TMP007_MANUFACTURER_ID 0xFE +#define TMP007_DEVICE_ID 0xFF + +#define TMP007_ALERT_ENABLE 0x0100 +#define TMP007_RESET 0x8000 +//#define TMP007_POWER_DOWN 0x0000 +#define TMP007_POWER_UP 0x1000 +#define TMP007_READY 0x4000 + +#define TMP007_CONVERSION_DONE 0x0080 + + +// Code +Sensor_TMP007::Sensor_TMP007() +{ + +} + +void Sensor_TMP007::begin(uint16_t totalSamples) +{ + writeRegister16(TMP007_SLAVE_ADDRESS, TMP007_CONFIGURATION, TMP007_RESET); + writeRegister16(TMP007_SLAVE_ADDRESS, TMP007_CONFIGURATION, TMP007_POWER_UP | totalSamples); + // writeRegister16(TMP007_SLAVE_ADDRESS, TMP007_STATUS_MASK, TMP007_READY); + delay(100); +} + +void Sensor_TMP007::get() +{ + int16_t _rawTemperature; + + _rawTemperature = readRegister16(TMP007_SLAVE_ADDRESS, TMP007_INTERNAL_TEMPERATURE); + // .03125 = 1 / 32 + _internalTemperature = (float)(_rawTemperature >> 2) * .03125 + 273.15; + + // Serial.print("?=\t"); + // Serial.print(readRegister16(TMP007_SLAVE_ADDRESS, TMP007_STATUS), BIN); + // Serial.print("\t"); + // Serial.print(readRegister16(TMP007_SLAVE_ADDRESS, TMP007_CONFIGURATION), BIN); + // Serial.print("\t"); + // Serial.print("\tb0="); + // Serial.print(_rawTemperature, BIN); + // Serial.print("\tb0&="); + // Serial.print(((_rawTemperature & 0b1) == 0), DEC); + // Serial.print("\t"); + + _rawTemperature = readRegister16(TMP007_SLAVE_ADDRESS, TMP007_EXTERNAL_TEMPERATURE); + // Check validity in bit 0 + if ((_rawTemperature & 0b1) == 0) + { + _externalTemperature = (float)(_rawTemperature >> 2) * .03125 + 273.15; + } + else + { + _externalTemperature = 0.0; // or keep previous reading + } +} + +String Sensor_TMP007::WhoAmI() +{ + return "TMP007 IR temperature"; +} + +float Sensor_TMP007::internalTemperature() +{ + return _internalTemperature; +} + +float Sensor_TMP007::externalTemperature() +{ + return _externalTemperature; +} + +void Sensor_TMP007::setPowerMode(uint8_t mode) +{ + // uint16_t statusMaskRegister = readRegister16(TMP007_SLAVE_ADDRESS, TMP007_STATUS_MASK); + // Serial.print("sm=\t"); + // Serial.print(statusMaskRegister, BIN); + + uint16_t configurationRegister = readRegister16(TMP007_SLAVE_ADDRESS, TMP007_CONFIGURATION); + + // Serial.print(configurationRegister, BIN); + + if (mode == HIGH) + { + configurationRegister |= TMP007_POWER_UP; + } + else + { + configurationRegister &= ~TMP007_POWER_UP; + } + + // Serial.print("\tc=\t"); + // Serial.print(configurationRegister, BIN); + // Serial.println(); + // + writeRegister16(TMP007_SLAVE_ADDRESS, TMP007_CONFIGURATION, configurationRegister); +} + diff --git a/src/Sensor_TMP007.h b/src/Sensor_TMP007.h new file mode 100644 index 0000000..9c1363c --- /dev/null +++ b/src/Sensor_TMP007.h @@ -0,0 +1,131 @@ +/// +/// @file Sensor_TMP007.h +/// @brief Library header for TMP007 sensor +/// @details TMP007 Infrared Thermopile Contactless Temperature Sensor with Integrated Math Engine +/// @n +/// @n @b Project SensorsBoosterPack +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author a0273900 Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// +/// @date 20/08/2015 13:42 +/// @version 102 +/// +/// @copyright (c) Rei Vilo, 2015-2016 +/// @copyright CC = BY SA NC +/// +/// @see ReadMe.txt for references +/// + + +// Core library for code-sense - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(ROBOTIS) // Robotis specific +#include "libpandora_types.h" +#include "pandora.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#elif defined(LITTLEROBOTFRIENDS) // LittleRobotFriends specific +#include "LRF.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(REDBEARLAB) // RedBearLab specific +#include "Arduino.h" +#elif defined(RFDUINO) // RFduino specific +#include "Arduino.h" +#elif defined(SPARK) // Spark specific +#include "application.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +# error Platform not defined +#endif // end IDE + +#ifndef Sensor_TMP007_cpp +/// +/// @brief Release +/// +#define Sensor_TMP007_cpp 102 + + +/// +/// @brief TMP007 constants +/// @{ +#define TMP007_ONE_SAMPLE 0x0000 +#define TMP007_TWO_SAMPLES 0x0200 +#define TMP007_FOUR_SAMPLES 0x0400 +#define TMP007_EIGHT_SAMPLES 0x0600 +#define TMP007_SIXTEEN_SAMPLES 0x0800 +#define TMP007_ONE_SAMPLE_LOW_POWER 0x0A00 +#define TMP007_TWO_SAMPLES_LOW_POWER 0x0C00 +#define TMP007_FOUR_SAMPLES_LOW_POWER 0x0E00 +/// @} + +#include "Wire.h" + +/// +/// @brief Class for sensor TMP007 +/// @details Infrared Thermopile Contactless Temperature Sensor with Integrated Math Engine +/// @see http://www.ti.com/product/TMP007 +/// +class Sensor_TMP007 +{ + public: + /// + /// @brief Constructor + /// + Sensor_TMP007(); + + /// + /// @brief Initialisation + /// @param totalSamples default = 4 samples, use pre-defined constants + /// + void begin(uint16_t totalSamples = TMP007_FOUR_SAMPLES); + + /// + /// @brief Who Am I? + /// @return name of the sensor, string + /// + String WhoAmI(); + + /// + /// @brief Acquisition + /// + void get(); + + /// + /// @brief Measure + /// @return Internal temperature in °K + /// + float internalTemperature(); + + /// + /// @brief Measure + /// @return External temperature in °K + /// + float externalTemperature(); + + /// + /// @brief Manage power + /// @param mode LOW=default=off, HIGH=on + /// + void setPowerMode(uint8_t mode = LOW); + + + private: + float _internalTemperature; + float _externalTemperature; +}; + + +#endif diff --git a/src/Sensor_Units.cpp b/src/Sensor_Units.cpp new file mode 100644 index 0000000..ee5c7b8 --- /dev/null +++ b/src/Sensor_Units.cpp @@ -0,0 +1,24 @@ +// +// Sensor_Units.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode+ +// http://embedXcode.weebly.com +// +// Project SensorsBoosterPack +// +// Created by Rei Vilo, 20/08/2015 19:03 +// http://embeddedcomputing.weebly.com +// +// Copyright (c) Rei Vilo, 2015-2016 +// Licence CC = BY SA NC +// +// See Sensor_Units.h for references +// + + +// Include library header +#include "Sensor_Units.h" + +// Library code +// Empty, because template shall be in the same file. diff --git a/src/Sensor_Units.h b/src/Sensor_Units.h new file mode 100644 index 0000000..9dd5398 --- /dev/null +++ b/src/Sensor_Units.h @@ -0,0 +1,148 @@ +/// +/// @file Sensor_Units.h +/// @brief Library header +/// @details Units conversion for sensors +/// @n +/// @n @b Project SensorsBoosterPack +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// +/// @date Aug 20, 2015 19:03 +/// @version 102 +/// +/// @copyright (c) Rei Vilo, 2015-2016 +/// @copyright CC = SA BY NC +/// +/// @see ReadMe.txt for references +/// + +#ifndef Sensor_Units_RELEASE +/// +/// @brief Release +/// +#define Sensor_Units_RELEASE 102 + + +// Include core library - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(ROBOTIS) // Robotis specific +#include "libpandora_types.h" +#include "pandora.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#elif defined(LITTLEROBOTFRIENDS) // LittleRobotFriends specific +#include "LRF.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(REDBEARLAB) // RedBearLab specific +#include "Arduino.h" +#elif defined(RFDUINO) // RFduino specific +#include "Arduino.h" +#elif defined(SPARK) // Spark specific +#include "application.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +# error Platform not defined +#endif // end IDE + + +// Library header +/// +/// @brief Units +/// @details A unit contains gain and base for conversion based on the SI reference unit. +/// @note For each set of units, all units are defined the SI reference unit +/// @todo A better solution would be typed enum. +/// @n unit = (SI reference unit) * gain + base +/// +/// @{ +struct unit_conversion_s +{ + float gain; ///< gain + float base; ///< base + char symbol[4]; ///< symbol +}; +/// @} + +/// +/// @brief Temperature units +/// @{ +typedef unit_conversion_s temperature_unit_t; +const temperature_unit_t KELVIN = { 1, 0, "°K"}; ///< °K degree kelvin, SI reference +const temperature_unit_t CELSIUS = { 1, -273.15, "°C"}; ///< °C degree celsius +const temperature_unit_t FAHRENHEIT = { 1.8, -459.67, "°F"}; ///< °F degree fahrenheit +/// @} + +/// +/// @brief Pressure units +/// @{ +typedef unit_conversion_s pressure_unit_t; +const pressure_unit_t PASCAL = { 1, 0, "Pa"}; ///< Pa pascal, SI reference +const pressure_unit_t HECTOPASCAL = { 1e-2, 0, "hPa"}; ///< hPa hecto pascal, SI reference +const pressure_unit_t BAR = { 1e-5, 0, "bar"}; ///< bar +const pressure_unit_t ATMOSPHERE = { 1.0 / 101325.0, 0, "atm"}; ///< atmosphere +const pressure_unit_t PSI = { 0.014503773801, 0, "atm"}; ///< 0.014503773801 pound force/square inch +/// @} + +/// +/// @brief Altitude units +/// @{ +typedef unit_conversion_s altitude_unit_t; +const altitude_unit_t METRE = { 1, 0, "m"}; ///< m metre, SI reference +const altitude_unit_t FOOT = { 0.3048, 0, "ft"}; ///< ft foot +/// @} + +/// +/// @brief Light units +/// @{ +typedef unit_conversion_s light_unit_t; +const light_unit_t LUX = { 1, 0, "lux"}; ///< lux, SI reference +/// @} + +/// +/// @brief Conversion utility +/// @param value input value to be converted, float +/// @param unitFrom unit of the input value to be converted +/// @param unitTo unit for the output converted value +/// @return output converted value, float +/// +template +float conversion(float value, myType unitFrom, myType unitTo) +{ + return (value - unitFrom.base) / unitFrom.gain * unitTo.gain + unitTo.base; +} + +/// +/// @brief Unit symbol as String +/// @param unit unit constant +/// @return symbol as String +/// +template +String symbolString(myType unit) +{ + return String(unit.symbol); +} + +/// +/// @brief Unit symbol as char* +/// @param unit unit constant +/// @return symbol as char* +/// +template +char * symbolChar(myType unit) +{ + return unit.symbol; +} + +#endif diff --git a/src/Wire_Utilities.cpp b/src/Wire_Utilities.cpp new file mode 100644 index 0000000..ec6b64d --- /dev/null +++ b/src/Wire_Utilities.cpp @@ -0,0 +1,88 @@ +// +// Wire_Utilities.cpp +// Library C++ code +// ---------------------------------- +// Developed with embedXcode+ +// http://embedXcode.weebly.com +// +// Project SensorsBoosterPack +// +// Created by Rei Vilo, 20/08/2015 18:02 +// http://embeddedcomputing.weebly.com +// +// Copyright (c) Rei Vilo, 2015-2016 +// Licence CC = BY SA NC +// +// See Wire_Utilities.h for references +// + + +// Include library header +#include "Wire_Utilities.h" + +// Library code +void writeRegister8(uint8_t device, uint8_t command, uint8_t data8) +{ + Wire.beginTransmission(device); + Wire.write(command); + Wire.write(data8); + Wire.endTransmission(); +} + +void writeRegister16(uint8_t device, uint8_t command, uint16_t data16, uint8_t mode) +{ + Wire.beginTransmission(device); + Wire.write(command); + if (mode == MSBFIRST) + { + Wire.write(highByte(data16)); + Wire.write(lowByte(data16)); + } + else + { + Wire.write(lowByte(data16)); + Wire.write(highByte(data16)); + } + Wire.endTransmission(); +} + +uint8_t readRegister8(uint8_t device, uint8_t command) +{ + uint8_t value; + + Wire.beginTransmission(device); + Wire.write(command); + Wire.endTransmission(); + + uint8_t w = Wire.requestFrom(device, 1); + while (Wire.available() < 1); + value = Wire.read(); + + return value; +} + +uint16_t readRegister16(uint8_t device, uint8_t command, uint8_t mode) +{ + uint16_t value; + + Wire.beginTransmission(device); + Wire.write(command); + Wire.endTransmission(); + + uint8_t w = Wire.requestFrom(device, 2); + while (Wire.available() < 2); + + if (mode == MSBFIRST) + { + value = Wire.read() << 8; + value |= Wire.read(); + } + else + { + value = Wire.read(); + value |= Wire.read() << 8; + } + + return value; +} + diff --git a/src/Wire_Utilities.h b/src/Wire_Utilities.h new file mode 100644 index 0000000..c6f6da9 --- /dev/null +++ b/src/Wire_Utilities.h @@ -0,0 +1,103 @@ +/// +/// @file Wire_Utilities.h +/// @brief Library header +/// @details Utilities for 8- and 16-bit read and write operations +/// @n +/// @n @b Project SensorsBoosterPack +/// @n @a Developed with [embedXcode+](http://embedXcode.weebly.com) +/// +/// @author Rei Vilo +/// @author http://embeddedcomputing.weebly.com +/// +/// @date 20/08/2015 18:02 +/// @version 102 +/// +/// @copyright (c) Rei Vilo, 2015-2016 +/// @copyright CC = BY SA NC +/// +/// @see ReadMe.txt for references +/// + +#ifndef Wire_Utilities_RELEASE +#define Wire_Utilities_RELEASE 102 + +// Include core library - IDE-based +#if defined(WIRING) // Wiring specific +#include "Wiring.h" +#elif defined(MAPLE_IDE) // Maple specific +#include "WProgram.h" +#elif defined(ROBOTIS) // Robotis specific +#include "libpandora_types.h" +#include "pandora.h" +#elif defined(MPIDE) // chipKIT specific +#include "WProgram.h" +#elif defined(DIGISPARK) // Digispark specific +#include "Arduino.h" +#elif defined(ENERGIA) // LaunchPad specific +#include "Energia.h" +#elif defined(LITTLEROBOTFRIENDS) // LittleRobotFriends specific +#include "LRF.h" +#elif defined(MICRODUINO) // Microduino specific +#include "Arduino.h" +#elif defined(TEENSYDUINO) // Teensy specific +#include "Arduino.h" +#elif defined(REDBEARLAB) // RedBearLab specific +#include "Arduino.h" +#elif defined(RFDUINO) // RFduino specific +#include "Arduino.h" +#elif defined(SPARK) // Spark specific +#include "application.h" +#elif defined(ARDUINO) // Arduino 1.0 and 1.5 specific +#include "Arduino.h" +#else // error +# error Platform not defined +#endif // end IDE + + +#include "Wire.h" + + +// Library header +/// +/// @brief Write 1 byte +/// @param device I2C address, 7-bit coded +/// @param command command or register, 8-bit +/// @param data8 value, 8-bit +/// +void writeRegister8(uint8_t device, uint8_t command, uint8_t data8); + + +/// +/// @brief Write 2 bytes +/// @param device I2C address, 7-bit coded +/// @param command command or register, 8-bit +/// @param data16 value, 16-bit +/// @param mode default=MSBFIRST, other option=LSBFIRST +/// @note * with MSBFIRST, data16[15..8] written to command, data16[7..Ø] to command + 1 +/// @note * with LSBFIRST, data16[7..Ø] written to command, data16[15..8] to command + 1 +/// +void writeRegister16(uint8_t device, uint8_t command, uint16_t data16, uint8_t mode = MSBFIRST); + + +/// +/// @brief Read 1 byte +/// @param device I2C address, 7-bit coded +/// @param command command, 8-bit +/// @return data8 value, 8-bit +/// +uint8_t readRegister8(uint8_t device, uint8_t command); + + +/// +/// @brief Read 2 bytes +/// @param device I2C address, 7-bit coded +/// @param command command or register, 8-bit +/// @param mode default=MSBFIRST, other option=LSBFIRST +/// @return data16 value, 16-bit +/// @note * with MSBFIRST, data16[15..8] read from command, data16[7..Ø] from command + 1 +/// @note * with LSBFIRST, data16[7..Ø] read from command, data16[15..8] from command + 1 +/// +uint16_t readRegister16(uint8_t device, uint8_t command, uint8_t mode = MSBFIRST); + + +#endif