XIAO ESP32S3 rebooting when trying to run code

Hey! I’m working on a school project that’s a self driving RC car powered by an ESP32 but I’ve run into an issue where the Xiao boot loops after uploading the code.
Here’s the error message I usually got after the Xiao rebooted:

EPC1    : 0x4203aa97  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x4200725e


Backtrace: 0x4200725b:0x3fc93d10 0x42002810:0x3fc93d30 0x4203a5fd:0x3fc93d50 0x403752a1:0x3fc93d70 0x403752c6:0x3fc93d90 0x403783bd:0x3fc93db0 0x40377b21:0x3fcebdb0 0x4037daa6:0x3fcebdc0 0x4037b4d5:0x3fcebde0 0x4200524e:0x3fcebe20 0x420056ef:0x3fcebe50 0x420057a1:0x3fcebe70 0x42002b47:0x3fcebe90 0x420071e9:0x3fcebee0


Core  0 register dump:
PC      : 0x4203b036  PS      : 0x00060434  A0      : 0x8200c599  A1      : 0x3fcf46e0  
A2      : 0x00000000  A3      : 0x42028640  A4      : 0x00060120  A5      : 0x80000000  
A6      : 0x02c93de0  A7      : 0x00ffffff  A8      : 0x8200c02e  A9      : 0x3fcf46b0  
A10     : 0x00000000  A11     : 0x3fc93dd0  A12     : 0x3fc93dd0  A13     : 0x00000000  
A14     : 0x00060120  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  


Backtrace: 0x4203b033:0x3fcf46e0 0x4200c596:0x3fcf4700 0x4037bf08:0x3fcf4720




ELF file SHA256: 65743e7570fe92ce

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x40382597  PS      : 0x00020034  A0      : 0x8202392a  A1      : 0x3fc93b20  
A2      : 0x00020023  A3      : 0xa5a5a5a5  A4      : 0x8202392a  A5      : 0x00060025  
A6      : 0xfffbfff0  A7      : 0x00000046  A8      : 0x3fc94188  A9      : 0x00000001  
A10     : 0x60000000  A11     : 0x00000001  A12     : 0x0000000a  A13     : 0x3fc93b0c  
A14     : 0x00000001  A15     : 0x3fcf4720  SAR     : 0x0000000a  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400570e8  LEND    : 0x400570f3  LCOUNT  : 0x00000000  
Core  1 was running in ISR context:
EPC1    : 0x4203aa97  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40382597


Backtrace: 0x40382594:0x3fc93b20 0x42023927:0x3fc93b30 0x42023f29:0x3fc93b50 0x4200ca6e:0x3fc93b70 0x4200cd4a:0x3fc93be0 0x40377221:0x3fc93c30 0x40376bb0:0x3fc93c50 0x00040022:0x3fc93d10 |<-CORRUPTED


Core  0 register dump:
PC      : 0x4203b036  PS      : 0x00060434  A0      : 0x8200c599  A1      : 0x3fcf46e0  
A2      : 0x00000000  A3      : 0x42028640  A4      : 0x00060120  A5      : 0x80000000  
A6      : 0x02c93de0  A7      : 0x00ffffff  A8      : 0x8200c02e  A9      : 0x3fcf46b0  
A10     : 0x00000000  A11     : 0x3fc93dd0  A12     : 0x3fc93dd0  A13     : 0x00000000  
A14     : 0x00060120  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  


Backtrace: 0x4203b033:0x3fcf46e0 0x4200c596:0x3fcf4700 0x4037bf08:0x3fcf4720

And here’s the code:

#include <WiFi.h>
#include <SD.h>
#include <SPI.h>
#include <esp_camera.h>
#include <FS.h>
#include <LittleFS.h>

#define CAMERA_MODEL_XIAO_ESP32S3
#include "camera_pins.h"
#define FORMAT_LITTLEFS_IF_FAILED true


unsigned long lastCaptureTime = 0; // Last shooting time
int imageCount = 1;                // File Counter
bool camera_sign = false;          // Check camera status
bool sd_sign = false;              // Check sd status
volatile unsigned int throttleValue;
volatile unsigned int steeringValue;
#define steeringInPin 5
#define throttleInPin 4



// Save pictures to SD card
void photo_save(const char * fileName) {
  // Take a photo
  camera_fb_t *fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Failed to get camera frame buffer");
    return;
  }
  // Save photo to file
  writeFile(SD, fileName, fb->buf, fb->len);
  
  // Release image buffer
  esp_camera_fb_return(fb);

  Serial.println("Photo saved to file");
}

// SD card write file
void writeFile(fs::FS &fs, const char * path, uint8_t * data, size_t len){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.write(data, len) == len){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}

