0.3.3 SHT31

This commit is contained in:
rob tillaart 2021-08-24 16:01:55 +02:00
parent 5c68ece376
commit 8bfec2fd12
6 changed files with 129 additions and 89 deletions

View File

@ -1,7 +1,9 @@
[![Arduino CI](https://github.com/robtillaart/SHT31/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/SHT31.svg?maxAge=3600)](https://github.com/RobTillaart/SHT31/releases)
[![JSON check](https://github.com/RobTillaart/SHT31/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/SHT31/actions/workflows/jsoncheck.yml)
[![Arduino-lint](https://github.com/RobTillaart/SHT31/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/SHT31/actions/workflows/arduino-lint.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/SHT31/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/SHT31.svg?maxAge=3600)](https://github.com/RobTillaart/SHT31/releases)
# SHT31
@ -19,7 +21,7 @@ This library should also work for SHT30 and SHT35 but these are
not tested yet.
| SENSOR | Temperature accuracy | Humidity accuracy |
|:----:|:----:|:----:|
|:------:|:------:|:-----:|
| SHT30 | ~0.3 | 2.0 |
| SHT31 | ~0.3 | 1.5 |
| SHT35 | ~0.2 | 1.5 |
@ -35,31 +37,31 @@ https://github.com/hawesg/SHT31D_Particle_Photon_ClosedCube
#### Base interface
- **SHT31()** constructor.
- **begin(address, dataPin, clockPin)** begin function for ESP8266 & ESP32;
- **bool begin(address, dataPin, clockPin)** begin function for ESP8266 & ESP32;
returns false if device address is incorrect or device cannot be reset.
- **begin(address)** for single I2C bus platforms, e.g UNO.
- **begin(address, TwoWire \*wire)** for platforms with multiple I2C busses.
- **read(bool fast = true)** blocks 4 (fast) or 15 (slow) milliseconds + actual read + math.
- **bool begin(address)** for single I2C bus platforms, e.g UNO.
- **bool begin(address, TwoWire \*wire)** for platforms with multiple I2C busses.
- **bool read(bool fast = true)** blocks 4 (fast) or 15 (slow) milliseconds + actual read + math.
Does read both the temperature and humidity.
- **isConnected()** check sensor is reachable over I2C. Returns false if not connected.
- **uint16_t readStatus()** details see datasheet and **Status fields** below
- **bool isConnected()** check sensor is reachable over I2C. Returns false if not connected.
- **uint16_t readStatus()** details see datasheet and **Status fields** below.
- **uint32_t lastRead()** in milliSeconds since start of program.
- **reset(bool hard = false)** resets the sensor, soft reset by default. Returns false if fails.
- **getHumidity()** computes the relative humidity in % based off the latest raw reading, and returns it
- **getTemperature()** computes the temperature in °C based off the latest raw reading, and returns it
- **getRawHumidity()** returns the raw two-byte representation of humidity directly from the sensor
- **getRawTemperature()** returns the raw two-byte representation of temperature directly from the sensor
- **bool reset(bool hard = false)** resets the sensor, soft reset by default. Returns false if fails.
- **float getHumidity()** computes the relative humidity in % based off the latest raw reading, and returns it.
- **float getTemperature()** computes the temperature in °C based off the latest raw reading, and returns it.
- **uint16_t getRawHumidity()** returns the raw two-byte representation of humidity directly from the sensor.
- **uint16_t getRawTemperature()** returns the raw two-byte representation of temperature directly from the sensor.
Note that the temperature and humidity values are recalculated on every call to getHumidity() and getTemperature(). If you're worried about the extra cycles, you should make sure to cache these values or only request them after you've performed a new reading.
#### Error interface
- **getError()** returns last set error flag and clear it.
- **int getError()** returns last set error flag and clear it.
Be sure to clear the error flag by calling **getError()** before calling any command as the error flag could be from a previous command.
| Error | Symbolic | Description |
|:----:|:----|:----|
| Error | Symbolic | Description
|:-----:|:--------------------------|:----------------------------|
| 0x00 | SHT31_OK | no error |
| 0x81 | SHT31_ERR_WRITECMD | I2C write failed |
| 0x82 | SHT31_ERR_READBYTES | I2C read failed |
@ -68,63 +70,76 @@ Be sure to clear the error flag by calling **getError()** before calling any com
| 0x85 | SHT31_ERR_CRC_TEMP | CRC error in temperature |
| 0x86 | SHT31_ERR_CRC_HUM | CRC error in humidity |
| 0x87 | SHT31_ERR_CRC_STATUS | CRC error in statusfield |
| 0x88 | SHT31_ERR_HEATER_COOLDOWN | Heater need to cool down |
| 0x88 | SHT31_ERR_HEATER_ON | Could not switch on heater |
#### Heater interface
Use the heater for max **180** seconds, and let it cool down an equal period of time.
**WARNING:** Do not use heater for long periods.
**WARNING:** The user is responsible to switch the heater off manually!
The class does **NOT** do this automatically.
Use the heater for max **180** seconds, and let it cool down **180** seconds = 3 minutes.
Version 0.3.3 and up guards the cool down time by preventing switching the heater on
within **180** seconds of the last switch off. Note: this guarding is not reboot persistent.
- **setHeatTimeout(uint8_t seconds)** Set the time out of the heat cycle.
**WARNING:** The user is responsible to switch the heater off manually!
The class does **NOT** do this automatically.
Switch off the heater by directly calling **heatOff()** or indirectly by calling **isHeaterOn()**.
- **void setHeatTimeout(uint8_t seconds)** Set the time out of the heat cycle.
This value is truncated to max 180 seconds.
- **heatOn()** switches heat cycle on. Returns false if fails.
- **heatOff()** switches heat cycle off. Returns false if fails.
- **isHeaterOn()** is the sensor still in heating cycle? replaces **heatUp()**.
Will switch heat off if max heating time has passed.
- **heatUp()** will be obsolete in the future.
- **uint8_t getHeatTimeout
- **bool heatOn()** switches heat cycle on if not already on.
Returns false if fails, setting error to **SHT31_ERR_HEATER_COOLDOWN**
or to **SHT31_ERR_HEATER_ON**.
- **bool heatOff()** switches heat cycle off.
Returns false if fails, setting error to **SHT31_ERR_HEATER_OFF**.
- **bool isHeaterOn()** is the sensor still in heating cycle? replaces **heatUp()**.
Will switch the heater off if max heating time has passed.
- **bool heatUp()** will be obsolete in the future. replaced by **isHeaterOn()**
#### Async interface
See async example for usage
- **requestData()** requests a new measurement. Returns false if this fails.
- **dataReady()** checks if enough time has passed to read the data. (15 millis)
- **readData(bool fast = true)** fast skips CRC check. Returns false if reading fails or in case of a CRC fail.
- **bool requestData()** requests a new measurement. Returns false if this fails.
- **bool dataReady()** checks if enough time has passed to read the data. (15 milliseconds)
- **bool readData(bool fast = true)** fast = true skips the CRC check.
Returns false if reading fails or in case of a CRC failure.
## Status fields
| BIT | Description | values |
|:----:|:----|:----|
| 15 | Alert pending status | '0': no pending alerts|
| | | '1': at least one pending alert - default |
| 14 | Reserved | '0' |
| 13 | Heater status | '0 : Heater OFF - default |
| | | '1 : Heater ON |
| 12 | Reserved | '0' |
| 11 | Humidity tracking alert | '0 : no alert - default |
| | | '1 : alert |
| 10 | Temperature tracking alert | '0 : no alert - default |
| | | '1 : alert |
| 9-5 | Reserved | '00000' |
| 4 | System reset detected | '0': no reset since last clear status register command |
| | | '1': reset detected (hard or soft reset command or supply fail) - default |
| 3-2 | Reserved | '00' |
| 1 | Command status | '0': last cmd executed successfully |
| | | '1': last cmd not processed. Invalid or failed checksum |
| 0 | Write data checksum status | '0': checksum of last write correct |
| | | '1': checksum of last write transfer failed |
| BIT | Description | value | notes |
|:-----|:---------------------------|:--------|:------|
| 15 | Alert pending status | 0 | no pending alerts
| | | 1 | at least one pending alert - default
| 14 | Reserved | 0 |
| 13 | Heater status | 0 | Heater OFF - default
| | | 1 | Heater ON
| 12 | Reserved | 0 |
| 11 | Humidity tracking alert | 0 | no alert - default
| | | 1 | alert
| 10 | Temperature tracking alert | 0 | no alert - default
| | | 1 | alert
| 9-5 | Reserved | 00000 |
| 4 | System reset detected | 0 | no reset since last clear status register command
| | | 1 | reset detected (hard or soft reset command or supply fail) - default
| 3-2 | Reserved | 00 |
| 1 | Command status | 0 | last cmd executed successfully
| | | 1 | last cmd not processed. Invalid or failed checksum
| 0 | Write data checksum status | 0 | checksum of last write correct
| | | 1 | checksum of last write transfer failed
## Future
- merge with other SHT sensors if possible
- direct Fahrenheit formula
- direct Fahrenheit formula ?
- improve error handling / status. (all code paths)
## Operation

View File

@ -1,7 +1,7 @@
//
// FILE: SHT31.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.2
// VERSION: 0.3.3
// DATE: 2019-02-08
// PURPOSE: Arduino library for the SHT31 temperature and humidity sensor
// https://www.adafruit.com/product/2857
@ -26,6 +26,8 @@
// 0.3.0 2021-01-04 arduino-ci
// 0.3.1 2021-05-27 arduino-lint fixes
// 0.3.2 2021-08-05 expose raw data from sensor
// 0.3.3 2021-08-24 fix #22 prevent heater to switch on too fast.
// update readme
#include "SHT31.h"
@ -43,15 +45,18 @@
#define SHT31_HEAT_ON 0x306D
#define SHT31_HEAT_OFF 0x3066
#define SHT31_HEATER_TIMEOUT 180000UL // milliseconds
SHT31::SHT31()
{
_addr = 0;
_address = 0;
_lastRead = 0;
rawTemperature = 0;
rawHumidity = 0;
_heatTimeout = 0;
_heaterStart = 0;
_heaterStop = 0;
_heaterOn = false;
_error = SHT31_OK;
}
@ -63,7 +68,7 @@ bool SHT31::begin(const uint8_t address, const uint8_t dataPin, const uint8_t cl
{
return false;
}
_addr = address;
_address = address;
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255))
@ -89,7 +94,7 @@ bool SHT31::begin(const uint8_t address, TwoWire *wire)
{
return false;
}
_addr = address;
_address = address;
_wire = wire;
_wire->begin();
return reset();
@ -109,7 +114,7 @@ bool SHT31::read(bool fast)
bool SHT31::isConnected()
{
_wire->beginTransmission(_addr);
_wire->beginTransmission(_address);
int rv = _wire->endTransmission();
if (rv != 0) _error = SHT31_ERR_NOT_CONNECT;
return (rv == 0);
@ -184,46 +189,56 @@ bool SHT31::reset(bool hard)
void SHT31::setHeatTimeout(uint8_t seconds)
{
_heatTimeOut = seconds;
if (_heatTimeOut > 180) _heatTimeOut = 180;
_heatTimeout = seconds;
if (_heatTimeout > 180) _heatTimeout = 180;
}
bool SHT31::heatOn()
{
if (isHeaterOn()) return true;
if ((_heaterStop > 0) && (millis() - _heaterStop < SHT31_HEATER_TIMEOUT))
{
_error = SHT31_ERR_HEATER_COOLDOWN;
return false;
}
if (writeCmd(SHT31_HEAT_ON) == false)
{
_error = SHT31_ERR_HEATER_ON;
return false;
}
_heaterStart = millis();
_heaterOn = true;
return true;
}
bool SHT31::heatOff()
{
// always switch off the heater - ignore _heaterOn flag.
if (writeCmd(SHT31_HEAT_OFF) == false)
{
_error = SHT31_ERR_HEATER_OFF; // can be serious!
return false;
}
_heaterStart = 0;
_heaterStop = millis();
_heaterOn = false;
return true;
}
bool SHT31::isHeaterOn()
{
if (_heaterStart == 0)
if (_heaterOn == false)
{
return false;
}
// did not exceed time out
if (millis() - _heaterStart < (_heatTimeOut * 1000UL))
if (millis() - _heaterStart < (_heatTimeout * 1000UL))
{
return true;
}
heatOff(); // should this be done here?
heatOff();
return false;
}
@ -307,7 +322,7 @@ uint8_t SHT31::crc8(const uint8_t *data, uint8_t len)
bool SHT31::writeCmd(uint16_t cmd)
{
_wire->beginTransmission(_addr);
_wire->beginTransmission(_address);
_wire->write(cmd >> 8 );
_wire->write(cmd & 0xFF);
if (_wire->endTransmission() != 0)
@ -321,7 +336,7 @@ bool SHT31::writeCmd(uint16_t cmd)
bool SHT31::readBytes(uint8_t n, uint8_t *val)
{
int rv = _wire->requestFrom(_addr, (uint8_t) n);
int rv = _wire->requestFrom(_address, (uint8_t) n);
if (rv == n)
{
for (uint8_t i = 0; i < n; i++)

View File

@ -2,7 +2,7 @@
//
// FILE: SHT31.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.2
// VERSION: 0.3.3
// DATE: 2019-02-08
// PURPOSE: Arduino library for the SHT31 temperature and humidity sensor
// https://www.adafruit.com/product/2857
@ -14,7 +14,7 @@
#include "Wire.h"
#define SHT31_LIB_VERSION (F("0.3.2"))
#define SHT31_LIB_VERSION (F("0.3.3"))
// fields readStatus
@ -35,6 +35,8 @@
#define SHT31_ERR_CRC_TEMP 0x85
#define SHT31_ERR_CRC_HUM 0x86
#define SHT31_ERR_CRC_STATUS 0x87
#define SHT31_ERR_HEATER_COOLDOWN 0x88
#define SHT31_ERR_HEATER_ON 0x89
class SHT31
@ -51,7 +53,7 @@ public:
// blocks 15 milliseconds + actual read + math
bool read(bool fast = true);
// check senosr is reachable over I2C
// check sensor is reachable over I2C
bool isConnected();
// details see datasheet; summary in SHT31.cpp file
@ -64,8 +66,10 @@ public:
// do not use heater for long periods,
// use it for max 3 minutes to heat up
// and let it cool down an equal period.
// and let it cool down at least 3 minutes.
void setHeatTimeout(uint8_t seconds);
uint8_t getHeatTimeout() { return _heatTimeout; };
;
bool heatOn();
bool heatOff();
bool isHeaterOn(); // is the sensor still heating up?
@ -89,11 +93,13 @@ private:
bool readBytes(uint8_t n, uint8_t *val);
TwoWire* _wire;
uint8_t _addr;
uint8_t _heatTimeOut; // seconds
uint8_t _address;
uint8_t _heatTimeout; // seconds
uint32_t _lastRead;
uint32_t _lastRequest; // for async interface
uint32_t _heaterStart;
uint32_t _heaterStop;
bool _heaterOn;
uint16_t rawHumidity;
uint16_t rawTemperature;

View File

@ -1,7 +1,7 @@
# Syntax Coloring Map For SHT31 temperature and humidity sensor
# Syntax Colouring Map For SHT31 temperature and humidity sensor
# Datatypes (KEYWORD1)
# Data types (KEYWORD1)
SHT31 KEYWORD1
@ -28,6 +28,7 @@ readData KEYWORD2
getRawHumidity KEYWORD2
getRawTemperature KEYWORD2
# Instances (KEYWORD2)
@ -40,3 +41,6 @@ SHT31_STATUS_TEMP_TRACK_ALERT LITERAL1
SHT31_STATUS_SYSTEM_RESET LITERAL1
SHT31_STATUS_COMMAND_STATUS LITERAL1
SHT31_STATUS_WRITE_CRC_STATUS LITERAL1
SHT31_ERR_HEATER_COOLDOWN LITERAL1
SHT31_ERR_HEATER_ON LITERAL1

View File

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

View File

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