SHT41 Arduino ESP32 Guide: Wiring, I2C Code and Troubleshooting

The direct answer

Connect the SHT41 breakout to the classic ESP32 using 3.3 V, GND, GPIO21 (SDA) and GPIO22 (SCL).

Then follow this sequence: scan for 0x44 → send 0xFD → wait for conversion → read six bytes → verify both CRCs. The two sketches below take you through the scan and measurement separately.

NYFEA supplies electronic components, including temperature and humidity sensors. This guide is for engineers bringing up an Espressif ESP32-DevKitC with an Adafruit SHT41 breakout (product 5776) in Arduino IDE. Steps 1–4 lead to temperature and humidity output in Serial Monitor. Step 5 checks whether the assembled device measures the intended air. If a read fails, use the troubleshooting table.

ESP32 and SHT41 breakout arranged for a four-wire I2C connection
ESP32 and SHT41 bench layout; use the connection table below for the pin assignments.

What you need

  • An Espressif ESP32-DevKitC with a classic ESP32
  • An Adafruit SHT41 breakout (product 5776)
  • Jumper wires
  • A USB data cable
  • A computer with Arduino IDE

The example uses GPIO21 for SDA and GPIO22 for SCL. Pin assignments can differ on ESP32-S3, ESP32-C3, ESP32-H2 and individual development boards. Check the pinout for your exact board before adapting the sketches.

Check the breakout board before connecting power

Check the chip and the breakout separately. The SHT41 chip operates from 1.08 V to 3.6 V. A breakout may add a regulator, pull-ups or level shifting; its input requirements depend on that board's circuit.

For the Adafruit breakout used here:

  • Power: connect ESP32 3V3 to the breakout's VIN, not its 3V regulator output.
  • I²C: SDA and SCL already include level shifting and 10 kΩ pull-ups.
  • Another module: verify its schematic and printed pin labels before using this connection table.

Check existing pull-ups before adding more. Parallel pull-ups reduce the effective resistance and increase the current a device must sink when it pulls the line low. The named breakout already has a pair.

SHT41 bare-chip supply and external components compared with the regulator, level shifting and pull-ups on a breakout board
Chip and board functions compared. For the Adafruit breakout in this guide, connect ESP32 3V3 to VIN; use the wiring diagram below for connections. Breakout pin reference

Step 1: Wire the SHT41 to the ESP32

Disconnect USB power before making the connections.

Adafruit SHT41 breakout ESP32-DevKitC Function
VIN 3V3 Breakout supply
GND GND Common ground
SDA GPIO21 I²C data
SCL GPIO22 I²C clock
Four-wire board-level wiring from a classic ESP32-DevKitC to an Adafruit SHT41 breakout: 3V3 to VIN, GND to GND, GPIO21 to SDA, and GPIO22 to SCL
Board-level wiring for the named ESP32-DevKitC and Adafruit SHT41 breakout. Match pin labels on your physical boards before applying power.

Check that:

  • SDA connects to SDA and SCL connects to SCL.
  • The sensor board and ESP32 share ground.
  • The breakout's pull-ups connect to a voltage suitable for both devices.
  • The GPIO numbers match the actual ESP32 board.

Reconnect USB power after checking the wiring. See Adafruit's breakout pinout and Espressif's Arduino I²C pin guidance.

Step 2: Prepare Arduino IDE

  1. Install Arduino IDE and add the ESP32 board package using the Espressif installation instructions.
  2. Connect the ESP32 with a USB data cable.
  3. In Tools → Board, select the board that matches your ESP32.
  4. In Tools → Port, select the port associated with the board.
  5. After uploading a sketch, open Tools → Serial Monitor and set the baud rate to 115200.

If no serial port appears, check the USB cable, USB connection and any driver requirements for your development board.

Library setup: both sketches use Wire, which comes with the ESP32 board package. No separate SHT41 library installation is needed.

Step 3: Scan the I²C bus

The named Adafruit SHT41 breakout uses the 7-bit address 0x44. Start with a scan to check whether a device acknowledges that address. Both sketches set the I²C clock to 100 kHz; change the pin definitions if your ESP32 board uses different SDA/SCL pins.

Upload this scanner as a separate sketch:

I²C address scanner · Arduino
#include <Wire.h>

constexpr int SDA_PIN = 21;  // Classic ESP32 DevKit
constexpr int SCL_PIN = 22;

