diff --git a/src/libs/Adafruit_BMP280_Library-master/.github/ISSUE_TEMPLATE.md b/src/libs/Adafruit_BMP280_Library-master/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..f0e2614 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,46 @@ +Thank you for opening an issue on an Adafruit Arduino library repository. To +improve the speed of resolution please review the following guidelines and +common troubleshooting steps below before creating the issue: + +- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use + the forums at http://forums.adafruit.com to ask questions and troubleshoot why + something isn't working as expected. In many cases the problem is a common issue + that you will more quickly receive help from the forum community. GitHub issues + are meant for known defects in the code. If you don't know if there is a defect + in the code then start with troubleshooting on the forum first. + +- **If following a tutorial or guide be sure you didn't miss a step.** Carefully + check all of the steps and commands to run have been followed. Consult the + forum if you're unsure or have questions about steps in a guide/tutorial. + +- **For Arduino projects check these very common issues to ensure they don't apply**: + + - For uploading sketches or communicating with the board make sure you're using + a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes + very hard to tell the difference between a data and charge cable! Try using the + cable with other devices or swapping to another cable to confirm it is not + the problem. + + - **Be sure you are supplying adequate power to the board.** Check the specs of + your board and plug in an external power supply. In many cases just + plugging a board into your computer is not enough to power it and other + peripherals. + + - **Double check all soldering joints and connections.** Flakey connections + cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. + + - **Ensure you are using an official Arduino or Adafruit board.** We can't + guarantee a clone board will have the same functionality and work as expected + with this code and don't support them. + +If you're sure this issue is a defect in the code and checked the steps above +please fill in the following fields to provide enough troubleshooting information. +You may delete the guideline and text above to just leave the following details: + +- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** + +- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO + VERSION HERE** + +- List the steps to reproduce the problem below (if possible attach a sketch or + copy the sketch code in too): **LIST REPRO STEPS BELOW** diff --git a/src/libs/Adafruit_BMP280_Library-master/.github/PULL_REQUEST_TEMPLATE.md b/src/libs/Adafruit_BMP280_Library-master/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7b641eb --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +Thank you for creating a pull request to contribute to Adafruit's GitHub code! +Before you open the request please review the following guidelines and tips to +help it be more easily integrated: + +- **Describe the scope of your change--i.e. what the change does and what parts + of the code were modified.** This will help us understand any risks of integrating + the code. + +- **Describe any known limitations with your change.** For example if the change + doesn't apply to a supported platform of the library please mention it. + +- **Please run any tests or examples that can exercise your modified code.** We + strive to not break users of the code and running tests/examples helps with this + process. + +Thank you again for contributing! We will try to test and integrate the change +as soon as we can, but be aware we have many GitHub repositories to manage and +can't immediately respond to every request. There is no need to bump or check in +on a pull request (it will clutter the discussion of the request). + +Also don't be worried if the request is closed or not integrated--sometimes the +priorities of Adafruit's GitHub code (education, ease of use) might not match the +priorities of the pull request. Don't fret, the open source community thrives on +forks and GitHub makes it easy to keep your changes in a forked repo. + +After reviewing the guidelines above you can delete this text from the pull request. diff --git a/src/libs/Adafruit_BMP280_Library-master/.gitignore b/src/libs/Adafruit_BMP280_Library-master/.gitignore new file mode 100644 index 0000000..542d266 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/.gitignore @@ -0,0 +1,8 @@ +# osx +.DS_Store + +# doxygen +Doxyfile* +doxygen_sqlite3.db +html +*.tmp diff --git a/src/libs/Adafruit_BMP280_Library-master/.travis.yml b/src/libs/Adafruit_BMP280_Library-master/.travis.yml new file mode 100644 index 0000000..d62fe09 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/.travis.yml @@ -0,0 +1,29 @@ +language: c +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ +git: + depth: false + quiet: true +env: + global: + - ARDUINO_IDE_VERSION="1.8.7" + - PRETTYNAME="Adafruit BMP280 Arduino Library" +# Optional, will default to "$TRAVIS_BUILD_DIR/Doxyfile" +# - DOXYFILE: $TRAVIS_BUILD_DIR/Doxyfile + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +install: + - true + +script: + - build_main_platforms + +# Generate and deploy documentation +after_success: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh) + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh) diff --git a/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.cpp b/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.cpp new file mode 100644 index 0000000..e1b8bcc --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.cpp @@ -0,0 +1,414 @@ +/*! + * @file Adafruit_BMP280.cpp + * + * This is a library for the BMP280 orientation sensor + * + * Designed specifically to work with the Adafruit BMP280 Sensor. + * + * Pick one up today in the adafruit shop! + * ------> https://www.adafruit.com/product/2651 + * + * These sensors use I2C to communicate, 2 pins are required to interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * K.Townsend (Adafruit Industries) + * + * BSD license, all text above must be included in any redistribution + */ + +#include "Adafruit_BMP280.h" +#include "Arduino.h" +#include + +/*! + * @brief BMP280 constructor using i2c + * @param *theWire + * optional wire + */ +Adafruit_BMP280::Adafruit_BMP280(TwoWire *theWire) + : _cs(-1), _mosi(-1), _miso(-1), _sck(-1) { + _wire = theWire; +} + +/*! + * @brief BMP280 constructor using hardware SPI + * @param cspin + * cs pin number + * @param theSPI + * optional SPI object + */ +Adafruit_BMP280::Adafruit_BMP280(int8_t cspin, SPIClass *theSPI) + : _cs(cspin), _mosi(-1), _miso(-1), _sck(-1) { + _spi = theSPI; +} + +/*! + * @brief BMP280 constructor using bitbang SPI + * @param cspin + * The pin to use for CS/SSEL. + * @param mosipin + * The pin to use for MOSI. + * @param misopin + * The pin to use for MISO. + * @param sckpin + * The pin to use for SCK. + */ +Adafruit_BMP280::Adafruit_BMP280(int8_t cspin, int8_t mosipin, int8_t misopin, + int8_t sckpin) + : _cs(cspin), _mosi(mosipin), _miso(misopin), _sck(sckpin) {} + +/*! + * Initialises the sensor. + * @param addr + * The I2C address to use (default = 0x77) + * @param chipid + * The expected chip ID (used to validate connection). + * @return True if the init was successful, otherwise false. + */ +bool Adafruit_BMP280::begin(uint8_t addr, uint8_t chipid) { + _i2caddr = addr; + + if (_cs == -1) { + // i2c + _wire->begin(); + } else { + digitalWrite(_cs, HIGH); + pinMode(_cs, OUTPUT); + + if (_sck == -1) { + // hardware SPI + _spi->begin(); + } else { + // software SPI + pinMode(_sck, OUTPUT); + pinMode(_mosi, OUTPUT); + pinMode(_miso, INPUT); + } + } + + if (read8(BMP280_REGISTER_CHIPID) != chipid) + return false; + + readCoefficients(); + // write8(BMP280_REGISTER_CONTROL, 0x3F); /* needed? */ + setSampling(); + delay(100); + return true; +} + +/*! + * Sets the sampling config for the device. + * @param mode + * The operating mode of the sensor. + * @param tempSampling + * The sampling scheme for temp readings. + * @param pressSampling + * The sampling scheme for pressure readings. + * @param filter + * The filtering mode to apply (if any). + * @param duration + * The sampling duration. + */ +void Adafruit_BMP280::setSampling(sensor_mode mode, + sensor_sampling tempSampling, + sensor_sampling pressSampling, + sensor_filter filter, + standby_duration duration) { + _measReg.mode = mode; + _measReg.osrs_t = tempSampling; + _measReg.osrs_p = pressSampling; + + _configReg.filter = filter; + _configReg.t_sb = duration; + + write8(BMP280_REGISTER_CONFIG, _configReg.get()); + write8(BMP280_REGISTER_CONTROL, _measReg.get()); +} + +uint8_t Adafruit_BMP280::spixfer(uint8_t x) { + if (_sck == -1) + return _spi->transfer(x); + + // software spi + // Serial.println("Software SPI"); + uint8_t reply = 0; + for (int i = 7; i >= 0; i--) { + reply <<= 1; + digitalWrite(_sck, LOW); + digitalWrite(_mosi, x & (1 << i)); + digitalWrite(_sck, HIGH); + if (digitalRead(_miso)) + reply |= 1; + } + return reply; +} + +/**************************************************************************/ +/*! + @brief Writes an 8 bit value over I2C/SPI +*/ +/**************************************************************************/ +void Adafruit_BMP280::write8(byte reg, byte value) { + if (_cs == -1) { + _wire->beginTransmission((uint8_t)_i2caddr); + _wire->write((uint8_t)reg); + _wire->write((uint8_t)value); + _wire->endTransmission(); + } else { + if (_sck == -1) + _spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); + digitalWrite(_cs, LOW); + spixfer(reg & ~0x80); // write, bit 7 low + spixfer(value); + digitalWrite(_cs, HIGH); + if (_sck == -1) + _spi->endTransaction(); // release the SPI bus + } +} + +/*! + * @brief Reads an 8 bit value over I2C/SPI + * @param reg + * selected register + * @return value from selected register + */ +uint8_t Adafruit_BMP280::read8(byte reg) { + uint8_t value; + + if (_cs == -1) { + _wire->beginTransmission((uint8_t)_i2caddr); + _wire->write((uint8_t)reg); + _wire->endTransmission(); + _wire->requestFrom((uint8_t)_i2caddr, (byte)1); + value = _wire->read(); + + } else { + if (_sck == -1) + _spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); + digitalWrite(_cs, LOW); + spixfer(reg | 0x80); // read, bit 7 high + value = spixfer(0); + digitalWrite(_cs, HIGH); + if (_sck == -1) + _spi->endTransaction(); // release the SPI bus + } + return value; +} + +/*! + * @brief Reads a 16 bit value over I2C/SPI + */ +uint16_t Adafruit_BMP280::read16(byte reg) { + uint16_t value; + + if (_cs == -1) { + _wire->beginTransmission((uint8_t)_i2caddr); + _wire->write((uint8_t)reg); + _wire->endTransmission(); + _wire->requestFrom((uint8_t)_i2caddr, (byte)2); + value = (_wire->read() << 8) | _wire->read(); + + } else { + if (_sck == -1) + _spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); + digitalWrite(_cs, LOW); + spixfer(reg | 0x80); // read, bit 7 high + value = (spixfer(0) << 8) | spixfer(0); + digitalWrite(_cs, HIGH); + if (_sck == -1) + _spi->endTransaction(); // release the SPI bus + } + + return value; +} + +uint16_t Adafruit_BMP280::read16_LE(byte reg) { + uint16_t temp = read16(reg); + return (temp >> 8) | (temp << 8); +} + +/*! + * @brief Reads a signed 16 bit value over I2C/SPI + */ +int16_t Adafruit_BMP280::readS16(byte reg) { return (int16_t)read16(reg); } + +int16_t Adafruit_BMP280::readS16_LE(byte reg) { + return (int16_t)read16_LE(reg); +} + +/*! + * @brief Reads a 24 bit value over I2C/SPI + */ +uint32_t Adafruit_BMP280::read24(byte reg) { + uint32_t value; + + if (_cs == -1) { + _wire->beginTransmission((uint8_t)_i2caddr); + _wire->write((uint8_t)reg); + _wire->endTransmission(); + _wire->requestFrom((uint8_t)_i2caddr, (byte)3); + + value = _wire->read(); + value <<= 8; + value |= _wire->read(); + value <<= 8; + value |= _wire->read(); + + } else { + if (_sck == -1) + _spi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); + digitalWrite(_cs, LOW); + spixfer(reg | 0x80); // read, bit 7 high + + value = spixfer(0); + value <<= 8; + value |= spixfer(0); + value <<= 8; + value |= spixfer(0); + + digitalWrite(_cs, HIGH); + if (_sck == -1) + _spi->endTransaction(); // release the SPI bus + } + + return value; +} + +/*! + * @brief Reads the factory-set coefficients + */ +void Adafruit_BMP280::readCoefficients() { + _bmp280_calib.dig_T1 = read16_LE(BMP280_REGISTER_DIG_T1); + _bmp280_calib.dig_T2 = readS16_LE(BMP280_REGISTER_DIG_T2); + _bmp280_calib.dig_T3 = readS16_LE(BMP280_REGISTER_DIG_T3); + + _bmp280_calib.dig_P1 = read16_LE(BMP280_REGISTER_DIG_P1); + _bmp280_calib.dig_P2 = readS16_LE(BMP280_REGISTER_DIG_P2); + _bmp280_calib.dig_P3 = readS16_LE(BMP280_REGISTER_DIG_P3); + _bmp280_calib.dig_P4 = readS16_LE(BMP280_REGISTER_DIG_P4); + _bmp280_calib.dig_P5 = readS16_LE(BMP280_REGISTER_DIG_P5); + _bmp280_calib.dig_P6 = readS16_LE(BMP280_REGISTER_DIG_P6); + _bmp280_calib.dig_P7 = readS16_LE(BMP280_REGISTER_DIG_P7); + _bmp280_calib.dig_P8 = readS16_LE(BMP280_REGISTER_DIG_P8); + _bmp280_calib.dig_P9 = readS16_LE(BMP280_REGISTER_DIG_P9); +} + +/*! + * Reads the temperature from the device. + * @return The temperature in degress celcius. + */ +float Adafruit_BMP280::readTemperature() { + int32_t var1, var2; + + int32_t adc_T = read24(BMP280_REGISTER_TEMPDATA); + adc_T >>= 4; + + var1 = ((((adc_T >> 3) - ((int32_t)_bmp280_calib.dig_T1 << 1))) * + ((int32_t)_bmp280_calib.dig_T2)) >> + 11; + + var2 = (((((adc_T >> 4) - ((int32_t)_bmp280_calib.dig_T1)) * + ((adc_T >> 4) - ((int32_t)_bmp280_calib.dig_T1))) >> + 12) * + ((int32_t)_bmp280_calib.dig_T3)) >> + 14; + + t_fine = var1 + var2; + + float T = (t_fine * 5 + 128) >> 8; + return T / 100; +} + +/*! + * Reads the barometric pressure from the device. + * @return Barometric pressure in Pa. + */ +float Adafruit_BMP280::readPressure() { + int64_t var1, var2, p; + + // Must be done first to get the t_fine variable set up + readTemperature(); + + int32_t adc_P = read24(BMP280_REGISTER_PRESSUREDATA); + adc_P >>= 4; + + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)_bmp280_calib.dig_P6; + var2 = var2 + ((var1 * (int64_t)_bmp280_calib.dig_P5) << 17); + var2 = var2 + (((int64_t)_bmp280_calib.dig_P4) << 35); + var1 = ((var1 * var1 * (int64_t)_bmp280_calib.dig_P3) >> 8) + + ((var1 * (int64_t)_bmp280_calib.dig_P2) << 12); + var1 = + (((((int64_t)1) << 47) + var1)) * ((int64_t)_bmp280_calib.dig_P1) >> 33; + + if (var1 == 0) { + return 0; // avoid exception caused by division by zero + } + p = 1048576 - adc_P; + p = (((p << 31) - var2) * 3125) / var1; + var1 = (((int64_t)_bmp280_calib.dig_P9) * (p >> 13) * (p >> 13)) >> 25; + var2 = (((int64_t)_bmp280_calib.dig_P8) * p) >> 19; + + p = ((p + var1 + var2) >> 8) + (((int64_t)_bmp280_calib.dig_P7) << 4); + return (float)p / 256; +} + +/*! + * @brief Calculates the approximate altitude using barometric pressure and the + * supplied sea level hPa as a reference. + * @param seaLevelhPa + * The current hPa at sea level. + * @return The approximate altitude above sea level in meters. + */ +float Adafruit_BMP280::readAltitude(float seaLevelhPa) { + float altitude; + + float pressure = readPressure(); // in Si units for Pascal + pressure /= 100; + + altitude = 44330 * (1.0 - pow(pressure / seaLevelhPa, 0.1903)); + + return altitude; +} + +/*! + * Calculates the pressure at sea level (in hPa) from the specified altitude + * (in meters), and atmospheric pressure (in hPa). + * @param altitude Altitude in meters + * @param atmospheric Atmospheric pressure in hPa + * @return The approximate pressure + */ +float Adafruit_BMP280::seaLevelForAltitude(float altitude, float atmospheric) { + // Equation taken from BMP180 datasheet (page 17): + // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf + + // Note that using the equation from wikipedia can give bad results + // at high altitude. See this thread for more information: + // http://forums.adafruit.com/viewtopic.php?f=22&t=58064 + return atmospheric / pow(1.0 - (altitude / 44330.0), 5.255); +} + +/*! + * @brief Take a new measurement (only possible in forced mode) + * !!!todo!!! + */ +/* +void Adafruit_BMP280::takeForcedMeasurement() +{ + // If we are in forced mode, the BME sensor goes back to sleep after each + // measurement and we need to set it to forced mode once at this point, so + // it will take the next measurement and then return to sleep again. + // In normal mode simply does new measurements periodically. + if (_measReg.mode == MODE_FORCED) { + // set to forced mode, i.e. "take next measurement" + write8(BMP280_REGISTER_CONTROL, _measReg.get()); + // wait until measurement has been completed, otherwise we would read + // the values from the last measurement + while (read8(BMP280_REGISTER_STATUS) & 0x08) + delay(1); + } +} +*/ diff --git a/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.h b/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.h new file mode 100644 index 0000000..6941f42 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/Adafruit_BMP280.h @@ -0,0 +1,225 @@ +/*! + * @file Adafruit_BMP280.h + * + * This is a library for the Adafruit BMP280 Breakout. + * + * Designed specifically to work with the Adafruit BMP280 Breakout. + * + * Pick one up today in the adafruit shop! + * ------> https://www.adafruit.com/product/2651 + * + * These sensors use I2C to communicate, 2 pins are required to interface. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit andopen-source hardware by purchasing products + * from Adafruit! + * + * K.Townsend (Adafruit Industries) + * + * BSD license, all text above must be included in any redistribution + */ +#ifndef __BMP280_H__ +#define __BMP280_H__ + +#include "Arduino.h" +#include +#include + +/*! + * I2C ADDRESS/BITS/SETTINGS + */ +#define BMP280_ADDRESS (0x77) /**< The default I2C address for the sensor. */ +#define BMP280_ADDRESS_ALT \ + (0x76) /**< Alternative I2C address for the sensor. */ +#define BMP280_CHIPID (0x58) /**< Default chip ID. */ + +// Forward declarations of Wire and SPI for board/variant combinations that don't have a default 'Wire' or 'SPI' +extern TwoWire Wire; /**< Forward declaration of Wire object */ +extern SPIClass SPI; /**< Forward declaration of SPI object */ + +/*! + * Registers available on the sensor. + */ +enum { + BMP280_REGISTER_DIG_T1 = 0x88, + BMP280_REGISTER_DIG_T2 = 0x8A, + BMP280_REGISTER_DIG_T3 = 0x8C, + BMP280_REGISTER_DIG_P1 = 0x8E, + BMP280_REGISTER_DIG_P2 = 0x90, + BMP280_REGISTER_DIG_P3 = 0x92, + BMP280_REGISTER_DIG_P4 = 0x94, + BMP280_REGISTER_DIG_P5 = 0x96, + BMP280_REGISTER_DIG_P6 = 0x98, + BMP280_REGISTER_DIG_P7 = 0x9A, + BMP280_REGISTER_DIG_P8 = 0x9C, + BMP280_REGISTER_DIG_P9 = 0x9E, + BMP280_REGISTER_CHIPID = 0xD0, + BMP280_REGISTER_VERSION = 0xD1, + BMP280_REGISTER_SOFTRESET = 0xE0, + BMP280_REGISTER_CAL26 = 0xE1, /**< R calibration = 0xE1-0xF0 */ + BMP280_REGISTER_CONTROL = 0xF4, + BMP280_REGISTER_CONFIG = 0xF5, + BMP280_REGISTER_PRESSUREDATA = 0xF7, + BMP280_REGISTER_TEMPDATA = 0xFA, +}; + +/*! + * Struct to hold calibration data. + */ +typedef struct { + uint16_t dig_T1; /**< dig_T1 cal register. */ + int16_t dig_T2; /**< dig_T2 cal register. */ + int16_t dig_T3; /**< dig_T3 cal register. */ + + uint16_t dig_P1; /**< dig_P1 cal register. */ + int16_t dig_P2; /**< dig_P2 cal register. */ + int16_t dig_P3; /**< dig_P3 cal register. */ + int16_t dig_P4; /**< dig_P4 cal register. */ + int16_t dig_P5; /**< dig_P5 cal register. */ + int16_t dig_P6; /**< dig_P6 cal register. */ + int16_t dig_P7; /**< dig_P7 cal register. */ + int16_t dig_P8; /**< dig_P8 cal register. */ + int16_t dig_P9; /**< dig_P9 cal register. */ +} bmp280_calib_data; + +/** + * Driver for the Adafruit BMP280 barometric pressure sensor. + */ +class Adafruit_BMP280 { +public: + /** Oversampling rate for the sensor. */ + enum sensor_sampling { + /** No over-sampling. */ + SAMPLING_NONE = 0x00, + /** 1x over-sampling. */ + SAMPLING_X1 = 0x01, + /** 2x over-sampling. */ + SAMPLING_X2 = 0x02, + /** 4x over-sampling. */ + SAMPLING_X4 = 0x03, + /** 8x over-sampling. */ + SAMPLING_X8 = 0x04, + /** 16x over-sampling. */ + SAMPLING_X16 = 0x05 + }; + + /** Operating mode for the sensor. */ + enum sensor_mode { + /** Sleep mode. */ + MODE_SLEEP = 0x00, + /** Forced mode. */ + MODE_FORCED = 0x01, + /** Normal mode. */ + MODE_NORMAL = 0x03, + /** Software reset. */ + MODE_SOFT_RESET_CODE = 0xB6 + }; + + /** Filtering level for sensor data. */ + enum sensor_filter { + /** No filtering. */ + FILTER_OFF = 0x00, + /** 2x filtering. */ + FILTER_X2 = 0x01, + /** 4x filtering. */ + FILTER_X4 = 0x02, + /** 8x filtering. */ + FILTER_X8 = 0x03, + /** 16x filtering. */ + FILTER_X16 = 0x04 + }; + + /** Standby duration in ms */ + enum standby_duration { + /** 0.5 ms standby. */ + STANDBY_MS_1 = 0x00, + /** 62.5 ms standby. */ + STANDBY_MS_63 = 0x01, + /** 125 ms standby. */ + STANDBY_MS_125 = 0x02, + /** 250 ms standby. */ + STANDBY_MS_250 = 0x03, + /** 500 ms standby. */ + STANDBY_MS_500 = 0x04, + /** 1000 ms standby. */ + STANDBY_MS_1000 = 0x05, + /** 2000 ms standby. */ + STANDBY_MS_2000 = 0x06, + /** 4000 ms standby. */ + STANDBY_MS_4000 = 0x07 + }; + + Adafruit_BMP280(TwoWire *theWire = &Wire); + Adafruit_BMP280(int8_t cspin, SPIClass *theSPI = &SPI); + Adafruit_BMP280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin); + + bool begin(uint8_t addr = BMP280_ADDRESS, uint8_t chipid = BMP280_CHIPID); + + float readTemperature(); + + float seaLevelForAltitude(float altitude, float atmospheric); + + float readPressure(void); + + float readAltitude(float seaLevelhPa = 1013.25); + + // void takeForcedMeasurement(); + + void setSampling(sensor_mode mode = MODE_NORMAL, + sensor_sampling tempSampling = SAMPLING_X16, + sensor_sampling pressSampling = SAMPLING_X16, + sensor_filter filter = FILTER_OFF, + standby_duration duration = STANDBY_MS_1); + + TwoWire *_wire; /**< Wire object */ + SPIClass *_spi; /**< SPI object */ + +private: + /** Encapsulates the config register */ + struct config { + /** Inactive duration (standby time) in normal mode */ + unsigned int t_sb : 3; + /** Filter settings */ + unsigned int filter : 3; + /** Unused - don't set */ + unsigned int none : 1; + /** Enables 3-wire SPI */ + unsigned int spi3w_en : 1; + /** Used to retrieve the assembled config register's byte value. */ + unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; } + }; + + /** Encapsulates trhe ctrl_meas register */ + struct ctrl_meas { + /** Temperature oversampling. */ + unsigned int osrs_t : 3; + /** Pressure oversampling. */ + unsigned int osrs_p : 3; + /** Device mode */ + unsigned int mode : 2; + /** Used to retrieve the assembled ctrl_meas register's byte value. */ + unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; } + }; + + void readCoefficients(void); + uint8_t spixfer(uint8_t x); + void write8(byte reg, byte value); + uint8_t read8(byte reg); + uint16_t read16(byte reg); + uint32_t read24(byte reg); + int16_t readS16(byte reg); + uint16_t read16_LE(byte reg); + int16_t readS16_LE(byte reg); + + uint8_t _i2caddr; + + + int32_t _sensorID; + int32_t t_fine; + int8_t _cs, _mosi, _miso, _sck; + bmp280_calib_data _bmp280_calib; + config _configReg; + ctrl_meas _measReg; +}; + +#endif diff --git a/src/libs/Adafruit_BMP280_Library-master/README.md b/src/libs/Adafruit_BMP280_Library-master/README.md new file mode 100644 index 0000000..dbca8f9 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/README.md @@ -0,0 +1,47 @@ +# Adafruit BMP280 Driver (Barometric Pressure Sensor) [![Build Status](https://travis-ci.com/adafruit/Adafruit_BMP280_Library.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_BMP280_Library) + +This driver is for the [Adafruit BMP280 Breakout](http://www.adafruit.com/products/2651) + + + +## About the BMP280 ## + +This precision sensor from Bosch is the best low-cost sensing solution for measuring barometric pressure and temperature. Because pressure changes with altitude you can also use it as an altimeter! + +## About this Driver ## + +Adafruit invests time and resources providing this open source code. Please support Adafruit and open-source hardware by purchasing products from Adafruit! + +Written by Kevin (KTOWN) Townsend for Adafruit Industries. + + + +## Compatibility + +MCU | Tested Works | Doesn't Work | Not Tested | Notes +------------------ | :----------: | :----------: | :---------: | ----- +Atmega328 @ 16MHz | X | | | +Atmega328 @ 12MHz | X | | | +Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D2 & D3 +Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D2 & D3 +ESP8266 | X | | | SDA/SCL default to pins 4 & 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL) +Atmega2560 @ 16MHz | X | | | Use SDA/SCL on pins 20 & 21 +ATSAM3X8E | X | | | Use SDA/SCL on pins 20 & 21 +ATSAM21D | X | | | +ATtiny85 @ 16MHz | | X | | +ATtiny85 @ 8MHz | | X | | +Intel Curie @ 32MHz | | | X | +STM32F2 | | | X | + + * ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini + * ATmega328 @ 12MHz : Adafruit Pro Trinket 3V + * ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0 + * ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro + * ESP8266 : Adafruit Huzzah + * ATmega2560 @ 16MHz : Arduino Mega + * ATSAM3X8E : Arduino Due + * ATSAM21D : Arduino Zero, M0 Pro + * ATtiny85 @ 16MHz : Adafruit Trinket 5V + * ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V + + diff --git a/src/libs/Adafruit_BMP280_Library-master/assets/board.jpg b/src/libs/Adafruit_BMP280_Library-master/assets/board.jpg new file mode 100644 index 0000000..cd0d947 Binary files /dev/null and b/src/libs/Adafruit_BMP280_Library-master/assets/board.jpg differ diff --git a/src/libs/Adafruit_BMP280_Library-master/examples/bmp280test/bmp280test.ino b/src/libs/Adafruit_BMP280_Library-master/examples/bmp280test/bmp280test.ino new file mode 100644 index 0000000..ceb4fa6 --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/examples/bmp280test/bmp280test.ino @@ -0,0 +1,63 @@ +/*************************************************************************** + This is a library for the BMP280 humidity, temperature & pressure sensor + + Designed specifically to work with the Adafruit BMEP280 Breakout + ----> http://www.adafruit.com/products/2651 + + These sensors use I2C or SPI to communicate, 2 or 4 pins are required + to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit andopen-source hardware by purchasing products + from Adafruit! + + Written by Limor Fried & Kevin Townsend for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ***************************************************************************/ + +#include +#include +#include + +#define BMP_SCK (13) +#define BMP_MISO (12) +#define BMP_MOSI (11) +#define BMP_CS (10) + +Adafruit_BMP280 bmp; // I2C +//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI +//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); + +void setup() { + Serial.begin(9600); + Serial.println(F("BMP280 test")); + + if (!bmp.begin()) { + Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); + while (1); + } + + /* Default settings from datasheet. */ + bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ + Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ + Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */ + Adafruit_BMP280::FILTER_X16, /* Filtering. */ + Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ +} + +void loop() { + Serial.print(F("Temperature = ")); + Serial.print(bmp.readTemperature()); + Serial.println(" *C"); + + Serial.print(F("Pressure = ")); + Serial.print(bmp.readPressure()); + Serial.println(" Pa"); + + Serial.print(F("Approx altitude = ")); + Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */ + Serial.println(" m"); + + Serial.println(); + delay(2000); +} diff --git a/src/libs/Adafruit_BMP280_Library-master/library.properties b/src/libs/Adafruit_BMP280_Library-master/library.properties new file mode 100644 index 0000000..c05bb1b --- /dev/null +++ b/src/libs/Adafruit_BMP280_Library-master/library.properties @@ -0,0 +1,9 @@ +name=Adafruit BMP280 Library +version=1.0.5 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for BMP280 sensors. +paragraph=Arduino library for BMP280 pressure and altitude sensors. +category=Sensors +url=https://github.com/adafruit/Adafruit_BMP280_Library +architectures=* diff --git a/src/libs/HTU21D-master/README.md b/src/libs/HTU21D-master/README.md new file mode 100644 index 0000000..cf7795e --- /dev/null +++ b/src/libs/HTU21D-master/README.md @@ -0,0 +1,34 @@ +[![license-badge][]][license] ![version] [![stars][]][stargazers] [![hit-count][]][count] [![github-issues][]][issues] + +# HTU21D + +This is an Arduino library for SHT21, HTU21D & Si70xx Digital Humidity and Temperature Sensor + +Supports all sensors features: + +- read humidity for SHT21, HTU21D or compensated humidity for Si70xx** +- calculate compensated humidity for SHT21, HTU21D** +- read temperature for SHT21, HTU21D, Si70xx or retrive temperature value after RH measurement for Si70xx** +- soft reset +- check battery status +- turn ON/OFF build-in Heater +- read FW version** +- read sensor ID** + +Tested on: + +- Arduino AVR +- Arduino ESP8266 +- Arduino STM32 + +[license-badge]: https://img.shields.io/badge/License-GPLv3-blue.svg +[license]: https://choosealicense.com/licenses/gpl-3.0/ +[version]: https://img.shields.io/badge/Version-1.2.1-green.svg +[stars]: https://img.shields.io/github/stars/enjoyneering/HTU21D.svg +[hit-count]: http://hits.dwyl.io/enjoyneering/HTU21D/badges.svg +[count]: http://hits.dwyl.io/enjoyneering/HTU21D/badges +[stargazers]: https://github.com/enjoyneering/HTU21D/stargazers +[github-issues]: https://img.shields.io/github/issues/enjoyneering/HTU21D.svg +[issues]: https://github.com/enjoyneering/HTU21D/issues/ + +**Library returns 255, if there is a CRC8 mismatch or a communication error has occurred diff --git a/src/libs/HTU21D-master/examples/HTU21D_ATtinny85_Demo/HTU21D_ATtinny85_Demo.ino b/src/libs/HTU21D-master/examples/HTU21D_ATtinny85_Demo/HTU21D_ATtinny85_Demo.ino new file mode 100644 index 0000000..45445a6 --- /dev/null +++ b/src/libs/HTU21D-master/examples/HTU21D_ATtinny85_Demo/HTU21D_ATtinny85_Demo.ino @@ -0,0 +1,141 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sensor uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details: + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include +#include +#include //https://github.com/enjoyneering/LiquidCrystal_I2C + +#define LCD_ROWS 4 //qnt. of lcd rows +#define LCD_COLUMNS 20 //qnt. of lcd columns +#define DEGREE_SYMBOL 0xDF //degree symbol from the LCD ROM +#define MAX_HUMIDITY 100 //max. relative humidity +#define LED 1 //connect led to ATtiny85 pin no.6 in series with 470 Ohm resistor + +float humidity = 0; + +const uint8_t humidity_icon[8] PROGMEM = {0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 0x00}; //PROGMEM saves variable to flash & keeps dynamic memory free +const uint8_t plus_minus_icon[8] PROGMEM = {0x00, 0x04, 0x0E, 0x04, 0x00, 0x0E, 0x00, 0x00}; +const uint8_t temperature_icon[8] PROGMEM = {0x04, 0x0A, 0x0A, 0x0E, 0x0E, 0x1F, 0x1F, 0x0E}; + +/* +HTU21D(resolution) + +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12-Bit, Temperature: 14-Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8-Bit, Temperature: 12-Bit +HTU21D_RES_RH10_TEMP13 - RH: 10-Bit, Temperature: 13-Bit +HTU21D_RES_RH11_TEMP11 - RH: 11-Bit, Temperature: 11-Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); +LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); + + +void setup() +{ + pinMode(LED, OUTPUT); + + /* LCD connection check */ + while (lcd.begin(LCD_COLUMNS, LCD_ROWS) != true) //20 colums, 4 rows + { + digitalWrite(LED, HIGH); + delay(500); + digitalWrite(LED, LOW); + delay(500); + } + + /* HTU21D connection check */ + while (myHTU21D.begin() != true) + { + lcd.print(F("HTU21D error")); //(F()) saves string to flash & keeps dynamic memory free + delay(5000); + } + + lcd.clear(); + + lcd.print(F("HTU21D OK")); + delay(2000); + + lcd.clear(); + + /* load custom symbol to CGRAM */ + lcd.createChar(0, humidity_icon); + lcd.createChar(1, temperature_icon); + lcd.createChar(2, plus_minus_icon); + + /* prints static text */ + lcd.setCursor(0, 0); + lcd.write(1); //print custom tempereture symbol + + lcd.setCursor(0, 1); //set 1-st colum & 2-nd row, first colum & row started at zero + lcd.write(0); //print custom humidity symbol + + lcd.setCursor(0, 2); + lcd.print(F("Battery:")); + + lcd.setCursor(11, 2); + lcd.print(F("FW:")); +} + + +void loop() +{ + humidity = myHTU21D.readCompensatedHumidity(); + + /* prints dynamic text & data */ + lcd.setCursor(1, 0); + lcd.print(myHTU21D.readTemperature()); + lcd.write(2); //print custom plus/minus symbol + lcd.print(F("0.3")); + lcd.write(DEGREE_SYMBOL); //print degree symbol from the LCD ROM + lcd.print(F("C ")); + + lcd.setCursor(1, 1); + lcd.print(humidity); + lcd.write(2); + lcd.print(F("2% ")); + + lcd.setCursor(7, 2); + if (myHTU21D.batteryStatus() == true) + { + lcd.print(F("OK ")); + } + else + { + lcd.print(F("Low")); + } + + lcd.setCursor(14, 2); + lcd.print(myHTU21D.readFirmwareVersion()); + + /* prints horizontal graph from 0 to MAX_HUMIDITY */ + lcd.printHorizontalGraph('H', 3, humidity, MAX_HUMIDITY); //name of the bar, row, current value, max. value + + delay(20000); +} diff --git a/src/libs/HTU21D-master/examples/HTU21D_Demo/HTU21D_Demo.ino b/src/libs/HTU21D-master/examples/HTU21D_Demo/HTU21D_Demo.ino new file mode 100644 index 0000000..89fd941 --- /dev/null +++ b/src/libs/HTU21D-master/examples/HTU21D_Demo/HTU21D_Demo.ino @@ -0,0 +1,105 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sensor uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details: + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include +#include + +/* +HTU21D(resolution) + +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12Bit, Temperature: 14Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8Bit, Temperature: 12Bit +HTU21D_RES_RH10_TEMP13 - RH: 10Bit, Temperature: 13Bit +HTU21D_RES_RH11_TEMP11 - RH: 11Bit, Temperature: 11Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); + + +void setup() +{ + Serial.begin(115200); + Serial.println(); + + while (myHTU21D.begin() != true) + { + Serial.println(F("HTU21D, SHT21 sensor is faild or not connected")); //(F()) saves string to flash & keeps dynamic memory free + delay(5000); + } + Serial.println(F("HTU21D, SHT21 sensor is active")); +} + + +void loop() +{ + /* DEMO - 1 */ + Serial.println(F("DEMO 1: 12-Bit Resolution")); + Serial.print(F("Humidity............: ")); Serial.print(myHTU21D.readHumidity()); Serial.println(F(" +-2%")); + Serial.print(F("Compensated Humidity: ")); Serial.print(myHTU21D.readCompensatedHumidity()); Serial.println(F(" +-2%")); + + Serial.println(F("DEMO 1: 14-Bit Resolution")); + Serial.print(F("Temperature.........: ")); Serial.print(myHTU21D.readTemperature()); Serial.println(F(" +-0.3C")); + + + /* DEMO - 2 */ + Serial.println(F("DEMO 2: 11-Bit Resolution")); + myHTU21D.setResolution(HTU21D_RES_RH11_TEMP11); + Serial.print(F("Humidity............: ")); Serial.print(myHTU21D.readHumidity()); Serial.println(F(" +-2%")); + Serial.print(F("Compensated Humidity: ")); Serial.print(myHTU21D.readCompensatedHumidity()); Serial.println(F(" +-2%")); + + Serial.println(F("DEMO 2: 11-Bit Resolution")); + Serial.print(F("Temperature.........: ")); Serial.print(myHTU21D.readTemperature()); Serial.println(F(" +-0.3C")); + + + /* DEMO - 3 */ + Serial.println(F("DEMO 3: Battery Status")); + if (myHTU21D.batteryStatus() == true) Serial.println(F("Battery.............: OK. Level > 2.25v")); + else Serial.println(F("Battery.............: LOW. Level < 2.25v")); + + + /* DEMO - 4 */ + Serial.println(F("DEMO 4:")); + Serial.print(F("Firmware version....: ")); Serial.println(myHTU21D.readFirmwareVersion()); + + + /* DEMO - 5 */ + Serial.println(F("DEMO 5:")); + Serial.print(F("Sensor's ID.........: ")); Serial.println(myHTU21D.readDeviceID()); + + + /* back to lib. default resolution */ + myHTU21D.softReset(); + myHTU21D.setResolution(HTU21D_RES_RH12_TEMP14); + + + /* DEMO - END */ + Serial.print(F("DEMO starts over again in 20 sec.")); + delay(20000); +} diff --git a/src/libs/HTU21D-master/examples/HTU21D_ESP8266-01_LCD_i2c/HTU21D_ESP8266-01_LCD_i2c.ino b/src/libs/HTU21D-master/examples/HTU21D_ESP8266-01_LCD_i2c/HTU21D_ESP8266-01_LCD_i2c.ino new file mode 100644 index 0000000..0bf487b --- /dev/null +++ b/src/libs/HTU21D-master/examples/HTU21D_ESP8266-01_LCD_i2c/HTU21D_ESP8266-01_LCD_i2c.ino @@ -0,0 +1,138 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor shows how to + reassign default SDA/SCL pins for ESP8266-01 + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sketch uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include //use bug free i2c driver https://github.com/enjoyneering/ESP8266-I2C-Driver +#include +#include //https://github.com/enjoyneering/LiquidCrystal_I2C +#include + +#undef SDA //delete dafault SDA pin number +#undef SCL //delete dafault SCL pin number + +#define SDA 1 //assign new SDA pin to GPIO1/D2/0TX for all slaves on i2c bus +#define SCL 3 //assign new SCL pin to GPIO3/D7/0RX for all slaves on i2c bus + +#define LCD_ROWS 4 //qnt. of lcd rows +#define LCD_COLUMNS 20 //qnt. of lcd columns +#define DEGREE_SYMBOL 0xDF //degree symbol from the LCD ROM +#define SPACE_SYMBOL 0x20 //space symbol from lcd ROM + +const uint8_t temperature_icon[8] PROGMEM = {0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x1F, 0x1F, 0x0E}; //PROGMEM saves variable to flash & keeps dynamic memory free +const uint8_t humidity_icon[8] PROGMEM = {0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 0x00}; + +float temperature = 0; +float humidity = 0; + + +/* +HTU21D(resolution) +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12Bit, Temperature: 14Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8Bit, Temperature: 12Bit +HTU21D_RES_RH10_TEMP13 - RH: 10Bit, Temperature: 13Bit +HTU21D_RES_RH11_TEMP11 - RH: 11Bit, Temperature: 11Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); +LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); + + +void setup() +{ + WiFi.persistent(false); //disable saving wifi config into SDK flash area + WiFi.forceSleepBegin(); //disable AP & station by calling "WiFi.mode(WIFI_OFF)" & put modem to sleep + + Serial.begin(115200); + Serial.swap(); //remap serial pins GPIO1/D2/UART0TXD & GPIO3/D7/UART0RXD to GPIO15/UART0RTS & GPIO13/UART0CTS + + /* LCD connection check */ + while (lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS) != true) //20 colums, 4 rows, 5x8 pixels char size + { + digitalWrite(LED, LOW); + delay(500); + digitalWrite(LED, HIGH); + delay(500); + } + + lcd.print(F("PCF8574 is OK")); + delay(1000); + + lcd.clear(); + + /* HTU21D connection check */ + while (myHTU21D.begin() != true) + { + lcd.setCursor(0, 0); + lcd.print(F("HTU21D error")); + delay(5000); + } + + lcd.clear(); + + lcd.print(F("HTU21D OK")); + delay(1000); + + lcd.clear(); + + /* load custom symbol to CGRAM */ + lcd.createChar(0, temperature_icon); //variable stored in flash + lcd.createChar(1, humidity_icon); + + /* prints static text */ + lcd.setCursor(0, 0); //set 1-st colum & 1-st row + lcd.write(0); //print custom tempereture symbol + + lcd.setCursor(0, 1); + lcd.write(1); +} + +void loop() +{ + humidity = myHTU21D.readCompensatedHumidity(); + temperature = myHTU21D.readTemperature(); + + /* prints dynamic temperature data */ + lcd.setCursor(1, 0); + + if (temperature != HTU21D_ERROR) lcd.print(temperature); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic humidity data */ + lcd.setCursor(1, 1); + + if (humidity != HTU21D_ERROR) lcd.print(humidity); + else lcd.print(F("xxx")); + lcd.print(F("%")); + lcd.write(SPACE_SYMBOL); + + delay(10000); +} diff --git a/src/libs/HTU21D-master/examples/HTU21D_ESP8266_Humidex_Windchill/HTU21D_ESP8266_Humidex_Windchill.ino b/src/libs/HTU21D-master/examples/HTU21D_ESP8266_Humidex_Windchill/HTU21D_ESP8266_Humidex_Windchill.ino new file mode 100644 index 0000000..d8d058d --- /dev/null +++ b/src/libs/HTU21D-master/examples/HTU21D_ESP8266_Humidex_Windchill/HTU21D_ESP8266_Humidex_Windchill.ino @@ -0,0 +1,298 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor shows how to + reassign default SDA/SCL pins for ESP8266-01 + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sketch uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include //use bug free i2c driver https://github.com/enjoyneering/ESP8266-I2C-Driver +#include +#include //https://github.com/enjoyneering/LiquidCrystal_I2C +#include + +#define LCD_ROWS 4 //qnt. of lcd rows +#define LCD_COLUMNS 20 //qnt. of lcd columns + +#define DEGREE_SYMBOL 0xDF //degree symbol from lcd ROM +#define SPACE_SYMBOL 0x20 //space symbol from lcd ROM + +#define WIND_SPEED 5 //assuming wind speed is 5 m/sec +#define ERROR 255 //error code + +const uint8_t temperature_icon[8] PROGMEM = {0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x1F, 0x1F, 0x0E}; //PROGMEM saves variable to flash & keeps dynamic memory free +const uint8_t humidity_icon[8] PROGMEM = {0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 0x00}; + +float temperature = 0; +float humidity = 0; +float dewpoint = 0; +float humidex = 0; +float windchill = 0; + +/* +HTU21D(resolution) + +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12Bit, Temperature: 14Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8Bit, Temperature: 12Bit +HTU21D_RES_RH10_TEMP13 - RH: 10Bit, Temperature: 13Bit +HTU21D_RES_RH11_TEMP11 - RH: 11Bit, Temperature: 11Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); +LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); + + +/**************************************************************************/ +/* + setup() + + Main setup +*/ +/**************************************************************************/ +void setup() +{ + WiFi.persistent(false); //disable saving wifi config into SDK flash area + WiFi.forceSleepBegin(); //disable swAP & station by calling "WiFi.mode(WIFI_OFF)" & put modem to sleep + + Serial.begin(115200); + + /* LCD connection check */ + while (lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS) != true) //20x4 display, LCD_5x8DOTS pixels size, SDA - D2, SCL - D1 + { + Serial.println(F("PCF8574 is not connected or lcd pins declaration is wrong. Only pins numbers: 4,5,6,16,11,12,13,14 are legal.")); + delay(5000); + } + + lcd.print(F("PCF8574 is OK")); //(F()) saves string to flash & keeps dynamic memory free + delay(1000); + + lcd.clear(); + + /* HTU21D connection check */ + while (myHTU21D.begin() != true) + { + lcd.setCursor(0, 0); + lcd.print(F("HTU21D error")); + delay(5000); + } + + lcd.clear(); + + lcd.print(F("HTU21D OK")); + delay(1000); + + lcd.clear(); + + /* load custom symbol to CGRAM */ + lcd.createChar(0, temperature_icon); + lcd.createChar(1, humidity_icon); + + /* prints static text */ + lcd.setCursor(0, 0); //set 1-st colum & 1-st row, first colum & row started at zero + lcd.write(0); //print custom tempereture symbol + + lcd.setCursor(10, 0); + lcd.write(1); //print custom humidity symbol + + lcd.setCursor(0, 1); + lcd.print(F("Dewpoint :")); + + lcd.setCursor(0, 2); + lcd.print(F("Humidex :")); + + lcd.setCursor(0, 3); + lcd.print(F("Windchill:")); +} + +/**************************************************************************/ +/* + loop() + + Main loop +*/ +/**************************************************************************/ +void loop() +{ + humidity = myHTU21D.readCompensatedHumidity(); + temperature = myHTU21D.readTemperature(); + + dewpoint = calculateDewPoint(temperature, humidity); + humidex = calculateHumidex(temperature, dewpoint); + windchill = calculateWindchill(temperature, WIND_SPEED); + + /* prints dynamic temperature data */ + lcd.setCursor(1, 0); + if (temperature != HTU21D_ERROR) lcd.print(temperature); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic humidity data */ + lcd.setCursor(11, 0); + if (humidity != HTU21D_ERROR) lcd.print(humidity); + else lcd.print(F("xxx")); + lcd.print("%"); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic dewpoint data */ + lcd.setCursor(10, 1); + if (dewpoint != ERROR) lcd.print(dewpoint); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic humidex data */ + lcd.setCursor(10, 2); + if (humidex != ERROR) lcd.print(humidex); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic windchill data */ + lcd.setCursor(10, 3); + if (windchill != ERROR) lcd.print(windchill); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints serial data */ + Serial.print(F("Humidity............: ")); Serial.print(humidity); Serial.println(F("%")); + Serial.print(F("Temperature.........: ")); Serial.print(temperature); Serial.println(F("C")); + Serial.print(F("Dew Point...........: ")); Serial.print(dewpoint); Serial.println(F("C")); + Serial.print(F("Humidex/Feels like..: ")); Serial.print(humidex); Serial.print(F("C, ")); humidexDiscomfortIndex(humidex); + Serial.print(F("Windchill/Feels like: ")); Serial.print(windchill); Serial.print(F("C, ")); windchillDiscomfortIndex(humidex); + + delay(20000); +} + +/**************************************************************************/ +/* + calculateDewPoint() + + Dew point calculation +*/ +/**************************************************************************/ +float calculateDewPoint(float temperature, float humidity) +{ + float a = 17.271; + float b = 237.7; + + if (temperature != HTU21D_ERROR && humidity != HTU21D_ERROR) + { + float gamma = ((a * temperature) / (b + temperature)) + log(humidity / 100); + float dewpoint = (b * gamma) / (a - gamma); + + return (dewpoint); + } + return ERROR; +} + +/**************************************************************************/ +/* + calculateHumidex() + + Humidex calculation + + Humidex is an index number used to describe how hot the weather feels + to the average person, by combining the effect of heat and humidity. + + Humidex is calculated as: + Humidex = air temperature + h + h = (0.5555) * (e - 10.0) + e = 6.11 * exp(5417.7530 * ((1 / 273.16) - (1 / dewpoint))) +*/ +/**************************************************************************/ +float calculateHumidex(float temperature, float dewpoint) +{ + if (temperature > 5 && temperature != HTU21D_ERROR && dewpoint != ERROR) + { + float e = 5417.7530 * ((1 / 273.16) - (1 / (273.16 + dewpoint))); + float humidex = temperature + 0.5555 * ( 6.11 * exp(e) - 10); + + return (humidex); + } + return ERROR; +} + +/**************************************************************************/ +/* + calculateWindchill() + + Windchill calculation + + Wind chill is an index number used to describe how cold the weather feels + to the average person, by combining the effect of cold and wind speeds. + + Wind chill is calculated: + Windchill = 13.12 + 0.6215 * ta - 11.37 * v^0.16 + 0.3965 * ta * v^0.16 + ta = air temperature below 10C + v = wind velocity greater than 4.8 km/h +*/ +/**************************************************************************/ +float calculateWindchill(float temperature, float velocity) +{ + if (temperature != HTU21D_ERROR && temperature <= 5 && velocity >= 5) + { + float windchill = 13.12 + 0.6215 * temperature - 11.37 * pow(velocity, 0.16) + 0.3965 * temperature * pow(velocity, 0.16); + + return windchill; + } + return ERROR; +} + +/**************************************************************************/ +/* + humidexDiscomfortIndex() + + Describes discomfort levels of humidex index +*/ +/**************************************************************************/ +void humidexDiscomfortIndex(float humidex) +{ + if ((humidex >= 21 ) && (humidex < 27)) Serial.println(F("Little discomfort.")); + else if ((humidex >= 27) && (humidex < 35)) Serial.println(F("Noticeable discomfort.")); + else if ((humidex >= 35) && (humidex < 40)) Serial.println(F("Great discomfort.")); + else if ((humidex >= 40) && (humidex < 46)) Serial.println(F("Intense discomfort.")); + else if ((humidex >= 46) && (humidex < 54)) Serial.println(F("Dangerous discomfort.")); + else Serial.println(F("Heat stroke warning.")); +} + +/**************************************************************************/ +/* + windchillDiscomfortIndex() + + Describes discomfort levels of windchill index +*/ +/**************************************************************************/ + +void windchillDiscomfortIndex(float windchill) +{ + if (windchill >= -24) Serial.println(F("Low risk of frostbite.")); + else if ((windchill < -24) && (windchill >= -39)) Serial.println(F("High risk of frostbite within 30 minutes of exposure.")); + else if ((windchill < -39) && (windchill >= -47)) Serial.println(F("High risk of frostbite within 5 to 10 minutes of exposure.")); + else if ((windchill < -47) && (windchill >= -54)) Serial.println(F("High risk of frostbite within 2 to 5 minutes of exposure.")); + else Serial.println(F("High risk of frostbite within 2 minutes of exposure.")); +} diff --git a/src/libs/HTU21D-master/examples/HTU21D_Heater_Demo/HTU21D_Heater_Demo.ino b/src/libs/HTU21D-master/examples/HTU21D_Heater_Demo/HTU21D_Heater_Demo.ino new file mode 100644 index 0000000..494fcf9 --- /dev/null +++ b/src/libs/HTU21D-master/examples/HTU21D_Heater_Demo/HTU21D_Heater_Demo.ino @@ -0,0 +1,135 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor shows how to + reassign default SDA/SCL pins for ESP8266-01 + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sketch uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include //https://github.com/enjoyneering/ESP8266-I2C-Driver +#include +#include //https://github.com/enjoyneering/LiquidCrystal_I2C +#include + +#undef SDA //delete dafault SDA pin number +#undef SCL //delete dafault SCL pin number + +#define SDA 1 //assign new SDA pin to GPIO1/D2/0TX for all slaves on i2c bus +#define SCL 3 //assign new SCL pin to GPIO3/D7/0RX for all slaves on i2c bus + +#define LCD_ROWS 4 //qnt. of lcd rows +#define LCD_COLUMNS 20 //qnt. of lcd columns +#define DEGREE_SYMBOL 0xDF //degree symbol from the LCD ROM +#define SPACE_SYMBOL 0x20 //space symbol from lcd ROM + +const uint8_t temperature_icon[8] PROGMEM = {0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x1F, 0x1F, 0x0E}; //PROGMEM saves variable to flash & keeps dynamic memory free +const uint8_t humidity_icon[8] PROGMEM = {0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 0x00}; + +float temperature = 0; +float humidity = 0; + + +/* +HTU21D(resolution) +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12Bit, Temperature: 14Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8Bit, Temperature: 12Bit +HTU21D_RES_RH10_TEMP13 - RH: 10Bit, Temperature: 13Bit +HTU21D_RES_RH11_TEMP11 - RH: 11Bit, Temperature: 11Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); +LiquidCrystal_I2C lcd(PCF8574_ADDR_A21_A11_A01, 4, 5, 6, 16, 11, 12, 13, 14, POSITIVE); + + +void setup() +{ + WiFi.persistent(false); //disable saving wifi config into SDK flash area + WiFi.forceSleepBegin(); //disable AP & station by calling "WiFi.mode(WIFI_OFF)" & put modem to sleep + + Serial.begin(115200); + + /* LCD connection check */ + while (lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS) != true) //20x4 display with 5x8 pixels size + { + Serial.println(F("PCF8574 is not connected or lcd pins declaration is wrong. Only pins numbers: 4,5,6,16,11,12,13,14 are legal.")); //(F()) saves string to flash & keeps dynamic memory free + delay(5000); + } + + lcd.print(F("PCF8574 is OK")); + delay(1000); + + lcd.clear(); + + /* HTU21D connection check */ + while (myHTU21D.begin() != true) + { + lcd.setCursor(0, 0); + lcd.print(F("HTU21D error")); + delay(5000); + } + + lcd.clear(); + + lcd.print(F("HTU21D OK")); + delay(1000); + + lcd.clear(); + + /* load custom symbol to CGRAM */ + lcd.createChar(0, temperature_icon); //variable stored in flash + lcd.createChar(1, humidity_icon); + + /* prints static text */ + lcd.setCursor(0, 0); //set 1-st colum & 1-st row + lcd.write(0); //print custom tempereture symbol + + lcd.setCursor(0, 1); + lcd.write(1); +} + +void loop() +{ + humidity = myHTU21D.readCompensatedHumidity(); + temperature = myHTU21D.readTemperature(); + + /* prints dynamic temperature data */ + lcd.setCursor(1, 0); + + if (temperature != HTU21D_ERROR) lcd.print(temperature); + else lcd.print(F("xxx")); + lcd.write(DEGREE_SYMBOL); + lcd.write(SPACE_SYMBOL); + + /* prints dynamic humidity data */ + lcd.setCursor(1, 1); + + if (humidity != HTU21D_ERROR) lcd.print(humidity); + else lcd.print(F("xxx")); + lcd.print(F("%")); + lcd.write(SPACE_SYMBOL); + + delay(10000); +} diff --git a/src/libs/HTU21D-master/examples/Si7021_Demo/Si7021_Demo.ino b/src/libs/HTU21D-master/examples/Si7021_Demo/Si7021_Demo.ino new file mode 100644 index 0000000..576fc01 --- /dev/null +++ b/src/libs/HTU21D-master/examples/Si7021_Demo/Si7021_Demo.ino @@ -0,0 +1,102 @@ +/***************************************************************************************************/ +/* + This is an Arduino example for SHT21, HTU21D Digital Humidity & Temperature Sensor shows how to + reassign default SDA/SCL pins for ESP8266-01 + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + This sketch uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 + Mega2560, Due............................ 20 21 + Leonardo, Micro, ATmega32U4.............. 2 3 + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 + Blue Pill, STM32F103xxxx boards.......... PB7* PB6* + ESP8266 ESP-01:.......................... GPIO0/D5 GPIO2/D3 + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 + + *STM32F103xxxx pins B7/B7 are 5v tolerant, but bi-directional + logic level converter is recommended + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP8266 Core - https://github.com/esp8266/Arduino + ESP8266 I2C lib fixed - https://github.com/enjoyneering/ESP8266-I2C-Driver + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, see link below for details + - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ +#include +#include + +/* +HTU21D(resolution) + +resolution: +HTU21D_RES_RH12_TEMP14 - RH: 12Bit, Temperature: 14Bit, by default +HTU21D_RES_RH8_TEMP12 - RH: 8Bit, Temperature: 12Bit +HTU21D_RES_RH10_TEMP13 - RH: 10Bit, Temperature: 13Bit +HTU21D_RES_RH11_TEMP11 - RH: 11Bit, Temperature: 11Bit +*/ +HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14); + + +void setup() +{ + Serial.begin(115200); + + while (myHTU21D.begin() != true) + { + Serial.println(F("Si7021 sensor is faild or not connected")); + delay(5000); + } + Serial.println(F("Si7021 sensor is active")); +} + +void loop() +{ + /* DEMO - 1 */ + Serial.println(F("DEMO 1: 12-Bit Resolution")); + Serial.print(F("Compensated Humidity: ")); Serial.print(myHTU21D.readHumidity()); Serial.println(F(" +-2%")); + + Serial.println(F("DEMO 1: 14-Bit Resolution")); + Serial.print(F("Temperature.........: ")); Serial.print(myHTU21D.readTemperature(SI70xx_TEMP_READ_AFTER_RH_MEASURMENT)); Serial.println(F(" +-0.5C")); + + + /* DEMO - 2 */ + Serial.println(F("DEMO 2: 11-Bit Resolution")); + myHTU21D.setResolution(HTU21D_RES_RH11_TEMP11); + + Serial.print(F("Compensated Humidity: ")); Serial.print(myHTU21D.readHumidity()); Serial.println(F(" +-2%")); + + Serial.println(F("DEMO 2: 11-Bit Resolution")); + Serial.print(F("Temperature.........: ")); Serial.print(myHTU21D.readTemperature(SI70xx_TEMP_READ_AFTER_RH_MEASURMENT)); Serial.println(F(" +-0.5C")); + + + /* DEMO - 3 */ + Serial.println(F("DEMO 3: Battery Status")); + if (myHTU21D.batteryStatus() == true) Serial.println(F("Battery.........: OK. Level > 1.90v")); + else Serial.println(F("Battery.........: LOW. Level < 1.90v")); + + + /* DEMO - 4 */ + Serial.println(F("DEMO 4:")); + Serial.print(F("Firmware version....: ")); Serial.println(myHTU21D.readFirmwareVersion()); + + + /* DEMO - 5 */ + Serial.println(F("DEMO 5:")); + Serial.print(F("Sensor's ID.........: ")); Serial.println(myHTU21D.readDeviceID()); + + + /* back to lib. default resolution */ + myHTU21D.setResolution(HTU21D_RES_RH12_TEMP14); + + + /* DEMO - END */ + Serial.print(F("DEMO starts over again in 20 sec.")); + delay(20000); +} diff --git a/src/libs/HTU21D-master/keywords.txt b/src/libs/HTU21D-master/keywords.txt new file mode 100644 index 0000000..fc01faa --- /dev/null +++ b/src/libs/HTU21D-master/keywords.txt @@ -0,0 +1,50 @@ +####################################### +# Syntax Coloring Map HTU21D +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +readHumidity KEYWORD2 +readCompensatedHumidity KEYWORD2 +readTemperatureAfterRH KEYWORD2 +readTemperature KEYWORD2 +setResolution KEYWORD2 +softReset KEYWORD2 +batteryStatus KEYWORD2 +setHeater KEYWORD2 +readFirmwareVersion KEYWORD2 +readDeviceID KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +HTU21D KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +HTU21D_ERROR LITERAL1 + +HTU21D_RES_RH12_TEMP14 LITERAL1 +HTU21D_RES_RH8_TEMP12 LITERAL1 +HTU21D_RES_RH10_TEMP13 LITERAL1 +HTU21D_RES_RH11_TEMP11 LITERAL1 + +HTU21D_TRIGGER_HUMD_MEASURE_HOLD LITERAL1 +HTU21D_TRIGGER_HUMD_MEASURE_NOHOLD LITERAL1 + +HTU21D_TRIGGER_TEMP_MEASURE_HOLD LITERAL1 +HTU21D_TRIGGER_TEMP_MEASURE_NOHOLD LITERAL1 +SI70xx_TEMP_READ_AFTER_RH_MEASURMENT LITERAL1 + +HTU21D_ON LITERAL1 +HTU21D_OFF LITERAL1 diff --git a/src/libs/HTU21D-master/library.json b/src/libs/HTU21D-master/library.json new file mode 100644 index 0000000..bbe4ce5 --- /dev/null +++ b/src/libs/HTU21D-master/library.json @@ -0,0 +1,18 @@ +{ + "name": "HTU21D", + "keywords": "humidity, temperature, sht21, htu21d, si7021, i2c", + "description": "SHT21, HTU21D & Si70xx Digital Humidity & Temperature Sensor", + "authors": + { + "name": "ejoyneering", + "email": "enjoyneering@protonmail.com" + }, + "repository": + { + "type": "git", + "url": "https://github.com/enjoyneering/HTU21D.git" + }, + "version": "1.2.1", + "frameworks": "arduino", + "platforms": "*" +} diff --git a/src/libs/HTU21D-master/library.properties b/src/libs/HTU21D-master/library.properties new file mode 100644 index 0000000..e60a94f --- /dev/null +++ b/src/libs/HTU21D-master/library.properties @@ -0,0 +1,9 @@ +name = HTU21D/SHT21/Si70xx +version = 1.2.1 +author = Enjoyneering +maintainer = Enjoyneering +sentence = Meas-Spec HTU21D, Sensirion SHT21 & Silicon Labs Si70xx, I²C Temperature & Humidity Sensor +paragraph = Meas-Spec HTU21D, Sensirion SHT21 & Silicon Labs Si70xx, I²C Temperature & Humidity Sensor +category = Sensors +url = https://github.com/enjoyneering/HTU21D +architectures = * diff --git a/src/libs/HTU21D-master/src/HTU21D.cpp b/src/libs/HTU21D-master/src/HTU21D.cpp new file mode 100644 index 0000000..6dcbe12 --- /dev/null +++ b/src/libs/HTU21D-master/src/HTU21D.cpp @@ -0,0 +1,601 @@ +/***************************************************************************************************/ +/* + This is an Arduino library for SHT21, HTU21D & Si70xx Digital Humidity and Temperature Sensor + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + + This chip uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL Level + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 5v + Mega2560................................. 20 21 5v + Due, SAM3X8E............................. 20 21 3.3v + Leonardo, Micro, ATmega32U4.............. 2 3 5v + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 5v + Blue Pill, STM32F103xxxx boards.......... PB7 PB6 3.3v/5v + ESP8266 ESP-01........................... GPIO0/D5 GPIO2/D3 3.3v/5v + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 3.3v/5v + ESP32.................................... GPIO21/D21 GPIO22/D22 3.3v + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP32 Core - https://github.com/espressif/arduino-esp32 + ESP8266 Core - https://github.com/esp8266/Arduino + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, + see link for details - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ + +#include "HTU21D.h" + + +/**************************************************************************/ +/* + Constructor +*/ +/**************************************************************************/ +HTU21D::HTU21D(HTU21D_RESOLUTION sensorResolution) +{ + _resolution = sensorResolution; +} + +/**************************************************************************/ +/* + begin() + + Initializes I2C and configures the sensor, call this function before + doing anything else + + NOTE: + - Wire.endTransmission() returned value: + - 0 success + - 1 data too long to fit in transmit data16 + - 2 received NACK on transmit of address + - 3 received NACK on transmit of data + - 4 other error +*/ +/**************************************************************************/ +#if defined(ESP8266) +bool HTU21D::begin(uint8_t sda, uint8_t scl) +{ + Wire.begin(sda, scl); + Wire.setClock(100000UL); //experimental! ESP8266 i2c bus speed: 100kHz..400kHz/100000UL..400000UL, default 100000UL + Wire.setClockStretchLimit(230); //experimental! default 230usec +#else +bool HTU21D::begin(void) +{ + Wire.begin(); + Wire.setClock(100000UL); //experimental! AVR i2c bus speed: 31kHz..400kHz/31000UL..400000UL, default 100000UL +#endif + + Wire.beginTransmission(HTU21D_ADDRESS); + if (Wire.endTransmission(true) != 0) return false; //safety check, make sure the sensor is connected + + setResolution(_resolution); + setHeater(HTU21D_OFF); + + return true; +} + +/**************************************************************************/ +/* + setResolution() + + Sets sensor's resolution +*/ +/**************************************************************************/ +void HTU21D::setResolution(HTU21D_RESOLUTION sensorResolution) +{ + uint8_t userRegisterData = 0; + + userRegisterData = read8(HTU21D_USER_REGISTER_READ); //reads current user register state + userRegisterData &= 0x7E; //clears current resolution bits with 0 + userRegisterData |= sensorResolution; //adds new resolution bits to user register byte + + write8(HTU21D_USER_REGISTER_WRITE, userRegisterData); //writes updeted byte to the user register + + _resolution = sensorResolution; //updates private variable +} + +/**************************************************************************/ +/* + softReset() + + Soft reset, switch sensor OFF & ON + + NOTE: + - takes ~15ms + - all registers & bits except heater bit will set to default +*/ +/**************************************************************************/ +void HTU21D::softReset(void) +{ + Wire.beginTransmission(HTU21D_ADDRESS); + + #if ARDUINO >= 100 + Wire.write(HTU21D_SOFT_RESET); + #else + Wire.send(HTU21D_SOFT_RESET); + #endif + + Wire.endTransmission(true); + + delay(HTU21D_SOFT_RESET_DELAY); +} + +/**************************************************************************/ +/* + batteryStatus() + + Checks the battery status. + + NOTE: + - for SHT21, HTU21D: + - if VDD > 2.25v ±0.1v return TRUE + - if VDD < 2.25v ±0.1v return FALSE + + - for Si70xx: + - if VDD > 1.9v ±0.1v return TRUE + - if VDD < 1.9v ±0.1v return FALSE +*/ +/**************************************************************************/ +bool HTU21D::batteryStatus(void) +{ + uint8_t userRegisterData = 0; + + userRegisterData = read8(HTU21D_USER_REGISTER_READ); + userRegisterData &= 0x40; + + if (userRegisterData == 0x00) return true; + return false; +} + +/**************************************************************************/ +/* + setHeater() + + Turn ON/OFF build-in heater + + NOTE: + - prolonged exposure to high humidity will result gradual upward drift + of the RH reading, the heater is used to drive off condensation & + reverse drift effect. + - heater consumtion is 3.09mA - 94.20mA @ 3.3v. +*/ +/**************************************************************************/ +void HTU21D::setHeater(HTU21D_HEATER_SWITCH heaterSwitch) +{ + uint8_t userRegisterData = 0; + + userRegisterData = read8(HTU21D_USER_REGISTER_READ); + + switch(heaterSwitch) + { + case HTU21D_ON: + userRegisterData |= heaterSwitch; + break; + + case HTU21D_OFF: + userRegisterData &= heaterSwitch; + break; + } + + write8(HTU21D_USER_REGISTER_WRITE, userRegisterData); +} + +/**************************************************************************/ +/* + readHumidity() + + Reads Humidity, % + + NOTE: + - maximum accuracy ±2%RH in range 20%..80% at 25°C + - maximum measurement time ~29ms + - suggested minimum time between measurements 17sec + - "operationMode" could be set up as: + + - "HTU21D_TRIGGER_TEMP_MEASURE_NOHOLD" mode, allows communication with + another slave devices on I2C bus while sensor is measuring. + WARNING!!! Could create collision if more than one slave devices are + connected to the same bus. + + - "HTU21D_TRIGGER_HUMD_MEASURE_HOLD" mode, sensor blocks communication + on I2C bus by keeping SCL line LOW during measurement. +*/ +/**************************************************************************/ +float HTU21D::readHumidity(HTU21D_HUMD_OPERATION_MODE sensorOperationMode) +{ + uint16_t rawHumidity = 0; + uint8_t checksum = 0; + float humidity = 0; + + /* request humidity measurement */ + Wire.beginTransmission(HTU21D_ADDRESS); + #if ARDUINO >= 100 + Wire.write(sensorOperationMode); + #else + Wire.send(sensorOperationMode); + #endif + if (Wire.endTransmission(true) != 0) return HTU21D_ERROR; //error handler, collision on the i2c bus + + /* humidity measurement delay */ + switch(_resolution) + { + case HTU21D_RES_RH12_TEMP14: + delay(29); //HTU21D - 14..16msec, Si7021 - 10..12msec, SHT21 - 22..29msec + break; + + case HTU21D_RES_RH11_TEMP11: + delay(15); //HTU21D - 7..8msec, Si7021 - 6..7msec, SHT21 - 12..15msec + break; + + case HTU21D_RES_RH10_TEMP13: + delay(9); //HTU21D - 4..5msec, Si7021 - 4..5msec, SHT21 - 7..9msec + break; + + case HTU21D_RES_RH8_TEMP12: + delay(4); //HTU21D - 2..3msec, Si7021 - 3..4msec, SHT21 - 3..4msec + break; + } + + /* read humidity measurement to "wire.h" rxBuffer */ + #if defined(_VARIANT_ARDUINO_STM32_) + Wire.requestFrom(HTU21D_ADDRESS, 3); + #else + Wire.requestFrom(HTU21D_ADDRESS, 3, true); //true, stop message after transmission & releas the I2C bus + #endif + if (Wire.available() != 3) return HTU21D_ERROR; //check rxBuffer & error handler, collision on the i2c bus + + /* reads MSB, LSB byte & checksum from "wire.h" rxBuffer */ + #if ARDUINO >= 100 + rawHumidity = Wire.read() << 8; //reads MSB byte & shift it to the right + rawHumidity |= Wire.read(); //reads LSB byte & sum with MSB byte + checksum = Wire.read(); //reads checksum + #else + rawHumidity = Wire.receive() << 8; + rawHumidity |= Wire.receive(); + checksum = Wire.receive(); + #endif + + if (checkCRC8(rawHumidity) != checksum) return HTU21D_ERROR; //error handler, checksum verification + + rawHumidity ^= 0x02; //clear status bits, humidity always returns xxxxxx10 in the LSB field + humidity = (0.001907 * (float)rawHumidity - 6); + + if (humidity < 0) humidity = 0; //due to RH accuracy, measured value might be slightly less than 0 or more 100 + else if (humidity > 100) humidity = 100; + + return humidity; +} + +/**************************************************************************/ +/* + readTemperature() + + Reads Temperature, C + + NOTE: + - maximum accuracy ±0.3°C in range 0C..60°C + - maximum measurement time ~85ms + - suggested minimum time between measurements 17sec + - "operationMode" could be set up as: + + - "HTU21D_TRIGGER_TEMP_MEASURE_NOHOLD" mode, allows communication with + another slave devices on I2C bus while sensor is measuring. + WARNING!!! Could create collision if more than one slave devices are + connected to the same bus. + + - "HTU21D_TRIGGER_HUMD_MEASURE_HOLD" mode, sensor blocks communication + on I2C bus by keeping SCL line LOW during measurement. + + - "SI7021_TEMP_READ_AFTER_RH_MEASURMENT" mode, allows to retrive + temperature measurement, which was made at previouse RH measurement. + For HTU21D & SHT21 you have to manualy call + "readCompensatedHumidity()" +*/ +/**************************************************************************/ +float HTU21D::readTemperature(HTU21D_TEMP_OPERATION_MODE sensorOperationMode) +{ + int8_t qntRequest = 3; //3 bytes -> MSB, LSB byte & checksum or 2 bytes -> MSB, LSB byte + uint16_t rawTemperature = 0; + uint8_t checksum = 0; + + /* request temperature measurement */ + Wire.beginTransmission(HTU21D_ADDRESS); + #if ARDUINO >= 100 + Wire.write(sensorOperationMode); + #else + Wire.send(sensorOperationMode); + #endif + if (Wire.endTransmission(true) != 0) return HTU21D_ERROR; //error handler, collision on the i2c bus + + /* temperature measurement delay */ + if (sensorOperationMode != SI70xx_TEMP_READ_AFTER_RH_MEASURMENT) + { + switch(_resolution) + { + case HTU21D_RES_RH12_TEMP14: + delay(85); //HTU21D - 44..50msec, Si7021 - 7..11msec, SHT21 - 66..85msec + break; + + case HTU21D_RES_RH10_TEMP13: + delay(43); //HTU21D - 22..25msec, Si7021 - 4..7msec, SHT21 - 33..43msec + break; + + case HTU21D_RES_RH8_TEMP12: + delay(22); //HTU21D - 11..13msec, Si7021 - 3..4msec, SHT21 - 17..22msec + break; + + case HTU21D_RES_RH11_TEMP11: + delay(11); //HTU21D - 6..7msec, Si7021 - 2..3msec, SHT21 - 9..11msec + break; + } + } + else qntRequest = 2; //checksum is not available with "SI70xx_TEMP_READ_AFTER_RH_MEASURMENT" + + /* read temperature measurement to "wire.h" rxBuffer */ + #if defined(_VARIANT_ARDUINO_STM32_) + Wire.requestFrom(HTU21D_ADDRESS, qntRequest); + #else + Wire.requestFrom(HTU21D_ADDRESS, qntRequest, true); //true, stop message after transmission & releas the I2C bus + #endif + if (Wire.available() != qntRequest) return HTU21D_ERROR; //check rxBuffer & error handler, collision on the i2c bus + + /* reads MSB, LSB byte & checksum from "wire.h" rxBuffer */ + #if ARDUINO >= 100 + rawTemperature = Wire.read() << 8; //reads MSB byte & shift it to the right + rawTemperature |= Wire.read(); //reads LSB byte and sum. with MSB byte + if (sensorOperationMode != SI70xx_TEMP_READ_AFTER_RH_MEASURMENT) checksum = Wire.read(); //checksum is not available with "SI70xx_TEMP_READ_AFTER_RH_MEASURMENT" + #else + rawTemperature = Wire.receive() << 8; + rawTemperature |= Wire.receive(); + if (sensorOperationMode != SI70xx_TEMP_READ_AFTER_RH_MEASURMENT) checksum = Wire.receive(); + #endif + + /* checksum is not available with "SI70xx_TEMP_READ_AFTER_RH_MEASURMENT" */ + if (sensorOperationMode != SI70xx_TEMP_READ_AFTER_RH_MEASURMENT && checkCRC8(rawTemperature) != checksum) return HTU21D_ERROR; //error handler, checksum verification + + return (0.002681 * (float)rawTemperature - 46.85); //temperature always returns xxxxxx00 in the LSB field +} + +/**************************************************************************/ +/* + readCompensatedHumidity() + + Only for HTU21D & SHT21. Calculates temperature compensated Humidity, %RH + + NOTE: + - Si7021 automatically compensates temperature influence on RH every + humidity measurement + - maximum accuracy ±2%RH in range 0%..100% at 0°C..80°C + - maximum measurement time ~114ms + - suggested minimun time between measurements 17sec +*/ +/**************************************************************************/ +float HTU21D::readCompensatedHumidity(float temperature) +{ + float humidity = 0; + + humidity = readHumidity(); + + if (temperature == HTU21D_FORCE_READ_TEMP) temperature = readTemperature(); //force to read temperature + + if (humidity == HTU21D_ERROR || temperature == HTU21D_ERROR) return HTU21D_ERROR; //error handler, collision on the i2c bus + + if (temperature > 0 && temperature < 80) humidity = humidity + (25.0 - temperature) * HTU21D_TEMP_COEFFICIENT; //apply compensation coefficient + + return humidity; +} + +/***************************************************************************/ +/* + readDeviceID() + + Reads device id + + NOTE: + - see p.23 of Si7021 datasheet for details + - full serial number is {SNA3, SNA2, SNA1, SNA0, SNB3**, SNB2, SNB1, SNB0} + - **chip ID: + - 0x0D: Si7013 + - 0x14: Si7020 + - 0x15: Si7021 + - 0x32: HTU21D & SHT21 +*/ +/**************************************************************************/ +uint16_t HTU21D::readDeviceID(void) +{ + uint16_t deviceID = 0; + uint8_t checksum = 0; + + /* request serial_2 -> SNB3**, SNB2, SNB1, SNB0 */ + Wire.beginTransmission(HTU21D_ADDRESS); + + #if ARDUINO >= 100 + Wire.write(HTU21D_SERIAL2_READ1); + Wire.write(HTU21D_SERIAL2_READ2); + #else + Wire.send(HTU21D_SERIAL2_READ1); + Wire.send(HTU21D_SERIAL2_READ2); + #endif + Wire.endTransmission(true); + + /* read serial_2 -> SNB3**, SNB2, CRC */ + #if defined(_VARIANT_ARDUINO_STM32_) + Wire.requestFrom(HTU21D_ADDRESS, 3); + #else + Wire.requestFrom(HTU21D_ADDRESS, 3, true); //true, stop message after transmission & releas the I2C bus + #endif + + #if ARDUINO >= 100 + deviceID = Wire.read() << 8; + deviceID |= Wire.read(); + checksum = Wire.read(); + #else + deviceID = Wire.receive() << 8; + deviceID |= Wire.receive(); + checksum = Wire.receive(); + #endif + + if (checkCRC8(deviceID) != checksum) return HTU21D_ERROR; //error handler, checksum verification + + deviceID = deviceID >> 8; + + switch(deviceID) + { + case HTU21D_CHIPID: + deviceID = 21; + break; + + case SI7013_CHIPID: + deviceID = 7013; + break; + + case SI7020_CHIPID: + deviceID = 7020; + break; + + case SI7021_CHIPID: + deviceID = 7021; + break; + + default: + deviceID = HTU21D_ERROR; + break; + } + return deviceID; +} + +/***************************************************************************/ +/* + readFirmwareVersion() + + Reads firware version + + NOTE: + - see p.24 of Si7021 datasheet for details +*/ +/**************************************************************************/ +uint8_t HTU21D::readFirmwareVersion(void) +{ + uint8_t firmwareVersion = 0; + + /* request firware version */ + Wire.beginTransmission(HTU21D_ADDRESS); + + #if ARDUINO >= 100 + Wire.write(HTU21D_FIRMWARE_READ1); + Wire.write(HTU21D_FIRMWARE_READ2); + #else + Wire.send(HTU21D_FIRMWARE_READ1); + Wire.send(HTU21D_FIRMWARE_READ2); + #endif + Wire.endTransmission(true); + + /* read firware version */ + #if defined(_VARIANT_ARDUINO_STM32_) + Wire.requestFrom(HTU21D_ADDRESS, 1); + #else + Wire.requestFrom(HTU21D_ADDRESS, 1, true); //true, stop message after transmission & releas the I2C bus + #endif + + #if ARDUINO >= 100 + firmwareVersion = Wire.read(); + #else + firmwareVersion = Wire.read(); + #endif + + switch(firmwareVersion) + { + case HTU21D_FIRMWARE_V1: + firmwareVersion = 1; + break; + + case HTU21D_FIRMWARE_V2: + firmwareVersion = 2; + break; + + default: + firmwareVersion = HTU21D_ERROR; + break; + } + return firmwareVersion; +} + +/**************************************************************************/ +/* + write8() + + Writes 8-bit to the sensor register over I2C +*/ +/**************************************************************************/ +void HTU21D::write8(uint8_t reg, uint8_t value) +{ + Wire.beginTransmission(HTU21D_ADDRESS); + #if ARDUINO >= 100 + Wire.write(reg); + Wire.write(value); + #else + Wire.send(reg); + Wire.send(value); + #endif + Wire.endTransmission(true); + +} + +/**************************************************************************/ +/* + read8() + + Reads 8-bit value from the sensor over I2C +*/ +/**************************************************************************/ +uint8_t HTU21D::read8(uint8_t reg) +{ + Wire.beginTransmission(HTU21D_ADDRESS); + #if ARDUINO >= 100 + Wire.write(reg); + #else + Wire.send(reg); + #endif + if (Wire.endTransmission(true) != 0) return HTU21D_ERROR; //error handler, collision on the i2c bus; + + #if defined(_VARIANT_ARDUINO_STM32_) + Wire.requestFrom(HTU21D_ADDRESS, 1); + #else + Wire.requestFrom(HTU21D_ADDRESS, 1, true); //true, stop message after transmission & releas the I2C bus + #endif + if (Wire.available() != 1) return HTU21D_ERROR; //check rxBuffer & error handler, collision on the i2c bus + + /* read byte from "wire.h" rxBuffer */ + #if ARDUINO >= 100 + return Wire.read(); + #else + return Wire.receive(); + #endif +} + +/**************************************************************************/ +/* + checkCRC8() + + Calculates CRC8 for 16-bit received data + + NOTE: + - for more info about Cyclic Redundancy Check (CRC) see + http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks +*/ +/**************************************************************************/ +uint8_t HTU21D::checkCRC8(uint16_t data) +{ + for (uint8_t bit = 0; bit < 16; bit++) + { + if (data & 0x8000) data = (data << 1) ^ HTU21D_CRC8_POLYNOMINAL; + else data <<= 1; + } + return data >>= 8; +} diff --git a/src/libs/HTU21D-master/src/HTU21D.h b/src/libs/HTU21D-master/src/HTU21D.h new file mode 100644 index 0000000..9c5df82 --- /dev/null +++ b/src/libs/HTU21D-master/src/HTU21D.h @@ -0,0 +1,147 @@ +/***************************************************************************************************/ +/* + This is an Arduino library for SHT21, HTU21D & Si70xx Digital Humidity and Temperature Sensor + + written by : enjoyneering79 + sourse code: https://github.com/enjoyneering/ + + + This chip uses I2C bus to communicate, specials pins are required to interface + Board: SDA SCL Level + Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 5v + Mega2560................................. 20 21 5v + Due, SAM3X8E............................. 20 21 3.3v + Leonardo, Micro, ATmega32U4.............. 2 3 5v + Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 5v + Blue Pill, STM32F103xxxx boards.......... PB7 PB6 3.3v/5v + ESP8266 ESP-01........................... GPIO0/D5 GPIO2/D3 3.3v/5v + NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 3.3v/5v + ESP32.................................... GPIO21/D21 GPIO22/D22 3.3v + + Frameworks & Libraries: + ATtiny Core - https://github.com/SpenceKonde/ATTinyCore + ESP32 Core - https://github.com/espressif/arduino-esp32 + ESP8266 Core - https://github.com/esp8266/Arduino + STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32 + + GNU GPL license, all text above must be included in any redistribution, + see link for details - https://www.gnu.org/licenses/licenses.html +*/ +/***************************************************************************************************/ + +#ifndef HTU21D_h +#define HTU21D_h + +#if defined(ARDUINO) && ((ARDUINO) >= 100) //arduino core v1.0 or later +#include +#else +#include +#endif + +#if defined(__AVR__) +#include //use for PROGMEM Arduino AVR +#elif defined(ESP8266) +#include //use for PROGMEM Arduino ESP8266 +#elif defined(_VARIANT_ARDUINO_STM32_) +#include //use for PROGMEM Arduino STM32 +#endif + +#include + + +#define HTU21D_ADDRESS 0x40 //chip i2c address + +#define HTU21D_USER_REGISTER_WRITE 0xE6 //write user register +#define HTU21D_USER_REGISTER_READ 0xE7 //read user register + +#define HTU21D_HEATER_REGISTER_WRITE 0x51 //write heater control register +#define HTU21D_HEATER_REGISTER_READ 0x11 //read heater control register + +#define HTU21D_SOFT_RESET 0xFE //soft reset + +#define HTU21D_SERIAL1_READ1 0xFA //read 1-st two serial bytes +#define HTU21D_SERIAL1_READ2 0x0F //read 2-nd two serial bytes +#define HTU21D_SERIAL2_READ1 0xFC //read 3-rd two serial bytes +#define HTU21D_SERIAL2_READ2 0xC9 //read 4-th two serial bytes + +#define SI7013_CHIPID 0x0D //device id SI7013 +#define SI7020_CHIPID 0x14 //device id SI7020 +#define SI7021_CHIPID 0x15 //device id SI7021 +#define HTU21D_CHIPID 0x32 //device id HTU21D/SHT21 + +#define HTU21D_FIRMWARE_READ1 0x84 //read firmware revision, 1-st part of the command +#define HTU21D_FIRMWARE_READ2 0xB8 //read firmware revision, 2-nd part of the command + +#define HTU21D_FIRMWARE_V1 0xFF //sensor firmware v1.0 +#define HTU21D_FIRMWARE_V2 0x20 //sensor firmware 2.0 + +#define HTU21D_TEMP_COEFFICIENT -0.15 //temperature coefficient for RH compensation at range 0°C..80°C, for HTU21D & SHT21 only +#define HTU21D_CRC8_POLYNOMINAL 0x13100 //crc8 polynomial for 16bit value, CRC8 -> x^8 + x^5 + x^4 + 1 + + +#define HTU21D_SOFT_RESET_DELAY 15 //in milliseconds + +#define HTU21D_FORCE_READ_TEMP 0xFE //force to read temperature, see https://github.com/enjoyneering/HTU21D/pull/3 +#define HTU21D_ERROR 0xFF //returns 255, if CRC8 or communication error is occurred + +typedef enum : uint8_t +{ + HTU21D_RES_RH12_TEMP14 = 0x00, //resolution, temperature: 14-Bit & humidity: 12-Bit + HTU21D_RES_RH8_TEMP12 = 0x01, //resolution, temperature: 12-Bit & humidity: 8-Bit + HTU21D_RES_RH10_TEMP13 = 0x80, //resolution, temperature: 13-Bit & humidity: 10-Bit + HTU21D_RES_RH11_TEMP11 = 0x81 //resolution, temperature: 11-Bit & humidity: 11-Bit +} +HTU21D_RESOLUTION; + +typedef enum : uint8_t +{ + HTU21D_TRIGGER_HUMD_MEASURE_HOLD = 0xE5, //humidity measurement with hold master + HTU21D_TRIGGER_HUMD_MEASURE_NOHOLD = 0xF5 //temperature measurement with no hold master +} +HTU21D_HUMD_OPERATION_MODE; + +typedef enum : uint8_t +{ + HTU21D_TRIGGER_TEMP_MEASURE_HOLD = 0xE3, //temperature measurement with hold master + HTU21D_TRIGGER_TEMP_MEASURE_NOHOLD = 0xF3, //temperature measurement with no hold master + SI70xx_TEMP_READ_AFTER_RH_MEASURMENT = 0xE0 //read temperature value from previous RH measurement, for Si7021 only +} +HTU21D_TEMP_OPERATION_MODE; + +typedef enum : uint8_t +{ + HTU21D_ON = 0x04, //heater ON + HTU21D_OFF = 0xFB //heater OFF +} +HTU21D_HEATER_SWITCH; + + +class HTU21D +{ + public: + HTU21D(HTU21D_RESOLUTION = HTU21D_RES_RH12_TEMP14); + + #if defined(ESP8266) + bool begin(uint8_t sda = SDA, uint8_t scl = SCL); + #else + bool begin(void); + #endif + float readHumidity(HTU21D_HUMD_OPERATION_MODE = HTU21D_TRIGGER_HUMD_MEASURE_HOLD); //max accuracy ±2%RH in range 20%..80% at 25°C + float readCompensatedHumidity(float temperature = HTU21D_FORCE_READ_TEMP); //max accuracy ±2%RH in range 0%..100% at 0°C..80°C + float readTemperature(HTU21D_TEMP_OPERATION_MODE = HTU21D_TRIGGER_TEMP_MEASURE_HOLD); //max accuracy ±0.3°C in range 0°C..60°C + void setResolution(HTU21D_RESOLUTION sensorResolution); + void softReset(void); + bool batteryStatus(void); + void setHeater(HTU21D_HEATER_SWITCH heaterSwitch); + uint16_t readDeviceID(void); + uint8_t readFirmwareVersion(void); + + private: + HTU21D_RESOLUTION _resolution; + + void write8(uint8_t reg, uint8_t value); + uint8_t read8(uint8_t reg); + uint8_t checkCRC8(uint16_t data); +}; + +#endif diff --git a/src/libs/Low-Power-master/Examples/idleWakePeriodic/idleWakePeriodic.ino b/src/libs/Low-Power-master/Examples/idleWakePeriodic/idleWakePeriodic.ino new file mode 100644 index 0000000..f2c59af --- /dev/null +++ b/src/libs/Low-Power-master/Examples/idleWakePeriodic/idleWakePeriodic.ino @@ -0,0 +1,36 @@ +// **** INCLUDES ***** +#include "LowPower.h" + +void setup() +{ + // No setup is required for this library +} + +void loop() +{ + // Enter idle state for 8 s with the rest of peripherals turned off + // Each microcontroller comes with different number of peripherals + // Comment off line of code where necessary + + // ATmega328P, ATmega168 + LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, + SPI_OFF, USART0_OFF, TWI_OFF); + + // ATmega32U4 + //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER4_OFF, TIMER3_OFF, TIMER1_OFF, + // TIMER0_OFF, SPI_OFF, USART1_OFF, TWI_OFF, USB_OFF); + + // ATmega2560 + //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF, + // TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART3_OFF, + // USART2_OFF, USART1_OFF, USART0_OFF, TWI_OFF); + + // ATmega256RFR2 + //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF, + // TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, + // USART1_OFF, USART0_OFF, TWI_OFF); + + // Do something here + // Example: Read sensor, data logging, data transmission. +} + diff --git a/src/libs/Low-Power-master/Examples/powerDownWakeExternalInterrupt/powerDownWakeExternalInterrupt.ino b/src/libs/Low-Power-master/Examples/powerDownWakeExternalInterrupt/powerDownWakeExternalInterrupt.ino new file mode 100644 index 0000000..f914bd6 --- /dev/null +++ b/src/libs/Low-Power-master/Examples/powerDownWakeExternalInterrupt/powerDownWakeExternalInterrupt.ino @@ -0,0 +1,33 @@ +// **** INCLUDES ***** +#include "LowPower.h" + +// Use pin 2 as wake up pin +const int wakeUpPin = 2; + +void wakeUp() +{ + // Just a handler for the pin interrupt. +} + +void setup() +{ + // Configure wake up pin as input. + // This will consumes few uA of current. + pinMode(wakeUpPin, INPUT); +} + +void loop() +{ + // Allow wake up pin to trigger interrupt on low. + attachInterrupt(0, wakeUp, LOW); + + // Enter power down state with ADC and BOD module disabled. + // Wake up when wake up pin is low. + LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); + + // Disable external pin interrupt on wake up pin. + detachInterrupt(0); + + // Do something here + // Example: Read sensor, data logging, data transmission. +} diff --git a/src/libs/Low-Power-master/Examples/powerDownWakePeriodic/powerDownWakePeriodic.ino b/src/libs/Low-Power-master/Examples/powerDownWakePeriodic/powerDownWakePeriodic.ino new file mode 100644 index 0000000..bce822a --- /dev/null +++ b/src/libs/Low-Power-master/Examples/powerDownWakePeriodic/powerDownWakePeriodic.ino @@ -0,0 +1,16 @@ +// **** INCLUDES ***** +#include "LowPower.h" + +void setup() +{ + // No setup is required for this library +} + +void loop() +{ + // Enter power down state for 8 s with ADC and BOD module disabled + LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); + + // Do something here + // Example: Read sensor, data logging, data transmission. +} diff --git a/src/libs/Low-Power-master/Examples/standbyExternalInterruptSAMD21/standbyExternalInterruptSAMD21.ino b/src/libs/Low-Power-master/Examples/standbyExternalInterruptSAMD21/standbyExternalInterruptSAMD21.ino new file mode 100644 index 0000000..662d42f --- /dev/null +++ b/src/libs/Low-Power-master/Examples/standbyExternalInterruptSAMD21/standbyExternalInterruptSAMD21.ino @@ -0,0 +1,59 @@ +// **** INCLUDES ***** +#include "LowPower.h" + +// External interrupt on pin 0 (use pin 0 to 24, except pin 4 on Arduino Zero) +const int pin = 0; +unsigned char count = 10; + +void setup() +{ + // Wait for serial USB port to open + while(!SerialUSB); + SerialUSB.println("***** ATSAMD21 Standby Mode Example *****"); + + // ***** IMPORTANT ***** + // Delay is required to allow the USB interface to be active during + // sketch upload process + SerialUSB.println("Entering standby mode in:"); + for (count; count > 0; count--) + { + SerialUSB.print(count); + SerialUSB.println(" s"); + delay(1000); + } + // ********************* + + // External interrupt on pin (example: press of an active low button) + // A pullup resistor is used to hold the signal high when no button press + attachInterrupt(pin, blink, LOW); +} + +void loop() +{ + SerialUSB.println("Entering standby mode."); + SerialUSB.println("Apply low signal to wake the processor."); + SerialUSB.println("Zzzz..."); + // Detach USB interface + USBDevice.detach(); + // Enter standby mode + LowPower.standby(); + // Attach USB interface + USBDevice.attach(); + // Wait for serial USB port to open + while(!SerialUSB); + // Serial USB is blazing fast, you might miss the messages + delay(1000); + SerialUSB.println("Awake!"); + SerialUSB.println("Send any character to enter standby mode again"); + // Wait for user response + while(!SerialUSB.available()); + while(SerialUSB.available() > 0) + { + SerialUSB.read(); + } +} + +void blink(void) +{ + +} diff --git a/src/libs/Low-Power-master/LowPower.cpp b/src/libs/Low-Power-master/LowPower.cpp new file mode 100644 index 0000000..6aff586 --- /dev/null +++ b/src/libs/Low-Power-master/LowPower.cpp @@ -0,0 +1,1195 @@ +/******************************************************************************* +* LowPower Library +* Version: 1.80 +* Date: 04-10-2018 +* Author: Lim Phang Moh +* Company: Rocket Scream Electronics +* Website: www.rocketscream.com +* +* This is a lightweight low power library for Arduino. +* +* This library is licensed under Creative Commons Attribution-ShareAlike 3.0 +* Unported License. +* +* Revision Description +* ======== =========== +* 1.80 Added support for ATmega88 and ATmega168P. PowerExtStandby() +* modified because not supported on Atmega88 / Atmega168 +* Contributed by mrguen. +* 1.70 Added support for ATmega644P and ATmega1284P. +* Contributed by alexreinert. +* 1.60 Added support for ATmega256RFR2. Contributed by Rodmg. +* 1.50 Fixed compiler optimization (Arduino IDE 1.6.x branch) on BOD enable +* function that causes the function to be over optimized. +* 1.40 Added support for ATSAMD21G18A. +* Library format compliant with Arduino IDE 1.5.x. +* 1.30 Added support for ATMega168, ATMega2560, ATMega1280 & ATMega32U4. +* Tested to work with Arduino IDE 1.0.1 - 1.0.4. +* 1.20 Remove typo error in idle method for checking whether Timer 0 was +* turned off. +* Remove dependecy on WProgram.h which is not required. +* Tested to work with Arduino IDE 1.0. +* 1.10 Added #ifndef for sleep_bod_disable() for compatibility with future +* Arduino IDE release. +* 1.00 Initial public release. +*******************************************************************************/ +#if defined (__AVR__) + #include + #include + #include + #include +#elif defined (__arm__) + +#else + #error "Processor architecture is not supported." +#endif + +#include "LowPower.h" + +#if defined (__AVR__) +// Only Pico Power devices can change BOD settings through software +#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) +#ifndef sleep_bod_disable +#define sleep_bod_disable() \ +do { \ + unsigned char tempreg; \ + __asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \ + "ori %[tempreg], %[bods_bodse]" "\n\t" \ + "out %[mcucr], %[tempreg]" "\n\t" \ + "andi %[tempreg], %[not_bodse]" "\n\t" \ + "out %[mcucr], %[tempreg]" \ + : [tempreg] "=&d" (tempreg) \ + : [mcucr] "I" _SFR_IO_ADDR(MCUCR), \ + [bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \ + [not_bodse] "i" (~_BV(BODSE))); \ +} while (0) +#endif +#endif + +#define lowPowerBodOn(mode) \ +do { \ + set_sleep_mode(mode); \ + cli(); \ + sleep_enable(); \ + sei(); \ + sleep_cpu(); \ + sleep_disable(); \ + sei(); \ +} while (0); + +// Only Pico Power devices can change BOD settings through software +#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) +#define lowPowerBodOff(mode)\ +do { \ + set_sleep_mode(mode); \ + cli(); \ + sleep_enable(); \ + sleep_bod_disable(); \ + sei(); \ + sleep_cpu(); \ + sleep_disable(); \ + sei(); \ +} while (0); +#endif + +// Some macros is still missing from AVR GCC distribution for ATmega32U4 +#if defined __AVR_ATmega32U4__ + // Timer 4 PRR bit is currently not defined in iom32u4.h + #ifndef PRTIM4 + #define PRTIM4 4 + #endif + + // Timer 4 power reduction macro is not defined currently in power.h + #ifndef power_timer4_disable + #define power_timer4_disable() (PRR1 |= (uint8_t)(1 << PRTIM4)) + #endif + + #ifndef power_timer4_enable + #define power_timer4_enable() (PRR1 &= (uint8_t)~(1 << PRTIM4)) + #endif +#endif + +/******************************************************************************* +* Name: idle +* Description: Putting ATmega328P/168 into idle state. Please make sure you +* understand the implication and result of disabling module. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control: +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +* 4. timer1 Timer 1 module disable control: +* (a) TIMER1_OFF - Turn off Timer 1 module +* (b) TIMER1_ON - Leave Timer 1 module in its default state +* +* 5. timer0 Timer 0 module disable control: +* (a) TIMER0_OFF - Turn off Timer 0 module +* (b) TIMER0_ON - Leave Timer 0 module in its default state +* +* 6. spi SPI module disable control: +* (a) SPI_OFF - Turn off SPI module +* (b) SPI_ON - Leave SPI module in its default state +* +* 7. usart0 USART0 module disable control: +* (a) USART0_OFF - Turn off USART0 module +* (b) USART0_ON - Leave USART0 module in its default state +* +* 8. twi TWI module disable control: +* (a) TWI_OFF - Turn off TWI module +* (b) TWI_ON - Leave TWI module in its default state +* +*******************************************************************************/ +#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega88__) +void LowPowerClass::idle(period_t period, adc_t adc, timer2_t timer2, + timer1_t timer1, timer0_t timer0, + spi_t spi, usart0_t usart0, twi_t twi) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + + power_timer2_disable(); + } + + if (adc == ADC_OFF) + { + ADCSRA &= ~(1 << ADEN); + power_adc_disable(); + } + + if (timer1 == TIMER1_OFF) power_timer1_disable(); + if (timer0 == TIMER0_OFF) power_timer0_disable(); + if (spi == SPI_OFF) power_spi_disable(); + if (usart0 == USART0_OFF) power_usart0_disable(); + if (twi == TWI_OFF) power_twi_disable(); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_IDLE); + + if (adc == ADC_OFF) + { + power_adc_enable(); + ADCSRA |= (1 << ADEN); + } + + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + + power_timer2_enable(); + } + + if (timer1 == TIMER1_OFF) power_timer1_enable(); + if (timer0 == TIMER0_OFF) power_timer0_enable(); + if (spi == SPI_OFF) power_spi_enable(); + if (usart0 == USART0_OFF) power_usart0_enable(); + if (twi == TWI_OFF) power_twi_enable(); +} +#endif + +/******************************************************************************* +* Name: idle +* Description: Putting ATmega32U4 into idle state. Please make sure you +* understand the implication and result of disabling module. +* Take note that Timer 2 is not available and USART0 is replaced +* with USART1 on ATmega32U4. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control: +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer4 Timer 4 module disable control: +* (a) TIMER4_OFF - Turn off Timer 4 module +* (b) TIMER4_ON - Leave Timer 4 module in its default state +* +* 4. timer3 Timer 3 module disable control: +* (a) TIMER3_OFF - Turn off Timer 3 module +* (b) TIMER3_ON - Leave Timer 3 module in its default state +* +* 5. timer1 Timer 1 module disable control: +* (a) TIMER1_OFF - Turn off Timer 1 module +* (b) TIMER1_ON - Leave Timer 1 module in its default state +* +* 6. timer0 Timer 0 module disable control: +* (a) TIMER0_OFF - Turn off Timer 0 module +* (b) TIMER0_ON - Leave Timer 0 module in its default state +* +* 7. spi SPI module disable control: +* (a) SPI_OFF - Turn off SPI module +* (b) SPI_ON - Leave SPI module in its default state +* +* 8. usart1 USART1 module disable control: +* (a) USART1_OFF - Turn off USART1 module +* (b) USART1_ON - Leave USART1 module in its default state +* +* 9. twi TWI module disable control: +* (a) TWI_OFF - Turn off TWI module +* (b) TWI_ON - Leave TWI module in its default state +* +* 10.usb USB module disable control: +* (a) USB_OFF - Turn off USB module +* (b) USB_ON - Leave USB module in its default state +*******************************************************************************/ +#if defined __AVR_ATmega32U4__ +void LowPowerClass::idle(period_t period, adc_t adc, + timer4_t timer4, timer3_t timer3, + timer1_t timer1, timer0_t timer0, + spi_t spi, usart1_t usart1, twi_t twi, usb_t usb) +{ + if (adc == ADC_OFF) + { + ADCSRA &= ~(1 << ADEN); + power_adc_disable(); + } + + if (timer4 == TIMER4_OFF) power_timer4_disable(); + if (timer3 == TIMER3_OFF) power_timer3_disable(); + if (timer1 == TIMER1_OFF) power_timer1_disable(); + if (timer0 == TIMER0_OFF) power_timer0_disable(); + if (spi == SPI_OFF) power_spi_disable(); + if (usart1 == USART1_OFF) power_usart1_disable(); + if (twi == TWI_OFF) power_twi_disable(); + if (usb == USB_OFF) power_usb_disable(); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_IDLE); + + if (adc == ADC_OFF) + { + power_adc_enable(); + ADCSRA |= (1 << ADEN); + } + + if (timer4 == TIMER4_OFF) power_timer4_enable(); + if (timer3 == TIMER3_OFF) power_timer3_enable(); + if (timer1 == TIMER1_OFF) power_timer1_enable(); + if (timer0 == TIMER0_OFF) power_timer0_enable(); + if (spi == SPI_OFF) power_spi_enable(); + if (usart1 == USART1_OFF) power_usart1_enable(); + if (twi == TWI_OFF) power_twi_enable(); + if (usb == USB_OFF) power_usb_enable(); +} +#endif + +/******************************************************************************* +* Name: idle +* Description: Putting ATmega644P & ATmega1284P into idle state. Please make sure +* you understand the implication and result of disabling module. +* Take note that extra USART 1 compared to an ATmega328P/168. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control: +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +* 4. timer1 Timer 1 module disable control: +* (a) TIMER1_OFF - Turn off Timer 1 module +* (b) TIMER1_ON - Leave Timer 1 module in its default state +* +* 5. timer0 Timer 0 module disable control: +* (a) TIMER0_OFF - Turn off Timer 0 module +* (b) TIMER0_ON - Leave Timer 0 module in its default state +* +* 6. spi SPI module disable control: +* (a) SPI_OFF - Turn off SPI module +* (b) SPI_ON - Leave SPI module in its default state +* +* 7. usart1 USART1 module disable control: +* (a) USART1_OFF - Turn off USART1 module +* (b) USART1_ON - Leave USART1 module in its default state +* +* 8. usart0 USART0 module disable control: +* (a) USART0_OFF - Turn off USART0 module +* (b) USART0_ON - Leave USART0 module in its default state +* +* 9. twi TWI module disable control: +* (a) TWI_OFF - Turn off TWI module +* (b) TWI_ON - Leave TWI module in its default state +* +*******************************************************************************/ +#if defined (__AVR_ATmega644P__) || defined (__AVR_ATmega1284P__) +void LowPowerClass::idle(period_t period, adc_t adc, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart1_t usart1, usart0_t usart0, twi_t twi) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + + power_timer2_disable(); + } + + if (adc == ADC_OFF) + { + ADCSRA &= ~(1 << ADEN); + power_adc_disable(); + } + + if (timer1 == TIMER1_OFF) power_timer1_disable(); + if (timer0 == TIMER0_OFF) power_timer0_disable(); + if (spi == SPI_OFF) power_spi_disable(); + if (usart1 == USART1_OFF) power_usart1_disable(); + if (usart0 == USART0_OFF) power_usart0_disable(); + if (twi == TWI_OFF) power_twi_disable(); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_IDLE); + + if (adc == ADC_OFF) + { + power_adc_enable(); + ADCSRA |= (1 << ADEN); + } + + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + + power_timer2_enable(); + } + + if (timer1 == TIMER1_OFF) power_timer1_enable(); + if (timer0 == TIMER0_OFF) power_timer0_enable(); + if (spi == SPI_OFF) power_spi_enable(); + if (usart1 == USART1_OFF) power_usart1_enable(); + if (usart0 == USART0_OFF) power_usart0_enable(); + if (twi == TWI_OFF) power_twi_enable(); +} +#endif + +/******************************************************************************* +* Name: idle +* Description: Putting ATmega2560 & ATmega1280 into idle state. Please make sure +* you understand the implication and result of disabling module. +* Take note that extra Timer 5, 4, 3 compared to an ATmega328P/168. +* Also take note that extra USART 3, 2, 1 compared to an +* ATmega328P/168. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control: +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer5 Timer 5 module disable control: +* (a) TIMER5_OFF - Turn off Timer 5 module +* (b) TIMER5_ON - Leave Timer 5 module in its default state +* +* 4. timer4 Timer 4 module disable control: +* (a) TIMER4_OFF - Turn off Timer 4 module +* (b) TIMER4_ON - Leave Timer 4 module in its default state +* +* 5. timer3 Timer 3 module disable control: +* (a) TIMER3_OFF - Turn off Timer 3 module +* (b) TIMER3_ON - Leave Timer 3 module in its default state +* +* 6. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +* 7. timer1 Timer 1 module disable control: +* (a) TIMER1_OFF - Turn off Timer 1 module +* (b) TIMER1_ON - Leave Timer 1 module in its default state +* +* 8. timer0 Timer 0 module disable control: +* (a) TIMER0_OFF - Turn off Timer 0 module +* (b) TIMER0_ON - Leave Timer 0 module in its default state +* +* 9. spi SPI module disable control: +* (a) SPI_OFF - Turn off SPI module +* (b) SPI_ON - Leave SPI module in its default state +* +* 10.usart3 USART3 module disable control: +* (a) USART3_OFF - Turn off USART3 module +* (b) USART3_ON - Leave USART3 module in its default state +* +* 11.usart2 USART2 module disable control: +* (a) USART2_OFF - Turn off USART2 module +* (b) USART2_ON - Leave USART2 module in its default state +* +* 12.usart1 USART1 module disable control: +* (a) USART1_OFF - Turn off USART1 module +* (b) USART1_ON - Leave USART1 module in its default state +* +* 13.usart0 USART0 module disable control: +* (a) USART0_OFF - Turn off USART0 module +* (b) USART0_ON - Leave USART0 module in its default state +* +* 14.twi TWI module disable control: +* (a) TWI_OFF - Turn off TWI module +* (b) TWI_ON - Leave TWI module in its default state +* +*******************************************************************************/ +#if defined (__AVR_ATmega2560__) || defined (__AVR_ATmega1280__) +void LowPowerClass::idle(period_t period, adc_t adc, timer5_t timer5, + timer4_t timer4, timer3_t timer3, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart3_t usart3, usart2_t usart2, usart1_t usart1, + usart0_t usart0, twi_t twi) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + + power_timer2_disable(); + } + + if (adc == ADC_OFF) + { + ADCSRA &= ~(1 << ADEN); + power_adc_disable(); + } + + if (timer5 == TIMER5_OFF) power_timer5_disable(); + if (timer4 == TIMER4_OFF) power_timer4_disable(); + if (timer3 == TIMER3_OFF) power_timer3_disable(); + if (timer1 == TIMER1_OFF) power_timer1_disable(); + if (timer0 == TIMER0_OFF) power_timer0_disable(); + if (spi == SPI_OFF) power_spi_disable(); + if (usart3 == USART3_OFF) power_usart3_disable(); + if (usart2 == USART2_OFF) power_usart2_disable(); + if (usart1 == USART1_OFF) power_usart1_disable(); + if (usart0 == USART0_OFF) power_usart0_disable(); + if (twi == TWI_OFF) power_twi_disable(); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_IDLE); + + if (adc == ADC_OFF) + { + power_adc_enable(); + ADCSRA |= (1 << ADEN); + } + + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + + power_timer2_enable(); + } + + if (timer5 == TIMER5_OFF) power_timer5_enable(); + if (timer4 == TIMER4_OFF) power_timer4_enable(); + if (timer3 == TIMER3_OFF) power_timer3_enable(); + if (timer1 == TIMER1_OFF) power_timer1_enable(); + if (timer0 == TIMER0_OFF) power_timer0_enable(); + if (spi == SPI_OFF) power_spi_enable(); + if (usart3 == USART3_OFF) power_usart3_enable(); + if (usart2 == USART2_OFF) power_usart2_enable(); + if (usart1 == USART1_OFF) power_usart1_enable(); + if (usart0 == USART0_OFF) power_usart0_enable(); + if (twi == TWI_OFF) power_twi_enable(); +} +#endif + +/******************************************************************************* +* Name: idle +* Description: Putting ATmega256RFR2 into idle state. Please make sure +* you understand the implication and result of disabling module. +* Take note that extra Timer 5, 4, 3 compared to an ATmega328P/168. +* Also take note that extra USART 1 compared to an +* ATmega328P/168. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control: +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer5 Timer 5 module disable control: +* (a) TIMER5_OFF - Turn off Timer 5 module +* (b) TIMER5_ON - Leave Timer 5 module in its default state +* +* 4. timer4 Timer 4 module disable control: +* (a) TIMER4_OFF - Turn off Timer 4 module +* (b) TIMER4_ON - Leave Timer 4 module in its default state +* +* 5. timer3 Timer 3 module disable control: +* (a) TIMER3_OFF - Turn off Timer 3 module +* (b) TIMER3_ON - Leave Timer 3 module in its default state +* +* 6. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +* 7. timer1 Timer 1 module disable control: +* (a) TIMER1_OFF - Turn off Timer 1 module +* (b) TIMER1_ON - Leave Timer 1 module in its default state +* +* 8. timer0 Timer 0 module disable control: +* (a) TIMER0_OFF - Turn off Timer 0 module +* (b) TIMER0_ON - Leave Timer 0 module in its default state +* +* 9. spi SPI module disable control: +* (a) SPI_OFF - Turn off SPI module +* (b) SPI_ON - Leave SPI module in its default state +* +* 10.usart1 USART1 module disable control: +* (a) USART1_OFF - Turn off USART1 module +* (b) USART1_ON - Leave USART1 module in its default state +* +* 11.usart0 USART0 module disable control: +* (a) USART0_OFF - Turn off USART0 module +* (b) USART0_ON - Leave USART0 module in its default state +* +* 12.twi TWI module disable control: +* (a) TWI_OFF - Turn off TWI module +* (b) TWI_ON - Leave TWI module in its default state +* +*******************************************************************************/ +#if defined (__AVR_ATmega256RFR2__) +void LowPowerClass::idle(period_t period, adc_t adc, timer5_t timer5, + timer4_t timer4, timer3_t timer3, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart1_t usart1, + usart0_t usart0, twi_t twi) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + + power_timer2_disable(); + } + + if (adc == ADC_OFF) + { + ADCSRA &= ~(1 << ADEN); + power_adc_disable(); + } + + if (timer5 == TIMER5_OFF) power_timer5_disable(); + if (timer4 == TIMER4_OFF) power_timer4_disable(); + if (timer3 == TIMER3_OFF) power_timer3_disable(); + if (timer1 == TIMER1_OFF) power_timer1_disable(); + if (timer0 == TIMER0_OFF) power_timer0_disable(); + if (spi == SPI_OFF) power_spi_disable(); + if (usart1 == USART1_OFF) power_usart1_disable(); + if (usart0 == USART0_OFF) power_usart0_disable(); + if (twi == TWI_OFF) power_twi_disable(); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_IDLE); + + if (adc == ADC_OFF) + { + power_adc_enable(); + ADCSRA |= (1 << ADEN); + } + + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + + power_timer2_enable(); + } + + if (timer5 == TIMER5_OFF) power_timer5_enable(); + if (timer4 == TIMER4_OFF) power_timer4_enable(); + if (timer3 == TIMER3_OFF) power_timer3_enable(); + if (timer1 == TIMER1_OFF) power_timer1_enable(); + if (timer0 == TIMER0_OFF) power_timer0_enable(); + if (spi == SPI_OFF) power_spi_enable(); + if (usart1 == USART1_OFF) power_usart1_enable(); + if (usart0 == USART0_OFF) power_usart0_enable(); + if (twi == TWI_OFF) power_twi_enable(); +} +#endif + + +/******************************************************************************* +* Name: adcNoiseReduction +* Description: Putting microcontroller into ADC noise reduction state. This is +* a very useful state when using the ADC to achieve best and low +* noise signal. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control. Turning off the ADC module is +* basically removing the purpose of this low power mode. +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +*******************************************************************************/ +void LowPowerClass::adcNoiseReduction(period_t period, adc_t adc, + timer2_t timer2) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + } + #endif + + if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + lowPowerBodOn(SLEEP_MODE_ADC); + + if (adc == ADC_OFF) ADCSRA |= (1 << ADEN); + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + + } + #endif +} + +/******************************************************************************* +* Name: powerDown +* Description: Putting microcontroller into power down state. This is +* the lowest current consumption state. Use this together with +* external pin interrupt to wake up through external event +* triggering (example: RTC clockout pin, SD card detect pin). +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control. Turning off the ADC module is +* basically removing the purpose of this low power mode. +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. bod Brown Out Detector (BOD) module disable control: +* (a) BOD_OFF - Turn off BOD module +* (b) BOD_ON - Leave BOD module in its default state +* +*******************************************************************************/ +void LowPowerClass::powerDown(period_t period, adc_t adc, bod_t bod) +{ + if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + if (bod == BOD_OFF) + { + #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) + lowPowerBodOff(SLEEP_MODE_PWR_DOWN); + #else + lowPowerBodOn(SLEEP_MODE_PWR_DOWN); + #endif + } + else + { + lowPowerBodOn(SLEEP_MODE_PWR_DOWN); + } + + if (adc == ADC_OFF) ADCSRA |= (1 << ADEN); +} + +/******************************************************************************* +* Name: powerSave +* Description: Putting microcontroller into power save state. This is +* the lowest current consumption state after power down. +* Use this state together with an external 32.768 kHz crystal (but +* 8/16 MHz crystal/resonator need to be removed) to provide an +* asynchronous clock source to Timer 2. Please take note that +* Timer 2 is also used by the Arduino core for PWM operation. +* Please refer to wiring.c for explanation. Removal of the external +* 8/16 MHz crystal/resonator requires the microcontroller to run +* on its internal RC oscillator which is not so accurate for time +* critical operation. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control. Turning off the ADC module is +* basically removing the purpose of this low power mode. +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. bod Brown Out Detector (BOD) module disable control: +* (a) BOD_OFF - Turn off BOD module +* (b) BOD_ON - Leave BOD module in its default state +* +* 4. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +*******************************************************************************/ +void LowPowerClass::powerSave(period_t period, adc_t adc, bod_t bod, + timer2_t timer2) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + } + #endif + + if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + if (bod == BOD_OFF) + { + #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) + lowPowerBodOff(SLEEP_MODE_PWR_SAVE); + #else + lowPowerBodOn(SLEEP_MODE_PWR_SAVE); + #endif + } + else + { + lowPowerBodOn(SLEEP_MODE_PWR_SAVE); + } + + if (adc == ADC_OFF) ADCSRA |= (1 << ADEN); + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + } + #endif +} + +/******************************************************************************* +* Name: powerStandby +* Description: Putting microcontroller into power standby state. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control. Turning off the ADC module is +* basically removing the purpose of this low power mode. +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. bod Brown Out Detector (BOD) module disable control: +* (a) BOD_OFF - Turn off BOD module +* (b) BOD_ON - Leave BOD module in its default state +* +*******************************************************************************/ +void LowPowerClass::powerStandby(period_t period, adc_t adc, bod_t bod) +{ + if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + if (bod == BOD_OFF) + { + #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) + lowPowerBodOff(SLEEP_MODE_STANDBY); + #else + lowPowerBodOn(SLEEP_MODE_STANDBY); + #endif + } + else + { + lowPowerBodOn(SLEEP_MODE_STANDBY); + } + + if (adc == ADC_OFF) ADCSRA |= (1 << ADEN); +} + +/******************************************************************************* +* Name: powerExtStandby +* Description: Putting microcontroller into power extended standby state. This +* is different from the power standby state as it has the +* capability to run Timer 2 asynchronously. +* Not implemented on Atmega88 and Atmega168. +* +* Argument Description +* ========= =========== +* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake +* up resource: +* (a) SLEEP_15MS - 15 ms sleep +* (b) SLEEP_30MS - 30 ms sleep +* (c) SLEEP_60MS - 60 ms sleep +* (d) SLEEP_120MS - 120 ms sleep +* (e) SLEEP_250MS - 250 ms sleep +* (f) SLEEP_500MS - 500 ms sleep +* (g) SLEEP_1S - 1 s sleep +* (h) SLEEP_2S - 2 s sleep +* (i) SLEEP_4S - 4 s sleep +* (j) SLEEP_8S - 8 s sleep +* (k) SLEEP_FOREVER - Sleep without waking up through WDT +* +* 2. adc ADC module disable control. +* (a) ADC_OFF - Turn off ADC module +* (b) ADC_ON - Leave ADC module in its default state +* +* 3. bod Brown Out Detector (BOD) module disable control: +* (a) BOD_OFF - Turn off BOD module +* (b) BOD_ON - Leave BOD module in its default state +* +* 4. timer2 Timer 2 module disable control: +* (a) TIMER2_OFF - Turn off Timer 2 module +* (b) TIMER2_ON - Leave Timer 2 module in its default state +* +*******************************************************************************/ +void LowPowerClass::powerExtStandby(period_t period, adc_t adc, bod_t bod, + timer2_t timer2) +{ + // Temporary clock source variable + unsigned char clockSource = 0; + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (TCCR2B & CS22) clockSource |= (1 << CS22); + if (TCCR2B & CS21) clockSource |= (1 << CS21); + if (TCCR2B & CS20) clockSource |= (1 << CS20); + + // Remove the clock source to shutdown Timer2 + TCCR2B &= ~(1 << CS22); + TCCR2B &= ~(1 << CS21); + TCCR2B &= ~(1 << CS20); + } + #endif + + if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN); + + if (period != SLEEP_FOREVER) + { + wdt_enable(period); + WDTCSR |= (1 << WDIE); + } + + + #if defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__) // SLEEP_MODE_EXT_STANDBY not implemented on Atmega88 / Atmega168 + #else + if (bod == BOD_OFF) + { + #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168P__) + lowPowerBodOff(SLEEP_MODE_EXT_STANDBY); + #else + lowPowerBodOn(SLEEP_MODE_EXT_STANDBY); + #endif + } + else + { + lowPowerBodOn(SLEEP_MODE_EXT_STANDBY); + } + #endif + + if (adc == ADC_OFF) ADCSRA |= (1 << ADEN); + + #if !defined(__AVR_ATmega32U4__) + if (timer2 == TIMER2_OFF) + { + if (clockSource & CS22) TCCR2B |= (1 << CS22); + if (clockSource & CS21) TCCR2B |= (1 << CS21); + if (clockSource & CS20) TCCR2B |= (1 << CS20); + } + #endif +} + +/******************************************************************************* +* Name: ISR (WDT_vect) +* Description: Watchdog Timer interrupt service routine. This routine is +* required to allow automatic WDIF and WDIE bit clearance in +* hardware. +* +*******************************************************************************/ +ISR (WDT_vect) +{ + // WDIE & WDIF is cleared in hardware upon entering this ISR + wdt_disable(); +} + +#elif defined (__arm__) +#if defined (__SAMD21G18A__) +/******************************************************************************* +* Name: standby +* Description: Putting SAMD21G18A into idle mode. This is the lowest current +* consumption mode. Requires separate handling of clock and +* peripheral management (disabling and shutting down) to achieve +* the desired current consumption. +* +* Argument Description +* ========= =========== +* 1. idleMode Idle mode level (0, 1, 2) where IDLE_2 level provide lowest +* current consumption in this mode. +* +*******************************************************************************/ +void LowPowerClass::idle(idle_t idleMode) +{ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + PM->SLEEP.reg = idleMode; + __DSB(); + __WFI(); +} + +/******************************************************************************* +* Name: standby +* Description: Putting SAMD21G18A into standby mode. This is the lowest current +* consumption mode. Use this together with the built-in RTC (use +* RTCZero library) or external pin interrupt to wake up through +* external event triggering. +* +* Argument Description +* ========= =========== +* 1. NIL +* +*******************************************************************************/ +void LowPowerClass::standby() +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); +} + +#else + #error "Please ensure chosen MCU is ATSAMD21G18A." +#endif +#else + #error "Processor architecture is not supported." +#endif + +LowPowerClass LowPower; diff --git a/src/libs/Low-Power-master/LowPower.h b/src/libs/Low-Power-master/LowPower.h new file mode 100644 index 0000000..5a8864b --- /dev/null +++ b/src/libs/Low-Power-master/LowPower.h @@ -0,0 +1,173 @@ +#ifndef LowPower_h +#define LowPower_h + +#include "Arduino.h" + +enum period_t +{ + SLEEP_15MS, + SLEEP_30MS, + SLEEP_60MS, + SLEEP_120MS, + SLEEP_250MS, + SLEEP_500MS, + SLEEP_1S, + SLEEP_2S, + SLEEP_4S, + SLEEP_8S, + SLEEP_FOREVER +}; + +enum bod_t +{ + BOD_OFF, + BOD_ON +}; + +enum adc_t +{ + ADC_OFF, + ADC_ON +}; + +enum timer5_t +{ + TIMER5_OFF, + TIMER5_ON +}; + +enum timer4_t +{ + TIMER4_OFF, + TIMER4_ON +}; + +enum timer3_t +{ + TIMER3_OFF, + TIMER3_ON +}; + +enum timer2_t +{ + TIMER2_OFF, + TIMER2_ON +}; + +enum timer1_t +{ + TIMER1_OFF, + TIMER1_ON +}; + +enum timer0_t +{ + TIMER0_OFF, + TIMER0_ON +}; + +enum spi_t +{ + SPI_OFF, + SPI_ON +}; + +enum usart0_t +{ + USART0_OFF, + USART0_ON +}; + +enum usart1_t +{ + USART1_OFF, + USART1_ON +}; + +enum usart2_t +{ + USART2_OFF, + USART2_ON +}; + +enum usart3_t +{ + USART3_OFF, + USART3_ON +}; + +enum twi_t +{ + TWI_OFF, + TWI_ON +}; + +enum usb_t +{ + USB_OFF, + USB_ON +}; + +enum idle_t +{ + IDLE_0, + IDLE_1, + IDLE_2 +}; + +class LowPowerClass +{ + public: + #if defined (__AVR__) + + #if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega88__) + void idle(period_t period, adc_t adc, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart0_t usart0, twi_t twi); + #elif defined __AVR_ATmega644P__ || defined (__AVR_ATmega1284P__) + void idle(period_t period, adc_t adc, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart1_t usart1, usart0_t usart0, twi_t twi); + #elif defined __AVR_ATmega2560__ + void idle(period_t period, adc_t adc, timer5_t timer5, + timer4_t timer4, timer3_t timer3, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart3_t usart3, usart2_t usart2, usart1_t usart1, + usart0_t usart0, twi_t twi); + #elif defined __AVR_ATmega256RFR2__ + void idle(period_t period, adc_t adc, timer5_t timer5, + timer4_t timer4, timer3_t timer3, timer2_t timer2, + timer1_t timer1, timer0_t timer0, spi_t spi, + usart1_t usart1, + usart0_t usart0, twi_t twi); + #elif defined __AVR_ATmega32U4__ + void idle(period_t period, adc_t adc, timer4_t timer4, + timer3_t timer3, timer1_t timer1, timer0_t timer0, + spi_t spi, usart1_t usart1, twi_t twi, usb_t usb); + #else + #error "Please ensure chosen MCU is either 88, 168, 168P, 328P, 32U4, 2560 or 256RFR2." + #endif + void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2) __attribute__((optimize("-O1"))); + void powerDown(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1"))); + void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1"))); + void powerStandby(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1"))); + void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1"))); + + #elif defined (__arm__) + + #if defined (__SAMD21G18A__) + void idle(idle_t idleMode); + void standby(); + #else + #error "Please ensure chosen MCU is ATSAMD21G18A." + #endif + + #else + + #error "Processor architecture is not supported." + + #endif +}; + +extern LowPowerClass LowPower; +#endif diff --git a/src/libs/Low-Power-master/README.md b/src/libs/Low-Power-master/README.md new file mode 100644 index 0000000..de61264 --- /dev/null +++ b/src/libs/Low-Power-master/README.md @@ -0,0 +1,21 @@ +### Low-Power +Lightweight low power library for Arduino. + +Version: 1.80 + +Date: 04-10-2018 + +Devices Supported: +* ATMega88 +* ATMega168 +* ATMega168P +* ATMega328P +* ATMega32U4 +* ATMega644P +* ATMega1284P +* ATMega2560 +* ATMega256RFR2 +* ATSAMD21G18A + +####Notes: +External interrupt during standby on ATSAMD21G18A requires a patch to the Arduino SAMD Core in order for it to work. Fix is provided by this particular pull request. diff --git a/src/libs/Low-Power-master/keywords.txt b/src/libs/Low-Power-master/keywords.txt new file mode 100644 index 0000000..c01a5b8 --- /dev/null +++ b/src/libs/Low-Power-master/keywords.txt @@ -0,0 +1,72 @@ +####################################### +# Syntax Coloring Map LowPower +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +idle KEYWORD2 +adcNoiseReduction KEYWORD2 +powerDown KEYWORD2 +powerSave KEYWORD2 +powerStandby KEYWORD2 +powerExtStandby KEYWORD2 +standby KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +LowPower KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +SLEEP_15MS LITERAL1 +SLEEP_30MS LITERAL1 +SLEEP_60MS LITERAL1 +SLEEP_120MS LITERAL1 +SLEEP_250MS LITERAL1 +SLEEP_500MS LITERAL1 +SLEEP_1S LITERAL1 +SLEEP_2S LITERAL1 +SLEEP_4S LITERAL1 +SLEEP_8S LITERAL1 +SLEEP_FOREVER LITERAL1 +ADC_OFF LITERAL1 +ADC_ON LITERAL1 +BOD_OFF LITERAL1 +BOD_ON LITERAL1 +TIMER4_OFF LITERAL1 +TIMER4_ON LITERAL1 +TIMER3_OFF LITERAL1 +TIMER3_ON LITERAL1 +TIMER2_OFF LITERAL1 +TIMER2_ON LITERAL1 +TIMER1_OFF LITERAL1 +TIMER1_ON LITERAL1 +TIMER0_OFF LITERAL1 +TIMER0_ON LITERAL1 +USART3_OFF LITERAL1 +USART3_ON LITERAL1 +USART2_OFF LITERAL1 +USART2_ON LITERAL1 +USART1_OFF LITERAL1 +USART1_ON LITERAL1 +USART0_OFF LITERAL1 +USART0_ON LITERAL1 +SPI_OFF LITERAL1 +SPI_ON LITERAL1 +TWI_OFF LITERAL1 +TWI_ON LITERAL1 +USB_OFF LITERAL1 +USB_ON LITERAL1 +IDLE_0 LITERAL1 +IDLE_1 LITERAL1 +IDLE_2 LITERAL1 diff --git a/src/libs/Low-Power-master/library.properties b/src/libs/Low-Power-master/library.properties new file mode 100644 index 0000000..1ba34b5 --- /dev/null +++ b/src/libs/Low-Power-master/library.properties @@ -0,0 +1,9 @@ +name=Low-Power +version=1.6 +author=Rocket Scream Electronics +maintainer=Rocket Scream Electronics +sentence=Lightweight power management library +paragraph=Lightweight power management library +category=Other +url=https://github.com/rocketscream/Low-Power +architectures=avr,samd