XIAO ESP32S3 Deep Sleep cannot wake up after random cycles

I’m using deep sleep to wake up xiao esp32s3 and send some data from sensor via lora every 300 seconds. But after random power cycles, xiao esp32s3 will stop working and cannot wake up anymore, no matter how long I wait. I powered it with battery, and there is still sufficient voltage (4v). Here is my code, any ideas?

#include <Wire.h>
#include "esp_sleep.h"
// #include "driver/rtc_io.h"
#include "config.h"

#define PD_PIN GPIO_NUM_3
#define I2C_ADDR 0x6D

float pressure;  // celsius
float temperature;  // gauge pressure in kPa

void setup() {
  // turn on debug led
  // pinMode(LED_BUILTIN, OUTPUT);
  // digitalWrite(LED_BUILTIN, LOW);
  
  // add watch dog
  esp_task_wdt_deinit();
  esp_task_wdt_init(&wdt_config);
  esp_task_wdt_add(NULL);

  // turn on sensor
  // rtc_gpio_deinit(PD_PIN);
  pinMode(PD_PIN, OUTPUT);
  digitalWrite(PD_PIN, LOW);
  Wire.begin();
  delay(5);

  // default interval
  uint32_t uplinkIntervalSeconds = 300UL;

  // init lora
  radio.begin();
  radio.setRfSwitchPins(38, RADIOLIB_NC);
  node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
  node.activateOTAA();
  node.setDwellTime(true, 400);

  // collect data
  uint8_t reg[0xD0] = {0};  
  if (readRegisters(0x00, reg, sizeof(reg))) {
    processSensorData(reg);
  }

  // package data
  uint8_t temperature_est = (uint8_t)(temperature + 128);
  uint16_t pressure_est = (pressure > 0) ? (uint16_t)pressure : 0;
  uint8_t uplinkPayload[3];
  uplinkPayload[0] = temperature_est;
  uplinkPayload[1] = highByte(pressure_est);
  uplinkPayload[2] = lowByte(pressure_est);
  
  // send data
  if (node.sendReceive(uplinkPayload, sizeof(uplinkPayload)) != RADIOLIB_ERR_NONE) {
    uplinkIntervalSeconds = 60UL;
  };
  
  // sleep
  radio.sleep();
  esp_sleep_enable_timer_wakeup(uplinkIntervalSeconds * 1000000UL);
  esp_deep_sleep_start();
}

void loop() {}

bool readRegisters(uint8_t startAddr, uint8_t *data, uint8_t length) {
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(startAddr);
  if(Wire.endTransmission() != 0) {
    return false;
  }
  
  Wire.requestFrom(I2C_ADDR, length);
  for(int i=0; i<length && Wire.available(); i++) {
    data[i] = Wire.read();
  }
  return true;
}

void processSensorData(uint8_t *Reg) {
  // pressure data
  int32_t pdata = (((uint32_t)Reg[0x06] << 16) | 
                 ((uint32_t)Reg[0x07] << 8) | 
                  Reg[0x08]) & 0xFFFFFF;
  if(Reg[0x06] & 0x80) pdata |= 0xFF000000;

  // temperature data
  int32_t tdata = (((uint32_t)Reg[0x09] << 16) | 
                 ((uint32_t)Reg[0x0A] << 8) | 
                  Reg[0x0B]) & 0xFFFFFF;
  if(Reg[0x09] & 0x80) tdata |= 0xFF000000;

  // calc temp in C
  temperature = (float)tdata / 65536.0 + 25.0;

  uint8_t decimal_places = (Reg[0xCF] >> 5) & 0x07;
  int16_t rangeL_raw = (Reg[0xC5] << 8) | Reg[0xC6];
  int16_t rangeH_raw = (Reg[0xC7] << 8) | Reg[0xC8];
  
  float rangeL = (float)rangeL_raw / pow(10, decimal_places);
  float rangeH = (float)rangeH_raw / pow(10, decimal_places);

  // calc pressure in MPa
  pressure = (rangeH - rangeL) * 
          ((float)(pdata - 8388608 * 0.1) / (8388608 * 0.8)) + 
           rangeL;

  // MPa to kPa
  pressure *= 1000;
}

Hi there,

So I see the GPIO 3 is what you are using and on the S3 that pin likes to be floating on Boot or it thinks its in JTAG mode. Can you try with a different pin and post a picture of the connections ?

HTH
GL :slight_smile: PJ :v:

strapping pins for the S3 a GPIO 0, 3, 45, 46 avoid using those when possible or be sure of there state when booting! :+1:

Thanks for your advice! I will change PD to GPIO 4 and see if it works. Here is my current connections:

Blue: PD ↔ GPIO3 (LOW enables sensor, HIGH disables sensor)
Green: SDA
Yello: SDL
Red: 3v3
Black: GND