SHT31 use readTemperature and readHumidity or readBoth

Morning,

As per the title.

I'm running some SHT31-D Temperature & Humidity Sensors from Adafruit and am wondering if anyone has experience of reading the values individually or together?

Running them over i2c, I'm experiencing issues with the sensors locking over time and am looking at contingencies. They can run for hours fine and then get locked up and fail to read.

Is it safer, more reliable and/or quicker to poll separately or together or does it make no difference (this is my reluctant opinion).

Regards

Check your pull up resistors they may be just on the weak side. They should be about 4.7K total for 5V and 3.1K for 3V3.

You didn't mention the distance to the sensors. I2C was designed for connections between ICs and not long distances.
And as per @gilshultz , in this context 10k resistors would be weaker than 4.7k

Are you positive that it is a hardware problem? How can you be sure?

Hardware is not the only cause of random lockups a while after program start.

Post your code.
Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

FWIW I ran this code for over a week with no issues:

My board was powered by a wall wart, the sensor leads were about 6" long.

Might your issue be noise and not related directly to the SHT30?

Consider this test:

  1. Leave the SHT30 connected but do not initiate or poll
  2. Read an analog input at the same rate you were reading the SHT30.

If the issue is with the SHT30 the above test should run for days without an issue. If the above test "locks up" then the issue is not with reading the SHT30.

/*

Target:
    Pro Mini 8 Mhz (3.3v)
    SHT30 assembly  (I²C)
    	yellow = clock
    	White = Data
    OLED 128 x 32  (I²C)
2022-04-05  v0.01 

Library:  Sensitron version=1.2.1
*/

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

#include "SHTSensor.h"

#define OLED_address 0x3C

//SHTSensor sht;		// probes the bus for sensor type.
// To use a specific sensor instead of probing the bus use this command:
SHTSensor sht(SHTSensor::SHT3X);
SSD1306AsciiWire oled;

void setup() {
  // put your setup code here, to run once:

    Wire.begin();
    delay(100);

    oled.begin(&Adafruit128x32, OLED_address);
    oled.setFont(ZevvPeep8x16);
    oled.displayRemap(true);          // rotate text 180°
    oled.clear();

	oled.SSD1306Ascii::setCursor(0,0);


	if (sht.init()) {
    	oled.print("init(): success\n");
  	} else {
    	oled.print("init(): failed\n");
  	}
	sht.setAccuracy(SHTSensor::SHT_ACCURACY_HIGH); // only supported by SHT3x

}  //  -- setup --


bool toggleColon = true;

void loop() {

oled.setCursor(0,0);

if (sht.readSample()) {
		oled.print("SHT: ");
		oled.print("  RH: ");
		oled.println(sht.getHumidity(), 1);

    if(toggleColon){               // toggles colon every reading to show activity
        oled.print("  T:");
        toggleColon = false;
    }
    else {
     	oled.print("  T "); toggleColon = true;
    }
	    oled.println(sht.getTemperature()*9/5+32, 1);
} else {
    	oled.print("Error in readSample()\n");
	}





	delay(5000);
}  // -- loop --

// -- eof --

/*

    oled.SSD1306Ascii::setCursor(0,0);

    if(toggleColon){               // toggles colon every reading to show activity
      oled.print("T:");
      toggleColon = false;
    }
    else {
     	 oled.print("T "); toggleColon = true;
    }

    oled.SSD1306Ascii::setCursor(3*15,0);
    oled.clearToEOL ();      // Need to over write the previous last char else parts will remain.
    oled.print(currTemp *9/5+32,1);
    oled.print(" $F");              //ZevvPeep8x16MOD  prints $ as °
  	delay(5000);

      */

Thanks for the reply @gilshultz. I briefly looked into this and came to the conclusion that the sensor breakouts I'm using have them onboard. SHT31-d. I also have SGP30s, LTR310s and a DSP (although its not enabled yet) and believe them all to be the same.

Hi @cncnotes, thanks for the reply. Yes - its unfortunate I only learnt of this fact after travelling a long way down this route. At the moment they are short(ish) - 20cm. I say this hoping of course as in situ I'd like them to be slightly longer and believe it should be possible.

Hi @groundFungus, thanks for your reply. The simple answer is I'm not convinced its a hardware problem which is why my question was software specific - "Is it safer, more reliable and/or quicker to poll separately or together or does it make no difference".

I'm looking at best practice as part of my own debugging process.

I do wonder if its a memory issue over time. My C is pretty rusty these days. I've seen people advocating restarting ESP8266s running over a long period of time. I also have it in my mind I might just be asking too much from the ESP8266 and have some ESP32s to try.

As for code the complete system is quite extensive and I've divided the sections into libraries. You can see work in progress at https://byteinsight.net/ but the documentation needs updating.

Hi @JohnRob,

When I began developing this system I ran it for extended periods of time. I had 3 sensors (SHT, SGP and LTR) in series on one branch. They were being polled every 30 secs and sending updates via MQTT. I have since added a SDCard breakout for reading a config.ini and a TCA i2c Multiplexor for additional branches. Due to the complexity I have had PCBs printed avoiding dodgy connections on the board.

In principal, it works but in scaling it I have introduced problems so am now trying to find where I could have introduced issues due to not following best practice.

@groundFungus ,

I have uploaded the code to a git - https://github.com/byteinsight/HiveScientiaNode

Regards

Have you considered I2C bus lockup?
It doesn't have to happen at a consistent time or location. Glitches on the data line may keep the device from releasing the bus.
One remedy is for the controller to send 10 clock pulses, which should help release the line.

Have a look at this article:

BTW, nice website :+1:

1 Like

Hi,

Yeah, this is on my potential causes list. I was reading this the other day.

I had a related question in the queue relating to TCA9548A.

It has a reset pin which "RST - this is the reset pin, for resetting the multiplexer chip. Pulled high by default, connect to ground to reset" If my interpretation is correct I can connect this pin to GPIO and if I set that pin to LOW it will reset. Thus I can have software reset. If I start getting None values from the sensors I can trigger a reset.

That article you referenced is excellent.
Resetting the TCA seem like a good idea. Perhaps periodically, at intervals less than expected time to hang up. That way, you could re-initialise the bus/TCA in a planned manner.

1 Like

@cncnotes, Thanks for the help and ideas. Really appreciated.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.