0.1.0 AM2315

This commit is contained in:
rob tillaart 2022-01-06 12:08:13 +01:00
parent a2ab58e222
commit 8ccf1b205d
14 changed files with 731 additions and 0 deletions

View File

@ -0,0 +1,11 @@
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
# - due
# - zero
# - leonardo
- m4
- esp32
# - esp8266
# - mega2560

View File

@ -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

View File

@ -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

View File

@ -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$"

228
libraries/AM2315/AM2315.cpp Normal file
View File

@ -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 --

108
libraries/AM2315/AM2315.h Normal file
View File

@ -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 --

21
libraries/AM2315/LICENSE Normal file
View File

@ -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.

View File

@ -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

Binary file not shown.

View File

@ -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 --

View File

@ -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

View File

@ -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"
}

View File

@ -0,0 +1,11 @@
name=AM2315
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
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=

View File

@ -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 <ArduinoUnitTests.h>
#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()
// --------