Connection issues between ESP32-S2 board and SHTC3 humidity sensor

I am having an issue getting readings from the SparkFun Humidity Sensor Breakout - SHTC3 (SKU: SEN-16467) when using the SparkFun Thing Plus - ESP32-S2 WROOM (SKU: WRL-17743). Oddly, the SHTC3 works and gets readings when paired with an Arduino, and the ESP32-S2 works and produces outputs for other QWIIC sensors. I have tried both the QWIIC connection as well as SCL → SCL, SDA→ SDA, GND→ GND, and 3.3V→ 3.3V after soldering headers onto both the sensor breakout and the ESP32-S2. Additionally, the error that I’m receiving is the same as the error when the ESP32-S2 is not connected to anything. So, it seems as though the board is not registering that it is connected to the SHTC3 sensor, despite the LED indicating that the SHTC3 is receiving power.

I am using the arduino library for the SHTC3 downloaded from github directly from the hookup guide and this is the error I am receiving:

“Update failed, error: Error E (37867) i2c.master: I2C transaction timeout detected E (37867) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed E (37868) i2c.master: i2c_master_multi_buffer_transmit(1214): I2C transaction failed: /*”

Are the pullup resistors still in place on the SHTC3 ?

Try an I2c scanner to see it is still detected (0x70) ?

The pullup resistors are still in place and when I ran an I2c scanner, it outputted “I2C device found at address 0x70”

The pull-up resistors were initially still in place on the SHTC3. We also tried troubleshooting with the removal of one pullup resistor, and then with the removal of both pullup resistors. We bought an additional SHTC3 so that we now have one breakout board with both pull up resistors attached and one with both removed.

  1. The ESP32-S2 may not be using the correct I2C pins. Unlike Arduinos, ESP32 sometimes requires explicit pin definitions.

Try this in your code:

#include <Wire.h>
#include "SparkFun_SHTC3.h"

SHTC3 mySHTC3;

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  // Explicitly define I2C pins for ESP32-S2 Thing Plus
  Wire.begin(SDA, SCL); // Default should be GPIO 21 (SDA) and GPIO 22 (SCL)
  // OR try:
  Wire.begin(21, 22); // Explicitly set pins
  
  Wire.setClock(100000); // Start with 100kHz (see point 2)
  
  if(mySHTC3.begin() != SHTC3_Status_Nominal) {
    Serial.println("SHTC3 not detected");
  } else {
    Serial.println("SHTC3 detected!");
  }
}
  1. The ESP32’s default I2C speed might be too fast for your setup, especially with longer wires or breadboard connections.

Try adding this after Wire.begin():

Wire.setClock(100000); // Reduce to 100kHz (default is often 400kHz)
  1. Maybe see if internal pullup are enabled, if so try disabling and re-attempt

Hello,

We attempted the explicit pin settings and default settings, and both did not work with and without the clock reduction. We received the error: “Update failed, error: Error E (37867) i2c.master: I2C transaction timeout detected E (37867) i2c.master: s_i2c_synchronous_transaction(945): I2C transaction failed E (37868) i2c.master: i2c_master_multi_buffer_transmit(1214): I2C transaction failed: /*” when using the code:

/*
Take humidity and temperature readings with the SHTC3 using I2C
By: Owen Lyke
SparkFun Electronics
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
Example1_BasicReadings
To connect the sensor to an Arduino:
This library supports the sensor using the I2C protocol
On Qwiic enabled boards simply connnect the sensor with a Qwiic cable and it is set to go
On non-qwiic boards you will need to connect 4 wires between the sensor and the host board
(Arduino pin) = (Display pin)
SCL = SCL on display carrier
SDA = SDA
GND = GND
3.3V = 3.3V
*/

#include “SparkFun_SHTC3.h” // Click here to get the library: http://librarymanager/All#SparkFun_SHTC3
#include <Wire.h>
#include “SparkFun_SHTC3.h”

SHTC3 mySHTC3;

void setup() {
Serial.begin(115200);
delay(1000);
// Explicitly define I2C pins for ESP32-S2 Thing Plus
//Wire.begin(SDA, SCL); // Default should be GPIO 21 (SDA) and GPIO 22 (SCL)
// OR try:
Wire.begin(21, 22); // Explicitly set pins
Wire.setClock(100000); // Start with 100kHz (see point 2)
if(mySHTC3.begin() != SHTC3_Status_Nominal) {
Serial.println(“SHTC3 not detected”);
} else {
Serial.println(“SHTC3 detected!”);
}
}