void setup() {
  Serial.begin(115200);

  if (!Wire.begin(SDA_PIN, SCL_PIN, 100000)) {
    Serial.println("I2C initialization failed.");
    while (true) {
      delay(1000);
    }
  }

  delay(10);
  Serial.println("Scanning I2C bus...");

  unsigned int found = 0;

  for (uint8_t address = 1; address < 127; ++address) {
    Wire.beginTransmission(address);
    uint8_t status = Wire.endTransmission();

    if (status == 0) {
      Serial.print("Device acknowledged at 0x");

      if (address < 0x10) {
        Serial.print("0");
      }

      Serial.println(address, HEX);
      ++found;
    }
  }

  if (found == 0) {
    Serial.println("No I2C devices acknowledged.");
  } else {
    Serial.println("Scan complete.");
  }
}

void loop() {
}

Open Serial Monitor at 115200 baud and check the scanner output:

  • 0x44 appears: a device acknowledged at that address. Continue to the measurement sketch.
  • No device appears: check supply voltage at the breakout, common ground, SDA and SCL wiring, pull-ups and the GPIO definitions.
  • A different address appears: identify the device and check the exact sensor ordering code and breakout documentation.

What the scan proves: a device acknowledged an address. The next sketch checks whether a complete measurement can be read with valid CRCs.

Step 4: Read temperature and humidity

Once the scanner finds 0x44, replace the scanner sketch with the measurement sketch below. It sends 0xFD, waits for conversion and reads the six-byte response shown in this table.

Response bytes Meaning
0–1 Raw temperature
2 Temperature CRC
3–4 Raw relative humidity
5 Humidity CRC

The sketch verifies each CRC before converting and printing the readings.

SHT41 measurement with CRC · Arduino
#include <Wire.h>

constexpr uint8_t SHT41_ADDRESS = 0x44;  // SHT41 breakout, 7-bit address
constexpr int SDA_PIN = 21;              // Classic ESP32 DevKit
constexpr int SCL_PIN = 22;
constexpr uint32_t I2C_FREQUENCY = 100000;

uint8_t sht41Crc(const uint8_t *data, size_t length) {
  uint8_t crc = 0xFF;

  for (size_t i = 0; i < length; ++i) {
    crc ^= data[i];

    for (uint8_t bit = 0; bit < 8; ++bit) {
      if (crc & 0x80) {
        crc = (uint8_t)((crc << 1) ^ 0x31);
      } else {
        crc = (uint8_t)(crc << 1);
      }
    }
  }

  return crc;
}

bool readSht41(float &temperatureC, float &humidityRH) {
  // Start a high-repeatability measurement.
  Wire.beginTransmission(SHT41_ADDRESS);
  Wire.write((uint8_t)0xFD);

  uint8_t status = Wire.endTransmission();

  if (status != 0) {
    Serial.print("SHT41 command failed; I2C status: ");
    Serial.println(status);
    return false;
  }

  // Wait for the sensor to complete the measurement.
  delay(10);

  uint8_t received = Wire.requestFrom(SHT41_ADDRESS, (uint8_t)6);

  if (received != 6) {
    Serial.print("Incomplete SHT41 response; bytes received: ");
    Serial.println(received);

    while (Wire.available()) {
      Wire.read();
    }

    return false;
  }

  uint8_t data[6];

  for (uint8_t i = 0; i < 6; ++i) {
    data[i] = (uint8_t)Wire.read();
  }

  if (sht41Crc(&data[0], 2) != data[2]) {
    Serial.println("Temperature CRC check failed.");
    return false;
  }

  if (sht41Crc(&data[3], 2) != data[5]) {
    Serial.println("Humidity CRC check failed.");
    return false;
  }

  uint16_t rawTemperature = ((uint16_t)data[0] << 8) | data[1];
  uint16_t rawHumidity = ((uint16_t)data[3] << 8) | data[4];

  temperatureC = -45.0f + 175.0f * rawTemperature / 65535.0f;
  humidityRH = -6.0f + 125.0f * rawHumidity / 65535.0f;

  // Limit the displayed value to the physical RH range.
  if (humidityRH < 0.0f) {
    humidityRH = 0.0f;
  }

  if (humidityRH > 100.0f) {
    humidityRH = 100.0f;
  }

  return true;
}

void setup() {
  Serial.begin(115200);

  if (!Wire.begin(SDA_PIN, SCL_PIN, I2C_FREQUENCY)) {
    Serial.println("I2C initialization failed. Check the selected pins.");

    while (true) {
      delay(1000);
    }
  }

  // Allow a normally powered sensor time to start.
  delay(10);
  Serial.println("SHT41 measurement started.");
}

