diff --git a/README.md b/README.md index 783a97e..c647e90 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ If you have any questions or problems, check out [our forum](https://forum.airgr - [Sensirion Core](https://github.com/Sensirion/arduino-core/) - [Sensirion I2C SGP41](https://github.com/Sensirion/arduino-i2c-sgp41) - [Sensirion I2C SHT4x](https://github.com/Sensirion/arduino-i2c-sht4x) +- [Sensirion I2C SHT3x](https://github.com/Sensirion/arduino-i2c-sht3x) - [PMS](https://github.com/fu-hsi/pms) ## License diff --git a/examples/BASIC_v4/BASIC_v4.ino b/examples/BASIC_v4/BASIC_v4.ino index 6a0f939..ac3431b 100644 --- a/examples/BASIC_v4/BASIC_v4.ino +++ b/examples/BASIC_v4/BASIC_v4.ino @@ -471,7 +471,7 @@ void connectToWifi() { static void boardInit(void) { /** Init SHT sensor */ - if (ag.sht.begin(Wire) == false) { + if (ag.sht4x.begin(Wire) == false) { failedHandler("SHT init failed"); } @@ -545,8 +545,8 @@ void pmPoll() { } static void tempHumPoll() { - temp = ag.sht.getTemperature(); - hum = ag.sht.getRelativeHumidity(); + temp = ag.sht4x.getTemperature(); + hum = ag.sht4x.getRelativeHumidity(); Serial.printf("Temperature: %0.2f\r\n", temp); Serial.printf(" Humidity: %d\r\n", hum); diff --git a/examples/ONE_I-9PSL/ONE_I-9PSL.ino b/examples/ONE_I-9PSL/ONE_I-9PSL.ino index 5874d86..8f643b8 100644 --- a/examples/ONE_I-9PSL/ONE_I-9PSL.ino +++ b/examples/ONE_I-9PSL/ONE_I-9PSL.ino @@ -884,7 +884,7 @@ static void boardInit(void) { } /** INit SHT */ - if (ag.sht.begin(Wire) == false) { + if (ag.sht4x.begin(Wire) == false) { failedHandler("Init SHT failed"); } @@ -1329,8 +1329,8 @@ static void sendDataToServer(void) { * @brief Update temperature and humidity value */ static void tempHumPoll(void) { - temp = ag.sht.getTemperature(); - hum = ag.sht.getRelativeHumidity(); + temp = ag.sht4x.getTemperature(); + hum = ag.sht4x.getRelativeHumidity(); Serial.printf("Temperature: %0.2f\r\n", temp); Serial.printf(" Humidity: %d\r\n", hum); diff --git a/examples/TestESP32/TestESP32.ino b/examples/TestESP32/TestESP32.ino index 70e2736..1bd7ba5 100644 --- a/examples/TestESP32/TestESP32.ino +++ b/examples/TestESP32/TestESP32.ino @@ -99,7 +99,7 @@ void setup() { #if TEST_SENSOR_SHT4x - if (ag.sht.begin(Wire)) { + if (ag.sht4x.begin(Wire)) { log_i("SHT init success"); } else { log_i("SHT init failed"); @@ -218,9 +218,9 @@ void loop() { ms = (uint32_t)(millis() - shtTime); if (ms >= 1000) { shtTime = millis(); - log_i("Get sht temperature: %0.2f (degree celsius)", - ag.sht.getTemperature()); - log_i("Get sht temperature: %0.2f (%%)", ag.sht.getRelativeHumidity()); + log_i("Get sht4x temperature: %0.2f (degree celsius)", + ag.sht4x.getTemperature()); + log_i("Get sht4x temperature: %0.2f (%%)", ag.sht4x.getRelativeHumidity()); } #endif diff --git a/examples/TestESP8266/TestESP8266.ino b/examples/TestESP8266/TestESP8266.ino index fd515d6..ced36fb 100644 --- a/examples/TestESP8266/TestESP8266.ino +++ b/examples/TestESP8266/TestESP8266.ino @@ -58,7 +58,7 @@ void setup() { #endif #if TEST_SENSOR_SHT4x - if (ag.sht.begin(Wire, Serial)) { + if (ag.sht4x.begin(Wire, Serial)) { Serial.println("SHT init success"); } else { Serial.println("SHT init failed"); @@ -131,7 +131,7 @@ void loop() { shtTime = millis(); float temperature, humidity; Serial.printf("SHT Temperature: %f, Humidity: %f\r\n", - ag.sht.getTemperature(), ag.sht.getRelativeHumidity()); + ag.sht4x.getTemperature(), ag.sht4x.getRelativeHumidity()); } #endif diff --git a/examples/TestSht3x/TestSht3x.ino b/examples/TestSht3x/TestSht3x.ino new file mode 100644 index 0000000..7684fdc --- /dev/null +++ b/examples/TestSht3x/TestSht3x.ino @@ -0,0 +1,39 @@ +#include + +AirGradient ag(DIY_BASIC); + +void failedHandler(String msg); + +void setup() { + Serial.begin(115200); + Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin()); + + if (ag.sht3x.begin(Wire, Serial) == false) { + failedHandler("SHT3x init failed"); + } +} + +void loop() { + float temp = ag.sht3x.getTemperature(); + if (temp <= -256.0f) { + Serial.println("Get temperature failed"); + } else { + Serial.printf("Get temperature: %f\r\n", temp); + } + + float hum = ag.sht3x.getRelativeHumidity(); + if (hum < 0) { + Serial.println("Get humidity failed"); + } else { + Serial.printf("Get humidity: %f\r\n", hum); + } + + delay(1000); +} + +void failedHandler(String msg) { + while (true) { + Serial.println(msg); + delay(1000); + } +} diff --git a/src/AirGradient.cpp b/src/AirGradient.cpp index 3825ed1..e60a4d8 100644 --- a/src/AirGradient.cpp +++ b/src/AirGradient.cpp @@ -3,9 +3,9 @@ #define AG_LIB_VER "2.5.0" AirGradient::AirGradient(BoardType type) - : pms5003(type), pms5003t_1(type), pms5003t_2(type), s8(type), sht(type), sgp41(type), - display(type), boardType(type), button(type), statusLed(type), - ledBar(type), watchdog(type) {} + : pms5003(type), pms5003t_1(type), pms5003t_2(type), s8(type), sht4x(type), + sht3x(type), sgp41(type), display(type), boardType(type), button(type), + statusLed(type), ledBar(type), watchdog(type) {} /** * @brief Get pin number for I2C SDA diff --git a/src/AirGradient.h b/src/AirGradient.h index 576c8db..8034f60 100644 --- a/src/AirGradient.h +++ b/src/AirGradient.h @@ -11,7 +11,8 @@ #include "pms/pms5003t.h" #include "s8/s8.h" #include "sgp41/sgp41.h" -#include "sht4x/sht4x.h" +#include "sht/sht4x.h" +#include "sht/sht3x.h" /** * @brief Class with define all the sensor has supported by Airgradient. Each @@ -44,7 +45,13 @@ public: /** * @brief SHT41 Temperature and humidity sensor */ - Sht sht; + Sht4x sht4x; + + /** + * @brief SHT3x Temperature and humidity sensor + * + */ + Sht3x sht3x; /** * @brief SGP41 TVOC and NOx sensor diff --git a/src/library/arduino-i2c-sht3x/.clang-format b/src/library/arduino-i2c-sht3x/.clang-format new file mode 100644 index 0000000..047f2ad --- /dev/null +++ b/src/library/arduino-i2c-sht3x/.clang-format @@ -0,0 +1,14 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +IndentWidth: 4 +AlignAfterOpenBracket: Align +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +IndentCaseLabels: true +SpacesBeforeTrailingComments: 2 +PointerAlignment: Left +AlignEscapedNewlines: Left +ForEachMacros: ['TEST_GROUP', 'TEST'] +... diff --git a/src/library/arduino-i2c-sht3x/.gitlab-ci.yml b/src/library/arduino-i2c-sht3x/.gitlab-ci.yml new file mode 100644 index 0000000..1b859e0 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/.gitlab-ci.yml @@ -0,0 +1,110 @@ +stages: + - validate + - test + +variables: + YQ_URL: https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64 + +compile_test: + stage: test + image: + name: registry.gitlab.sensirion.lokal/sensirion/docker/docker-arduino:0.4.0 + tags: [docker, linux] + before_script: + - rm -rf ../sensirion-core-arduino-library + script: + - git clone --depth 1 --branch 0.5.2 https://github.com/Sensirion/arduino-core.git ../sensirion-core-arduino-library + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:samd:mkrzero ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:mega ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:nano ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:uno ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn esp32:esp32:esp32 ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn esp8266:esp8266:generic ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino + + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:samd:mkrzero ./examples/exampleUsage/exampleUsage.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:mega ./examples/exampleUsage/exampleUsage.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:nano ./examples/exampleUsage/exampleUsage.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:uno ./examples/exampleUsage/exampleUsage.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn esp32:esp32:esp32 ./examples/exampleUsage/exampleUsage.ino + - arduino-cli compile --libraries=".." --warnings all --fqbn esp8266:esp8266:generic ./examples/exampleUsage/exampleUsage.ino + +arduino_lint: + stage: validate + image: + name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0 + tags: [linux, docker] + script: + - mkdir ~/arlint + - PATH=~/arlint:$PATH + - curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | BINDIR=~/arlint sh + - arduino-lint --library-manager false + +syntax_check: + stage: validate + image: + name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0 + tags: [linux, docker] + script: + - find . -type f -iregex ".*\.\(c\|h\|cpp\|ino\)" -exec clang-format-6.0 -i -style=file {} \; && git diff --exit-code + + +cppcheck: + stage: validate + image: + name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0 + tags: [linux, docker] + script: + - cppcheck --std=c++11 --language=c++ --error-exitcode=1 --enable=warning,style,performance,portability --suppress=unreadVariable src/* + +TODO_check: + stage: validate + image: + name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0 + tags: [linux, docker] + script: + - '! grep -rnw --exclude=.gitlab-ci.yml --exclude-dir=.git . -e "TODO"' + +metadata_check: + stage: validate + image: + name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0 + tags: [linux, docker] + before_script: + - apt-get -qq update && apt-get -qq install -y wget + - if ! [ -d downloads/ ]; then mkdir downloads; fi + - if ! [ -e downloads/yq ]; then wget --no-verbose $YQ_URL -O downloads/yq; fi + - cp downloads/yq /usr/local/bin/yq && chmod +x /usr/local/bin/yq + script: + # check if metadata.yml exists + - > + if ! [ -f "metadata.yml" ]; then + echo "metadata.yml file not found" + exit 1 + fi + # check that dg_status is 'released' + - export DG_STATUS=$(yq ".dg_status.[]" ./metadata.yml) + - > + if [ $DG_STATUS != "released" ]; then + echo "dg_status in metadata.yml has to be 'released', not '$DG_STATUS'" + exit 1 + fi + # check that last_generated is not older than timestamp of last non-merge commit (+ 3 minutes) + - export IS_MANUALLY_MODIFIED=$(yq ".is_manually_modified" ./metadata.yml) + - > + if [ $IS_MANUALLY_MODIFIED = false ]; then + export LAST_GENERATED_TS=$(yq ".last_generated" ./metadata.yml) + export LAST_GENERATED_TS_EPOCH=$(date -d "$LAST_GENERATED_TS" +%s) + export LAST_NON_MERGE_COMMIT_TS=$(git log --format=%ad --date=iso-strict --no-merges -1) + export COMMIT_TS_EPOCH=$(date -d "$LAST_NON_MERGE_COMMIT_TS" +%s) + if [ $(($LAST_GENERATED_TS_EPOCH + 180)) -lt $COMMIT_TS_EPOCH ]; then + echo "'last_generated' timestamp in metadata.yml is older than commit timestamp ($LAST_GENERATED_TS vs $LAST_NON_MERGE_COMMIT_TS)" + exit 1 + fi + fi + # check that 'is_manually_modified' is set to true if commit is not from driver generator + - export LAST_NON_MERGE_COMMIT_AUTHOR=$(git log --format=%an --no-merges -1) + - > + if ! [ "$LAST_NON_MERGE_COMMIT_AUTHOR" = "Driver Generator 2" ] && [ "$IS_MANUALLY_MODIFIED" = false ]; then + echo "Last commit is not from Driver Generator. Please update 'is_manually_modified' in metadata.yml" + exit 1 + fi \ No newline at end of file diff --git a/src/library/arduino-i2c-sht3x/CHANGELOG.md b/src/library/arduino-i2c-sht3x/CHANGELOG.md new file mode 100644 index 0000000..5baa52d --- /dev/null +++ b/src/library/arduino-i2c-sht3x/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [Unreleased] + +## [1.0.0] - 2023-10-27 + +Initial release + diff --git a/src/library/arduino-i2c-sht3x/LICENSE b/src/library/arduino-i2c-sht3x/LICENSE new file mode 100644 index 0000000..f95f5fe --- /dev/null +++ b/src/library/arduino-i2c-sht3x/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2023, Sensirion AG +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/library/arduino-i2c-sht3x/README.md b/src/library/arduino-i2c-sht3x/README.md new file mode 100644 index 0000000..b77edaa --- /dev/null +++ b/src/library/arduino-i2c-sht3x/README.md @@ -0,0 +1,217 @@ +# Sensirion I²C SHT3X Arduino Library + +This is the Sensirion SHT3X library for Arduino allowing you to +communicate with a sensor of the SHT3X family over I²C. + + + +Click [here](https://sensirion.com/products/catalog/SHT30-DIS-B) to learn more about the Sensirion SHT3X sensor family. + + +Not all sensors of this driver family support all measurements. +In case a measurement is not supported by all sensors, the products that +support it are listed in the API description. + + + +## Supported sensor types + +| Sensor name | I²C Addresses | +| ------------- | -------------- | +|[SHT30A](https://sensirion.com/products/catalog/SHT30A-DIS-B)| **0x44**, 0x45| +|[SHT30](https://sensirion.com/products/catalog/SHT30-DIS-B)| **0x44**, 0x45| +|[SHT31A](https://sensirion.com/products/catalog/SHT31A-DIS-B)| **0x44**, 0x45| +|[SHT31](https://sensirion.com/products/catalog/SHT31-DIS-B)| **0x44**, 0x45| +|[SHT33](https://sensirion.com/products/catalog/SHT33-DIS)| **0x44**, 0x45| +|[SHT35A](https://sensirion.com/products/catalog/SHT35A-DIS-B)| **0x44**, 0x45| +|[SHT35](https://sensirion.com/products/catalog/SHT35-DIS-B)| **0x44**, 0x45| +|[SHT85](https://sensirion.com/sht85)| **0x44** | + +The following instructions and examples use a *SHT30*. + + + +## Installation of the library + +This library can be installed using the Arduino Library manager: +Start the [Arduino IDE](http://www.arduino.cc/en/main/software) and open +the Library Manager via + +`Sketch` ➔ `Include Library` ➔ `Manage Libraries...` + +Search for the `Sensirion I2C SHT3X` library in the `Filter +your search...` field and install it by clicking the `install` button. + +If you cannot find it in the library manager, download the latest release as .zip file +and add it to your [Arduino IDE](http://www.arduino.cc/en/main/software) via + +`Sketch` ➔ `Include Library` ➔ `Add .ZIP Library...` + +Don't forget to **install the dependencies** listed below the same way via library +manager or `Add .ZIP Library` + +#### Dependencies +* [Sensirion Core](https://github.com/Sensirion/arduino-core) + +## Sensor wiring + +Use the following pin description to connect your SHT3X to the standard I²C bus of your Arduino board: + + + +| *Pin* | *Cable Color* | *Name* | *Description* | *Comments* | +|-------|---------------|:------:|----------------|------------| +| 1 | green | SDA | I2C: Serial data input / output | +| 2 | black | GND | Ground | +| 3 | yellow | SCL | I2C: Serial clock input | +| 4 | red | VDD | Supply Voltage | 2.15V to 5.5V + + + + +The recommended voltage is 3.3V. + +### Board specific wiring +You will find pinout schematics for recommended board models below: + + + +
Arduino Uno +

+ +| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* | +| :---: | --- | --- | --- | +| SDA | 1 | green | D18/SDA | +| GND | 2 | black | GND | +| SCL | 3 | yellow | D19/SCL | +| VDD | 4 | red | 3.3V | + + + + +

+
+ + + +
Arduino Nano +

+ +| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* | +| :---: | --- | --- | --- | +| SDA | 1 | green | A4 | +| GND | 2 | black | GND | +| SCL | 3 | yellow | A5 | +| VDD | 4 | red | 3.3V | + + + + +

+
+ + + +
Arduino Micro +

+ +| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* | +| :---: | --- | --- | --- | +| SDA | 1 | green | D2/SDA | +| GND | 2 | black | GND | +| SCL | 3 | yellow | ~D3/SCL | +| VDD | 4 | red | 3.3V | + + + + +

+
+ + + +
Arduino Mega 2560 +

+ +| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* | +| :---: | --- | --- | --- | +| SDA | 1 | green | D20/SDA | +| GND | 2 | black | GND | +| SCL | 3 | yellow | D21/SCL | +| VDD | 4 | red | 3.3V | + + + + +

+
+ + + +
ESP32 DevKitC +

+ +| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* | +| :---: | --- | --- | --- | +| SDA | 1 | green | GPIO 21 | +| GND | 2 | black | GND | +| SCL | 3 | yellow | GPIO 22 | +| VDD | 4 | red | 3V3 | + + + + +

+
+ + +## Quick Start + +1. Install the libraries and dependencies according to [Installation of the library](#installation-of-the-library) + +2. Connect the SHT3X sensor to your Arduino as explained in [Sensor wiring](#sensor-wiring) + +3. Open the `exampleUsage` sample project within the Arduino IDE: + + `File` ➔ `Examples` ➔ `Sensirion I2C SHT3X` ➔ `exampleUsage` + + + The provided example is working with a SHT30, I²C address 0x44. + In order to use the code with another product or I²C address you need to change it in the code of `exampleUsage`. + You find the list with pre-defined addresses in `src/SensirionI2CSht3x.h`. + + +5. Click the `Upload` button in the Arduino IDE or `Sketch` ➔ `Upload` + +4. When the upload process has finished, open the `Serial Monitor` or `Serial + Plotter` via the `Tools` menu to observe the measurement values. Note that + the `Baud Rate` in the used tool has to be set to `115200 baud`. + +## Contributing + +**Contributions are welcome!** + +We develop and test this driver using our company internal tools (version +control, continuous integration, code review etc.) and automatically +synchronize the master branch with GitHub. But this doesn't mean that we don't +respond to issues or don't accept pull requests on GitHub. In fact, you're very +welcome to open issues or create pull requests :) + +This Sensirion library uses +[`clang-format`](https://releases.llvm.org/download.html) to standardize the +formatting of all our `.cpp` and `.h` files. Make sure your contributions are +formatted accordingly: + +The `-i` flag will apply the format changes to the files listed. + +```bash +clang-format -i src/*.cpp src/*.h +``` + +Note that differences from this formatting will result in a failed build until +they are fixed. + + +## License + +See [LICENSE](LICENSE). diff --git a/src/library/arduino-i2c-sht3x/examples/exampleUsage/exampleUsage.ino b/src/library/arduino-i2c-sht3x/examples/exampleUsage/exampleUsage.ino new file mode 100644 index 0000000..06a6945 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/examples/exampleUsage/exampleUsage.ino @@ -0,0 +1,98 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * Generator: sensirion-driver-generator 0.33.0 + * Product: sht3x + * Model-Version: 1.0.0 + */ +/* + * Copyright (c) 2023, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +SensirionI2cSht3x sensor; + +static char errorMessage[64]; +static int16_t error; + +void setup() { + + Serial.begin(115200); + while (!Serial) { + delay(100); + } + Wire.begin(); + sensor.begin(Wire, SHT30_I2C_ADDR_44); + + sensor.stopMeasurement(); + delay(1); + sensor.softReset(); + delay(100); + uint16_t aStatusRegister = 0u; + error = sensor.readStatusRegister(aStatusRegister); + if (error != NO_ERROR) { + Serial.print("Error trying to execute readStatusRegister(): "); + errorToString(error, errorMessage, sizeof errorMessage); + Serial.println(errorMessage); + return; + } + Serial.print("aStatusRegister: "); + Serial.print(aStatusRegister); + Serial.println(); + error = sensor.startPeriodicMeasurement(REPEATABILITY_MEDIUM, + MPS_ONE_PER_SECOND); + if (error != NO_ERROR) { + Serial.print("Error trying to execute startPeriodicMeasurement(): "); + errorToString(error, errorMessage, sizeof errorMessage); + Serial.println(errorMessage); + return; + } +} + +void loop() { + + float aTemperature = 0.0; + float aHumidity = 0.0; + error = sensor.blockingReadMeasurement(aTemperature, aHumidity); + if (error != NO_ERROR) { + Serial.print("Error trying to execute blockingReadMeasurement(): "); + errorToString(error, errorMessage, sizeof errorMessage); + Serial.println(errorMessage); + return; + } + Serial.print("aTemperature: "); + Serial.print(aTemperature); + Serial.print("\t"); + Serial.print("aHumidity: "); + Serial.print(aHumidity); + Serial.println(); +} diff --git a/src/library/arduino-i2c-sht3x/examples/exampleUsageSingleShot/exampleUsageSingleShot.ino b/src/library/arduino-i2c-sht3x/examples/exampleUsageSingleShot/exampleUsageSingleShot.ino new file mode 100644 index 0000000..0d65fc5 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/examples/exampleUsageSingleShot/exampleUsageSingleShot.ino @@ -0,0 +1,91 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * Generator: sensirion-driver-generator 0.33.0 + * Product: sht3x + * Model-Version: 1.0.0 + */ +/* + * Copyright (c) 2023, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +SensirionI2cSht3x sensor; + +static char errorMessage[64]; +static int16_t error; + +void setup() { + + Serial.begin(115200); + while (!Serial) { + delay(100); + } + Wire.begin(); + sensor.begin(Wire, SHT30_I2C_ADDR_44); + + sensor.stopMeasurement(); + delay(1); + sensor.softReset(); + delay(100); + uint16_t aStatusRegister = 0u; + error = sensor.readStatusRegister(aStatusRegister); + if (error != NO_ERROR) { + Serial.print("Error trying to execute readStatusRegister(): "); + errorToString(error, errorMessage, sizeof errorMessage); + Serial.println(errorMessage); + return; + } + Serial.print("aStatusRegister: "); + Serial.print(aStatusRegister); + Serial.println(); +} + +void loop() { + + float aTemperature = 0.0; + float aHumidity = 0.0; + error = sensor.measureSingleShot(REPEATABILITY_MEDIUM, false, aTemperature, + aHumidity); + if (error != NO_ERROR) { + Serial.print("Error trying to execute measureSingleShot(): "); + errorToString(error, errorMessage, sizeof errorMessage); + Serial.println(errorMessage); + return; + } + Serial.print("aTemperature: "); + Serial.print(aTemperature); + Serial.print("\t"); + Serial.print("aHumidity: "); + Serial.print(aHumidity); + Serial.println(); +} diff --git a/src/library/arduino-i2c-sht3x/images/Arduino-Mega-2560-Rev3-i2c-pinout-3.3V.png b/src/library/arduino-i2c-sht3x/images/Arduino-Mega-2560-Rev3-i2c-pinout-3.3V.png new file mode 100644 index 0000000..942173d Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/Arduino-Mega-2560-Rev3-i2c-pinout-3.3V.png differ diff --git a/src/library/arduino-i2c-sht3x/images/Arduino-Micro-i2c-pinout-3.3V.png b/src/library/arduino-i2c-sht3x/images/Arduino-Micro-i2c-pinout-3.3V.png new file mode 100644 index 0000000..ca9ba6c Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/Arduino-Micro-i2c-pinout-3.3V.png differ diff --git a/src/library/arduino-i2c-sht3x/images/Arduino-Nano-i2c-pinout-3.3V.png b/src/library/arduino-i2c-sht3x/images/Arduino-Nano-i2c-pinout-3.3V.png new file mode 100644 index 0000000..55fd2ff Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/Arduino-Nano-i2c-pinout-3.3V.png differ diff --git a/src/library/arduino-i2c-sht3x/images/Arduino-Uno-Rev3-i2c-pinout-3.3V.png b/src/library/arduino-i2c-sht3x/images/Arduino-Uno-Rev3-i2c-pinout-3.3V.png new file mode 100644 index 0000000..a6daad7 Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/Arduino-Uno-Rev3-i2c-pinout-3.3V.png differ diff --git a/src/library/arduino-i2c-sht3x/images/SHT3x.png b/src/library/arduino-i2c-sht3x/images/SHT3x.png new file mode 100644 index 0000000..795f29d Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/SHT3x.png differ diff --git a/src/library/arduino-i2c-sht3x/images/SHT3x_pinout.png b/src/library/arduino-i2c-sht3x/images/SHT3x_pinout.png new file mode 100644 index 0000000..d8b293b Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/SHT3x_pinout.png differ diff --git a/src/library/arduino-i2c-sht3x/images/esp32-devkitc-i2c-pinout-3.3V.png b/src/library/arduino-i2c-sht3x/images/esp32-devkitc-i2c-pinout-3.3V.png new file mode 100644 index 0000000..319b021 Binary files /dev/null and b/src/library/arduino-i2c-sht3x/images/esp32-devkitc-i2c-pinout-3.3V.png differ diff --git a/src/library/arduino-i2c-sht3x/keywords.txt b/src/library/arduino-i2c-sht3x/keywords.txt new file mode 100644 index 0000000..388e59e --- /dev/null +++ b/src/library/arduino-i2c-sht3x/keywords.txt @@ -0,0 +1,59 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SensirionI2cSht3x KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +measureSingleShot KEYWORD2 +startPeriodicMeasurement KEYWORD2 +blockingReadMeasurement KEYWORD2 +readStatusRegister KEYWORD2 +measureSingleShotHighRepeatability KEYWORD2 +measureSingleShotHighRepeatabilityClockStretching KEYWORD2 +measureSingleShotMediumRepeatability KEYWORD2 +measureSingleShotMediumRepeatabilityClockStretching KEYWORD2 +measureSingleShotLowRepeatability KEYWORD2 +measureSingleShotLowRepeatabilityClockStretching KEYWORD2 +startMeasurement05MpsHighRepeatability KEYWORD2 +startMeasurement05MpsMediumRepeatability KEYWORD2 +startMeasurement05MpsLowRepeatability KEYWORD2 +startMeasurement1MpsHighRepeatability KEYWORD2 +startMeasurement1MpsMediumRepeatability KEYWORD2 +startMeasurement1MpsLowRepeatability KEYWORD2 +startMeasurement2MpsHighRepeatability KEYWORD2 +startMeasurement2MpsMediumRepeatability KEYWORD2 +startMeasurement2MpsLowRepeatability KEYWORD2 +startMeasurement4MpsHighRepeatability KEYWORD2 +startMeasurement4MpsMediumRepeatability KEYWORD2 +startMeasurement4MpsLowRepeatability KEYWORD2 +startMeasurement10MpsHighRepeatability KEYWORD2 +startMeasurement10MpsMediumRepeatability KEYWORD2 +startMeasurement10MpsLowRepeatability KEYWORD2 +startArtMeasurement KEYWORD2 +readMeasurement KEYWORD2 +stopMeasurement KEYWORD2 +enableHeater KEYWORD2 +disableHeater KEYWORD2 +llreadStatusRegister KEYWORD2 +clearStatusRegister KEYWORD2 +softReset KEYWORD2 +signalTemperature KEYWORD2 +signalHumidity KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +sensor KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### \ No newline at end of file diff --git a/src/library/arduino-i2c-sht3x/library.properties b/src/library/arduino-i2c-sht3x/library.properties new file mode 100644 index 0000000..0a86b30 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/library.properties @@ -0,0 +1,11 @@ +name=SensirionI2cSht3x +version=1.0.0 +author=Sensirion +maintainer=Sensirion +sentence=Library for the SHT3X sensor family by Sensirion +paragraph=Enables you to use the SHT3X sensor family via I2C. +url=https://github.com/Sensirion/arduino-i2c-sht3x +category=Sensors +architectures=* +depends=Sensirion Core +includes=SensirionI2cSht3x.h diff --git a/src/library/arduino-i2c-sht3x/metadata.yml b/src/library/arduino-i2c-sht3x/metadata.yml new file mode 100644 index 0000000..c438e43 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/metadata.yml @@ -0,0 +1,7 @@ +generator_version: 0.33.0 +model_version: 1.0.0 +dg_status: +- released +is_manually_modified: true +first_generated: '2023-10-27 14:38' +last_generated: '2023-10-27 14:38' diff --git a/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.cpp b/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.cpp new file mode 100644 index 0000000..8d7d6fe --- /dev/null +++ b/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.cpp @@ -0,0 +1,720 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * Generator: sensirion-driver-generator 0.33.0 + * Product: sht3x + * Model-Version: 1.0.0 + */ +/* + * Copyright (c) 2023, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "SensirionI2cSht3x.h" +#include + +static uint8_t communication_buffer[6] = {0}; + +SensirionI2cSht3x::SensirionI2cSht3x() { +} + +float SensirionI2cSht3x::signalTemperature(uint16_t temperatureTicks) { + float temperature = 0.0; + temperature = (float)(temperatureTicks); + temperature = -45 + ((temperature * 175.0) / 65535.0); + return temperature; +} + +float SensirionI2cSht3x::signalHumidity(uint16_t humidityTicks) { + float humidity = 0.0; + humidity = (float)(humidityTicks); + humidity = (100 * humidity) / 65535.0; + return humidity; +} + +int16_t +SensirionI2cSht3x::measureSingleShot(Repeatability measurementRepeatability, + bool isClockStretching, + float& aTemperature, float& aHumidity) { + uint16_t rawTemp = 0; + uint16_t rawHumi = 0; + int16_t localError = 0; + if (isClockStretching) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = measureSingleShotHighRepeatabilityClockStretching( + rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = measureSingleShotMediumRepeatabilityClockStretching( + rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = measureSingleShotLowRepeatabilityClockStretching( + rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } + } else if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = measureSingleShotHighRepeatability(rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = measureSingleShotMediumRepeatability(rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = measureSingleShotLowRepeatability(rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + } + aTemperature = signalTemperature(rawTemp); + aHumidity = signalHumidity(rawHumi); + return localError; +} + +int16_t SensirionI2cSht3x::startPeriodicMeasurement( + Repeatability measurementRepeatability, Mps messagesPerSecond) { + int16_t localError = 0; + if (messagesPerSecond == MPS_EVERY_TWO_SECONDS) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = startMeasurement05MpsHighRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = startMeasurement05MpsMediumRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = startMeasurement05MpsLowRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } + } else if (messagesPerSecond == MPS_ONE_PER_SECOND) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = startMeasurement1MpsHighRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = startMeasurement1MpsMediumRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = startMeasurement1MpsLowRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } + } else if (messagesPerSecond == MPS_TWO_PER_SECOND) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = startMeasurement2MpsHighRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = startMeasurement2MpsMediumRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = startMeasurement2MpsLowRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } + } else if (messagesPerSecond == MPS_FOUR_PER_SECOND) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = startMeasurement4MpsHighRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = startMeasurement4MpsMediumRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = startMeasurement4MpsLowRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } + } else if (messagesPerSecond == MPS_TEN_PER_SECOND) { + if (measurementRepeatability == REPEATABILITY_HIGH) { + localError = startMeasurement10MpsHighRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_MEDIUM) { + localError = startMeasurement10MpsMediumRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } else if (measurementRepeatability == REPEATABILITY_LOW) { + localError = startMeasurement10MpsLowRepeatability(); + if (localError != NO_ERROR) { + return localError; + } + } + } + return localError; +} + +int16_t SensirionI2cSht3x::blockingReadMeasurement(float& aTemperature, + float& aHumidity) { + uint16_t status = 0u; + uint16_t dataReadyFlag = 0u; + uint16_t rawTemp = 0; + uint16_t rawHumi = 0; + int16_t localError = 0; + localError = llreadStatusRegister(status); + if (localError != NO_ERROR) { + return localError; + } + dataReadyFlag = (status >> 6) & 15; + while (dataReadyFlag == 0) { + delay(100); + localError = llreadStatusRegister(status); + if (localError != NO_ERROR) { + return localError; + } + dataReadyFlag = (status >> 6) & 15; + } + localError = readMeasurement(rawTemp, rawHumi); + if (localError != NO_ERROR) { + return localError; + } + aTemperature = signalTemperature(rawTemp); + aHumidity = signalHumidity(rawHumi); + return localError; +} + +int16_t SensirionI2cSht3x::readStatusRegister(uint16_t& aStatusRegister) { + uint16_t status = 0u; + int16_t localError = 0; + localError = llreadStatusRegister(status); + if (localError != NO_ERROR) { + return localError; + } + aStatusRegister = static_cast(status); + + return localError; +} + +int16_t SensirionI2cSht3x::measureSingleShotHighRepeatability( + uint16_t& temperatureTicks, uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2400, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::measureSingleShotHighRepeatabilityClockStretching( + uint16_t& temperatureTicks, uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2c06, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::measureSingleShotMediumRepeatability( + uint16_t& temperatureTicks, uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x240b, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::measureSingleShotMediumRepeatabilityClockStretching( + uint16_t& temperatureTicks, uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2c0d, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t +SensirionI2cSht3x::measureSingleShotLowRepeatability(uint16_t& temperatureTicks, + uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2416, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::measureSingleShotLowRepeatabilityClockStretching( + uint16_t& temperatureTicks, uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2c10, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement05MpsHighRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2032, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement05MpsMediumRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2024, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement05MpsLowRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x202f, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement1MpsHighRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2130, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement1MpsMediumRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2126, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement1MpsLowRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x212d, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement2MpsHighRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2236, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement2MpsMediumRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2220, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement2MpsLowRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x222b, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement4MpsHighRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2334, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement4MpsMediumRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2322, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement4MpsLowRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2329, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement10MpsHighRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2737, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(16); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement10MpsMediumRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2721, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(7); + return localError; +} + +int16_t SensirionI2cSht3x::startMeasurement10MpsLowRepeatability() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x273a, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(5); + return localError; +} + +int16_t SensirionI2cSht3x::startArtMeasurement() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x2b32, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + return localError; +} + +int16_t SensirionI2cSht3x::readMeasurement(uint16_t& temperatureTicks, + uint16_t& humidityTicks) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0xe000, buffer_ptr, 6); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + SensirionI2CRxFrame rxFrame(buffer_ptr, 6); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(temperatureTicks); + localError |= rxFrame.getUInt16(humidityTicks); + return localError; +} + +int16_t SensirionI2cSht3x::stopMeasurement() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x3093, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(1); + return localError; +} + +int16_t SensirionI2cSht3x::enableHeater() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x306d, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(10); + return localError; +} + +int16_t SensirionI2cSht3x::disableHeater() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x3066, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(10); + return localError; +} + +int16_t SensirionI2cSht3x::llreadStatusRegister(uint16_t& statusRegister) { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0xf32d, buffer_ptr, 3); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(10); + SensirionI2CRxFrame rxFrame(buffer_ptr, 3); + localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 3, + rxFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + localError |= rxFrame.getUInt16(statusRegister); + return localError; +} + +int16_t SensirionI2cSht3x::clearStatusRegister() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x3041, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(10); + return localError; +} + +int16_t SensirionI2cSht3x::softReset() { + int16_t localError = NO_ERROR; + uint8_t* buffer_ptr = communication_buffer; + SensirionI2CTxFrame txFrame = + SensirionI2CTxFrame::createWithUInt16Command(0x30a2, buffer_ptr, 2); + localError = + SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus); + if (localError != NO_ERROR) { + return localError; + } + delay(2); + return localError; +} + +void SensirionI2cSht3x::begin(TwoWire& i2cBus, uint8_t i2cAddress) { + _i2cBus = &i2cBus; + _i2cAddress = i2cAddress; +} diff --git a/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.h b/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.h new file mode 100644 index 0000000..e9ff789 --- /dev/null +++ b/src/library/arduino-i2c-sht3x/src/SensirionI2cSht3x.h @@ -0,0 +1,548 @@ +/* + * THIS FILE IS AUTOMATICALLY GENERATED + * + * Generator: sensirion-driver-generator 0.33.0 + * Product: sht3x + * Model-Version: 1.0.0 + */ +/* + * Copyright (c) 2023, Sensirion AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Sensirion AG nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SENSIRIONI2CSHT3X_H +#define SENSIRIONI2CSHT3X_H + +#include "../../SensirionCore/src/SensirionCore.h" +#include + +#define NO_ERROR 0 +#define SHT30A_I2C_ADDR_44 0x44 +#define SHT30A_I2C_ADDR_45 0x45 +#define SHT30_I2C_ADDR_44 0x44 +#define SHT30_I2C_ADDR_45 0x45 +#define SHT31A_I2C_ADDR_44 0x44 +#define SHT31A_I2C_ADDR_45 0x45 +#define SHT31_I2C_ADDR_44 0x44 +#define SHT31_I2C_ADDR_45 0x45 +#define SHT33_I2C_ADDR_44 0x44 +#define SHT33_I2C_ADDR_45 0x45 +#define SHT35A_I2C_ADDR_44 0x44 +#define SHT35A_I2C_ADDR_45 0x45 +#define SHT35_I2C_ADDR_44 0x44 +#define SHT35_I2C_ADDR_45 0x45 + +typedef enum { + MEASURE_SINGLE_SHOT_HIGH_REPEATABILITY_CMD_ID = 0x2400, + MEASURE_SINGLE_SHOT_HIGH_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c06, + MEASURE_SINGLE_SHOT_MEDIUM_REPEATABILITY_CMD_ID = 0x240b, + MEASURE_SINGLE_SHOT_MEDIUM_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c0d, + MEASURE_SINGLE_SHOT_LOW_REPEATABILITY_CMD_ID = 0x2416, + MEASURE_SINGLE_SHOT_LOW_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c10, + START_MEASUREMENT_0_5_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2032, + START_MEASUREMENT_0_5_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2024, + START_MEASUREMENT_0_5_MPS_LOW_REPEATABILITY_CMD_ID = 0x202f, + START_MEASUREMENT_1_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2130, + START_MEASUREMENT_1_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2126, + START_MEASUREMENT_1_MPS_LOW_REPEATABILITY_CMD_ID = 0x212d, + START_MEASUREMENT_2_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2236, + START_MEASUREMENT_2_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2220, + START_MEASUREMENT_2_MPS_LOW_REPEATABILITY_CMD_ID = 0x222b, + START_MEASUREMENT_4_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2334, + START_MEASUREMENT_4_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2322, + START_MEASUREMENT_4_MPS_LOW_REPEATABILITY_CMD_ID = 0x2329, + START_MEASUREMENT_10_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2737, + START_MEASUREMENT_10_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2721, + START_MEASUREMENT_10_MPS_LOW_REPEATABILITY_CMD_ID = 0x273a, + START_ART_MEASUREMENT_CMD_ID = 0x2b32, + READ_MEASUREMENT_CMD_ID = 0xe000, + STOP_MEASUREMENT_CMD_ID = 0x3093, + ENABLE_HEATER_CMD_ID = 0x306d, + DISABLE_HEATER_CMD_ID = 0x3066, + READ_STATUS_REGISTER_CMD_ID = 0xf32d, + CLEAR_STATUS_REGISTER_CMD_ID = 0x3041, + SOFT_RESET_CMD_ID = 0x30a2, +} CmdId; + +typedef enum { + REPEATABILITY_LOW = 0, + REPEATABILITY_MEDIUM = 1, + REPEATABILITY_HIGH = 2, +} Repeatability; + +typedef enum { + MPS_EVERY_TWO_SECONDS = 0, + MPS_ONE_PER_SECOND = 1, + MPS_TWO_PER_SECOND = 2, + MPS_FOUR_PER_SECOND = 4, + MPS_TEN_PER_SECOND = 10, +} Mps; + +class SensirionI2cSht3x { + public: + SensirionI2cSht3x(); + /** + * @brief Initializes the SHT3x class. + * + * @param i2cBus Arduino stream object to be used for communication. + */ + void begin(TwoWire& i2cBus, uint8_t i2cAddress); + + /** + * @brief Single shot measurement with the specified properties + * + * @param[in] measurementRepeatability The repeatability of the periodic + * measurement + * @param[in] isClockStretching Toggle clock stretching + * @param[out] aTemperature Converted from ticks to degrees celsius by -45 + + * (175 * value / 65535) + * @param[out] aHumidity Converted from ticks to relative humidity by 100 * + * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShot(Repeatability measurementRepeatability, + bool isClockStretching, float& aTemperature, + float& aHumidity); + + /** + * @brief startPeriodicMeasurement + * + * Start the periodic measurement measurement mode. + * + * This is a convenience method that selects the correct measurement command + * based on the provided arguments. + * + * @param[in] measurementRepeatability The repeatability of the periodic + * measurement + * @param[in] messagesPerSecond The messages per second of the periodic + * measurement + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startPeriodicMeasurement(Repeatability measurementRepeatability, + Mps messagesPerSecond); + + /** + * @brief blockingReadMeasurement + * + * This is a convenience method that combines polling the data ready flag + * and reading out the data. As the minimal measurement interval is 2s and + * we sleep for 100ms we iterate at most 200 times. Note that this is + * blocking the system for a considerable amount of time! + * + * @param[out] aTemperature Converted from ticks to degrees celsius by -45 + + * (175 * value / 65535) + * @param[out] aHumidity Converted from ticks to relative humidity by 100 * + * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t blockingReadMeasurement(float& aTemperature, float& aHumidity); + + /** + * @brief Read the contents of the status register + * + * @param[out] aStatusRegister + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t readStatusRegister(uint16_t& aStatusRegister); + + /** + * @brief measureSingleShotHighRepeatability + * + * Single shot measurement with high repeatability + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShotHighRepeatability(uint16_t& temperatureTicks, + uint16_t& humidityTicks); + + /** + * @brief measureSingleShotHighRepeatabilityClockStretching + * + * Single shot measurement with high repeatability and clock stretching + * enabled + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShotHighRepeatabilityClockStretching( + uint16_t& temperatureTicks, uint16_t& humidityTicks); + + /** + * @brief measureSingleShotMediumRepeatability + * + * Single shot measurement with medium repeatability + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShotMediumRepeatability(uint16_t& temperatureTicks, + uint16_t& humidityTicks); + + /** + * @brief measureSingleShotMediumRepeatabilityClockStretching + * + * Single shot measurement with medium repeatability and clock stretching + * enabled + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShotMediumRepeatabilityClockStretching( + uint16_t& temperatureTicks, uint16_t& humidityTicks); + + /** + * @brief measureSingleShotLowRepeatability + * + * Single shot measurement with low repeatability + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t measureSingleShotLowRepeatability(uint16_t& temperatureTicks, + uint16_t& humidityTicks); + + /** + * @brief measureSingleShotLowRepeatabilityClockStretching + * + * Single shot measurement with low repeatability and clock stretching + * enabled + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t + measureSingleShotLowRepeatabilityClockStretching(uint16_t& temperatureTicks, + uint16_t& humidityTicks); + + /** + * @brief startMeasurement05MpsHighRepeatability + * + * Start periodic measurement mode with 0.5 mps and high repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement05MpsHighRepeatability(); + + /** + * @brief startMeasurement05MpsMediumRepeatability + * + * Start periodic measurement mode with 0.5 mps and medium repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement05MpsMediumRepeatability(); + + /** + * @brief startMeasurement05MpsLowRepeatability + * + * Start periodic measurement mode with 0.5 mps and low repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement05MpsLowRepeatability(); + + /** + * @brief startMeasurement1MpsHighRepeatability + * + * Start periodic measurement mode with 1 mps and high repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement1MpsHighRepeatability(); + + /** + * @brief startMeasurement1MpsMediumRepeatability + * + * Start periodic measurement mode with 1 mps and medium repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement1MpsMediumRepeatability(); + + /** + * @brief startMeasurement1MpsLowRepeatability + * + * Start periodic measurement mode with 1 mps and low repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement1MpsLowRepeatability(); + + /** + * @brief startMeasurement2MpsHighRepeatability + * + * Start periodic measurement mode with 2 mps and high repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement2MpsHighRepeatability(); + + /** + * @brief startMeasurement2MpsMediumRepeatability + * + * Start periodic measurement mode with 2 mps and medium repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement2MpsMediumRepeatability(); + + /** + * @brief startMeasurement2MpsLowRepeatability + * + * Start periodic measurement mode with 2 mps and low repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement2MpsLowRepeatability(); + + /** + * @brief startMeasurement4MpsHighRepeatability + * + * Start periodic measurement mode with 4 mps and high repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement4MpsHighRepeatability(); + + /** + * @brief startMeasurement4MpsMediumRepeatability + * + * Start periodic measurement mode with 4 mps and medium repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement4MpsMediumRepeatability(); + + /** + * @brief startMeasurement4MpsLowRepeatability + * + * Start periodic measurement mode with 4 mps and low repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement4MpsLowRepeatability(); + + /** + * @brief startMeasurement10MpsHighRepeatability + * + * Start periodic measurement mode with 10 mps and high repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement10MpsHighRepeatability(); + + /** + * @brief startMeasurement10MpsMediumRepeatability + * + * Start periodic measurement mode with 10 mps and medium repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement10MpsMediumRepeatability(); + + /** + * @brief startMeasurement10MpsLowRepeatability + * + * Start periodic measurement mode with 10 mps and low repeatability. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startMeasurement10MpsLowRepeatability(); + + /** + * @brief startArtMeasurement + * + * Start ART (accelerated response time) measurement + * + * @note After issuing the ART command the sensor will start acquiring data + * with a frequency of 4Hz. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t startArtMeasurement(); + + /** + * @brief readMeasurement + * + * Read out data after a "start measurement" or "start art measurement" + * command has been issued. + * + * @param[out] temperatureTicks Temperature ticks. Convert to degrees + * celsius by -45 + 175 * value / 65535 + * @param[out] humidityTicks Humidity ticks. Convert to relative humidity by + * 100 + * * value / 65535 + * + * @note After the read out command fetch data has been issued, the data + * memory is cleared, i.e. no measurement data is present. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t readMeasurement(uint16_t& temperatureTicks, + uint16_t& humidityTicks); + + /** + * @brief stopMeasurement + * + * Stop the periodic measurement mode. + * + * @note Upon reception of this command the sensor will abort the ongoing + * measurement and enter the single shot mode. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t stopMeasurement(); + + /** + * @brief enableHeater + * + * Enable the heater + * + * @note The SHT3x is equipped with an internal heater, which is meant for + * plausibility checking only. The temperature increase achieved by the + * heater depends on various parameters and lies in the range of a few + * degrees centigrade. + * + * After a reset the heater is disabled (default condition). + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t enableHeater(); + + /** + * @brief disableHeater + * + * Disable the heater + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t disableHeater(); + + /** + * @brief llreadStatusRegister + * + * Read out the status register + * + * @param[out] statusRegister The contents of the status register + * + * @note The status register contains information on the operational status + * of the heater, the alert mode and on the execution status of the last + * command and the last write sequence. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t llreadStatusRegister(uint16_t& statusRegister); + + /** + * @brief clearStatusRegister + * + * Clear (set to zero) all flags (Bit 4) in the status register. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t clearStatusRegister(); + + /** + * @brief softReset + * + * Perform a soft reset. + * + * @note A system reset of the SHT3x can be achieved in multiple ways: - + * Soft reset: use this command - I2C general call: all devices on the I2C + * bus are reset by sending the command 0x06 to the I2C address 0x00 - Reset + * pin: send a pulse to the dedicated nReset pin. The nReset pin has to be + * pulled low for a minimum of 1 µs to generate a reset of the sensor. - + * Hard reset: Power down (incl. pulling SDA, SCL and ADDR low) + * + * During the reset procedure the sensor will not process commands. + * + * @return error_code 0 on success, an error code otherwise. + */ + int16_t softReset(); + + private: + TwoWire* _i2cBus = nullptr; + uint8_t _i2cAddress = 0; + + /** + * @brief signalTemperature + * + * @param[in] temperatureTicks + * + * @return Converted from ticks to degrees celsius by -45 + (175 * value / + * 65535) + */ + float signalTemperature(uint16_t temperatureTicks); + + /** + * @brief signalHumidity + * + * @param[in] humidityTicks + * + * @return Converted from ticks to relative humidity by 100 * value / 65535 + */ + float signalHumidity(uint16_t humidityTicks); +}; + +#endif // SENSIRIONI2CSHT3X_H diff --git a/src/sht/sht3x.cpp b/src/sht/sht3x.cpp new file mode 100644 index 0000000..62aa5e3 --- /dev/null +++ b/src/sht/sht3x.cpp @@ -0,0 +1,163 @@ +#include "sht3x.h" +#include "../library/arduino-i2c-sht3x/src/SensirionI2cSht3x.h" + +#define sht3x() ((SensirionI2cSht3x *)(this->_sensor)) + +/** + * @brief Check that sensor has initialized + * + * @return true Initialized + * @return false Not-initialized + */ +bool Sht3x::isBegin(void) { + if (_isBegin) { + return true; + } + AgLog("Sensor not-initialized"); + return false; +} + +/** + * @brief Check sensor has supported by board + * + * @return true Supported + * @return false Not-supported + */ +bool Sht3x::boardSupported(void) { + if (_bsp == NULL) { + _bsp = getBoardDef(_boarType); + } + + if ((_bsp == NULL) || (_bsp->I2C.supported == false)) { + AgLog("Board not supported"); + return false; + } + return true; +} + +/** + * @brief Get temperature and humidity data + * + * @param temp Tempreature read out + * @param hum Humidity read out + * @return true Success + * @return false Failure + */ +bool Sht3x::measure(float &temp, float &hum) { + if (isBegin() == false) { + return false; + } + + if (sht3x()->measureSingleShot(REPEATABILITY_MEDIUM, false, temp, hum) == + NO_ERROR) { + return true; + } + return false; +} + +/** + * @brief Construct a new Sht 3x:: Sht 3x object + * + * @param type + */ +Sht3x::Sht3x(BoardType type) : _boarType(type) {} + +/** + * @brief Destroy the Sht 3x:: Sht 3x object + * + */ +Sht3x::~Sht3x() { end(); } + +#ifdef ESP8266 +/** + * @brief Initialized sensor + * + * @param wire TwoWire instance, must be initialized + * @param debugStream Point to debug Serial to print debug log + * @return true Success + * @return false Failure + */ +bool Sht3x::begin(TwoWire &wire, Stream &debugStream) { + _debugStream = &debugStream; + return begin(wire); +} +#else +#endif + +/** + * @brief Init sensor, should init before use sensor, if not call other method + * always return invalid + * + * @param wire TwoWire instance, must be initialized + * @return true Success + * @return false Failure + */ +bool Sht3x::begin(TwoWire &wire) { + if (_isBegin) { + AgLog("Initialized, call end() then try again"); + return true; + } + + /** Check sensor has supported on board */ + if (boardSupported() == false) { + return false; + } + + /** Create sensor and init */ + _sensor = new SensirionI2cSht3x(); + sht3x()->begin(wire, SHT30_I2C_ADDR_44); + if (sht3x()->softReset() != NO_ERROR) { + AgLog("Reset sensor fail, look like sensor is not on I2C bus"); + return false; + } + + _isBegin = true; + AgLog("Initialize"); + return true; +} + +/** + * @brief De-initialize sensor + * + */ +void Sht3x::end(void) { + if (_isBegin == false) { + return; + } + _isBegin = false; + _bsp = NULL; + delete sht3x(); +#ifdef ESP8266 + _debugStream = nullptr; +#endif + AgLog("De-initialize"); +} + +/** + * @brief Get temperature degree celsius + * + * @return float value <= 256.0f is invalid, that mean sensor has issue or + * communication to sensor not worked as well + */ +float Sht3x::getTemperature(void) { + float temp; + float hum; + if (measure(temp, hum)) { + return temp; + } + return -256.0f; +} + +/** + * @brief Get humidity + * + * @return float Percent(0 - 100), value < 0 is invalid. + */ +float Sht3x::getRelativeHumidity(void) { + float temp; + float hum; + if (measure(temp, hum)) { + return hum; + } + return -1.0f; +} diff --git a/src/sht/sht3x.h b/src/sht/sht3x.h new file mode 100644 index 0000000..971aaa6 --- /dev/null +++ b/src/sht/sht3x.h @@ -0,0 +1,42 @@ +#ifndef _AIR_GRADIENT_SHT3X_H_ +#define _AIR_GRADIENT_SHT3X_H_ + +#include "../main/BoardDef.h" +#include +#include + +/** + * @brief The class with define how to handle the Sensirion sensor SHT3x + * (temperature and humidity sensor). + */ +class Sht3x { +private: + BoardType _boarType; + bool _isBegin = false; + const BoardDef *_bsp = NULL; + void *_sensor; +#ifdef ESP8266 + Stream *_debugStream = nullptr; + const char *TAG = "SHT3x"; +#else +#endif + + bool isBegin(void); + bool boardSupported(void); + bool measure(float &temp, float &hum); + +public: + Sht3x(BoardType type); + ~Sht3x(); + +#ifdef ESP8266 + bool begin(TwoWire &wire, Stream &debugStream); +#else +#endif + bool begin(TwoWire &wire); + void end(void); + float getTemperature(void); + float getRelativeHumidity(void); +}; + +#endif /** _AIR_GRADIENT_SHT3X_H_ */ diff --git a/src/sht4x/sht4x.cpp b/src/sht/sht4x.cpp similarity index 88% rename from src/sht4x/sht4x.cpp rename to src/sht/sht4x.cpp index 42a157f..df49b7e 100644 --- a/src/sht4x/sht4x.cpp +++ b/src/sht/sht4x.cpp @@ -14,7 +14,7 @@ * @return true Sucecss * @return false Failure */ -bool Sht::begin(TwoWire &wire, Stream &debugStream) { +bool Sht4x::begin(TwoWire &wire, Stream &debugStream) { this->_debugStream = &debugStream; return this->begin(wire); } @@ -22,11 +22,11 @@ bool Sht::begin(TwoWire &wire, Stream &debugStream) { #endif /** - * @brief Construct a new Sht:: Sht object + * @brief Construct a new Sht4x:: Sht4x object * * @param type Board type @ref BoardType */ -Sht::Sht(BoardType type) : _boardType(type) {} +Sht4x::Sht4x(BoardType type) : _boardType(type) {} /** * @brief Init sensor, Ifthis funciton not call the other funtion call will @@ -36,7 +36,7 @@ Sht::Sht(BoardType type) : _boardType(type) {} * @return true Success * @return false Failure */ -bool Sht::begin(TwoWire &wire) { +bool Sht4x::begin(TwoWire &wire) { /** Ignore next step if sensor has intiialized */ if (this->_isBegin) { AgLog("Initialized, call end() then try again"); @@ -67,7 +67,7 @@ bool Sht::begin(TwoWire &wire) { * @brief De-initialize SHT41 sensor * */ -void Sht::end(void) { +void Sht4x::end(void) { if (this->_isBegin == false) { return; } @@ -87,7 +87,7 @@ AgLog("De-initialize"); * @return float value <= 256.0f is invalid, That mean sensor has issue or * communication to sensor not worked as well. */ -float Sht::getTemperature(void) { +float Sht4x::getTemperature(void) { float temperature; float humidity; if (this->measureMediumPrecision(temperature, humidity)) { @@ -102,7 +102,7 @@ float Sht::getTemperature(void) { * * @return float Percent(0 - 100), value < 0 is invalid. */ -float Sht::getRelativeHumidity(void) { +float Sht4x::getRelativeHumidity(void) { float temperature; float humidity; if (this->measureMediumPrecision(temperature, humidity)) { @@ -118,7 +118,7 @@ float Sht::getRelativeHumidity(void) { * @return true Supported * @return false Not supported */ -bool Sht::boardSupported(void) { +bool Sht4x::boardSupported(void) { if (this->_bsp == NULL) { this->_bsp = getBoardDef(this->_boardType); } @@ -136,7 +136,7 @@ bool Sht::boardSupported(void) { * @return true Initialized * @return false Not-initialized */ -bool Sht::isBegin(void) { +bool Sht4x::isBegin(void) { if (this->_isBegin) { return true; } @@ -152,7 +152,7 @@ bool Sht::isBegin(void) { * @return true Success * @return false Failure */ -bool Sht::measureMediumPrecision(float &temperature, float &humidity) { +bool Sht4x::measureMediumPrecision(float &temperature, float &humidity) { if (this->isBegin() == false) { return false; } diff --git a/src/sht4x/sht4x.h b/src/sht/sht4x.h similarity index 95% rename from src/sht4x/sht4x.h rename to src/sht/sht4x.h index 9290320..b7a3b11 100644 --- a/src/sht4x/sht4x.h +++ b/src/sht/sht4x.h @@ -10,13 +10,13 @@ * @brief The class with define how to handle the Sensirion sensor SHT41 * (temperature and humidity sensor). */ -class Sht { +class Sht4x { public: #if defined(ESP8266) bool begin(TwoWire &wire, Stream &debugStream); #else #endif - Sht(BoardType type); + Sht4x(BoardType type); bool begin(TwoWire &wire); void end(void); float getTemperature(void);