void setup() {

    //Webserver Setup
    Serial.begin(115200);
    while(!Serial);

    Serial.println("Setup started.");


    //RC control
    pinMode(steeringInPin, INPUT);
    pinMode(throttleInPin, INPUT);
    attachInterrupt(digitalPinToInterrupt(throttleInPin), throttle_ISR, CHANGE); 
    attachInterrupt(digitalPinToInterrupt(steeringInPin), steering_ISR, CHANGE); 


    //Camera stuff
      camera_config_t config;
      config.ledc_channel = LEDC_CHANNEL_0;
      config.ledc_timer = LEDC_TIMER_0;
      config.pin_d0 = Y2_GPIO_NUM;
      config.pin_d1 = Y3_GPIO_NUM;
      config.pin_d2 = Y4_GPIO_NUM;
      config.pin_d3 = Y5_GPIO_NUM;
      config.pin_d4 = Y6_GPIO_NUM;
      config.pin_d5 = Y7_GPIO_NUM;
      config.pin_d6 = Y8_GPIO_NUM;
      config.pin_d7 = Y9_GPIO_NUM;
      config.pin_xclk = XCLK_GPIO_NUM;
      config.pin_pclk = PCLK_GPIO_NUM;
      config.pin_vsync = VSYNC_GPIO_NUM;
      config.pin_href = HREF_GPIO_NUM;
      config.pin_sscb_sda = SIOD_GPIO_NUM;
      config.pin_sscb_scl = SIOC_GPIO_NUM;
      config.pin_pwdn = PWDN_GPIO_NUM;
      config.pin_reset = RESET_GPIO_NUM;
      config.xclk_freq_hz = 20000000;
      config.frame_size = FRAMESIZE_QVGA;
      config.pixel_format = PIXFORMAT_JPEG; // for streaming
      config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
      config.fb_location = CAMERA_FB_IN_PSRAM;
      config.jpeg_quality = 12;
      config.fb_count = 1;

      // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
      //                      for larger pre-allocated frame buffer.
      if(config.pixel_format == PIXFORMAT_JPEG){
        if(psramFound()){
          config.jpeg_quality = 10;
          config.fb_count = 2;
          config.grab_mode = CAMERA_GRAB_LATEST;
        } else {
          // Limit the frame size when PSRAM is not available
          config.frame_size = FRAMESIZE_SVGA;
          config.fb_location = CAMERA_FB_IN_DRAM;
        }
      } else {
        // Best option for face detection/recognition
        config.frame_size = FRAMESIZE_240X240;
      #if CONFIG_IDF_TARGET_ESP32S3
          config.fb_count = 2;
      #endif
        }

        // camera init
        esp_err_t err = esp_camera_init(&config);
        if (err != ESP_OK) {
          Serial.printf("Camera init failed with error 0x%x", err);
          return;
        }

        camera_sign = true; // Camera initialization check passes

        // Initialize SD card
        if(!SD.begin(21)){
          Serial.println("Card Mount Failed");
          return;
        }
        uint8_t cardType = SD.cardType();

        // Determine if the type of SD card is available
        if(cardType == CARD_NONE){
          Serial.println("No SD card attached");
          return;
        }

        Serial.print("SD Card Type: ");
        if(cardType == CARD_MMC){
          Serial.println("MMC");
        } else if(cardType == CARD_SD){
          Serial.println("SDSC");
        } else if(cardType == CARD_SDHC){
          Serial.println("SDHC");
        } else {
          Serial.println("UNKNOWN");
        }

        sd_sign = true; // sd initialization check passes

        if (!LittleFS.begin()) {
          Serial.println("An error has occurred while mounting LITTLEFS");
          return;
  }

}

void loop() {
 
  //data collection

  Serial.print("Throttle: ");
  Serial.print(throttleValue);
  Serial.print(", Steering: ");
  Serial.println(steeringValue);
  
  if(camera_sign && sd_sign){
    // Get the current time
    unsigned long now = millis();
  
    //framerate
    if ((now - lastCaptureTime) >= 200) {
      char filename[32];
      sprintf(filename, "/image%d.jpg", imageCount);
      photo_save(filename);
      //Serial.printf("Saved picture: %s\n", filename);

      appendFile(SD, "/data.csv", filename, throttleValue, steeringValue);

      imageCount++;
      lastCaptureTime = now;
    }
  }
  
}

#define BUFFER_SIZE 512

void appendFile(fs::FS &fs, const char * path, const char * filename, int throttle, int steering) {
  static char buffer[BUFFER_SIZE]; // Create a static buffer
  static int bufferIndex = 0; // Index to keep track of where to write in the buffer

  // Format the message and write it to the buffer
  bufferIndex += sprintf(buffer + bufferIndex, "%s, %d, %d\n", filename, throttle, steering);

  // If the buffer is full, write it to the SD card
  if (bufferIndex >= BUFFER_SIZE - 64) { // 64 is the maximum length of the message
    File file = fs.open(path, FILE_APPEND);
    if(!file){
      Serial.println("Failed to open file for appending");
      return;
    }
    if(file.write(file.write((const uint8_t*)buffer, bufferIndex))){
      Serial.println("Buffer written to file");
    } else {
      Serial.println("Write failed");
    }
    file.close();

    bufferIndex = 0; // Reset the buffer index
  }
}

void throttle_ISR() {
  throttleValue = pulseIn(throttleInPin, HIGH);  // Read pulse width for throttle
}

void steering_ISR() {
  steeringValue = pulseIn(steeringInPin, HIGH);  // Read pulse width for steering
} 

Thank you!