@@ -85,12 +85,12 @@ bool SHTI2cSensor::readFromI2c(TwoWire & wire,
8585 return true ;
8686}
8787
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 )
8989{
9090 // adapted from SHT21 sample code from
9191 // http://www.sensirion.com/en/products/humidity-temperature/download-center/
9292
93- uint8_t crc = 0xff ;
93+ uint8_t crc = crcInit ;
9494 uint8_t byteCtr;
9595 for (byteCtr = 0 ; byteCtr < len; ++byteCtr) {
9696 crc ^= data[byteCtr];
@@ -153,6 +153,82 @@ class SHTC1Sensor : public SHTI2cSensor
153153 }
154154};
155155
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+ };
156232
157233//
158234// class SHT3xSensor
@@ -274,6 +350,7 @@ float SHT3xAnalogSensor::readTemperature()
274350//
275351
276352const SHTSensor::SHTSensorType SHTSensor::AUTO_DETECT_SENSORS[] = {
353+ SHT2X,
277354 SHT3X,
278355 SHT3X_ALT,
279356 SHTC1,
@@ -289,6 +366,10 @@ bool SHTSensor::init(TwoWire & wire)
289366 }
290367
291368 switch (mSensorType ) {
369+ case SHT2X:
370+ mSensor = new SHT2xSensor (wire);
371+ break ;
372+
292373 case SHT3X:
293374 case SHT85:
294375 mSensor = new SHT3xSensor (wire);
0 commit comments