0.1.1 CHT8305

This commit is contained in:
rob tillaart 2022-10-09 16:31:16 +02:00
parent 9706b6a922
commit d175e87de6
8 changed files with 410 additions and 86 deletions

View File

@ -1,13 +1,17 @@
//
// FILE: CHT8305.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for CHT8305 temperature and humidity sensor
// URL: https://github.com/RobTillaart/CH8305
//
// HISTORY
// 2022-10-06 0.1.0 initial version
//
// 2022-10-08 0.1.1 add config specific functions
// fix ESP32 begin() address check
// add config ALERT functions.
// add constants for registers
// fix getVoltage() register
#include "CHT8305.h"
@ -27,7 +31,7 @@ CHT8305::CHT8305(TwoWire *wire)
#if defined (ESP8266) || defined(ESP32)
int CHT8305::begin(int sda, int scl, const uint8_t address)
{
if ((address < 0x50) || (address > 0x57)) return CHT8305_ERROR_ADDR;
if ((address < 0x40) || (address > 0x43)) return CHT8305_ERROR_ADDR;
_wire = &Wire;
_address = address;
@ -77,7 +81,8 @@ int CHT8305::read()
_lastRead = millis();
uint8_t data[4] = {0, 0, 0, 0 };
_readRegister(0, &data[0], 4);
_readRegister(CHT8305_REG_TEMPERATURE, &data[0], 4);
uint16_t tmp = data[0] << 8 | data[1];
_temperature = tmp * (165.0 / 65535.0) - 40.0;
tmp = data[2] << 8 | data[3];
@ -106,7 +111,7 @@ void CHT8305::setConfigRegister(uint16_t bitmask)
uint16_t CHT8305::getConfigRegister()
{
uint8_t data[2] = { 0, 0};
_readRegister(2, &data[0], 2);
_readRegister(CHT8305_REG_CONFIG, &data[0], 2);
uint16_t tmp = data[0] << 8 | data[1];
return tmp;
}
@ -114,9 +119,164 @@ uint16_t CHT8305::getConfigRegister()
void CHT8305::softReset()
{
uint16_t tmp = getConfigRegister();
tmp |= 0x8000;
setConfigRegister(tmp);
_setConfigMask(CHT8305_CFG_SOFT_RESET);
}
void CHT8305::setI2CClockStretch(bool on)
{
if (on) _setConfigMask(CHT8305_CFG_CLOCK_STRETCH);
else _clrConfigMask(CHT8305_CFG_CLOCK_STRETCH);
}
bool CHT8305::getI2CClockStretch()
{
return (getConfigRegister() & CHT8305_CFG_CLOCK_STRETCH) > 0;
}
void CHT8305::setHeaterOn(bool on)
{
if (on) _setConfigMask(CHT8305_CFG_HEATER);
else _clrConfigMask(CHT8305_CFG_HEATER);
}
bool CHT8305::getHeater()
{
return (getConfigRegister() & CHT8305_CFG_HEATER) > 0;
}
void CHT8305::setMeasurementMode(bool both)
{
if (both) _setConfigMask(CHT8305_CFG_MODE);
else _clrConfigMask(CHT8305_CFG_MODE);
}
bool CHT8305::getMeasurementMode()
{
return (getConfigRegister() & CHT8305_CFG_MODE) > 0;
}
bool CHT8305::getVCCstatus()
{
return (getConfigRegister() & CHT8305_CFG_VCCS) > 0;
}
void CHT8305::setTemperatureResolution(bool b)
{
if (b) _setConfigMask(CHT8305_CFG_TEMP_RES);
else _clrConfigMask(CHT8305_CFG_TEMP_RES);
}
bool CHT8305::getTemperatureResolution()
{
return (getConfigRegister() & CHT8305_CFG_TEMP_RES) > 0;
}
void CHT8305::setHumidityResolution(uint8_t res)
{
_clrConfigMask(CHT8305_CFG_HUMI_RES);
if (res == 2)_setConfigMask(0x0100); // magic
if (res == 3)_setConfigMask(0x0200); // magic
// default == 00 if not 2 or 3
}
uint8_t CHT8305::getHumidityResolution()
{
return (getConfigRegister() & CHT8305_CFG_HUMI_RES) >> 8;
}
void CHT8305::setVCCenable(bool enable)
{
if (enable) _setConfigMask(CHT8305_CFG_VCC_ENABLE);
else _clrConfigMask(CHT8305_CFG_VCC_ENABLE);
}
bool CHT8305::getVCCenable()
{
return (getConfigRegister() & CHT8305_CFG_VCC_ENABLE) > 0;
}
////////////////////////////////////////////////
//
// ALERT (config register)
//
bool CHT8305::setAlertTriggerMode(uint8_t mode)
{
_clrConfigMask(CHT8305_CFG_ALERT_MODE);
if (mode > 3) return false; // check 0,1,2,3
uint16_t mask = mode << 6;
_setConfigMask(mask);
return true;
}
uint8_t CHT8305::getAlertTriggerMode()
{
return (getConfigRegister() & CHT8305_CFG_ALERT_MODE) >> 6;
}
bool CHT8305::getAlertPendingStatus()
{
return (getConfigRegister() & CHT8305_CFG_ALERT_PENDING) > 0;
}
bool CHT8305::getAlertHumidityStatus()
{
return (getConfigRegister() & CHT8305_CFG_ALERT_HUMI) > 0;
}
bool CHT8305::getAlertTemperatureStatus()
{
return (getConfigRegister() & CHT8305_CFG_ALERT_TEMP) > 0;
}
bool CHT8305::setAlertLevels(float temperature, float humidity)
{
// range check
if ((temperature < -40 ) || (temperature > 125)) return false;
if ((humidity < 0 ) || (humidity > 100)) return false;
uint16_t mask = 0;
uint16_t tmp = humidity * (65535.0/100.0);
mask = tmp << 9;
tmp = (temperature + 40.0) * (65535.0 / 165.0);
mask |= tmp;
_writeRegister(CHT8305_REG_ALERT, (uint8_t *)&mask, 2);
return true;
}
float CHT8305::getAlertLevelTemperature()
{
uint16_t data = 0;
_readRegister(CHT8305_REG_ALERT, (uint8_t *)&data, 2);
data &= 0x01FF;
return data * (165.0 / 65535.0) - 40.0;
}
float CHT8305::getAlertLevelHumidity()
{
uint16_t data = 0;
_readRegister(CHT8305_REG_ALERT, (uint8_t *)&data, 2);
data >>= 9;
return data * (100.0 / 65535.0);
}
@ -124,12 +284,10 @@ void CHT8305::softReset()
//
// VOLTAGE
//
// TODO verify conversion unit
// TODO check datasheet.
float CHT8305::getVoltage()
{
uint8_t data[2] = { 0, 0};
_readRegister(2, &data[0], 2);
_readRegister(CHT8305_REG_VOLTAGE, &data[0], 2);
uint16_t tmp = data[0] << 8 | data[1];
return tmp * (5.0 / 65535.0); // this is best guess
}
@ -142,7 +300,7 @@ float CHT8305::getVoltage()
uint16_t CHT8305::getManufacturer()
{
uint8_t data[2] = { 0, 0};
_readRegister(0xFE, &data[0], 2);
_readRegister(CHT8305_REG_MANUFACTURER, &data[0], 2);
uint16_t tmp = data[0] << 8 | data[1];
return tmp;
}
@ -151,7 +309,7 @@ uint16_t CHT8305::getManufacturer()
uint16_t CHT8305::getVersionID()
{
uint8_t data[2] = { 0, 0};
_readRegister(0xFF, &data[0], 2);
_readRegister(CHT8305_REG_VERSION, &data[0], 2);
uint16_t tmp = data[0] << 8 | data[1];
return tmp;
}
@ -168,7 +326,10 @@ int CHT8305::_readRegister(uint8_t reg, uint8_t * buf, uint8_t size)
int n = _wire->endTransmission();
if (n != 0) return CHT8305_ERROR_I2C;
if (reg == 0x00) delay(14); // 2x 6.5 ms @ 14 bit.
if (reg == CHT8305_REG_TEMPERATURE) // wait for conversion...
{
delay(14); // 2x 6.5 ms @ 14 bit.
}
n = _wire->requestFrom(_address, size);
if (n == size)
@ -196,5 +357,21 @@ int CHT8305::_writeRegister(uint8_t reg, uint8_t * buf, uint8_t size)
}
void CHT8305::_setConfigMask(uint16_t mask)
{
uint16_t tmp = getConfigRegister();
tmp |= mask;
setConfigRegister(tmp);
}
void CHT8305::_clrConfigMask(uint16_t mask)
{
uint16_t tmp = getConfigRegister();
tmp &= ~mask;
setConfigRegister(tmp);
}
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
//
// FILE: CHT8305.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for CHT8305 temperature and humidity sensor
// URL: https://github.com/RobTillaart/CH8305
//
@ -12,17 +12,38 @@
#include "Wire.h"
#define CHT8305_LIB_VERSION (F("0.1.0"))
#define CHT8305_LIB_VERSION (F("0.1.1"))
// ERRORS
#define CHT8305_OK 0
#define CHT8305_ERROR_ADDR -10
#define CHT8305_ERROR_I2C -11
#define CHT8305_ERROR_CONNECT -12
#define CHT8305_ERROR_LASTREAD -20
// REGISTERS
#define CHT8305_REG_TEMPERATURE 0x00
#define CHT8305_REG_HUMIDITY 0x01
#define CHT8305_REG_CONFIG 0x02
#define CHT8305_REG_ALERT 0x03
#define CHT8305_REG_VOLTAGE 0x04
#define CHT8305_REG_MANUFACTURER 0xFE
#define CHT8305_REG_VERSION 0xFF
// REGISTER MASKS
#define CHT8305_CFG_SOFT_RESET 0x8000
#define CHT8305_CFG_CLOCK_STRETCH 0x4000
#define CHT8305_CFG_HEATER 0x2000
#define CHT8305_CFG_MODE 0x1000
#define CHT8305_CFG_VCCS 0x0800
#define CHT8305_CFG_TEMP_RES 0x0400
#define CHT8305_CFG_HUMI_RES 0x0300
#define CHT8305_CFG_ALERT_MODE 0x00C0
#define CHT8305_CFG_ALERT_PENDING 0x0020
#define CHT8305_CFG_ALERT_HUMI 0x0010
#define CHT8305_CFG_ALERT_TEMP 0x0008
#define CHT8305_CFG_VCC_ENABLE 0x0004
#define CHT8305_CFG_VCC_RESERVED 0x0003
class CHT8305
@ -57,39 +78,74 @@ public:
// CONFIG REGISTER
void setConfigRegister(uint16_t bitmask);
uint16_t getConfigRegister();
// TODO more specific functions. datasheet!
// bit meaning
// 15 softReset
// 14 clock stretch
// 13 heater
// 12 mode
// 11 vccs
// 10 T-RES
// 9-8 H-res
// 7-6 ALTM
// 5 APS
// 4 HALT
// 3 TALT
// 2 VCCenable
// 1-0 reserved.
//
// | bit | mask | name | description |
// |:-----:|:------:|:----------------|:--------------|
// | 15 | 0x8000 | soft reset | 1 = reboot the sensor to default
// | 14 | 0x4000 | clock stretch | 1 = ON, 0 = OFF (default)
// | 13 | 0x2000 | heater | 1 = ON, 0 = OFF (default) ==> user is responsible for timing!
// | 12 | 0x1000 | mode | 1 = read both (default), 0 = read T or RH
// | 11 | 0x0800 | vccs | 1 = >2.8V, 0 = <2.8V
// | 10 | 0x0400 | T-RES | 1 = 11 bit, 0 = 14 bit (default)
// | 9-8 | 0x0300 | H-RES | 10 = 8 bit, 01 = 11 bit, 00 = 14 bit (default)
// | 7-6 | 0x00C0 | ALTM | Alert Mode (datasheet)
// | 5 | 0x0020 | APS | Alert pending status
// | 4 | 0x0010 | H-ALT | Humidity Alert status
// | 3 | 0x0004 | T-ALT | Temperature Alert status
// | 2 | 0x0002 | VCC enable | 1 = enable VCC measurement, 0 = disable (default)
// | 1-0 | 0x0003 | reserved. | do not change.
//
// specific config functions. See datasheet!
// first iteration.
void softReset();
void setI2CClockStretch(bool on = false);
bool getI2CClockStretch();
void setHeaterOn(bool on = false); // !!! user is responsible for timing!
bool getHeater();
void setMeasurementMode(bool both = true);
bool getMeasurementMode();
bool getVCCstatus();
void setTemperatureResolution(bool b = false);
bool getTemperatureResolution();
void setHumidityResolution(uint8_t r = 0); // 0,2,3
uint8_t getHumidityResolution(); // 0,2,3
void setVCCenable(bool enable = false);
bool getVCCenable();
// ALERT FUNCTIONS
// mode trigger
// 0 T or H (default)
// 1 T
// 2 H
// 3 T and H
bool setAlertTriggerMode(uint8_t mode = 0); // 0,1,2,3
uint8_t getAlertTriggerMode();
bool getAlertPendingStatus();
bool getAlertHumidityStatus();
bool getAlertTemperatureStatus();
// mandatory to set them both.
bool setAlertLevels(float temperature, float humidity);
float getAlertLevelTemperature();
float getAlertLevelHumidity();
// VOLTAGE
float getVoltage();
// META DATA
uint16_t getManufacturer(); // expect 0x5959
uint16_t getVersionID(); // may vary
// ALERT REGISTER
//
// setAlarmT() - need to set them both at once.
// getAlarmT()
// setAlarmH()
// getAlarmH()
private:
float _humOffset = 0.0;
float _tempOffset = 0.0;
@ -100,8 +156,11 @@ private:
TwoWire* _wire;
uint8_t _address = 0x40;
int _readRegister(uint8_t reg, uint8_t * buf, uint8_t size);
int _writeRegister(uint8_t reg, uint8_t * buf, uint8_t size);
int _readRegister(uint8_t reg, uint8_t * buf, uint8_t size);
int _writeRegister(uint8_t reg, uint8_t * buf, uint8_t size);
void _setConfigMask(uint16_t mask);
void _clrConfigMask(uint16_t mask);
};

