if(sht30.get()==0) - How does this work?

I'm sure this is a simple thing, but I was wondering how this code works.

if(sht30.get()==0)

I first thought it was reading the temperature values, i.e.if the value read is equal to zero, then go ahead and read/print the values. But second time around the loop, the value is no longer zero, so how does it continue reading?

So digging into the .cpp I think get() is checking for any reading from the sensor i.e. sensor is alive.
I can see it returns 0 at the end, but it's a little over my head.

Any insights into how this works would be appreciated!

Sketch:

#include <WEMOS_SHT3X.h>

SHT3X sht30(0x45);

void setup() {

  Serial.begin(115200);

}

void loop() {

  if(sht30.get()==0){
    Serial.print("Temperature in Celsius : ");
    Serial.println(sht30.cTemp);
    Serial.print("Temperature in Fahrenheit : ");
    Serial.println(sht30.fTemp);
    Serial.print("Relative Humidity : ");
    Serial.println(sht30.humidity);
    Serial.println();
  }
  else
  {
    Serial.println("Error!");
  }
  delay(1000);

}

SHT3X.cpp:

#include "WEMOS_SHT3X.h"

/* Motor()

*/
SHT3X::SHT3X(uint8_t address)
{
	Wire.begin();
	_address=address;
}



byte SHT3X::get()
{
	unsigned int data[6];

	// Start I2C Transmission
	Wire.beginTransmission(_address);
	// Send measurement command
	Wire.write(0x2C);
	Wire.write(0x06);
	// Stop I2C transmission
	if (Wire.endTransmission()!=0) 
		return 1;  

	delay(500);

	// Request 6 bytes of data
	Wire.requestFrom(_address, 6);

	// Read 6 bytes of data
	// cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc
	for (int i=0;i<6;i++) {
		data[i]=Wire.read();
	};
	
	delay(50);
	
	if (Wire.available()!=0) 
		return 2;

	// Convert the data
	cTemp = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45;
	fTemp = (cTemp * 1.8) + 32;
	humidity = ((((data[3] * 256.0) + data[4]) * 100) / 65535.0);

	return 0;
}

I have rewritten this because it was wrong, see the posts by PaulRB.

The function sht30.get() reads data, calculates the temperature and humidity and puts those in the public variables of the object. It checks for I2C errors and returns zero if there is no error and 1 or 2 if there is an error.

The Wire.endTransmission() can be used to check if the sensor is connected. The Wire.endTransmission() returns 0 if everything is okay. That is tested and error 1 is returned if something was wrong.

if (Wire.endTransmission()!=0)
  return 1;

The Wire.requestFrom() reads 6 bytes, and the Wire.read() is used 6 times to read those bytes. After that, the Wire.available() is checked to see if it is not zero, in that case error code 2 is returned.

if (Wire.available()!=0)
  return 2;

Actually, that is a bug. After reading the 6 bytes, the Wire.available() returns always zero. So this second test is useless.
I have made an Issue at Github for that.

The .get() method is returning a status indicator value. 0 means all is good and its ok to read the object's temp & humidity attributes. Any other value such as 1 or 2 indicates some error occurred when communicating with the sensor.

But second time around the loop, the value is no longer zero, so how does it continue reading?

What value does it return the second time? What makes you say it continues reading? The code clearly only reads the data when .get() returns 0.

The function sht30.get() does not do a lot. It reads data, but it does not really use that data. ...
I think that the name "sht30.get()" is confusing. It could be:

  • sht30.helloSht30AreYouThere()
  • sht30.IsAvailable()
  • sht30.Test()
  • sht30.AreYouOkay()
  • sht30.CheckForTheSensor()

Maybe you should read the code again. It's called .get() because it gets the temp & humidity readings from the sensor. It does not only check the sensor is connected.

Koepel:
Actually, that is a bug. After reading the 6 bytes, the Wire.available() returns always zero. So this second test is useless.

Overall, the first test is okay. When the sensor is not connected, then error 1 is returned.
I think that the name "sht30.get()" is confusing. It could be:

  • sht30.helloSht30AreYouThere()
  • sht30.IsAvailable()
  • sht30.Test()
  • sht30.AreYouOkay()
  • sht30.CheckForTheSensor()
  • and so on

Thank you for the explanation, I agree the name is confusing as it implies it's reading sensor temp etc.. data to me.

PaulRB:
What value does it return the second time? What makes you say it continues reading? The code clearly only reads the data when .get() returns 0.

Hi PaulRB, I say it continues reading because the serial monitor prints out new temp/humidity readings on a regular basis. So the ==0 cannot refer to the value of temp/humidity, but rather some value being read to check the sensor is alive - correct?

@PaulRB, thank you for correcting me. I quickly rewrote my post an changed my Issue at Github. I owe you a beer (or two).

@877 O, no! I was too late with rewriting my post. Sorry 877, my answer was wrong :-[ The calculated values are stored in the object, they are public variables and can be read. The return value is still the error code.

Koepel:
@PaulRB, thank you for correcting me. I quickly rewrote my post an changed my Issue at Github. I owe you a beer (or two).

@877 O, no! I was too late with rewriting my post. Sorry 877, my answer was wrong :-[ The calculated values are stored in the object, they are public variables and can be read. The return value is still the error code.

I'm taking my karma back ;D

Ha only joking, thanks for the update. I have also previoulsy raised an issue on Github regarding a compile warning #10, I don't think the library is maintained regularly. It still compliles and works ok though!

Thanks for the information! :slight_smile:

I have added something to your issue at Github. You could change the titel at Github to be more specific what the problem is.

877:
So the ==0 cannot refer to the value of temp/humidity, but rather some value being read to check the sensor is alive - correct?

Yes, as previously mentioned, the return value is a status indicator value. If the code is printing temp/humidity values, the status must be 0.

Koepel:
I quickly rewrote my post an changed my Issue at Github.

I'm not sure I would have raised an issue. Those code lines are almost certainly useless, but they don't cause a problem. Did you test your suggested changes with a Wemos+sht30? It's helpful for the repo owner if you do that.

If I was going to complain about that library, I would complain about the delay(500). That's wasted time that the Wemos could spend connecting to WiFi, for example. I would suggest a new .request() method which would send the sensor a message requesting the readings but not wait for them to become available. Then change the .get() method so that it checks to see if a .request() had been issued. If not, issue it. Otherwise check the time it was issued and if that was less than 500ms ago, delay for the remainder of the 500ms before reading the sensor values. This would be useful in battery powered circuits where the Wemos needs to go back into deep sleep as soon as possible to maximise battery life.

So now we have three things wrong with that single function.
What shall we do ?
There is a pull request for the delays: Wondering why there are very long delays while reading data.. by fabianoriccardi · Pull Request #9 · wemos/WEMOS_SHT3x_Arduino_Library · GitHub

Koepel:
I have added something to your issue at Github. You could change the titel at Github to be more specific what the problem is.

I have done, thanks for your help. It's a little over my head at this point! :slight_smile: