Skip to content

Commit 8f185b8

Browse files
committed
added getTemperature and getHumidity
added upport for ESP I2C added constants for status masks added HARD reset added setHeatTimeout added heatUp refactored
1 parent e378e43 commit 8f185b8

File tree

13 files changed

+695
-1
lines changed

13 files changed

+695
-1
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Rob Tillaart
3+
Copyright (c) 2019-2020 Rob Tillaart
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,25 @@
11
# SHT31
2+
23
Arduino library for the SHT31 temperature and humidity sensor
4+
5+
# Description
6+
7+
The SHT3x family of sensors should work up to 1 MHz I2C
8+
9+
This library should also work for SHT30 and SHT35 but these are
10+
not tested yet.
11+
12+
| SENSOR | Temperature accuracy | Humidity accuracy |
13+
|:----:|:----:|:----:|
14+
| SHT30 | ~0.3 | 2 |
15+
| SHT31 | ~0.3 | 1.5 |
16+
| SHT35 | ~0.2 | 1.5 |
17+
18+
19+
An elaborated library for the SHT31 sensor can be found here
20+
https://github.com/hawesg/SHT31D_Particle_Photon_ClosedCube
21+
22+
# Operation
23+
24+
See examples
25+

SHT31.cpp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
//
2+
// FILE: SHT31.cpp
3+
// AUTHOR: Rob Tillaart
4+
// VERSION: 0.2.0
5+
// DATE: 2019-02-08
6+
// PURPOSE: Arduino library for the SHT31 temperature and humidity sensor
7+
// https://www.adafruit.com/product/2857
8+
// URL: https://github.com/RobTillaart/SHT31
9+
//
10+
// HISTORY:
11+
// 0.1.0 2019-02-08 initial version
12+
// 0.1.1 2019-02-18 add description readStatus(),
13+
// async interface
14+
// 0.1.2 2019-03-05 fix issue #123 - error in humidity
15+
// stable version
16+
// 0.2.0 2020-05-12 made humidity & temperature private;
17+
// support ESP32 I2C
18+
//
19+
20+
21+
#include "SHT31.h"
22+
23+
// SUPPORTED COMMANDS - single shot mode only
24+
#define SHT31_READ_STATUS 0xF32D
25+
#define SHT31_CLEAR_STATUS 0x3041
26+
27+
#define SHT31_SOFT_RESET 0x30A2
28+
#define SHT31_HARD_RESET 0x0006
29+
30+
#define SHT31_MEASUREMENT_FAST 0x2416 // page 10 datasheet
31+
#define SHT31_MEASUREMENT_SLOW 0x2400 // no clock stretching
32+
33+
#define SHT31_HEAT_ON 0x306D
34+
#define SHT31_HEAT_OFF 0x3066
35+
36+
37+
SHT31::SHT31()
38+
{
39+
_addr = 0;
40+
_lastRead = 0;
41+
temperature = 0;
42+
humidity = 0;
43+
_heaterStart = 0;
44+
}
45+
46+
#if defined(ESP8266) || defined(ESP32)
47+
bool SHT31::begin(const uint8_t address, const uint8_t dataPin, const uint8_t clockPin)
48+
{
49+
if (address != 0x44 && address != 0x45) return false;
50+
_addr = address;
51+
52+
_wire = &Wire;
53+
if ((dataPin < 255) && (clockPin < 255))
54+
{
55+
_wire->begin(dataPin, clockPin);
56+
} else {
57+
_wire->begin();
58+
}
59+
reset();
60+
return true;
61+
}
62+
#endif
63+
64+
bool SHT31::begin(const uint8_t address)
65+
{
66+
return begin(address, &Wire);
67+
}
68+
69+
bool SHT31::begin(const uint8_t address, TwoWire *wire)
70+
{
71+
if (address != 0x44 && address != 0x45) return false;
72+
_addr = address;
73+
_wire = wire;
74+
_wire->begin();
75+
reset();
76+
return true;
77+
}
78+
79+
bool SHT31::read(bool fast)
80+
{
81+
writeCmd(fast ? SHT31_MEASUREMENT_FAST : SHT31_MEASUREMENT_SLOW);
82+
delay(fast ? 4 : 15); // table 4 datasheet
83+
return readData(fast);
84+
}
85+
86+
uint16_t SHT31::readStatus()
87+
{
88+
uint32_t status = 0;
89+
writeCmd(SHT31_READ_STATUS); // page 13 datasheet
90+
readBytes(3, (uint8_t*) &status); // 16 bit status + CRC
91+
// TODO CRC check
92+
93+
return (uint16_t) (status >> 8);
94+
95+
// bit - description
96+
// ==================
97+
// 15 Alert pending status
98+
// '0': no pending alerts
99+
// '1': at least one pending alert - default
100+
// 14 Reserved ‘0’
101+
// 13 Heater status
102+
// '0’ : Heater OFF - default
103+
// '1’ : Heater ON
104+
// 12 Reserved '0’
105+
// 11 Humidity tracking alert
106+
// '0’ : no alert - default
107+
// '1’ : alert
108+
// 10 Temp tracking alert
109+
// '0’ : no alert - default
110+
// '1’ : alert
111+
// 9:5 Reserved '00000’
112+
// 4 System reset detected
113+
// '0': no reset since last ‘clear status register’ command
114+
// '1': reset detected (hard or soft reset command or supply fail) - default
115+
// 3:2 Reserved ‘00’
116+
// 1 Command status
117+
// '0': last cmd executed successfully
118+
// '1': last cmd not processed. Invalid or failed checksum
119+
// 0 Write data checksum status
120+
// '0': checksum of last write correct
121+
// '1': checksum of last write transfer failed
122+
}
123+
124+
void SHT31::reset(bool hard)
125+
{
126+
if (hard)
127+
{
128+
writeCmd(SHT31_HARD_RESET);
129+
} else {
130+
writeCmd(SHT31_SOFT_RESET);
131+
}
132+
delay(1); // table 4 datasheet
133+
}
134+
135+
void SHT31::setHeatTimeout(uint8_t seconds)
136+
{
137+
_heatTimeOut = min(180, seconds);
138+
}
139+
140+
void SHT31::heatOn()
141+
{
142+
writeCmd(SHT31_HEAT_ON);
143+
_heaterStart = millis();
144+
}
145+
146+
void SHT31::heatOff()
147+
{
148+
writeCmd(SHT31_HEAT_OFF);
149+
_heaterStart = 0;
150+
}
151+
152+
bool SHT31::heatUp()
153+
{
154+
if (_heaterStart == 0) return false;
155+
// did not exceed time out
156+
if (millis() - _heaterStart < (_heatTimeOut * 1000UL)) return true;
157+
heatOff();
158+
return false;
159+
}
160+
161+
void SHT31::requestData()
162+
{
163+
writeCmd(SHT31_MEASUREMENT_SLOW);
164+
_lastRequest = millis();
165+
}
166+
167+
bool SHT31::dataReady()
168+
{
169+
return ((millis() - _lastRequest) > 15);
170+
}
171+
172+
bool SHT31::readData(bool fast)
173+
{
174+
uint8_t buffer[6];
175+
readBytes(6, (uint8_t*) &buffer[0]);
176+
177+
uint16_t raw = (buffer[0] << 8) + buffer[1];
178+
temperature = raw * (175.0 / 65535) - 45;
179+
raw = (buffer[3] << 8) + buffer[4];
180+
humidity = raw * (100.0 / 65535);
181+
182+
_lastRead = millis();
183+
184+
if (!fast)
185+
{
186+
// TODO check CRC here
187+
// TODO rv = false;
188+
}
189+
return true;
190+
}
191+
192+
//////////////////////////////////////////////////////////
193+
194+
void SHT31::writeCmd(uint16_t cmd)
195+
{
196+
_wire->beginTransmission(_addr);
197+
_wire->write(cmd >> 8 );
198+
_wire->write(cmd & 0xFF);
199+
_wire->endTransmission();
200+
}
201+
202+
void SHT31::readBytes(uint8_t n, uint8_t *val)
203+
{
204+
_wire->requestFrom(_addr, (uint8_t) n);
205+
for (uint8_t i = 0; i < n; i++)
206+
{
207+
val[i] = _wire->read();
208+
}
209+
}
210+
211+
// -- END OF FILE --