View File

@ -8,7 +8,7 @@
Arduino library for CHT8305 temperature and humidity sensor.
**EXPERIMENTAL** not tested yet - TODO buy hardware + test.
**EXPERIMENTAL** not tested yet ==> buy hardware + test.
If you happen to have hardware and are able to test this library,
please let me know your experiences.
@ -20,7 +20,7 @@ The CHT8305 is a temperature and humidity sensor.
| sensor | range | accuracy\* | resolution |
|:-------------:|:------------:|:------------:|:------------:|
| temperature | -40°..125° | max 2°C | 0.1° C |
| temperature | -40°..125° | max 2°C | 0.1° C |
| humidity | 0%..100% RH | max 5% RH | 0.1% RH |
\* Accuracy for full range.
@ -104,7 +104,6 @@ Check the datasheet for details of the register bits.
- **void setConfigRegister(uint16_t bitmask)** idem.
- **uint16_t getConfigRegister()** idem.
- **void softReset()** sets the soft reset bit in the configuration, causing the sensor to reset.
| bit | mask | name | description |
|:-----:|:------:|:----------------|:--------------|
@ -122,53 +121,90 @@ Check the datasheet for details of the register bits.
| 2 | 0x0002 | VCC enable | 1 = enable VCC measurement, 0 = disable (default)
| 1-0 | 0x0003 | reserved. | do not change.
Additional specific functions per field might be added in future releases
#### Getters / setters config register
Wrapper functions for easy access.
- **void softReset()** sets the soft reset bit in the configuration, causing the sensor to reset.
- **void setI2CClockStretch(bool on = false)**
- **bool getI2CClockStretch()**
- **void setHeaterOn(bool on = false)** !user is responsible for timing!
- **bool getHeater()**
- **void setMeasurementMode(bool both = true)**
- **bool getMeasurementMode()**
- **bool getVCCstatus()**
- **void setTemperatureResolution(bool b = false)**
- **bool getTemperatureResolution()**
- **void setHumidityResolution(uint8_t r = 0)** 0,2,3
- **uint8_t getHumidityResolution()** returns 0,2,3
- **void setVCCenable(bool enable = false)**
- **bool getVCCenable()**
### Alert
TODO elaborate
See register 3 datasheet page 12.
- high limit only (no low limit alert) << verify.
- Register 3 datasheet page 12.
- FALLING edge
- **void setAlertTriggerMode(uint8_t mode)** see table below.
- **uint8_t getAlertTriggerMode()** returns 0, 1, 2 or 3.
| mode | trigger | notes |
|:------:|:---------:|:----------|
| 0 | T or H | default |
| 1 | T |
| 2 | H |
| 3 | T and H |
- **bool getAlertPendingStatus()**
- **bool getAlertHumidityStatus()**
- **bool getAlertTemperatureStatus()**
- **bool setAlertLevels(float temperature, float humidity)**
- the values will be truncated to the closest possible.
- the alert supports high limit only ==> there is no low limit alert.
- note: the datasheet is ambigue wrt the formula used.
- **float getAlertLevelTemperature()** idem.
- **float getAlertLevelHumidity()** idem.
The ALERT pin triggers with a falling edge (from HIGH to LOW).
### Voltage
Note: VCC measurement should be enabled (bit 2 config register)
VCC measurement should be enabled by means of **void setVCCenable(true)**
or by **setConfigRegister(0x0002)**.
- **float getVoltage()** to be tested what unit exactly
- **float getVoltage()** to be tested what unit is used.
16 bit data implies 5.0V \* value / 65535.0;
Expected: 16 bit data implies ```voltage = 5.0V \* value / 65535.0;```
similar to temperature and humidity. To be verified.
### Meta data
TODO elaborate
- **uint16_t getManufacturer()**
- **uint16_t getVersionID()**
- **uint16_t getManufacturer()** returns 0x5959.
- **uint16_t getVersionID()** return value may differ.
## Future
- improve documentation.
- make code functional complete.
- config register.
- alert function
- fix TODO's in code.
- fix TODO's in readme.
- implement ALERT functions
- Buy hardware.
- test (see below)
- elaborate documentation.
#### test
- buy hardware
- test AVR, ESP32, ...
- test performance
= test I2C speed
- test resolution bits
- test ALERT functions
- test getVoltage(), getManufacturer(), getVersionID().
- test Temperature and Humidity
- test AVR, ESP32, other platforms?
- test performance.
= test I2C speed.
- test resolution bits.
- test config functions.
- test ALERT functions.
- test getVoltage()
- test getManufacturer(), getVersionID().
- test write / readRegister with a single uint16_t to simplify code.

