diff --git a/libraries/AM2315/.arduino-ci.yml b/libraries/AM2315/.arduino-ci.yml new file mode 100644 index 00000000..e7cb4633 --- /dev/null +++ b/libraries/AM2315/.arduino-ci.yml @@ -0,0 +1,11 @@ +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + - uno + # - due + # - zero + # - leonardo + - m4 + - esp32 + # - esp8266 + # - mega2560 \ No newline at end of file diff --git a/libraries/AM2315/.github/workflows/arduino-lint.yml b/libraries/AM2315/.github/workflows/arduino-lint.yml new file mode 100644 index 00000000..b2ca058c --- /dev/null +++ b/libraries/AM2315/.github/workflows/arduino-lint.yml @@ -0,0 +1,13 @@ + +name: Arduino-lint + +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + compliance: strict diff --git a/libraries/AM2315/.github/workflows/arduino_test_runner.yml b/libraries/AM2315/.github/workflows/arduino_test_runner.yml new file mode 100644 index 00000000..096b975b --- /dev/null +++ b/libraries/AM2315/.github/workflows/arduino_test_runner.yml @@ -0,0 +1,17 @@ +--- +name: Arduino CI + +on: [push, pull_request] + +jobs: + runTest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/AM2315/.github/workflows/jsoncheck.yml b/libraries/AM2315/.github/workflows/jsoncheck.yml new file mode 100644 index 00000000..04603d08 --- /dev/null +++ b/libraries/AM2315/.github/workflows/jsoncheck.yml @@ -0,0 +1,18 @@ +name: JSON check + +on: + push: + paths: + - '**.json' + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: json-syntax-check + uses: limitusus/json-syntax-check@v1 + with: + pattern: "\\.json$" + diff --git a/libraries/AM2315/AM2315.cpp b/libraries/AM2315/AM2315.cpp new file mode 100644 index 00000000..a471c53f --- /dev/null +++ b/libraries/AM2315/AM2315.cpp @@ -0,0 +1,228 @@ +// +// FILE: AM2315.cpp +// AUTHOR: Rob.Tillaart@gmail.com +// VERSION: 0.1.0 +// PURPOSE: AM2315 Temperature and Humidity sensor library for Arduino +// URL: https://github.com/RobTillaart/AM2315 +// +// HISTORY: +// 0.1.0 2022-01-05 initial version + + +#include "AM2315.h" + + +// these defines are not for user to adjust +// READ_DELAY for blocking read +#define AM2315_READ_DELAY 2000 + +#define AM2315_ADDRESS 0x5C + + + +///////////////////////////////////////////////////// +// +// PUBLIC +// +AM2315::AM2315(TwoWire *wire) +{ + _wire = wire; + _temperature = 0; + _humidity = 0; + _humOffset = 0; + _tempOffset = 0; +}; + + +#if defined(ESP8266) || defined(ESP32) +bool AM2315::begin(const uint8_t dataPin, const uint8_t clockPin) +{ + if ((dataPin < 255) && (clockPin < 255)) + { + _wire->begin(dataPin, clockPin); + } else { + _wire->begin(); + } + return isConnected(); +} +#endif + + +bool AM2315::begin() +{ + _wire->begin(); + return isConnected(); +} + + +bool AM2315::isConnected() +{ + _wire->beginTransmission(AM2315_ADDRESS); + int rv = _wire->endTransmission(); + return rv == 0; +} + + +int AM2315::read() +{ + // reset readDelay + if (_readDelay == 0) _readDelay = 2000; + while (millis() - _lastRead < _readDelay) + { + if (!_waitForRead) return AM2315_WAITING_FOR_READ; + yield(); + } + int rv = _read(); + return rv; +} + + +float AM2315::getHumidity() +{ + float _hum = _humidity; + if (_humOffset != 0.0) _hum += _humOffset; + return _hum; +} + + +float AM2315::getTemperature() +{ + float _tem = _temperature; + if (_tempOffset != 0.0) _tem += _tempOffset; + return _tem; +} + + +/////////////////////////////////////////////////////////// +// +// PRIVATE +// +int AM2315::_read() +{ + // READ VALUES + int rv = _readSensor(); + + _lastRead = millis(); + + if (rv != AM2315_OK) + { + if (_suppressError == false) + { + _humidity = AM2315_INVALID_VALUE; + _temperature = AM2315_INVALID_VALUE; + } + return rv; // propagate error value + } + + _humidity = (_bits[0] * 256 + _bits[1]) * 0.1; + int16_t t = ((_bits[2] & 0x7F) * 256 + _bits[3]); + if (t == 0) + { + _temperature = 0.0; // prevent -0.0; + } + else + { + _temperature = t * 0.1; + if ((_bits[2] & 0x80) == 0x80 ) + { + _temperature = -_temperature; + } + } + + // TEST OUT OF RANGE +#ifdef AM2315_VALUE_OUT_OF_RANGE + if (_humidity > 100) + { + return AM2315_HUMIDITY_OUT_OF_RANGE; + } + if ((_temperature < -40) || (_temperature > 125)) + { + return AM2315_TEMPERATURE_OUT_OF_RANGE; + } +#endif + + return AM2315_OK; +} + + +///////////////////////////////////////////////////// +// +// PRIVATE +// + +// return values: +// AM2315_OK +// AM2315_ERROR_CONNECT +// AM2315_MISSING_BYTES +int AM2315::_readSensor() +{ + // EMPTY BUFFER + for (uint8_t i = 0; i < 5; i++) _bits[i] = 0; + + // HANDLE PENDING IRQ + yield(); + + // WAKE UP the sensor + _wire->beginTransmission(AM2315_ADDRESS); + for (int i = 0; i < 10; i++) _wire->write(0); + int rv = _wire->endTransmission(); + if (rv < 0) return rv; + + // REQUEST DATA + _wire->beginTransmission(AM2315_ADDRESS); + _wire->write(0X03); + _wire->write(0); + _wire->write(4); + rv = _wire->endTransmission(); + if (rv < 0) return rv; + + // GET DATA + const int length = 8; + int bytes = _wire->requestFrom(AM2315_ADDRESS, length); + if (bytes == 0) return AM2315_ERROR_CONNECT; + if (bytes < length) return AM2315_MISSING_BYTES; + + uint8_t buffer[12]; + for (int i = 0; i < bytes; i++) + { + buffer[i] = _wire->read(); + } + _bits[0] = buffer[2]; + _bits[1] = buffer[3]; + _bits[2] = buffer[4]; + _bits[3] = buffer[5]; + + // TODO ? + // TEST CHECKSUM HERE + // return AM2315_ERROR_CHECKSUM; + // uint16_t crc = _crc16(buffer, bytes - 2); + + return AM2315_OK; +} + + +uint16_t AM2315::_crc16(uint8_t *ptr, uint8_t len) +{ + uint16_t crc = 0xFFFF; + while(len--) + { + crc ^= *ptr++; + for (uint8_t i = 0; i < 8; i++) + { + if(crc & 0x01) + { + crc >>= 1; + crc ^= 0xA001; + } + else + { + crc>>=1; + } + } + } + return crc; +} + + +// -- END OF FILE -- + diff --git a/libraries/AM2315/AM2315.h b/libraries/AM2315/AM2315.h new file mode 100644 index 00000000..047db1ad --- /dev/null +++ b/libraries/AM2315/AM2315.h @@ -0,0 +1,108 @@ +#pragma once +// +// FILE: AM2315.h +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: AM2315 Temperature and Humidity sensor library for Arduino +// URL: https://github.com/RobTillaart/AM2315 + + +// AM232X PIN layout AM2315 COLOR +// ============================================ +// bottom view DESCRIPTION COLOR +// +---+ +// |o | VDD RED +// |o | SDA YELLOW +// |o | GND BLACK +// |o | SCL GREY +// +---+ + + +#include "Arduino.h" +#include "Wire.h" + + +#define AM2315_LIB_VERSION (F("0.1.0")) + + +#define AM2315_OK 0 +#define AM2315_ERROR_CHECKSUM -10 +#define AM2315_ERROR_CONNECT -11 +#define AM2315_MISSING_BYTES -12 +#define AM2315_WAITING_FOR_READ -50 + + +// optionally detect out of range values. +// occurs seldom so not enabled by default. +// #define AM2315_VALUE_OUT_OF_RANGE +#define AM2315_HUMIDITY_OUT_OF_RANGE -100 +#define AM2315_TEMPERATURE_OUT_OF_RANGE -101 + +// allows to overrule AM2315_INVALID_VALUE e.g. to prevent spike in graphs. +#ifndef AM2315_INVALID_VALUE +#define AM2315_INVALID_VALUE -999 +#endif + + +class AM2315 +{ +public: + + AM2315(TwoWire *wire = &Wire); + +#if defined(ESP8266) || defined(ESP32) + bool begin(const uint8_t dataPin, const uint8_t clockPin); +#endif + bool begin(); + bool isConnected(); + + int read(); + + // lastRead is in MilliSeconds since start sketch + uint32_t lastRead() { return _lastRead; }; + + // preferred interface + float getHumidity(); + float getTemperature(); + + // adding offsets works well in normal range + // might introduce under- or overflow at the ends of the sensor range + void setHumOffset(float offset) { _humOffset = offset; }; + void setTempOffset(float offset) { _tempOffset = offset; }; + float getHumOffset() { return _humOffset; }; + float getTempOffset() { return _tempOffset; }; + + bool getWaitForReading() { return _waitForRead; }; + void setWaitForReading(bool b ) { _waitForRead = b; }; + + // set readDelay to 0 will reset to datasheet values + uint16_t getReadDelay() { return _readDelay; }; + void setReadDelay(uint16_t rd = 0) { _readDelay = rd; }; + + + // suppress error values of -999 => check return value of read() instead + bool getSuppressError() { return _suppressError; }; + void setSuppressError(bool b) { _suppressError = b; }; + + +private: + float _humOffset = 0.0; + float _tempOffset = 0.0; + float _humidity = 0.0; + float _temperature = 0.0; + uint32_t _lastRead = 0; + bool _waitForRead = false; + bool _suppressError = false; + uint16_t _readDelay = 0; + + uint8_t _bits[5]; // buffer to receive data + int _read(); + int _readSensor(); + uint16_t _crc16(uint8_t *ptr, uint8_t len); + + TwoWire* _wire; +}; + + +// -- END OF FILE -- + diff --git a/libraries/AM2315/LICENSE b/libraries/AM2315/LICENSE new file mode 100644 index 00000000..cb502675 --- /dev/null +++ b/libraries/AM2315/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2022 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/AM2315/README.md b/libraries/AM2315/README.md new file mode 100644 index 00000000..4a5602aa --- /dev/null +++ b/libraries/AM2315/README.md @@ -0,0 +1,87 @@ + +[![Arduino CI](https://github.com/RobTillaart/AM2315/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/AM2315/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AM2315/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/AM2315/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AM2315/actions/workflows/jsoncheck.yml) +[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/AM2315/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/RobTillaart/AM2315.svg?maxAge=3600)](https://github.com/RobTillaart/AM2315/releases) + + +# AM2315 + +Arduino library for I2C AM2315 temperature and humidity sensor. + + +## Description + +**Experimental** + +The library should be initiated by calling the **begin()** function, +optionally **begin(dataPin, clockPin)** for **ESP32** and similar platforms. + +Thereafter one has to call the **read()** function to do the actual reading, +and with **getTemperature()** and **getHumidity()** to get the read values. +Calling these latter again will return the same values until a new **read()** is called. + + +## Interface + + +### Constructor + +- **AM2315(TwoWire \*wire)** constructor, using a specific Wire (I2C bus). +- **bool begin(uint8_t dataPin, uint8_t clockPin)** begin for ESP32 et al, to set I2C bus pins +- **bool begin()** initializer for non ESP32. Returns true if connected. +- **bool isConnected()** returns true if the address of the AM2315 can be seen on the I2C bus. + + +### Core + +- **int8_t read()** read the sensor and store the values internally. It returns the status of the read which should be 0. +- **float getHumidity()** returns last Humidity read, or -999 in case of error. +- **float getTemperature()** returns last Temperature read, or -999 in case of error. +- **uint32_t lastRead()** returns the timestamp in milliseconds since startup of the last successful read. + + +### Offset + +- **void setHumOffset(float offset)** set an offset to calibrate (1st order) the sensor. +- **float getHumOffset()** return current offset, default 0. +- **void setTempOffset(float offset)** set an offset to calibrate (1st order) the sensor +- **float getTempOffset()** return current offset, default 0. + + +### Control + +Functions to adjust the communication with the sensor. + +- **void setWaitForReading(bool b )** flag to enforce a blocking wait. +- **bool getWaitForReading()** returns the above setting. +- **void setReadDelay(uint16_t rd = 0)** To tune the time it waits before actual read. Default = 2000 ms. +set readDelay to 0 will reset to 2000 ms AFTER a call to **read()**. +- **uint16_t getReadDelay()** returns the above setting. +- **void setSuppressError(bool b)** suppress error values of -999 => you need to check the return value of read() instead. +This is used to keep spikes out of your graphs / logs. +- **bool getSuppressError()** returns the above setting. + + +## Operation + +See examples + + +## Future + +- found that the interface is like AM232X library.need to test first. +- get hardware and test test test ... +- update unit test +- documentation +- clean up code +- add examples +- add AM2320 derived class ? +- optimize + +**wont** +- add calls for meta information (no desxcription yet) + - 0x07 status register + - 0x08-0x0B user register HIGH LOW HIGH2 LOW2 + diff --git a/libraries/AM2315/docs/AM2315.pdf b/libraries/AM2315/docs/AM2315.pdf new file mode 100644 index 00000000..989eb75c Binary files /dev/null and b/libraries/AM2315/docs/AM2315.pdf differ diff --git a/libraries/AM2315/examples/AM2315_test/AM2315_test.ino b/libraries/AM2315/examples/AM2315_test/AM2315_test.ino new file mode 100644 index 00000000..d0c97699 --- /dev/null +++ b/libraries/AM2315/examples/AM2315_test/AM2315_test.ino @@ -0,0 +1,67 @@ +// +// FILE: AM2315_test.ino +// AUTHOR: Rob Tillaart +// PURPOSE: Demo for AM2315 I2C humidity & temperature sensor +// + + +#include "AM2315.h" +#include "Wire.h" + +AM2315 sensor(&Wire); + + +void setup() +{ + sensor.begin(); + // adjust your offsets + sensor.setTempOffset(-0.8); + sensor.setHumOffset(1.2); + + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("AM2315_LIB_VERSION: "); + Serial.println(AM2315_LIB_VERSION); + Serial.println(); + + delay(2000); + + Serial.println("Type,\tStatus,\tHumidity (%),\tTemperature (C)"); + delay(100); +} + + +void loop() +{ + if (millis() - sensor.lastRead() >= 2000) + { + // READ DATA + Serial.print("AM2315, \t"); + int status = sensor.read(); + switch (status) + { + case AM2315_OK: + Serial.print("OK,\t"); + break; + case AM2315_ERROR_CHECKSUM: + Serial.print("Checksum error,\t"); + break; + case AM2315_ERROR_CONNECT: + Serial.print("Connect error,\t"); + break; + case AM2315_MISSING_BYTES: + Serial.print("Bytes error,\t"); + break; + default: + Serial.print("Unknown error,\t"); + break; + } + // DISPLAY DATA, sensor has only one decimal. + Serial.print(sensor.getHumidity(), 1); + Serial.print(",\t"); + Serial.println(sensor.getTemperature(), 1); + } +} + + +// -- END OF FILE -- diff --git a/libraries/AM2315/keywords.txt b/libraries/AM2315/keywords.txt new file mode 100644 index 00000000..e97f6366 --- /dev/null +++ b/libraries/AM2315/keywords.txt @@ -0,0 +1,27 @@ +# Syntax Colouring Map For AM2315 + +# Data types (KEYWORD1) +AM2315 KEYWORD1 + +# Methods and Functions (KEYWORD2) +begin KEYWORD2 +isConnected KEYWORD2 +read KEYWORD2 + +getHumidity KEYWORD2 +getTemperature KEYWORD2 + +setHumOffset KEYWORD2 +setTempOffset KEYWORD2 +getHumOffset KEYWORD2 +getTempOffset KEYWORD2 +lastRead KEYWORD2 + + +# Constants (LITERAL1) +AM2315_LIB_VERSION LITERAL2 + +AM2315_OK LITERAL2 +AM2315_ERROR_CHECKSUM LITERAL1 +AM2315_ERROR_CONNECT LITERAL1 +AM2315_MISSING_BYTES LITERAL1 \ No newline at end of file diff --git a/libraries/AM2315/library.json b/libraries/AM2315/library.json new file mode 100644 index 00000000..fcf052e1 --- /dev/null +++ b/libraries/AM2315/library.json @@ -0,0 +1,23 @@ +{ + "name": "AM2315", + "keywords": "Temperature, Humidity, AM2315, I2C", + "description": "Arduino library for I2C AM2315 temperature and humidity sensor. ", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/AM2315.git" + }, + "version": "0.1.0", + "license": "MIT", + "frameworks": "arduino", + "platforms": "*", + "headers": "AM2315.h" +} diff --git a/libraries/AM2315/library.properties b/libraries/AM2315/library.properties new file mode 100644 index 00000000..587e474a --- /dev/null +++ b/libraries/AM2315/library.properties @@ -0,0 +1,11 @@ +name=AM2315 +version=0.1.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=Arduino library for I2C AM2315 temperature and humidity sensor. +paragraph=AM2315 +category=Sensors +url=https://github.com/RobTillaart/AM2315 +architectures=* +includes=AM2315.h +depends= diff --git a/libraries/AM2315/test/unit_test_001.cpp b/libraries/AM2315/test/unit_test_001.cpp new file mode 100644 index 00000000..5471c5ff --- /dev/null +++ b/libraries/AM2315/test/unit_test_001.cpp @@ -0,0 +1,100 @@ +// +// FILE: unit_test_001.cpp +// AUTHOR: Rob Tillaart +// DATE: 2022-01-05 +// PURPOSE: unit tests for the AM2315 library +// https://github.com/RobTillaart/AM2315 +// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md +// + +// supported assertions +// https://github.com/Arduino-CI/arduino_ci/blob/master/cpp/unittest/Assertion.h#L33-L42 +// ---------------------------- +// assertEqual(expected, actual) +// assertNotEqual(expected, actual) +// assertLess(expected, actual) +// assertMore(expected, actual) +// assertLessOrEqual(expected, actual) +// assertMoreOrEqual(expected, actual) +// assertTrue(actual) +// assertFalse(actual) +// assertNull(actual) +// assertNotNull(actual) + + +#include + + +#include "Wire.h" +#include "AM2315.h" + + +unittest_setup() +{ + fprintf(stderr, "AM2315_LIB_VERSION: %s \n", (char *) AM2315_LIB_VERSION); +} + +unittest_teardown() +{ +} + + +unittest(test_constants) +{ + assertEqual( 0, AM2315_OK); + assertEqual(-10, AM2315_ERROR_CHECKSUM); + assertEqual(-11, AM2315_ERROR_CONNECT); + assertEqual(-12, AM2315_MISSING_BYTES); + assertEqual(-50, AM2315_WAITING_FOR_READ); + + assertEqual(-100, AM2315_HUMIDITY_OUT_OF_RANGE); + assertEqual(-101, AM2315_TEMPERATURE_OUT_OF_RANGE); + assertEqual(-999, AM2315_INVALID_VALUE); + +} + + +unittest(test_constructor) +{ + AM2315 sensor(&Wire); + + assertEqualFloat(0, sensor.getTemperature(), 0.001); + assertEqualFloat(0, sensor.getHumidity(), 0.001); + assertEqualFloat(0, sensor.getTempOffset(), 0.001); + assertEqualFloat(0, sensor.getHumOffset(), 0.001); + + sensor.begin(); + assertEqual(AM2315_WAITING_FOR_READ, sensor.read()); + + assertEqualFloat(0, sensor.getTemperature(), 0.001); + assertEqualFloat(0, sensor.getHumidity(), 0.001); + assertEqualFloat(0, sensor.getTempOffset(), 0.001); + assertEqualFloat(0, sensor.getHumOffset(), 0.001); +} + + +unittest(test_offset) +{ + AM2315 sensor(&Wire); + sensor.begin(); + + assertEqualFloat(0, sensor.getTempOffset(), 0.001); + assertEqualFloat(0, sensor.getHumOffset(), 0.001); + + for (float offset = -1.5; offset < 1.5; offset += 0.5) + { + sensor.setHumOffset(offset); + sensor.setTempOffset(offset); + + assertEqualFloat(offset, sensor.getTempOffset(), 0.001); + assertEqualFloat(offset, sensor.getHumOffset(), 0.001); + + assertEqualFloat(offset, sensor.getTemperature(), 0.001); + assertEqualFloat(offset, sensor.getHumidity(), 0.001); + } +} + + +unittest_main() + +// --------