Closed asetyde closed 5 years ago
try this:
uint32_t start = millis();
while (Wire.available() < 3) {
if ((millis() - start) >= 300) { // Don't hang here for more than 300ms
return 0;
}
}
not work ..
@asetyde are you using "hold master" or "no hold master" commands Hold Master commands
no Hold MasterCommands
bool SHT2xClass::waitReady(uint32_t timeouMs){
bool ready = false;
uint32_t tick = millis();
while((!ready)&&(millis-tick < timeoutMs)){
Wire.beginTransmission(eSHT2xAddress);
ready = Wire.endTransmssion()==0;
if(!ready && timeoutMs>0){
delay(timeoutMs/5); // wait for sensor to complete sample
}
}
return ready;
}
uint16_t SHT2xClass::readSensor(uint8_t command)
{
uint16_t result=0;
if(waitReady(100)){ // wait up to 100ms for sensor to answer, could be in previous sample cycle
Wire.beginTransmission(eSHT2xAddress);
Wire.write(command);
uint8_t err = Wire.endTransmission();
if(err==0){ // command accepted
switch(command &0x10){
case 0x10 : // Hold Master command (SCL stretching)
Wire.setTimeOut(100); // chip specified max is 85ms for 14bit res (V.4 May 2014 datasheet)
break;
case 0 : // wait for sensor to complete conversion, polling for ready
Wire.setTimeout(50); // default i2c timeout
waitReady(100);
break;
default :;
}
err=Wire.requestFrom(eSHT2xAddress,3);
if(err == 0) {// no data
log_w("read Sensor command(0x%02X) fail =%d(%s)",command,Wire.lastError(),Wire.getErrorText(Wire.lastError()))
return 0;
}
if(err == 3){// got three bytes in buffer
//Store the result
result = Wire.read() << 8;
result += Wire.read();
result &= ~0x0003; // clear two low bits (status bits)
// don't care about last byte, next requestFrom() will overwrite
return result;
} else { // Command not accepted
log_w("write Sensor command(0x%02X) fail =%d(%s)",command,Wire.lastError(),Wire.getErrorText(Wire.lastError()))
return 0;
}
} else { // sensor never answered
log_e("Sensor at 0x%02X did not ACK, err = %d(%s)",eSHT2xAddress),Wire.lastError(),Wire.getErrorText(Wire.lastError()))
return 0;
}
}
I haven't compiled this so there could be syntax errors. Try it.
Chuck.
Ok tomorrow i test it (GMT+1)
I've many devices with i2c , SHT21x , VEML7700 , CAP1296 (Microchip touch) , i see sometimes a temporaly freeze on i2c, therefore also udp sometimes delay
i correct it some imperfection but result now is t: -273.00000 and hum 0 :(
// .h
#ifndef SHT2X_H
#define SHT2X_H
#include <stdint.h>
class SHT2xClass
{
private:
uint16_t readSensor(uint8_t command);
bool waitReady(uint32_t timeouMs);
public:
float GetHumidity(void);
float GetTemperature(void);
float GetDewPoint(void);
};
extern SHT2xClass SHT2x;
#endif
// .cpp
#include <stdint.h>
#include <math.h>
#include <Arduino.h>
#include "Sodaq_SHT2x.h"
#include <Wire.h>
// Specify the constants for water vapor and barometric pressure.
#define WATER_VAPOR 17.62f
#define BAROMETRIC_PRESSURE 243.5f
typedef enum {
eSHT2xAddress = 0x40,
} HUM_SENSOR_T;
typedef enum {
eTempHoldCmd = 0xE3,
eRHumidityHoldCmd = 0xE5,
eTempNoHoldCmd = 0xF3,
eRHumidityNoHoldCmd = 0xF5,
} HUM_MEASUREMENT_CMD_T;
/******************************************************************************
* Global Functions
******************************************************************************/
/**********************************************************
* GetHumidity
* Gets the current humidity from the sensor.
*
* @return float - The relative humidity in %RH
**********************************************************/
float SHT2xClass::GetHumidity(void)
{
float value = readSensor(eRHumidityNoHoldCmd);
if (value == 0) {
return 0; // Some unrealistic value
}
return -6.0 + 125.0 / 65536.0 * value;
}
/**********************************************************
* GetTemperature
* Gets the current temperature from the sensor.
*
* @return float - The temperature in Deg C
**********************************************************/
float SHT2xClass::GetTemperature(void)
{
float value = readSensor(eTempNoHoldCmd);
if (value == 0) {
return -273; // Roughly Zero Kelvin indicates an error
}
return -46.85 + 175.72 / 65536.0 * value;
}
/**********************************************************
* GetDewPoint
* Gets the current dew point based on the current humidity and temperature
*
* @return float - The dew point in Deg C
**********************************************************/
float SHT2xClass::GetDewPoint(void)
{
float humidity = GetHumidity();
float temperature = GetTemperature();
// Calculate the intermediate value 'gamma'
float gamma = log(humidity / 100) + WATER_VAPOR * temperature / (BAROMETRIC_PRESSURE + temperature);
// Calculate dew point in Celsius
float dewPoint = BAROMETRIC_PRESSURE * gamma / (WATER_VAPOR - gamma);
return dewPoint;
}
/******************************************************************************
* Private Functions
******************************************************************************/
uint16_t SHT2xClass::readSensor(uint8_t command)
{
uint16_t result = 0;
if (waitReady(100)) { // wait up to 100ms for sensor to answer, could be in previous sample cycle
Wire.beginTransmission(eSHT2xAddress);
Wire.write(command);
uint8_t err = Wire.endTransmission();
if (err == 0) { // command accepted
switch (command & 0x10) {
case 0x10: // Hold Master command (SCL stretching)
Wire.setTimeOut(100); // chip specified max is 85ms for 14bit res (V.4 May 2014 datasheet)
break;
case 0: // wait for sensor to complete conversion, polling for ready
Wire.setTimeout(50); // default i2c timeout
waitReady(100);
break;
default:;
}
err = Wire.requestFrom(eSHT2xAddress, 3);
if (err == 0) {// no data
char data[200]="";
snprintf(data,200,"read Sensor command(0x%02X) fail =%d(%s)", command, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
Serial.println(data);
return 0;
}
if (err == 3) {// got three bytes in buffer
//Store the result
result = Wire.read() << 8;
result += Wire.read();
result &= ~0x0003; // clear two low bits (status bits)
// don't care about last byte, next requestFrom() will overwrite
return result;
}
else { // Command not accepted
char data[200] = "";
snprintf(data, 200, "write Sensor command(0x%02X) fail =%d(%s)", command, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
Serial.println(data);
return 0;
}
}
else { // sensor never answered
char data[200] = "";
snprintf(data, 200, "Sensor at 0x%02X did not ACK, err = %d(%s)", eSHT2xAddress, Wire.lastError(), Wire.getErrorText(Wire.lastError()));
Serial.println(data);
return 0;
}
}
}
bool SHT2xClass::waitReady(uint32_t timeoutMs){
bool ready = false;
uint32_t tick = millis();
while((!ready)&&(tick < timeoutMs)){
Wire.beginTransmission(eSHT2xAddress);
ready = Wire.endTransmission() == 0 ;
if(!ready && timeoutMs>0){
delay(timeoutMs/5); // wait for sensor to complete sample
}
}
return ready;
}
SHT2xClass SHT2x;
bool SHT2xClass::waitReady(uint32_t timeoutMs){
bool ready = false;
uint32_t tick = millis();
while((!ready)&&(millis()-tick < timeoutMs)){
Wire.beginTransmission(eSHT2xAddress);
ready = Wire.endTransmission() == 0 ;
if(!ready && timeoutMs>0){
delay(timeoutMs/5); // wait for sensor to complete sample
}
}
return ready;
}
Try this.
Chuck.
reply :
read Sensor command(0xF5) fail =2(ACK) read Sensor command(0xF3) fail =2(ACK) [INFO] Sensor SHT21 fail values !! Temp : -273.000000 Hum : 0.00000
try running this sketch. post its results. i2c scan.ino
The ACK error says the device(sensor) never answered the read command. Based on this you have a hardware fault.
The i2c_scan.ino will probe the i2c bus and list all devices that answer. Run it so that we can confirm the sensor is operational.
Chuck.
I come back to original library with 1.0.1 final realese, all work perfect . Sensor is ok (scan code)
Thanks for support Chuck as always
as sensor VEML770 and SHT21x @me-no-dev all work
However SHT21X sensor seems not work correctly, I'm very tired about it, continues bug on i2c peripherals every update. Seems temperature air too high and humidity freezed. 10 days of monitor, consider about code that I come to you previous mod on sht21x library .
@asetyde I found that the SHT2n sensor are compatible with the Si7013, Si7020, Si7021. I adjusted Adafruits_Si7021 library to also work with the SHT25. Try my library adafruit_Si7021. It seems to work fine with a SHT25
Chuck.
i load code and now I order some devices to check temp and humidity reliability
I update with test result
It's working but I think sensor read 4/5 degree up than real value, I try to understand if esp is cause but is up on 13cm on my device and I think it's not correlated
I think sensor temperature work is fixed and not influence
@asetyde If your problem is solved, please close this issue.
Chuck.
Sodaq_SHT2x Issue
Read sensor with esp32 devkit gives strange value near zero with last pre-release 1.0.1 rc4 I can't see why, but I think some is linked to i2c driver
@stickbreaker cab be linked to i2c recent issue ? with rc4 bug on i2c ? I add my library under
Hardware:
Board: ESP32 Devkit Module Core Installation version: 1.0.1-rc4 IDE name: Arduino IDE Flash Frequency: 160Mhz/80mhz PSRAM enabled: no Upload Speed: 115200 Computer OS: Windows 10
my library for sht21x :
Sodaq_SHT2x.h
Sodaq_SHT2x.cpp