I will first tell you how I tried two different SHT31 sensors with the following configuration and then I will tell you my experiences.
My Setup: Arduino Pro Mini with SH1106 OLED display + SGP30 TVOC sensor + SHT31. This is basically a battery operated air monitor. It displays sensor data on the screen. Schematic is as below:
My code (It says "clap" in the code but it is actually a button press):
#include <Wire.h>
#include "Adafruit_SGP30.h"
#include "U8glib.h"
#include "Adafruit_SHT31.h"
#include <EEPROM.h>
Adafruit_SGP30 sgp;
Adafruit_SHT31 sht31 = Adafruit_SHT31();
bool HeaterState = false;
int8_t counter = 0;
int8_t counter2 = 0;
float t;
float h;
float Vread;
bool SGPenabled = EEPROM.read(0);
/* return absolute humidity [mg/m^3] with approximation formula
* @param temperature [°C]
* @param humidity [%RH]
*/
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
uint32_t getAbsoluteHumidity(float temperature, float humidity) {
// approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
return absoluteHumidityScaled;
}
void setup() {
preparesecreen();
sht31.begin(0x44);
if (SGPenabled) {
sgp.begin();
sgp.setIAQBaseline(0x99AF, 0x99AF); // (CO2_base , TVOC_base)
}
attachInterrupt(0, Clap, FALLING);
sht31.heater(false);
}
unsigned long t1 = 0; // holds info of rapid claps
unsigned long t2 = 0; // prevents wrong trigger of single clap
unsigned long currenttime;
void Clap() {
currenttime = millis();
if (currenttime - t2 < 100) {
t2 = currenttime; return;
}
if (!HeaterState) {
HeaterState = true;
counter = 80;
} else if (HeaterState) {
counter = 0;
}
if (currenttime - t1 <= 1000) {
EEPROM.write(0,!SGPenabled);
void(* resetFunc) (void) = 0;
resetFunc();
} else t1 = currenttime;
t2 = currenttime;
}
void loop() {
t = sht31.readTemperature();
h = sht31.readHumidity();
if (SGPenabled) {
sgp.setHumidity(getAbsoluteHumidity(t, h));
sgp.IAQmeasure();
}
displayMEAS(); delay(500);
while (HeaterState) {
if (sht31.isHeaterEnabled() == 0)
sht31.heater(true);
displayHEAT();
counter--;
if (counter<=0)
HeaterState = false;
if (counter<=40) {
if (sht31.isHeaterEnabled())
sht31.heater(false);
}
delay(1000);
}
}
bool first15 = true;
void displayMEAS() {
u8g.firstPage();
do {
if (SGPenabled) {
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 0, 10, "Temp:"); u8g.drawStr( 70, 10, "Hum:");
u8g.drawStr( 0, 45, "TVOC(ppb):"); u8g.drawStr( 70, 45, "eCO2(ppm):");
if (!first15) {
u8g.setPrintPos(0, 64);
u8g.setFont(u8g_font_fub14); // u8g_font_tpssb u8g_font_9x18B u8g_font_courB12 u8g_font_fub17
u8g.print(sgp.TVOC);
u8g.setPrintPos(70, 64);
u8g.print(sgp.eCO2);
} else {
u8g.setPrintPos(0, 64);
u8g.setFont(u8g_font_fub14);
u8g.print("...");
u8g.setPrintPos(70, 64);
u8g.print("...");
}
u8g.setPrintPos(0, 30);
u8g.print(t);
u8g.setPrintPos(70, 30);
u8g.print(h);
u8g.setFont(u8g_font_7x14B);
u8g.drawStr( 122, 30, "%"); // Hum
u8g.setFont(u8g_font_fub11);
u8g.drawStr( 52, 30, "C"); // Temp
} else {
u8g.setFont(u8g_font_fub11);
u8g.drawStr( 0, 30, "Temp: *C");
u8g.drawStr( 10, 57, "Hum: %");
u8g.setFont(u8g_font_fub14);
u8g.setPrintPos(52, 30);
u8g.print(t);
u8g.setPrintPos(52, 57);
u8g.print(h);
}
} while(u8g.nextPage());
if (first15) {
counter2++;
if (counter2>=23)
first15=false;
}
}
void displayHEAT() {
u8g.firstPage();
do {
u8g.setFont(u8g_font_fub11);
u8g.drawStr( 15, 15, "Evaporating"); u8g.drawStr( 10, 35, "Condensation");
u8g.setPrintPos(60, 60);
if (counter != 0)
u8g.print(counter);
else
u8g.drawStr( 15, 60, "CANCELLED!");
} while(u8g.nextPage());
}
void preparesecreen() {
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
}
Experiences:
- The whole system works normal when SHT31 is brand new for some time.
- SHT31 stops working after some time where I reupload adjusted codes and it halts the code at
sht31.begin(0x44)
. - The system works normally when SHT31 is unplugged, the code doesn't halt, it displays "nan" for temperature and humidity of course.
- The test code for SHT31 by Adafruit also halts at
sht31.begin(0x44)
and it doesn't give error an message. - Many libraries are tried but all of them halt at the start, only the "sht31 test" can be read from serial monitor.
- SHT31 does work for a single time when it has been unpowered for a long time, but it halts the code after the first reading, the readings are reasonable if I can feel the temperature correctly.
My Diagnosis: The sensor is electrically fine, it is not broken. Maybe the OLED secreen or SGP30 is incompatible to work with SHT31. Maybe a register is being wrongly written for SHT31 and it stops it. A code fix would remedy the problem.
Physical Photo: The connections seem loose, I will definitely not going to use jumpers again. I will connect JST to headers always. But in this case I checked with a multimeter, and everything is fine.
My Request: I would be glad if a hard coder could solve the issue by making changes in the Adafruit library. As is obvious from my code, my coding skills are far from great.
Plus: There is a similar problem here; Adafruit stuff was unable to solve it and the problem is left unsolved: Adafruit forum question link
0x45
? \$\endgroup\$