void loop() {
  float temperatureC;
  float humidityRH;

  if (readSht41(temperatureC, humidityRH)) {
    Serial.print("Temperature: ");
    Serial.print(temperatureC, 2);
    Serial.print(" °C   Humidity: ");
    Serial.print(humidityRH, 2);
    Serial.println(" %RH");
  } else {
    Serial.println("Measurement unavailable; retrying.");
  }

  delay(2000);
}

What success looks like: at 115200 baud, Serial Monitor prints temperature in °C and humidity in %RH. The sketch prints readings only after both CRC checks pass. If you get an error instead, use the matching symptom in the troubleshooting table. The example repeats the measurement every two seconds.

The displayed humidity is limited to 0–100% RH. If your application needs to investigate behavior near the range limits, retain the calculated value before clamping as a separate diagnostic value.

Step 5: Check readings in the finished assembly

Receiving data is the first milestone. Now check whether the sensor measures the intended air after installation. Compare it with a suitable reference under the same operating conditions.

Compare three assembly conditions: keep the sampling interval and reference arrangement consistent, and let each setup settle.

  1. Outside the enclosure: read the sensor away from obvious heat sources.
  2. Enclosure open: mount the sensor in its intended position and repeat the reading.
  3. Enclosure closed: operate the complete product normally and repeat the reading.
  4. Compare the results: investigate any change before applying a software offset.

If the reading changes after assembly, inspect the air path, nearby electronics and enclosure materials before applying a fixed software offset.

Full breadboard prototype scene with a classic ESP32 board, small SHT41 sensor module and OLED display
ESP32, SHT41 module and OLED in a breadboard prototype.

The OLED in this prototype is an optional display and needs separate code. The supplied sketches use Serial Monitor.

Illustrated wall-mounted temperature and humidity monitor with a separate vented sensor board
Separating the sensing area from warmer electronics helps the sensor sample the intended air.

For more detail on sensor placement and airflow, see SHT40 Enclosure Design: Airflow, Protection and Response Time.

Why does the sketch wait 10 ms?

The SHT4x datasheet specifies a high-repeatability measurement duration of 6.9 ms typical and 8.3 ms maximum. This sketch waits 10 ms after sending 0xFD before requesting the response.

The sensor also needs time to complete power-up. If your design switches the sensor supply separately from the ESP32, wait until the supply is stable and the sensor has completed its power-up interval before sending a command.

The example uses a blocking delay(10). A design that needs to perform other work during conversion can use a nonblocking state machine while maintaining the required wait.

Why can a read request return no data?

If a read returns no bytes, check two timing rules:

  • Wait before reading. During conversion, the SHT41 responds to a read request with a NACK. It does not hold the bus using clock stretching.
  • Start a new measurement for each sample. A result is available for one acknowledged read. Send a new 0xFD command and wait before requesting the next result.

If the scanner finds 0x44 but measurement reads fail, check this sequence alongside the wiring. See SHT4x datasheet, section 4.1.

How to troubleshoot an SHT41 on ESP32

Find the symptom that matches your setup and follow its next action. Work from power and wiring → address response → complete read → CRC → measurement conditions; stop at the first stage that fails.

What you see First checks Next action
No I²C device found Supply, ground, SDA, SCL, pull-ups and GPIO selection Measure the sensor board supply and repeat the scan.
0x44 appears, but the command fails Address and the pins used in the measurement sketch Confirm that the measurement sketch uses the same wiring and pins as the scanner.
Fewer than six bytes received Command success, conversion wait and bus connection Verify the 0xFD command and wait; inspect wiring and pull-ups.
Temperature or humidity CRC fails Loose connections, bus loading and pull-up voltage Check the electrical connection and repeat the read with both CRC checks enabled.
Valid readings appear but seem too warm Nearby electronics and sensor position Move the sensor away from heat sources and compare it with a suitable reference.
Humidity responds slowly in the enclosure Air path and placement Check whether ambient air reaches the sensing opening.
Serial Monitor is empty Baud rate, port, USB cable and upload Select 115200, verify the port and confirm that the sketch uploaded.
Engineer inspecting an ESP32 and small SHT41 breakout during I2C troubleshooting
Check the supply and jumper connections before changing the I²C code.

What does a passing CRC tell you?

A passing CRC means the received data word passed its checksum. It helps detect transfer errors between the sensor and ESP32.

Quick CRC check: input bytes 0xBE 0xEF should produce 0x92, using initial value 0xFF and polynomial 0x31. This datasheet test vector lets you check the CRC function independently of the bus.

A valid transfer does not establish measurement accuracy. Sensor placement, enclosure airflow and the reference instrument still need separate checks.

Why does Arduino use 0x44 instead of 0x88?

0x44 is the 7-bit I²C address for the named SHT41 breakout. Arduino Wire accepts the 7-bit address and handles the read/write bit during the transaction.

