Create AHT10.cpp

This commit is contained in:
enjoyneering 2020-01-21 12:38:08 -05:00 committed by GitHub
parent 2aa2f70f9d
commit a4f437bc34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

369
src/AHT10.cpp Normal file
View File

@ -0,0 +1,369 @@
/***************************************************************************************************/
/*
This is an Arduino library for Aosong ASAIR AHT10, AHT15 Digital Humidity & Temperature Sensor
written by : enjoyneering79
sourse code: https://github.com/enjoyneering/
This chip uses I2C bus to communicate, specials pins are required to interface
Board: SDA SCL Level
Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 5v
Mega2560................................. 20 21 5v
Due, SAM3X8E............................. 20 21 3.3v
Leonardo, Micro, ATmega32U4.............. 2 3 5v
Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 5v
Blue Pill, STM32F103xxxx boards.......... PB7 PB6 3.3v/5v
ESP8266 ESP-01........................... GPIO0/D5 GPIO2/D3 3.3v/5v
NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 3.3v/5v
ESP32.................................... GPIO21/D21 GPIO22/D22 3.3v
Frameworks & Libraries:
ATtiny Core - https://github.com/SpenceKonde/ATTinyCore
ESP32 Core - https://github.com/espressif/arduino-esp32
ESP8266 Core - https://github.com/esp8266/Arduino
STM32 Core - https://github.com/stm32duino/Arduino_Core_STM32
- https://github.com/rogerclarkmelbourne/Arduino_STM32
GNU GPL license, all text above must be included in any redistribution,
see link for details - https://www.gnu.org/licenses/licenses.html
*/
/***************************************************************************************************/
#include "AHT10.h"
/**************************************************************************/
/*
Constructor
*/
/**************************************************************************/
AHT10::AHT10(uint8_t address)
{
_address = address;
}
/**************************************************************************/
/*
begin()
Initialize I2C & configure the sensor, call this function before
doing anything else
NOTE:
- Wire.endTransmission() returned value:
- 0 success
- 1 data too long to fit in transmit data16
- 2 received NACK on transmit of address
- 3 received NACK on transmit of data
- 4 other error
*/
/**************************************************************************/
#if defined(ESP8266)
bool AHT10::begin(uint8_t sda, uint8_t scl)
{
Wire.begin(sda, scl);
Wire.setClock(100000); //experimental! ESP8266 I2C bus speed: 50kHz..400kHz/50000..400000, default 100000
Wire.setClockStretchLimit(230); //experimental! default 230usec
#else
bool AHT10::begin(void)
{
Wire.begin();
Wire.setClock(100000); //experimental! AVR I2C bus speed: 31kHz..400kHz/31000..400000, default 100000
#endif
/* sensor initialization, load factory calibration coeff */
return enableFactoryCalCoeff();
}
/**************************************************************************/
/*
readRawData()
Read raw measurment data from sensor over I2C
*/
/**************************************************************************/
uint8_t AHT10::readRawData()
{
/* send measurment command */
Wire.beginTransmission(_address);
#if ARDUINO >= 100
Wire.write(AHT10_START_MEASURMENT_CMD);
#else
Wire.send(AHT10_START_MEASURMENT_CMD);
#endif
if (Wire.endTransmission(true) != 0) return AHT10_ERROR; //error handler, collision on I2C bus
if (getBusyBit() != 0x00) delay(AHT10_MEASURMENT_DELAY); //measurement delay
/* read 6-bytes from sensor */
#if defined(_VARIANT_ARDUINO_STM32_)
Wire.requestFrom(_address, 6);
#else
Wire.requestFrom(_address, 6, true); //true - send stop after transmission & release I2C bus
#endif
if (Wire.available() != 6)
{
_rawDataBuffer[0] = AHT10_ERROR; //for condition when AHT10_FORCE_READ_DATA is not used
return AHT10_ERROR; //check rxBuffer & error handler, collision on the i2c bus
}
/* read 6 bytes from "wire.h" rxBuffer */
#if ARDUINO >= 100
for (uint8_t i = 0; i < 6 ; i++)
{
_rawDataBuffer[i] = Wire.read();
}
#else
for (uint8_t i = 0; i < 6 ; i++)
{
_rawDataBuffer[i] = Wire.receive();
}
#endif
return true;
}
/**************************************************************************/
/*
readTemperature()
Read temperature, °C
NOTE:
- temperature range -40°C..+80°C
- temperature resolution 0.01°C
- temperature accuracy ±0.3°C
*/
/**************************************************************************/
float AHT10::readTemperature(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA)
{
if (readRawData() == AHT10_ERROR) return AHT10_ERROR; //force to read data to _rawDataBuffer & error handler
}
if (_rawDataBuffer[0] == AHT10_ERROR) return AHT10_ERROR; //error handler, collision on I2C bus
uint32_t temperature = ((uint32_t)(_rawDataBuffer[3] & 0x0F) << 16) | ((uint16_t)_rawDataBuffer[4] << 8) | _rawDataBuffer[5]; //20-bit raw temperature data
return (float)temperature * 200 / 1048576 - 50;
}
/**************************************************************************/
/*
readHumidity()
Read relative humidity, %
NOTE:
- Prolonged exposure for 60 hours at humidity > 80% can lead to a
temporary drift of the signal +3%. Sensor slowly returns to the
calibrated state at normal operating conditions.
- relative humidity range 0%..100%
- relative humidity resolution 0.024%
- relative humidity accuracy ±2%
*/
/**************************************************************************/
float AHT10::readHumidity(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA)
{
if (readRawData() == AHT10_ERROR) return AHT10_ERROR; //force to read data to _rawDataBuffer & error handler
}
if (_rawDataBuffer[0] == AHT10_ERROR) return AHT10_ERROR; //error handler, collision on I2C bus
uint32_t rawData = (((uint32_t)_rawDataBuffer[1] << 16) | ((uint16_t)_rawDataBuffer[2] << 8) | (_rawDataBuffer[3])) >> 4; //20-bit raw humidity data
float humidity = (float)rawData * 100 / 1048576;
if (humidity < 0) return 0;
if (humidity > 100) return 100;
return humidity;
}
/**************************************************************************/
/*
softReset()
Restart sensor, without power off
NOTE:
- takes ~20ms
- all registers restores to default
*/
/**************************************************************************/
bool AHT10::softReset(void)
{
Wire.beginTransmission(_address);
#if ARDUINO >= 100
Wire.write(AHT10_SOFT_RESET_CMD);
#else
Wire.send(AHT10_SOFT_RESET_CMD);
#endif
if (Wire.endTransmission(true) != 0) return false; //safety check, make sure sensor reset
delay(AHT10_SOFT_RESET_DELAY);
return enableFactoryCalCoeff(); //reinitialize sensor registers after reset
}
/**************************************************************************/
/*
setNormalMode()
Set normal measurment mode
NOTE:
- one measurement & power down
*/
/**************************************************************************/
bool AHT10::setNormalMode(void)
{
Wire.beginTransmission(_address);
#if ARDUINO >= 100
Wire.write(AHT10_INIT_CMD);
Wire.write(AHT10_INIT_CAL_ENABLE);
#else
Wire.send(AHT10_INIT_CAL_ENABLE);
#endif
if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete
delay(AHT10_COMMAND_DELAY);
return true;
}
/**************************************************************************/
/*
setCycleMode()
Set cycle measurment mode
NOTE:
- continuous measurement
*/
/**************************************************************************/
bool AHT10::setCycleMode(void)
{
Wire.beginTransmission(_address);
#if ARDUINO >= 100
Wire.write(AHT10_INIT_CMD);
Wire.write(AHT10_INIT_CAL_ENABLE | AHT10_INIT_CYCLE_MODE);
#else
Wire.send(AHT10_INIT_CAL_ENABLE | AHT10_INIT_CYCLE_MODE);
#endif
if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete
delay(AHT10_COMMAND_DELAY);
return true;
}
/**************************************************************************/
/*
readStatusByte()
Read status byte from sensor over I2C
*/
/**************************************************************************/
uint8_t AHT10::readStatusByte()
{
#if defined(_VARIANT_ARDUINO_STM32_)
Wire.requestFrom(_address, 1);
#else
Wire.requestFrom(_address, 1, true); //true - send stop after transmission & release I2C bus
#endif
if (Wire.available() != 1) return AHT10_ERROR; //check rxBuffer & error handler, collision on I2C bus
/* read byte from "wire.h" rxBuffer */
#if ARDUINO >= 100
return Wire.read();
#else
return Wire.receive();
#endif
}
/**************************************************************************/
/*
getCalibrationBit()
Read Calibration bit from status byte
NOTE:
- 0, factory calibration coeff disabled
- 1, factory calibration coeff loaded
*/
/**************************************************************************/
uint8_t AHT10::getCalibrationBit(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA) _rawDataBuffer[0] = readStatusByte(); //force to read status byte
if (_rawDataBuffer[0] != AHT10_ERROR) return bitRead(_rawDataBuffer[0], 3); //get 3-rd bit
return AHT10_ERROR;
}
/**************************************************************************/
/*
enableFactoryCalCoeff()
Load factory calibration coefficients
*/
/**************************************************************************/
bool AHT10::enableFactoryCalCoeff()
{
/* load factory calibration coeff */
Wire.beginTransmission(_address);
#if ARDUINO >= 100
Wire.write(AHT10_INIT_CMD);
Wire.write(AHT10_INIT_CAL_ENABLE);
#else
Wire.send(AHT10_INIT_CMD);
Wire.send(AHT10_INIT_CAL_ENABLE);
#endif
if (Wire.endTransmission(true) != 0) return false; //safety check, make sure transmission complete
delay(AHT10_COMMAND_DELAY);
/*check calibration enable */
if (getCalibrationBit(AHT10_FORCE_READ_DATA) == 0x01) return true;
return false;
}
/**************************************************************************/
/*
getBusyBit()
Read busy bit from status byte
NOTE:
- 0, sensor idle
- 1, sensor busy
*/
/**************************************************************************/
uint8_t AHT10::getBusyBit(bool readI2C)
{
if (readI2C == AHT10_FORCE_READ_DATA) _rawDataBuffer[0] = readStatusByte(); //force to read status byte
if (_rawDataBuffer[0] != AHT10_ERROR) return bitRead(_rawDataBuffer[0], 7); //get 7-th bit
return AHT10_ERROR;
}