GY-63_MS5611/libraries/AM2315/AM2315.cpp

239 lines
4.3 KiB
C++
Raw Normal View History

2022-01-06 06:08:13 -05:00
//
// FILE: AM2315.cpp
// AUTHOR: Rob.Tillaart@gmail.com
2022-10-27 11:46:48 -04:00
// VERSION: 0.1.6
2022-01-06 06:08:13 -05:00
// PURPOSE: AM2315 Temperature and Humidity sensor library for Arduino
// URL: https://github.com/RobTillaart/AM2315
//
2022-10-27 11:46:48 -04:00
// HISTORY: see changelog.md
2022-01-06 06:08:13 -05:00
#include "AM2315.h"
2022-06-18 04:10:35 -04:00
const uint8_t AM2315_ADDRESS = 0x5C;
2022-01-06 06:08:13 -05:00
// READ_DELAY for blocking read
2022-06-18 04:10:35 -04:00
const uint16_t AM2315_READ_DELAY = 2000;
2022-01-06 06:08:13 -05:00
/////////////////////////////////////////////////////
//
// PUBLIC
//
AM2315::AM2315(TwoWire *wire)
{
2022-01-14 05:39:18 -05:00
_wire = wire;
2022-06-17 07:17:03 -04:00
// reset() or begin() ?
_humidity = 0.0;
_temperature = 0.0;
_humOffset = 0.0;
_tempOffset = 0.0;
2022-01-14 05:39:18 -05:00
_lastRead = 0;
_waitForRead = false;
_suppressError = false;
2022-06-17 07:17:03 -04:00
}
2022-01-06 06:08:13 -05:00
#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();
}
2022-06-17 07:17:03 -04:00
if (! isConnected()) return false;
this->read();
return true;
2022-01-06 06:08:13 -05:00
}
#endif
bool AM2315::begin()
{
_wire->begin();
2022-06-17 07:17:03 -04:00
if (! isConnected()) return false;
this->read();
return true;
2022-01-06 06:08:13 -05:00
}
2022-01-12 15:04:52 -05:00
bool AM2315::isConnected(uint16_t timeout)
2022-01-06 06:08:13 -05:00
{
2022-01-12 15:04:52 -05:00
uint32_t start = micros();
while (micros() - start < timeout)
{
_wire->beginTransmission(AM2315_ADDRESS);
if ( _wire->endTransmission() == 0) return true;
yield();
delayMicroseconds(100);
}
return false;
2022-01-06 06:08:13 -05:00
}
2022-01-14 05:39:18 -05:00
// return values:
// AM2315_OK
// AM2315_ERROR_CONNECT
// AM2315_MISSING_BYTES
// AM2315_ERROR_CHECKSUM;
// AM2315_HUMIDITY_OUT_OF_RANGE
// AM2315_TEMPERATURE_OUT_OF_RANGE
2022-01-06 06:08:13 -05:00
int AM2315::read()
{
2022-01-14 05:39:18 -05:00
while (millis() - _lastRead < AM2315_READ_DELAY)
2022-01-06 06:08:13 -05:00
{
if (!_waitForRead) return AM2315_WAITING_FOR_READ;
yield();
}
int rv = _read();
2022-01-14 05:39:18 -05:00
_lastRead = millis();
2022-01-06 06:08:13 -05:00
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
//
2022-01-14 05:39:18 -05:00
// return values:
// AM2315_OK
// AM2315_ERROR_CONNECT
// AM2315_MISSING_BYTES
// AM2315_ERROR_CHECKSUM;
// AM2315_HUMIDITY_OUT_OF_RANGE
// AM2315_TEMPERATURE_OUT_OF_RANGE
2022-01-06 06:08:13 -05:00
int AM2315::_read()
{
// READ VALUES
int rv = _readSensor();
if (rv != AM2315_OK)
{
if (_suppressError == false)
{
_humidity = AM2315_INVALID_VALUE;
_temperature = AM2315_INVALID_VALUE;
}
return rv; // propagate error value
}
2022-01-14 05:39:18 -05:00
// EXTRACT HUMIDITY AND TEMPERATURE
_humidity = (_bits[2] * 256 + _bits[3]) * 0.1;
int16_t t = ((_bits[4] & 0x7F) * 256 + _bits[5]);
2022-01-06 06:08:13 -05:00
if (t == 0)
{
_temperature = 0.0; // prevent -0.0;
}
else
{
_temperature = t * 0.1;
2022-01-14 05:39:18 -05:00
if ((_bits[4] & 0x80) == 0x80 )
2022-01-06 06:08:13 -05:00
{
_temperature = -_temperature;
}
}
#ifdef AM2315_VALUE_OUT_OF_RANGE
2022-01-14 05:39:18 -05:00
// TEST OUT OF RANGE
2022-01-06 06:08:13 -05:00
if (_humidity > 100)
{
return AM2315_HUMIDITY_OUT_OF_RANGE;
}
if ((_temperature < -40) || (_temperature > 125))
{
return AM2315_TEMPERATURE_OUT_OF_RANGE;
}
#endif
return AM2315_OK;
}
// return values:
// AM2315_OK
// AM2315_ERROR_CONNECT
// AM2315_MISSING_BYTES
2022-01-12 15:04:52 -05:00
// AM2315_ERROR_CHECKSUM;
2022-01-06 06:08:13 -05:00
int AM2315::_readSensor()
{
2022-01-14 05:39:18 -05:00
// HANDLE PENDING IRQ etc.
2022-01-06 06:08:13 -05:00
yield();
// WAKE UP the sensor
2022-01-14 05:39:18 -05:00
if (! isConnected() ) return AM2315_ERROR_CONNECT;
2022-01-06 06:08:13 -05:00
2022-01-14 05:39:18 -05:00
// SEND COMMAND
2022-01-06 06:08:13 -05:00
_wire->beginTransmission(AM2315_ADDRESS);
_wire->write(0X03);
_wire->write(0);
_wire->write(4);
2022-01-14 05:39:18 -05:00
int rv = _wire->endTransmission();
2022-01-06 06:08:13 -05:00
if (rv < 0) return rv;
2022-01-14 05:39:18 -05:00
// REQUEST DATA
2022-01-06 06:08:13 -05:00
const int length = 8;
2022-08-31 03:24:41 -04:00
int bytes = _wire->requestFrom((int)AM2315_ADDRESS, length);
2022-01-06 06:08:13 -05:00
if (bytes == 0) return AM2315_ERROR_CONNECT;
if (bytes < length) return AM2315_MISSING_BYTES;
2022-01-14 05:39:18 -05:00
// READ DATA
2022-01-06 06:08:13 -05:00
for (int i = 0; i < bytes; i++)
{
2022-01-14 05:39:18 -05:00
_bits[i] = _wire->read();
2022-01-06 06:08:13 -05:00
}
2022-01-12 15:04:52 -05:00
// TEST CHECKSUM
2022-01-14 05:39:18 -05:00
uint16_t crc = _bits[bytes - 1] * 256 + _bits[bytes - 2];
if (_crc16(_bits, bytes - 2) != crc)
{
return AM2315_ERROR_CHECKSUM;
}
2022-01-06 06:08:13 -05:00
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++)
{
2022-06-17 07:17:03 -04:00
if (crc & 0x01)
2022-01-06 06:08:13 -05:00
{
crc >>= 1;
crc ^= 0xA001;
}
else
{
2022-06-17 07:17:03 -04:00
crc >>= 1;
2022-01-06 06:08:13 -05:00
}
}
}
return crc;
}
// -- END OF FILE --