View File

@ -23,6 +23,7 @@ CHT8305 CHT;
uint8_t count = 0;
void setup()
{
CHT.begin(0x40); // default address
@ -35,7 +36,6 @@ void setup()
Serial.println(CHT8305_LIB_VERSION);
Serial.println();
Serial.println(CHT.getManufacturer());
Serial.println(CHT.getVersionID());
Serial.println(CHT.getVoltage());
@ -95,4 +95,4 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -3,6 +3,7 @@
# Data types (KEYWORD1)
CHT8305 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
@ -11,11 +12,42 @@ read KEYWORD2
lastRead KEYWORD2
getTemperature KEYWORD2
getHumidity KEYWORD2
setHumOffset KEYWORD2
setTempOffset KEYWORD2
getHumOffset KEYWORD2
getTempOffset KEYWORD2
setConfigRegister KEYWORD2
getConfigRegister KEYWORD2
softReset KEYWORD2
setI2CClockStretch KEYWORD2
getI2CClockStretch KEYWORD2
setHeaterOn KEYWORD2
getHeate KEYWORD2
setMeasurementMode KEYWORD2
getMeasurementMode KEYWORD2
getVCCstatus KEYWORD2
setTemperatureResolution KEYWORD2
getTemperatureResolution KEYWORD2
setHumidityResolution KEYWORD2
getHumidityResolution KEYWORD2
setVCCenable KEYWORD2
getVCCenable KEYWORD2
setAlertTriggerMode KEYWORD2
getAlertTriggerMode KEYWORD2
getAlertPendingStatus KEYWORD2
getAlertHumidityStatus KEYWORD2
getAlertTemperatureStatus KEYWORD2
setAlertLevels KEYWORD2
getAlertLevelTemperature KEYWORD2
getAlertLevelHumidity KEYWORD2
# Constants (LITERAL1)
CHT8305_LIB_VERSION LITERAL1

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/CHT8305.git"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=CHT8305
version=0.1.0
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for CHT8305 temperature and humidity sensor.

View File

@ -25,8 +25,6 @@
#include "Arduino.h"
#include "CHT8305.h"
#define A0 0
unittest_setup()
{
@ -37,16 +35,8 @@ unittest_teardown()
{
}
#define CHT8305_OK 0
#define CHT8305_ERROR_ADDR -10
#define CHT8305_ERROR_I2C -11
#define CHT8305_ERROR_CONNECT -12
#define CHT8305_ERROR_LASTREAD -20
unittest(test_constants)
unittest(test_constants_I)
{
assertEqual(0, CHT8305_OK);
assertEqual(-10, CHT8305_ERROR_ADDR);
@ -56,6 +46,36 @@ unittest(test_constants)
}
unittest(test_constants_II)
{
assertEqual(0x00, CHT8305_REG_TEMPERATURE);
assertEqual(0x01, CHT8305_REG_HUMIDITY);
assertEqual(0x02, CHT8305_REG_CONFIG);
assertEqual(0x03, CHT8305_REG_ALERT);
assertEqual(0x04, CHT8305_REG_VOLTAGE);
assertEqual(0xFE, CHT8305_REG_MANUFACTURER);
assertEqual(0xFF, CHT8305_REG_VERSION);
}
unittest(test_constants_III)
{
assertEqual(0x8000, CHT8305_CFG_SOFT_RESET);
assertEqual(0x4000, CHT8305_CFG_CLOCK_STRETCH);
assertEqual(0x2000, CHT8305_CFG_HEATER);
assertEqual(0x1000, CHT8305_CFG_MODE);
assertEqual(0x0800, CHT8305_CFG_VCCS);
assertEqual(0x0400, CHT8305_CFG_TEMP_RES);
assertEqual(0x0300, CHT8305_CFG_HUMI_RES);
assertEqual(0x00C0, CHT8305_CFG_ALERT_MODE);
assertEqual(0x0020, CHT8305_CFG_ALERT_PENDING);
assertEqual(0x0010, CHT8305_CFG_ALERT_HUMI);
assertEqual(0x0008, CHT8305_CFG_ALERT_TEMP);
assertEqual(0x0004, CHT8305_CFG_VCC_ENABLE);
assertEqual(0x0003, CHT8305_CFG_VCC_RESERVED);
}
unittest(test_offset)
{
CHT8305 cht;