mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.2 AM2315
This commit is contained in:
parent
d81dd5eb89
commit
328f724f17
@ -1,19 +1,20 @@
|
||||
//
|
||||
// FILE: AM2315.cpp
|
||||
// AUTHOR: Rob.Tillaart@gmail.com
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.1.2
|
||||
// PURPOSE: AM2315 Temperature and Humidity sensor library for Arduino
|
||||
// URL: https://github.com/RobTillaart/AM2315
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.0 2022-01-05 initial version
|
||||
// 0.1.1 2022-01-11 fix handshake.
|
||||
// 0.1.2 2022-01-13 fix wake-up in read() for ESP32.
|
||||
|
||||
|
||||
#include "AM2315.h"
|
||||
|
||||
|
||||
// these defines are not for user to adjust
|
||||
// these defines can not be tuned
|
||||
// READ_DELAY for blocking read
|
||||
#define AM2315_READ_DELAY 2000
|
||||
|
||||
@ -27,11 +28,14 @@
|
||||
//
|
||||
AM2315::AM2315(TwoWire *wire)
|
||||
{
|
||||
_wire = wire;
|
||||
_temperature = 0;
|
||||
_humidity = 0;
|
||||
_humOffset = 0;
|
||||
_tempOffset = 0;
|
||||
_wire = wire;
|
||||
_temperature = 0;
|
||||
_humidity = 0;
|
||||
_humOffset = 0;
|
||||
_tempOffset = 0;
|
||||
_lastRead = 0;
|
||||
_waitForRead = false;
|
||||
_suppressError = false;
|
||||
};
|
||||
|
||||
|
||||
@ -70,16 +74,22 @@ bool AM2315::isConnected(uint16_t timeout)
|
||||
}
|
||||
|
||||
|
||||
// return values:
|
||||
// AM2315_OK
|
||||
// AM2315_ERROR_CONNECT
|
||||
// AM2315_MISSING_BYTES
|
||||
// AM2315_ERROR_CHECKSUM;
|
||||
// AM2315_HUMIDITY_OUT_OF_RANGE
|
||||
// AM2315_TEMPERATURE_OUT_OF_RANGE
|
||||
int AM2315::read()
|
||||
{
|
||||
// reset readDelay
|
||||
if (_readDelay == 0) _readDelay = AM2315_READ_DELAY;
|
||||
while (millis() - _lastRead < _readDelay)
|
||||
while (millis() - _lastRead < AM2315_READ_DELAY)
|
||||
{
|
||||
if (!_waitForRead) return AM2315_WAITING_FOR_READ;
|
||||
yield();
|
||||
}
|
||||
int rv = _read();
|
||||
_lastRead = millis();
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -104,13 +114,19 @@ float AM2315::getTemperature()
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
// return values:
|
||||
// AM2315_OK
|
||||
// AM2315_ERROR_CONNECT
|
||||
// AM2315_MISSING_BYTES
|
||||
// AM2315_ERROR_CHECKSUM;
|
||||
// AM2315_HUMIDITY_OUT_OF_RANGE
|
||||
// AM2315_TEMPERATURE_OUT_OF_RANGE
|
||||
int AM2315::_read()
|
||||
{
|
||||
// READ VALUES
|
||||
int rv = _readSensor();
|
||||
|
||||
_lastRead = millis();
|
||||
|
||||
if (rv != AM2315_OK)
|
||||
{
|
||||
if (_suppressError == false)
|
||||
@ -121,8 +137,9 @@ int AM2315::_read()
|
||||
return rv; // propagate error value
|
||||
}
|
||||
|
||||
_humidity = (_bits[0] * 256 + _bits[1]) * 0.1;
|
||||
int16_t t = ((_bits[2] & 0x7F) * 256 + _bits[3]);
|
||||
// EXTRACT HUMIDITY AND TEMPERATURE
|
||||
_humidity = (_bits[2] * 256 + _bits[3]) * 0.1;
|
||||
int16_t t = ((_bits[4] & 0x7F) * 256 + _bits[5]);
|
||||
if (t == 0)
|
||||
{
|
||||
_temperature = 0.0; // prevent -0.0;
|
||||
@ -130,14 +147,14 @@ int AM2315::_read()
|
||||
else
|
||||
{
|
||||
_temperature = t * 0.1;
|
||||
if ((_bits[2] & 0x80) == 0x80 )
|
||||
if ((_bits[4] & 0x80) == 0x80 )
|
||||
{
|
||||
_temperature = -_temperature;
|
||||
}
|
||||
}
|
||||
|
||||
// TEST OUT OF RANGE
|
||||
#ifdef AM2315_VALUE_OUT_OF_RANGE
|
||||
// TEST OUT OF RANGE
|
||||
if (_humidity > 100)
|
||||
{
|
||||
return AM2315_HUMIDITY_OUT_OF_RANGE;
|
||||
@ -152,11 +169,6 @@ int AM2315::_read()
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
// return values:
|
||||
// AM2315_OK
|
||||
// AM2315_ERROR_CONNECT
|
||||
@ -164,53 +176,38 @@ int AM2315::_read()
|
||||
// AM2315_ERROR_CHECKSUM;
|
||||
int AM2315::_readSensor()
|
||||
{
|
||||
// EMPTY BUFFER
|
||||
for (uint8_t i = 0; i < 5; i++) _bits[i] = 0;
|
||||
|
||||
// HANDLE PENDING IRQ
|
||||
// HANDLE PENDING IRQ etc.
|
||||
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;
|
||||
if (! isConnected() ) return AM2315_ERROR_CONNECT;
|
||||
|
||||
// REQUEST DATA
|
||||
// SEND COMMAND
|
||||
_wire->beginTransmission(AM2315_ADDRESS);
|
||||
_wire->write(0X03);
|
||||
_wire->write(0);
|
||||
_wire->write(4);
|
||||
rv = _wire->endTransmission();
|
||||
int rv = _wire->endTransmission();
|
||||
if (rv < 0) return rv;
|
||||
|
||||
delayMicroseconds(1500);
|
||||
// GET DATA
|
||||
// REQUEST 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];
|
||||
// READ DATA
|
||||
for (int i = 0; i < bytes; i++)
|
||||
{
|
||||
buffer[i] = _wire->read();
|
||||
_bits[i] = _wire->read();
|
||||
}
|
||||
_bits[0] = buffer[2];
|
||||
_bits[1] = buffer[3];
|
||||
_bits[2] = buffer[4];
|
||||
_bits[3] = buffer[5];
|
||||
|
||||
// TEST CHECKSUM
|
||||
uint16_t crc0 = buffer[7] * 256 + buffer[6];
|
||||
uint16_t crc1 = _crc16(buffer, bytes - 2);
|
||||
// Serial.print("CRC: ");
|
||||
// Serial.print(crc0 - crc1);
|
||||
// Serial.print("\t");
|
||||
// Serial.print(crc1);
|
||||
// Serial.println();
|
||||
if (crc0 != crc1) return AM2315_ERROR_CHECKSUM;
|
||||
|
||||
uint16_t crc = _bits[bytes - 1] * 256 + _bits[bytes - 2];
|
||||
if (_crc16(_bits, bytes - 2) != crc)
|
||||
{
|
||||
return AM2315_ERROR_CHECKSUM;
|
||||
}
|
||||
return AM2315_OK;
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
//
|
||||
// FILE: AM2315.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: AM2315 Temperature and Humidity sensor library for Arduino
|
||||
// VERSION: 0.1.2
|
||||
// URL: https://github.com/RobTillaart/AM2315
|
||||
|
||||
|
||||
//
|
||||
// AM232X PIN layout AM2315 COLOR
|
||||
// ============================================
|
||||
// bottom view DESCRIPTION COLOR
|
||||
@ -16,13 +15,15 @@
|
||||
// |o | GND BLACK
|
||||
// |o | SCL GREY
|
||||
// +---+
|
||||
//
|
||||
// do not forget pull up resistors between SDA, SCL and VDD.
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define AM2315_LIB_VERSION (F("0.1.1"))
|
||||
#define AM2315_LIB_VERSION (F("0.1.2"))
|
||||
|
||||
|
||||
#define AM2315_OK 0
|
||||
@ -68,22 +69,18 @@ public:
|
||||
|
||||
// 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; };
|
||||
void setHumOffset(float offset = 0) { _humOffset = offset; };
|
||||
void setTempOffset(float offset = 0) { _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; };
|
||||
bool getWaitForReading() { return _waitForRead; };
|
||||
void setWaitForReading(bool b ) { _waitForRead = b; };
|
||||
|
||||
|
||||
// suppress error values of -999 => check return value of read() instead
|
||||
bool getSuppressError() { return _suppressError; };
|
||||
void setSuppressError(bool b) { _suppressError = b; };
|
||||
bool getSuppressError() { return _suppressError; };
|
||||
void setSuppressError(bool b) { _suppressError = b; };
|
||||
|
||||
bool wakeUp() { return isConnected(); };
|
||||
|
||||
@ -95,9 +92,8 @@ private:
|
||||
uint32_t _lastRead = 0;
|
||||
bool _waitForRead = false;
|
||||
bool _suppressError = false;
|
||||
uint16_t _readDelay = 0;
|
||||
|
||||
uint8_t _bits[5]; // buffer to receive data
|
||||
uint8_t _bits[8]; // buffer to hold raw data
|
||||
int _read();
|
||||
int _readSensor();
|
||||
uint16_t _crc16(uint8_t *ptr, uint8_t len);
|
||||
|
@ -10,18 +10,55 @@
|
||||
|
||||
Arduino library for I2C AM2315 temperature and humidity sensor.
|
||||
|
||||
The AM2315 can also be read with the https://github.com/RobTillaart/AM232X library as it uses the same protocol. The AM232X library allows to read some internal registers.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
**Experimental**
|
||||
|
||||
The library should be initiated by calling the **begin()** function,
|
||||
The library must 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.
|
||||
|
||||
The I2C address is 0x5C and is hardcoded in the device.
|
||||
If you need multiple AM2315 devices use a I2C multiplexer e.g. https://github.com/RobTillaart/TCA9548
|
||||
|
||||
|
||||
### I2C clock speed
|
||||
|
||||
The datasheet states the AM2315 should be used on 100 KHz I2C only.
|
||||
When overclocking I got good readings up to 190 KHz in a test with
|
||||
- Arduino UNO
|
||||
- very short wires (< 1 meter)
|
||||
- not using pull ups.
|
||||
- version 0.1.1 of this library
|
||||
|
||||
|
||||
| I2C clock | timing us | Notes |
|
||||
|:---------:|:---------:|:----------------------|
|
||||
| 50 KHz | 4570 | under-clocking works (e.g. long wires)
|
||||
| 100 KHz | 3276 | specs default, robust
|
||||
| 150 KHz | 2836 |
|
||||
| 160 KHz | 2792 |
|
||||
| 170 KHz | 2750 | 0.5 ms off, interesting for performance.
|
||||
| 180 KHz | 2700 | near critical. DO NOT USE.
|
||||
| 190 KHz | 2672 | near critical. DO NOT USE.
|
||||
| 200 KHz | crash | sensor needs a power cycle reboot. DO NOT USE.
|
||||
|
||||
|
||||
If robustness is mandatory stick to the default of 100 KHz.
|
||||
If performance is mandatory do not go beyond 170 KHz.
|
||||
|
||||
|
||||
### Wake up
|
||||
|
||||
As the sensor goes to sleep after 3 seconds after last read, it needs to be woken up.
|
||||
This is hard coded in the **readSensor()** function.
|
||||
There is also a **wakeUp()** function so the wake up can be done some time before the
|
||||
read is actual needed.
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
@ -40,51 +77,51 @@ minimum = 800 us and maximum = 3000 us according to datasheet.
|
||||
|
||||
- **int8_t read()** read the sensor and store the values internally.
|
||||
It returns the status of the read which should be **AM2315_OK** == 0.
|
||||
- **float getHumidity()** returns last Humidity read, or -999 in case of error.
|
||||
- **float getTemperature()** returns last Temperature read, or **AM2315_INVALID_VALUE** == -999 in case of error.
|
||||
- **float getHumidity()** returns last Humidity read + optional offset, or **AM2315_INVALID_VALUE** == -999 in case of error. This error can be suppressed, see below.
|
||||
- **float getTemperature()** returns last Temperature read + optional offset, or **AM2315_INVALID_VALUE** == -999 in case of error. This error can be suppressed, see below.
|
||||
- **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.
|
||||
- **void setHumOffset(float offset = 0)** set an offset for humidity to calibrate (1st order) the sensor.
|
||||
Default offset = 0, so no parameter will reset the offset.
|
||||
- **float getHumOffset()** return current humidity offset, default 0.
|
||||
- **void setTempOffset(float offset = 0)** set an offset for temperature to calibrate (1st order) the sensor.
|
||||
Default offset = 0, so no parameter will reset the offset.
|
||||
- **float getTempOffset()** return current temperature offset, default 0.
|
||||
|
||||
|
||||
### Control
|
||||
|
||||
Functions to adjust the communication with the sensor.
|
||||
|
||||
- **void setWaitForReading(bool b )** flag to enforce a blocking wait.
|
||||
- **void setWaitForReading(bool b )** flag to enforce a blocking wait (up to 2 seconds) when **read()** is called.
|
||||
- **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.
|
||||
- **void setSuppressError(bool b)** suppress error values of **AM2315_INVALID_VALUE** == -999 => you need to check the return value of read() instead.
|
||||
This can be used to keep spikes out of your graphs / logs.
|
||||
- **bool getSuppressError()** returns the above setting.
|
||||
|
||||
|
||||
### Misc
|
||||
|
||||
- **bool wakeUp()** function that will try for 3 milliseconds to wake up the sensor.
|
||||
This can be done before an actual read to minimize the **read()** call.
|
||||
|
||||
|
||||
### error codes
|
||||
|
||||
|
||||
| name | value | notes |
|
||||
|:----------------------------------|------:|:----------|
|
||||
| name | value | notes |
|
||||
|:----------------------------------|------:|:------------|
|
||||
| AM2315_OK | 0 |
|
||||
| AM2315_ERROR_CHECKSUM | -10 |
|
||||
| AM2315_ERROR_CONNECT | -11 |
|
||||
| AM2315_MISSING_BYTES | -12 |
|
||||
| AM2315_WAITING_FOR_READ | -50 |
|
||||
| AM2315_HUMIDITY_OUT_OF_RANGE | -100 |
|
||||
| AM2315_TEMPERATURE_OUT_OF_RANGE | -101 |
|
||||
| AM2315_INVALID_VALUE | -999 |
|
||||
| AM2315_ERROR_CHECKSUM | -10 | I2C problem.
|
||||
| AM2315_ERROR_CONNECT | -11 | I2C problem.
|
||||
| AM2315_MISSING_BYTES | -12 | I2C problem.
|
||||
| AM2315_WAITING_FOR_READ | -50 | called **read()** too fast, within 2 seconds.
|
||||
| AM2315_HUMIDITY_OUT_OF_RANGE | -100 | not used by default.
|
||||
| AM2315_TEMPERATURE_OUT_OF_RANGE | -101 | not used by default.
|
||||
| AM2315_INVALID_VALUE | -999 | can be suppressed.
|
||||
|
||||
|
||||
## Operation
|
||||
@ -94,17 +131,15 @@ 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
|
||||
- test
|
||||
- update unit test
|
||||
- add examples
|
||||
- add AM2320 derived class ?
|
||||
- optimize
|
||||
- merge with the AM232X library in a far future.
|
||||
|
||||
**wont**
|
||||
- add calls for meta information (no description yet)
|
||||
- 0x07 status register
|
||||
- 0x08-0x0B user register HIGH LOW HIGH2 LOW2
|
||||
(use AM232x library to access those)
|
||||
|
||||
|
@ -15,7 +15,14 @@ setHumOffset KEYWORD2
|
||||
setTempOffset KEYWORD2
|
||||
getHumOffset KEYWORD2
|
||||
getTempOffset KEYWORD2
|
||||
|
||||
getWaitForReading KEYWORD2
|
||||
setWaitForReading KEYWORD2
|
||||
getSuppressError KEYWORD2
|
||||
setSuppressError KEYWORD2
|
||||
|
||||
lastRead KEYWORD2
|
||||
wakeUp KEYWORD2
|
||||
|
||||
|
||||
# Constants (LITERAL1)
|
||||
@ -25,3 +32,10 @@ AM2315_OK LITERAL2
|
||||
AM2315_ERROR_CHECKSUM LITERAL1
|
||||
AM2315_ERROR_CONNECT LITERAL1
|
||||
AM2315_MISSING_BYTES LITERAL1
|
||||
AM2315_WAITING_FOR_READ LITERAL1
|
||||
|
||||
AM2315_VALUE_OUT_OF_RANGE LITERAL1
|
||||
AM2315_HUMIDITY_OUT_OF_RANGE LITERAL1
|
||||
AM2315_TEMPERATURE_OUT_OF_RANGE LITERAL1
|
||||
AM2315_INVALID_VALUE LITERAL1
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/AM2315.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=AM2315
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for I2C AM2315 temperature and humidity sensor.
|
||||
|
Loading…
Reference in New Issue
Block a user