Use the address documented for the exact sensor ordering code on your board.

Designing a PCB around the bare SHT41

The drawing below is a bare-chip PCB reference on a shared 3.3 V rail. It is a different circuit from the regulated Adafruit breakout.

  • Supply and ground: keep the chip supply within 1.08–3.6 V and provide a common ground.
  • Decoupling: the drawing shows a 100 nF capacitor between VDD and VSS near the sensor. Treat this as the circuit shown here; check the requirements of your actual PCB.
  • Bus pull-ups: choose SDA/SCL resistors for the rail voltage, bus capacitance and target speed. The shown 10 kΩ values are starting points; include any other pull-ups on the bus in the calculation.

The SHT4x datasheet, section 5.4 identifies the bare-chip pins as 1 SDA, 2 SCL, 3 VDD and 4 VSS. Use its package drawing and pin-1 indicator to orient the physical part; the box below shows electrical connections, not the package top view.

The Adafruit breakout already contains regulation, level shifting and pull-ups. Use the earlier four-wire connection table for that board.

Bare SHT41 reference circuit on a 3.3 V rail with 100 nF VDD-to-VSS capacitor, I2C pull-ups and pin numbers 1 SDA, 2 SCL, 3 VDD and 4 VSS
Bare-chip reference circuit for a custom 3.3 V PCB. The Adafruit breakout already includes supporting circuitry.

Frequently asked questions

Can I use the sketches with an ESP32-S3 or ESP32-C3?

The SHT41 measurement sequence can be adapted to other Arduino-compatible ESP32 boards. Select the correct board in Arduino IDE, choose available SDA and SCL pins, and change the pin definitions in both sketches to match the wiring.

Can I power an SHT41 from 5 V?

The SHT41 chip is specified for a maximum operating supply of 3.6 V. A particular breakout may accept 5 V at its input if its design includes suitable regulation. Check that board's documentation and its I²C voltage requirements before connecting it.

Is an I²C scan enough to verify the sensor?

No. Follow the scan with a measurement command, a complete six-byte read and both CRC checks. Then compare the measurement with an appropriate reference in the intended application.

Can I use a sensor library instead?

Yes. Sensirion provides an SHT4x Arduino library. Check its installation instructions, dependencies and example configuration for your board and sensor address.

From a working sketch to a product decision

A passing CRC and plausible serial output establish a useful bring-up point. Before release, verify the selected board's power rail, bus loading, sensor position, airflow, error recovery and assembled-product accuracy under the intended conditions.

Selecting a sensor for a new design? NYFEA FHT41 is a candidate for evaluation. Compare its published supply limits, I²C command behavior, timing, CRC, accuracy conditions, package and pinout against your design requirements. Similar function or address does not establish firmware or drop-in compatibility.

Consider FHT41 for your design · Discuss an engineering evaluation

Technical references

More Product Selection

NYFEA FHT30 digital temperature and humidity sensor

FHT30

FHT30 targets digital temperature and relative-humidity measurement where dual I²C addresses, periodic acquisition, an alert output and a compact open-cavity package are useful.

Learn More
NYFEA FHT31 digital temperature and humidity sensor

FHT31

The ±2%RH and ±0.2 °C figures are typical values, not guaranteed maximum limits across every temperature and humidity combination. Use the tolerance plots, response time, drift, chemical limits and assembled-product tests when setting a system accuracy claim.

Learn More
NYFEA FHT40 digital temperature and humidity sensor

FHT40

Typical accuracy is not a universal maximum. Review the humidity/temperature tolerance maps, response time, drift, chemical exposure, self-heating and mechanical placement before setting an end-product accuracy claim.

Learn More
NYFEA FHT41 digital temperature and humidity sensor

FHT41

FHT41 is a high-precision digital temperature and humidity sensor for low-power systems. Its compact package, selectable repeatability and integrated heater support space-constrained consumer, cabin and industrial designs.

Learn More
NYFEA FHTC3 digital temperature and humidity sensor

FHTC3

FHTC3 is a factory-calibrated digital sensor for simultaneous temperature and relative-humidity measurement. Its low standby current, two measurement-power modes and small leadless package suit compact connected products.

Learn More
NYFEA FT18B20 digital temperature sensor

FT18B20

FT18B20 is intended for direct digital temperature measurement on a single-drop or multidrop 1-Wire bus. Its ROM identity, alarm search, configurable conversion time and optional two-wire parasite-power connection suit distributed temperature sensing.

Learn More
© 2023 All Rights Reserved. www.nyfea.com Terms of Use | Privacy Policy