CubeCell HTCC-AB01 V2.2 - I2C Sensor (SHTC3) fails when combined with LoRaWAN stack (Solved)

Hi everyone,

I am having trouble getting my SHTC3 temperature/humidity sensor to work on a Heltec CubeCell HTCC-AB01 V2.2 when using the LoRaWAN library.

The Setup:

  • Board: HTCC-AB01 V2.2 (SDA on GPIO 7, SCL on GPIO 6).
  • Sensor: SHTC3 (connected via I2C).
  • Power: Powered via the Vext pin.

The Problem: I have a simple test sketch (see below) that works perfectly. It initializes the sensor and prints correct values to the Serial Monitor. However, as soon as I integrate this into a LoRaWAN sketch (using the standard Heltec LoRaWAN library), the sensor fails to initialize or return values.

I get error codes like SHTC3_Status_ID_Fail (1) or SHTC3_Status_CRC_Fail (3) inside the prepareTxFrame function. It seems like the LoRaWAN stack or the sleep cycles are interfering with the I2C bus or the Vext power stability.

I have tried:

  1. Adding long delays after Vext LOW.
  2. Manual I2C recovery/bit-banging pulses before Wire.begin .
  3. Lowering the I2C clock speed.
  4. Keeping Vext active throughout the cycle.

Nothing seems to work once the LoRaWAN stack is active, even though the hardware is clearly fine.

#include "Arduino.h"
#include "SparkFun_SHTC3.h"

SHTC3 mySHTC3;              
float temperature, humidity;

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

  // Vext controls power to the sensor on CubeCell
  pinMode(Vext, OUTPUT);
  digitalWrite(Vext, LOW); // LOW activates power on AB01
  delay(500);              // Give sensor time to start

  // Using GPIO 7 and 6 for V2.2
  Wire.begin(7, 6); 
  
  Serial.println("SHTC3 Test on CubeCell AB01");

  SHTC3_Status_TypeDef result = mySHTC3.begin();
  if (result != SHTC3_Status_Nominal) {
    Serial.println("Could not find SHTC3 sensor!");
  } else {
    Serial.println("SHTC3 found!");
  }
}

void loop() {
  SHTC3_Status_TypeDef result = mySHTC3.update();

  if (result == SHTC3_Status_Nominal) {
    temperature = mySHTC3.toDegC();    
    humidity = mySHTC3.toPercent();    

    Serial.print("Temp: ");
    Serial.print(temperature);
    Serial.print(" °C | Hum: ");
    Serial.print(humidity);
    Serial.println(" %");
  } else {
    Serial.print("Read error. Code: ");
    Serial.println(result);
  }

  delay(2000); 
}

Hopefull to be pointed in the right direction

Part of the problem with he Heltec libraries is that some of them do things internally that have nothing to do with their apparent function, like change the state of Vext or possibly even the I2C bus.

You could try explicitly turning Vext on each time you read the sensor and even explicitly starting and stopping the I2C bus (Wire.begin./Wire.end) each time you use the sensor. The latter will certainly be required if you’re using sleep mode—you will generally need to initialise everything any time you come out of sleep mode.

I use the I2C bus in conjunction with the LoRaWAN library in several CubeCell (V1, V2, V2.2) applications, although not with the specific sensor you are using, so it’s unlikely to be a fundamental hardware problem.

If none of that gets you anywhere, you could try using the RadioLib library. I’ve not used that with the CubeCell platform yet, but I have started using it with the Heltec ESP32 products to avoid these sorts of problems.

If I recall correctly, @BNS wasn’t very keen on some timing aspects but I’ll let me provide some details.

The CubeCell crystal is wildly off, it drifts like 20ms every 1000ms or so. RadioLib can live with that, but then the CubeCell secretly uses a 16-bit value for its millis() even though it says it’s 32-bit. Or something like that.
Heltec or whoever somehow managed to make a working LoRaWAN stack for this, but RadioLib requires a 32-bit clock with a 32-bit value or a 16-bit clock with a 16-bit value. I’ve gotten as far as a join and a handful of uplinks but then the clock rolls over in a weird fashion and it’s game over. I’ve personally given up on getting RadioLib running for this platform unfortunately.

Hi everyone,

I’m happy to report that I finally solved the issue where the sensor worked in a standalone sketch but failed when integrated with the LoRaWAN stack.

The Solution:

1. Hardware Change: Switched to SHT31 After struggling with the SHTC3 and getting constant ID_Fail or CRC_Fail errors, I decided to switch the sensor to an SHT31 . The SHT31 is more robust and better suited for this application.

2. Library Version (Critical Fix for nullptr) When using the Adafruit SHT31 library on the CubeCell/ESP32 architecture, newer versions can sometimes cause nullptr errors or crashes. I downgraded to version 1.0.0 of the Adafruit SHT31 library , which is much more stable for this specific hardware and resolved the crashes.

3. The Vext & I2C Timing The main problem was that Wire.begin() was being called before the sensor had properly stabilized after receiving power from Vext . Here is the specific sequence that worked:

  1. Set Vext to LOW (Power ON).
  2. Wait 1200ms (Essential for the sensor to boot from a cold start).
  3. Call Wire.begin(7, 6) AFTER the delay.
  4. Perform the measurement.
  5. Call Wire.end() and set Vext to HIGH (Power OFF) before entering sleep.

Example Code Snippet:

void doMeasurement() {
pinMode(Vext, OUTPUT);
digitalWrite(Vext, LOW); // Power up sensor
delay(1200); // Wait for SHT31 to wake up

Wire.begin(7, 6); // Initialize I2C on CubeCell pins
delay(100);

// Using Adafruit SHT31 Library v1.0.0
if (sht31.begin(0x44)) {
float t = sht31.readTemperature();
float h = sht31.readHumidity();

if (!isnan(t)) {
temperature = (int16_t)(t * 100);
humidity = (int16_t)(h * 100);
}
} else {
Serial.println(“SHT31 not found!”);
}

digitalWrite(Vext, HIGH); // Power down
Wire.end(); // Release I2C pins for deep sleep
}

By switching to the SHT31, using library version 1.0.0, and properly managing the Vext power cycle, the device is now 100% stable. Thanks for all the help!