SHT31.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#pragma once
2+
//
3+
// FILE: SHT31.h
4+
// AUTHOR: Rob Tillaart
5+
// VERSION: 0.2.0
6+
// DATE: 2019-02-08
7+
// PURPOSE: Arduino library for the SHT31 temperature and humidity sensor
8+
// https://www.adafruit.com/product/2857
9+
// URL: https://github.com/RobTillaart/SHT31
10+
//
11+
12+
#include "Arduino.h"
13+
#include "Wire.h"
14+
15+
#define SHT31_LIB_VERSION "0.2.0"
16+
17+
// fields readStatus
18+
#define SHT31_STATUS_ALERT_PENDING (1 << 15)
19+
#define SHT31_STATUS_HEATER_ON (1 << 13)
20+
#define SHT31_STATUS_HUM_TRACK_ALERT (1 << 11)
21+
#define SHT31_STATUS_TEMP_TRACK_ALERT (1 << 10)
22+
#define SHT31_STATUS_SYSTEM_RESET (1 << 4)
23+
#define SHT31_STATUS_COMMAND_STATUS (1 << 1)
24+
#define SHT31_STATUS_WRITE_CRC_STATUS (1 << 0)
25+
26+
class SHT31
27+
{
28+
public:
29+
SHT31();
30+
31+
#if defined(ESP8266) || defined(ESP32)
32+
void begin(const uint8_t address, uint8_t dataPin, uint8_t clockPin);
33+
#endif
34+
bool begin(const uint8_t address);
35+
bool begin(const uint8_t address, TwoWire *wire);
36+
37+
// blocks 15 milliseconds + actual read + math
38+
bool read(bool fast = true);
39+
40+
// details see datasheet; summary in SHT31.cpp file
41+
uint16_t readStatus();
42+
43+
// lastRead is in milliSeconds since start
44+
uint32_t lastRead() { return _lastRead; };
45+
46+
void reset(bool hard = false);
47+
48+
// do not use heater for long periods,
49+
// use it for max 3 minutes to heat up
50+
// and let it cool down an equal period.
51+
void setHeatTimeout(uint8_t seconds);
52+
void heatOn();
53+
void heatOff();
54+
bool heatUp(); // is the sensor still heating up?
55+
56+
float getHumidity() { return humidity; };
57+
float getTemperature() { return temperature; };
58+
59+
// ASYNC INTERFACE
60+
void requestData();
61+
bool dataReady();
62+
bool readData(bool fast = true);
63+
64+
private:
65+
void writeCmd(uint16_t cmd);
66+
void readBytes(uint8_t n, uint8_t *val);
67+
TwoWire* _wire;
68+
69+
uint8_t _addr;
70+
uint8_t _heatTimeOut; // seconds
71+
uint32_t _lastRead;
72+
uint32_t _lastRequest; // for async interface
73+
uint32_t _heaterStart;
74+
75+
float humidity;
76+
float temperature;
77+
};
78+
79+
// -- END OF FILE --
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// FILE: SHT31_I2Cspeed
3+
// AUTHOR: Rob Tillaart
4+
// VERSION: 0.0.2
5+
// PURPOSE: testing the performance at different I2C speeds
6+
//
7+
8+
#include "Wire.h"
9+
#include "SHT31.h"
10+
11+
uint32_t start;
12+
uint32_t stop;
13+
14+
SHT31 sht;
15+
16+
void setup()
17+
{
18+
Serial.begin(115200);
19+
Serial.println(__FILE__);
20+
Serial.print("SHT31_LIB_VERSION: \t");
21+
Serial.println(SHT31_LIB_VERSION);
22+
23+
Wire.begin();
24+
sht.begin(0x44);
25+
Wire.setClock(100000);
26+
27+
uint16_t stat = sht.readStatus();
28+
Serial.print(stat, HEX);
29+
Serial.println();
30+
}
31+
32+
void loop()
33+
{
34+
for (uint32_t I2Cfreq = 100000; I2Cfreq < 900000; I2Cfreq += 50000)
35+
{
36+
Serial.print(I2Cfreq/1000);
37+
Wire.setClock(I2Cfreq);
38+
test();
39+
}
40+
}
41+
42+
43+
void test()
44+
{
45+
start = micros();
46+
sht.read(true); // default = true/fast slow = false
47+
stop = micros();
48+
Serial.print("\t");
49+
Serial.print(stop - start);
50+
Serial.print("\t");
51+
Serial.print(sht.getTemperature(), 1);
52+
Serial.print("\t");
53+
Serial.println(sht.getHumidity(), 1);
54+
delay(100);
55+
}
56+
57+
// -- END OF FILE --

0 commit comments

Comments
 (0)