@@ -85,12 +85,12 @@ bool SHTI2cSensor::readFromI2c(TwoWire & wire,
85
85
return true ;
86
86
}
87
87
88
- uint8_t SHTI2cSensor::crc8 (const uint8_t *data, uint8_t len)
88
+ uint8_t SHTI2cSensor::crc8 (const uint8_t *data, uint8_t len, uint8_t crcInit )
89
89
{
90
90
// adapted from SHT21 sample code from
91
91
// http://www.sensirion.com/en/products/humidity-temperature/download-center/
92
92
93
- uint8_t crc = 0xff ;
93
+ uint8_t crc = crcInit ;
94
94
uint8_t byteCtr;
95
95
for (byteCtr = 0 ; byteCtr < len; ++byteCtr) {
96
96
crc ^= data[byteCtr];
@@ -153,6 +153,82 @@ class SHTC1Sensor : public SHTI2cSensor
153
153
}
154
154
};
155
155
156
+ //
157
+ // class SHT2xSensor (SHT20, SHT21, SHT25)
158
+ //
159
+
160
+ class SHT2xSensor : public SHTI2cSensor
161
+ {
162
+ public:
163
+ SHT2xSensor (TwoWire &wire)
164
+ // clock stretching disabled
165
+ : SHTI2cSensor(0x40 , // i2cAddress
166
+ 0xF3F5 , // i2cCommand Hi: T, Lo: RH
167
+ 85 , // duration
168
+ -46.85 , // a (sht_t_poly1)
169
+ 175.72 , // b (sht_t_poly2)
170
+ 65536.0 , // c (sht_t_poly3)
171
+ -6.0 , // x (sht_h_poly1)
172
+ 125.0 , // y (sht_h_poly2)
173
+ 65536.0 , // z (sht_h_poly3)
174
+ 1 , // cmd_Size
175
+ wire)
176
+ {
177
+ }
178
+
179
+ bool readSample () override
180
+ {
181
+ uint8_t data[EXPECTED_DATA_SIZE];
182
+ uint8_t cmd[mCmd_Size ];
183
+
184
+ // SHT2x sends T and RH in two separate commands (different to other sensors)
185
+ // so we have to spit the command into two bytes and
186
+ // have to read from I2C two times with EXPECTED_DATA_SIZE / 2
187
+
188
+ // Upper byte is T for SHT2x Sensors
189
+ cmd[0 ] = mI2cCommand >> 8 ;
190
+ // Lower byte is RH for SHT2x Sensors
191
+ cmd[1 ] = mI2cCommand & 0xff ;
192
+
193
+ // read T from SHT2x Sensor
194
+ if (!readFromI2c (mWire , mI2cAddress , cmd, mCmd_Size , data,
195
+ EXPECTED_DATA_SIZE / 2 , mDuration )) {
196
+ DEBUG_SHT (" SHT2x readFromI2c(T) false\n " );
197
+ return false ;
198
+ }
199
+ // read RH from SHT2x Sensor
200
+ if (!readFromI2c (mWire , mI2cAddress , &cmd[1 ], mCmd_Size , &data[3 ],
201
+ EXPECTED_DATA_SIZE / 2 , mDuration )) {
202
+ DEBUG_SHT (" SHT2x readFromI2c(RH) false\n " );
203
+ return false ;
204
+ }
205
+
206
+ // -- Important: assuming each 2 byte of data is followed by 1 byte of CRC
207
+
208
+ // check CRC for both RH and T with a crc init value of 0
209
+ if (crc8 (&data[0 ], 2 , 0 ) != data[2 ] || crc8 (&data[3 ], 2 , 0 ) != data[5 ]) {
210
+ DEBUG_SHT (" SHT2x crc8 false\n " );
211
+ return false ;
212
+ }
213
+
214
+ // check status bits [1..0] (see datasheet)
215
+ // bit 0: not used, bit 1: measurement type (0: temperature, 1 humidity)
216
+ if (((data[1 ] & 0x02 ) != 0x00 ) || ((data[4 ] & 0x02 ) != 0x02 )) {
217
+ DEBUG_SHT (" SHT2x status bits false\n " );
218
+ return false ;
219
+ }
220
+
221
+ // convert to Temperature/Humidity
222
+ uint16_t val;
223
+ val = (data[0 ] << 8 ) + (data[1 ] & ~0x03 ); // get value and clear status bits [1..0]
224
+ mTemperature = mA + mB * (val / mC );
225
+
226
+ val = (data[3 ] << 8 ) + (data[4 ] & ~0x03 ); // get value and clear status bits [1..0]
227
+ mHumidity = mX + mY * (val / mZ );
228
+
229
+ return true ;
230
+ }
231
+ };
156
232
157
233
//
158
234
// class SHT3xSensor
@@ -274,6 +350,7 @@ float SHT3xAnalogSensor::readTemperature()
274
350
//
275
351
276
352
const SHTSensor::SHTSensorType SHTSensor::AUTO_DETECT_SENSORS[] = {
353
+ SHT2X,
277
354
SHT3X,
278
355
SHT3X_ALT,
279
356
SHTC1,
@@ -289,6 +366,10 @@ bool SHTSensor::init(TwoWire & wire)
289
366
}
290
367
291
368
switch (mSensorType ) {
369
+ case SHT2X:
370
+ mSensor = new SHT2xSensor (wire);
371
+ break ;
372
+
292
373
case SHT3X:
293
374
case SHT85:
294
375
mSensor = new SHT3xSensor (wire);
0 commit comments