void loop() {
SHTC3_Status_TypeDef result = mySHTC3.update(); // Call “update()” to command a measurement, wait for measurement to complete, and update the RH and T members of the object
printInfo(); // This function is used to print a nice little line of info to the serial port
delay(190); // Delay for the data rate you want - note that measurements take ~10 ms so the fastest data rate is 100 Hz (when no delay is used)
}

///////////////////////
// Utility Functions //
///////////////////////
void printInfo()
{
if(mySHTC3.lastStatus == SHTC3_Status_Nominal) // You can also assess the status of the last command by checking the “.lastStatus” member of the object
{
Serial.print(“RH = “);
Serial.print(mySHTC3.toPercent()); // “toPercent” returns the percent humidity as a floating point number
Serial.print(”%, T = “);
Serial.print(mySHTC3.toDegF()); // “toDegF” and “toDegC” return the temperature as a flaoting point number in deg F and deg C respectively
Serial.println(” deg F”);
}
else
{
Serial.print("Update failed, error: ");
errorDecoder(mySHTC3.lastStatus);
Serial.println();
}
}

void errorDecoder(SHTC3_Status_TypeDef message) // The errorDecoder function prints “SHTC3_Status_TypeDef” resultsin a human-friendly way
{
switch(message)
{
case SHTC3_Status_Nominal : Serial.print(“Nominal”); break;
case SHTC3_Status_Error : Serial.print(“Error”); break;
case SHTC3_Status_CRC_Fail : Serial.print(“CRC Fail”); break;
default : Serial.print(“Unknown return code”); break;
}
}

We are not quite sure how to see if internal pullup are enabled, if so try disabling and re-attempt. We used pinMode(21, INPUT); pinMode(22,INPUT) before the Wire.begin, ran the code, and then repeated with pinMode(21, INPUT_PULLUP); pinMode(22, INPUT_PULLUP);, and received an error message for both.

Overall, we are wanting to integrate the SparkFun Air Quality PM1/PM2.5/PM10 Sensor - BMV080 (Qwiic) (SKU: SEN-26554), SparkFun Air Quality Sensor - SGP40 (Qwiic) (SKU: SEN-18345), SparkFun Humidity Sensor Breakout - SHTC3 (Qwiic) (SKU: SEN-16467) on one microcontroller board. Currently, the Air Quality Sensor and the Humidity Sensor both work with an Arduino Uno R4 Wifi, but the PM sensor does not. Additionally, the Air Quality Sensor and the PM sensor both work with the SparkFun Thing Plus - ESP32-S2 WROOM (SKU: WRL-17743), but the Humidity sensor does not.

We purchased the SparkFun Thing Plus - ESP32-S2 WROOM (SKU: WRL-17743) because we thought it would work with all three. Is there another development board that is guaranteed to work with all three of these sensors?

Looking at the source code the SHTC3 library only supports reading the SHTC3 with CLOCK STRETCHING. The STHC3 library is using SHTC3_CMD_CSE_RHF_NPM by default (clock stretching enabled, Read High byte First, Non-Polling)

While the EPS32-S2 supports clock stretching, there might be an issue with the ESP32 package library.

According to the page : Inter-Integrated Circuit (I2C) - ESP32-S2 - — ESP-IDF Programming Guide latest documentation , scl_wait_us needs to be set to define the wait time.

Looking at board package : esp32/3.2.1/cores/esp32/esp-hal-i2c-ng.cpp, around line 213 / fnction i2cAddDeviceIfNeeded, the value is set to 0 (zero). Hence use the “default register value”. During I2C_init this is set with i2c_set_timeout() to I2C_LL_MAX_TIMEOUT, defined as 0xffff or about 13ms.

Looks like some other person had issues with that, see: unexpected I2C timeout.

So maybe try include the i2c_set_timeout() in the wire library, or try to change esp32/3.2.1/cores/esp32/esp-hal-i2c-ng.cpp the value from 0 to 0xffff.

1 Like