ESP32 Complie error

Every time I compile this is what I experience

/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o:(.literal._Z17handleMoodChangesv+0x10): undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o:(.literal._Z15handleSleepModev+0x10): undefined reference to `_Z15enterLightSleepv'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o:(.literal._Z4loopv+0xc): undefined reference to `_Z13updateDisplayv'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z17handleMoodChangesv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:247: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z11handleShockv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:303: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z14enterDeepSleepv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:405: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z13handleBatteryv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:200: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: /home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:192: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o:/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:209: more undefined references to `_Z13setExpressioni' follow
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z15handleSleepModev':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:220: undefined reference to `_Z15enterLightSleepv'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z18wakeFromLightSleepv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:223: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z11handleTouchv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:266: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z5setupv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:507: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: sketch/CIMOL.ino.cpp.o: in function `_Z4loopv':
/home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:535: undefined reference to `_Z13updateDisplayv'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: /home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:542: undefined reference to `_Z13setExpressioni'
/home/gonit/.arduino15/packages/esp32/tools/esp-x32/2302/bin/../lib/gcc/xtensa-esp32-elf/12.2.0/../../../../xtensa-esp32-elf/bin/ld: /home/gonit/Dokumen/Project GONIT/CIMOL/CIMOL.ino:548: undefined reference to `_Z13setExpressioni'
collect2: error: ld returned 1 exit status
exit status 1
#include "Arduino.h"
#include "TFT_eSPI.h"
#include "SPI.h"
#include "SPIFFS.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorWAV.h"
#include "AudioOutputI2S.h"
#include <ESP32Time.h>
#include <Preferences.h>

// Pin Definitions
#define TOUCH_PIN 4
#define SHOCK_PIN 16
#define VIBRATION_PIN 17
#define SPEAKER_PIN 25
#define TFT_DC 2
#define TFT_CS 5
#define TFT_RST 4
#define BATTERY_PIN 35  // ADC pin for battery monitoring

// Constants
#define BATTERY_READ_INTERVAL 60000  // Check battery every minute
#define SLEEP_TIME_START 22  // Sleep time start (24-hour format)
#define SLEEP_TIME_END 7     // Sleep time end (24-hour format)
#define DEEP_SLEEP_TIMEOUT 300000  // 5 minutes without interaction
#define LIGHT_SLEEP_TIMEOUT 60000  // 1 minute without interaction

#define TFT_GREY      0x7BEF
#define TFT_DARKGREY  0x4208
#define TFT_LIGHTGREY 0xC618
#define TFT_GOLD      0xFEA0
#define TFT_RAINBOW   0xFE40  // You might want to implement a rainbow effect separately
#define TFT_PINK      0xFBB4

// Display setup
TFT_eSPI tft = TFT_eSPI();
AudioOutputI2S audio;
ESP32Time rtc;

// Structures
struct EyeParams {
    int width;
    int height;
    int angle;
    bool isDotted;
    int sparkleSize;
    bool isBlinking;
};

struct MouthParams {
    int width;
    int height;
    int curve;
    bool isOpen;
    int style;  // 0=curve, 1=straight, 2=zigzag, 3=dotted, 4=pixel
};

struct Expression {
    const char* name;
    EyeParams leftEye;
    EyeParams rightEye;
    MouthParams mouth;
    uint16_t primaryColor;
    uint16_t accentColor;
    int blinkRate;
    const char* soundFile;
    bool canInterrupt;  // Can this expression be interrupted by other events
    int duration;       // How long to show this expression (ms), 0 for indefinite
    int priority;       // Priority level (1-5, 5 being highest)
};

// Global Variables
unsigned long lastInteractionTime = 0;
unsigned long lastBatteryCheck = 0;
unsigned long lastBlinkTime = 0;
unsigned long expressionStartTime = 0;
int currentExpression = 0;
int batteryLevel = 100;
bool isInSleepMode = false;
bool isInLightSleep = false;
bool isCharging = false;  // Add this line
int moodLevel = 50;  // 0-100, affects expression selection
int energyLevel = 100;  // 0-100, affects activity level
int interactionCount = 0;  // Counts interactions for mood changes

// Interaction tracking
struct InteractionHistory {
    unsigned long timestamp;
    int type;  // 1=touch, 2=shock, 3=other
} lastInteractions[10];
int interactionIndex = 0;


// Expression Definitions (61 different expressions)
Expression expressions[] = {
    // Basic States (1-10)
    {"normal",     {20,20,0,false,0,false}, {20,20,0,false,0,false}, {40,10,0,false,0}, TFT_WHITE, TFT_BLUE, 3000, "normal.wav", true, 0, 1},
    {"happy",      {25,20,0,false,2,false}, {25,20,0,false,2,false}, {50,15,10,false,0}, TFT_YELLOW, TFT_WHITE, 2000, "happy.wav", true, 3000, 3},
    {"sad",        {15,20,-10,false,0,false}, {15,20,-10,false,0,false}, {30,10,-10,false,0}, TFT_BLUE, TFT_CYAN, 4000, "sad.wav", true, 4000, 3},
    {"angry",      {30,15,-20,false,0,false}, {30,15,-20,false,0,false}, {40,5,-5,false,1}, TFT_RED, TFT_ORANGE, 1000, "angry.wav", true, 3000, 4},
    {"surprised",  {35,35,0,false,3,false}, {35,35,0,false,3,false}, {30,30,0,true,0}, TFT_MAGENTA, TFT_PINK, 1500, "surprise.wav", true, 2000, 4},
    
    // Sleep States (11-15)
    {"sleepy",     {10,5,0,false,0,false}, {10,5,0,false,0,false}, {20,5,0,false,0}, TFT_LIGHTGREY, TFT_GREY, 5000, "sleepy.wav", false, 0, 2},
    {"sleeping",   {2,15,0,false,0,false}, {2,15,0,false,0,false}, {20,5,0,false,0}, TFT_DARKGREY, TFT_GREY, 6000, "sleep.wav", false, 0, 1},
    {"deep_sleep", {1,10,0,false,0,true}, {1,10,0,false,0,true}, {15,3,0,false,0}, TFT_DARKGREY, TFT_BLACK, 8000, "deepsleep.wav", false, 0, 1},
    {"waking",     {5,25,0,false,0,false}, {5,25,0,false,0,false}, {40,40,0,true,0}, TFT_LIGHTGREY, TFT_GREY, 4000, "wake.wav", true, 3000, 4},
    {"yawning",    {5,25,0,false,0,false}, {5,25,0,false,0,false}, {40,40,0,true,0}, TFT_LIGHTGREY, TFT_GREY, 4000, "yawn.wav", true, 2000, 3},
    
    // Battery States (16-20)
    {"low_battery",{15,15,-5,false,0,true}, {15,15,-5,false,0,true}, {30,8,-5,false,0}, TFT_RED, TFT_ORANGE, 5000, "lowbat.wav", false, 0, 5},
    {"charging",   {20,20,0,true,2,false}, {20,20,0,true,2,false}, {35,10,5,false,0}, TFT_GREEN, TFT_YELLOW, 2000, "charge.wav", true, 0, 4},
    {"charged",    {25,25,0,false,3,false}, {25,25,0,false,3,false}, {45,15,10,false,0}, TFT_GREEN, TFT_CYAN, 2000, "charged.wav", true, 3000, 4},
    {"power_saving",{10,10,-5,false,0,true}, {10,10,-5,false,0,true}, {25,5,-5,false,0}, TFT_ORANGE, TFT_RED, 6000, "powersave.wav", false, 0, 4},
    {"shutting_down",{5,5,0,false,0,true}, {5,5,0,false,0,true}, {20,5,-10,false,0}, TFT_RED, TFT_DARKGREY, 8000, "shutdown.wav", false, 5000, 5},

    // Interactive States (21-30)
    {"pet_happy",  {25,20,0,false,3,false}, {25,20,0,false,3,false}, {50,20,15,false,0}, TFT_YELLOW, TFT_WHITE, 1500, "pethappy.wav", true, 2000, 4},
    {"tickled",    {20,20,45,true,2,false}, {20,20,45,true,2,false}, {45,15,10,true,2}, TFT_CYAN, TFT_WHITE, 1000, "tickle.wav", true, 1500, 4},
    {"shocked",    {35,35,0,false,0,false}, {35,35,0,false,0,false}, {30,30,0,true,3}, TFT_WHITE, TFT_YELLOW, 1000, "shock.wav", true, 1000, 5},
    {"dizzy",      {30,30,45,true,0,false}, {30,30,-45,true,0,false}, {35,10,0,false,3}, TFT_PURPLE, TFT_BLUE, 2000, "dizzy.wav", true, 3000, 4},
    {"attention",  {25,25,0,false,2,false}, {25,25,0,false,2,false}, {30,10,0,false,0}, TFT_CYAN, TFT_WHITE, 2000, "attention.wav", true, 2000, 3},
    
// Emotional States (31-40)
    {"excited",    {30,25,0,true,3,false}, {30,25,0,true,3,false}, {45,20,15,true,0}, TFT_YELLOW, TFT_WHITE, 1000, "excited.wav", true, 2500, 4},
    {"curious",    {25,25,10,false,2,false}, {25,25,-10,false,2,false}, {25,10,0,false,0}, TFT_CYAN, TFT_WHITE, 2500, "curious.wav", true, 2000, 3},
    {"confused",   {20,20,30,false,0,false}, {20,20,-30,false,0,false}, {30,5,0,true,3}, TFT_MAGENTA, TFT_BLUE, 2000, "confused.wav", true, 2500, 3},
    {"worried",    {25,15,-5,false,0,false}, {25,15,-5,false,0,false}, {35,5,-5,false,1}, TFT_ORANGE, TFT_YELLOW, 3000, "worried.wav", true, 3000, 3},
    {"skeptical",  {20,15,15,false,0,false}, {20,15,-15,false,0,false}, {30,5,-10,false,1}, TFT_CYAN, TFT_BLUE, 2500, "skeptical.wav", true, 2000, 3},
    {"love",       {25,25,0,true,3,false}, {25,25,0,true,3,false}, {40,15,20,false,0}, TFT_RED, TFT_PINK, 1500, "love.wav", true, 2500, 4},
    {"proud",      {25,20,0,false,2,false}, {25,20,0,false,2,false}, {45,10,15,false,0}, TFT_GREEN, TFT_CYAN, 2000, "proud.wav", true, 3000, 3},
    {"bored",      {15,10,0,false,0,true}, {15,10,0,false,0,true}, {30,5,-5,false,1}, TFT_GREY, TFT_DARKGREY, 4000, "bored.wav", true, 3000, 2},
    {"mischievous",{20,20,15,false,2,false}, {20,20,15,false,2,false}, {40,10,10,false,2}, TFT_PURPLE, TFT_MAGENTA, 2000, "mischief.wav", true, 2500, 3},
    {"embarrassed",{15,15,-10,false,0,false}, {15,15,-10,false,0,false}, {25,5,-5,true,0}, TFT_PINK, TFT_RED, 2500, "embarrassed.wav", true, 2000, 3},

    // Action States (41-50)
    {"thinking",   {20,15,30,false,0,false}, {20,15,30,false,0,false}, {20,5,0,false,1}, TFT_BLUE, TFT_CYAN, 3000, "thinking.wav", true, 4000, 2},
    {"processing", {25,25,0,true,1,false}, {25,25,0,true,1,false}, {30,10,0,true,4}, TFT_CYAN, TFT_BLUE, 1000, "process.wav", true, 3000, 3},
    {"calculating",{20,20,0,true,2,true}, {20,20,0,true,2,true}, {25,5,0,false,4}, TFT_GREEN, TFT_CYAN, 1500, "calculate.wav", true, 3000, 3},
    {"searching",  {30,15,45,true,1,false}, {30,15,-45,true,1,false}, {20,5,0,true,3}, TFT_YELLOW, TFT_WHITE, 1000, "search.wav", true, 2500, 3},
    {"listening",  {25,25,0,false,2,false}, {25,25,0,false,2,false}, {20,5,0,false,0}, TFT_BLUE, TFT_CYAN, 2000, "listen.wav", true, 2000, 3},
    {"working",    {20,20,0,true,1,false}, {20,20,0,true,1,false}, {30,10,5,false,1}, TFT_GREEN, TFT_YELLOW, 2000, "working.wav", true, 3000, 3},
    {"dancing",    {25,25,45,true,3,false}, {25,25,-45,true,3,false}, {40,15,15,true,2}, TFT_MAGENTA, TFT_PINK, 1000, "dance.wav", true, 2000, 4},
    {"singing",    {20,20,0,false,2,false}, {20,20,0,false,2,false}, {35,30,0,true,0}, TFT_CYAN, TFT_WHITE, 1500, "sing.wav", true, 2500, 3},
    {"exercising", {25,15,30,false,1,false}, {25,15,30,false,1,false}, {35,10,10,false,2}, TFT_GREEN, TFT_YELLOW, 1500, "exercise.wav", true, 2000, 3},
    {"resting",    {15,10,0,false,0,true}, {15,10,0,false,0,true}, {25,5,0,false,0}, TFT_LIGHTGREY, TFT_GREY, 4000, "rest.wav", true, 3000, 2},

    // Special States (51-61)
    {"party",      {30,30,0,true,3,false}, {30,30,0,true,3,false}, {50,20,20,true,2}, TFT_RAINBOW, TFT_WHITE, 1000, "party.wav", true, 3000, 4},
    {"birthday",   {25,25,0,true,3,false}, {25,25,0,true,3,false}, {45,15,15,false,0}, TFT_RAINBOW, TFT_YELLOW, 1500, "birthday.wav", true, 3000, 4},
    {"holiday",    {25,25,0,false,3,false}, {25,25,0,false,3,false}, {40,15,10,false,0}, TFT_GREEN, TFT_RED, 2000, "holiday.wav", true, 3000, 4},
    {"winning",    {30,25,0,true,3,false}, {30,25,0,true,3,false}, {50,20,20,false,0}, TFT_GOLD, TFT_YELLOW, 1500, "win.wav", true, 3000, 4},
    {"losing",     {20,15,-10,false,0,false}, {20,15,-10,false,0,false}, {30,5,-10,false,1}, TFT_BLUE, TFT_LIGHTGREY, 3000, "lose.wav", true, 2500, 3},
    {"error",      {25,25,45,true,0,false}, {25,25,-45,true,0,false}, {35,10,-5,true,3}, TFT_RED, TFT_ORANGE, 1000, "error.wav", true, 2000, 5},
    {"debug",      {20,20,0,true,1,false}, {20,20,0,true,1,false}, {30,5,0,true,4}, TFT_GREEN, TFT_CYAN, 1500, "debug.wav", true, 2500, 3},
    {"update",     {25,25,0,true,2,false}, {25,25,0,true,2,false}, {35,10,5,false,4}, TFT_BLUE, TFT_CYAN, 2000, "update.wav", true, 3000, 4},
    {"overheating",{30,20,-10,true,0,false}, {30,20,-10,true,0,false}, {40,15,-5,true,2}, TFT_RED, TFT_ORANGE, 1500, "overheat.wav", true, 2500, 5},
    {"cooling",    {20,20,0,false,1,false}, {20,20,0,false,1,false}, {30,10,0,false,0}, TFT_CYAN, TFT_BLUE, 2500, "cooling.wav", true, 3000, 4},
    {"system_check",{25,25,0,true,2,true}, {25,25,0,true,2,true}, {25,5,0,true,4}, TFT_GREEN, TFT_CYAN, 2000, "syscheck.wav", true, 4000, 4}
};

// Function Declarations
void handleBattery();
void handleSleepMode();
void handleMoodChanges();
void playSound(const char* filename);
void setExpression(int index);
void handleTouch();
void handleShock();
void updateDisplay();
void enterLightSleep();
void enterDeepSleep();
void recordInteraction(int type);

// Battery Management
void handleBattery() {
    if (millis() - lastBatteryCheck >= BATTERY_READ_INTERVAL) {
        // Read battery voltage
        int rawValue = analogRead(BATTERY_PIN);
        batteryLevel = map(rawValue, 0, 4095, 0, 100);
        
        // Check charging status
        bool wasCharging = isCharging;
        isCharging = rawValue > 4000;  // Assuming voltage above 4V indicates charging
        
        // Handle battery states
        if (isCharging && !wasCharging) {
            setExpression(16);  // charging expression
        } else if (batteryLevel <= 10 && !isCharging) {
            setExpression(15);  // low battery expression
            if (batteryLevel <= 5) {
                enterDeepSleep();
            }
        } else if (batteryLevel <= 20 && !isCharging) {
            setExpression(18);  // power saving expression
        }
        
        lastBatteryCheck = millis();
    }
}

// Sleep Mode Management
void handleSleepMode() {
    int currentHour = rtc.getHour(true);
    bool shouldBeSleeping = (currentHour >= SLEEP_TIME_START || currentHour < SLEEP_TIME_END);
    
    if (shouldBeSleeping && !isInSleepMode) {
        isInSleepMode = true;
        setExpression(12);  // deep sleep expression
        energyLevel = max(energyLevel - 20, 0);
    } else if (!shouldBeSleeping && isInSleepMode) {
        isInSleepMode = false;
        setExpression(13);  // waking expression
        energyLevel = min(energyLevel + 30, 100);
    }
    
    // Handle sleep timeouts
    if (millis() - lastInteractionTime > DEEP_SLEEP_TIMEOUT) {
        enterDeepSleep();
    } else if (millis() - lastInteractionTime > LIGHT_SLEEP_TIMEOUT) {
        enterLightSleep();
    }
}

// Mood Management
void handleMoodChanges() {
    // Analyze recent interactions
    int recentInteractions = 0;
    unsigned long currentTime = millis();
    
    for (int i = 0; i < 10; i++) {
        if (currentTime - lastInteractions[i].timestamp < 300000) { // Last 5 minutes
            recentInteractions++;
        }
    }
    
    // Adjust mood based on interaction frequency
    if (recentInteractions > 5) {
        moodLevel = min(moodLevel + 10, 100);
    } else if (recentInteractions < 2) {
        moodLevel = max(moodLevel - 5, 0);
    }
    
    // Energy level affects available expressions
    if (energyLevel < 30) {
        // Limit to low energy expressions
        setExpression(15); // low energy state
    }
}

// Touch Interaction Handler
void handleTouch() {
    // Membaca status tombol sentuh
    if (digitalRead(TOUCH_PIN) == HIGH) {  // Sesuaikan dengan logika tombol Anda (HIGH/LOW)
        if (isInLightSleep) {
            wakeFromLightSleep();
            return;
        }
        
        recordInteraction(1);
        
        // Respons berbeda berdasarkan mood dan energyLevel
        if (moodLevel > 80) {
            // Respons sangat senang
            int happyResponses[] = {1, 20, 21, 31, 35, 36}; 
            setExpression(happyResponses[random(6)]);
        } else if (moodLevel > 50) {
            // Respons netral
            int neutralResponses[] = {0, 32, 33, 47, 48}; 
            setExpression(neutralResponses[random(5)]);
        } else {
            // Respons mood rendah
            int lowMoodResponses[] = {2, 37, 38, 39}; 
            setExpression(lowMoodResponses[random(4)]);
        }
        
        // Haptic feedback jika menggunakan vibration motor
        digitalWrite(VIBRATION_PIN, HIGH);
        delay(50);
        digitalWrite(VIBRATION_PIN, LOW);
        
        lastInteractionTime = millis();
        energyLevel = min(energyLevel + 5, 100);
        
        // Debounce delay
        delay(200);  // Mencegah multiple trigger
    }
}

// Shock Interaction Handler
void handleShock() {
    if (digitalRead(SHOCK_PIN)) {
        int shockValue = analogRead(SHOCK_PIN);
        
        if (shockValue > 3000) {
            int strongResponses[] = {22, 3, 4, 23}; // shocked, angry, surprised, dizzy
            setExpression(strongResponses[random(4)]);
        } else if (shockValue > 2000) {
            int mediumResponses[] = {33, 34, 24}; // confused, worried, attention
            setExpression(mediumResponses[random(3)]);
        } else {
            int lightResponses[] = {32, 35, 39}; // curious, love, embarrassed
            setExpression(lightResponses[random(3)]);
        }
    }
}

void handleTimeBasedExpressions() {
    int currentHour = rtc.getHour(true);
    
    // Pagi hari
    if (currentHour >= 6 && currentHour < 10) {
        int morningExpr[] = {13, 47, 48}; // waking, dancing, singing
        setExpression(morningExpr[random(3)]);
    }
    // Siang hari
    else if (currentHour >= 10 && currentHour < 15) {
        int dayExpr[] = {41, 42, 46}; // thinking, processing, working
        setExpression(dayExpr[random(3)]);
    }
    // Malam hari
    else if (currentHour >= 20 && currentHour < 22) {
        int nightExpr[] = {11, 49, 50}; // sleepy, exercising, resting
        setExpression(nightExpr[random(3)]);
    }
}

void handleBatteryExpressions() {
    if (batteryLevel > 90) {
        int highBatteryExpr[] = {1, 31, 36}; // happy, excited, proud
        setExpression(highBatteryExpr[random(3)]);
    } else if (batteryLevel < 20) {
        int lowBatteryExpr[] = {15, 18, 34}; // low_battery, power_saving, worried
        setExpression(lowBatteryExpr[random(3)]);
    }
}

// Display Functions
void drawEye(int x, int y, EyeParams params, uint16_t color, uint16_t accentColor) {
    // Sesuaikan ukuran mata dengan layar yang lebih kecil
    int scaledWidth = params.width * 0.6;  // Skala lebih kecil
    int scaledHeight = params.height * 0.6;
    
    if (params.isBlinking) {
        tft.drawLine(x - scaledWidth, y, x + scaledWidth, y, color);
        return;
    }
    
    if (params.isDotted) {
        for (int i = 0; i < scaledWidth; i += 2) {  // Kurangi jarak antar titik
            tft.fillCircle(x + i - scaledWidth/2, y, 1, color);  // Ukuran titik lebih kecil
        }
    } else {
        tft.fillEllipse(x, y, scaledWidth, scaledHeight, color);
        
        if (params.sparkleSize > 0) {
            tft.fillCircle(x + 1, y - 1, params.sparkleSize/2, accentColor);  // Sparkle lebih kecil
            tft.fillCircle(x - 1, y + 1, params.sparkleSize/4, TFT_WHITE);
        }
    }
}

void drawMouth(int x, int y, MouthParams params, uint16_t color) {
    // Sesuaikan ukuran mulut
    int scaledWidth = params.width * 0.6;
    int scaledHeight = params.height * 0.6;
    
    switch(params.style) {
        case 0: // Curved mouth
            for(int i = -scaledWidth/2; i <= scaledWidth/2; i++) {
                int yOffset = (params.curve * i * i) / (scaledWidth/2);
                tft.drawPixel(x + i, y + yOffset, color);
                if (scaledHeight > 1) {
                    tft.drawPixel(x + i, y + yOffset + 1, color);
                }
            }
            break;
            
        case 1: // Straight line
            tft.drawLine(x - scaledWidth/2, y, x + scaledWidth/2, y, color);
            break;
            
        case 2: // Zigzag
            for(int i = -scaledWidth/2; i < scaledWidth/2; i += 2) {
                tft.drawLine(x + i, y - 1, x + i + 1, y + 1, color);
                tft.drawLine(x + i + 1, y + 1, x + i + 2, y - 1, color);
            }
            break;
    }
}

// Sleep Management Functions
void displayExpression(int index) {
    Expression& expr = expressions[index];
    tft.fillScreen(TFT_BLACK);
    
    // Adjust positions for 80x160 display
    drawEye(25, 30, expr.leftEye, expr.primaryColor, expr.accentColor);   // Left eye
    drawEye(55, 30, expr.rightEye, expr.primaryColor, expr.accentColor);  // Right eye
    drawMouth(40, 70, expr.mouth, expr.primaryColor);  // Mouth
    
    // Battery indicator for charging and low battery states
    if (strcmp(expr.name, "charging") == 0 || strcmp(expr.name, "low_battery") == 0) {
        uint16_t indicatorColor = (strcmp(expr.name, "charging") == 0) ? TFT_GREEN : TFT_RED;
        tft.drawRect(30, 10, 20, 5, indicatorColor);
        tft.fillRect(30, 10, batteryLevel/5, 5, indicatorColor);
    }
    
    // Handle rainbow effect for special expressions
    if (expr.primaryColor == TFT_RAINBOW) {
        static uint8_t rainbowIndex = 0;
        uint16_t rainbowColors[] = {TFT_RED, TFT_ORANGE, TFT_YELLOW, TFT_GREEN, TFT_BLUE, TFT_PURPLE};
        // Use the cycled color for the next redraw
        uint16_t currentRainbowColor = rainbowColors[rainbowIndex];
        // Update expression and display elements with rainbow color
        drawEye(25, 30, expr.leftEye, currentRainbowColor, expr.accentColor);   
        drawEye(55, 30, expr.rightEye, currentRainbowColor, expr.accentColor);  
        drawMouth(40, 70, expr.mouth, currentRainbowColor);
        // Cycle to next color
        rainbowIndex = (rainbowIndex + 1) % 6;
    }
}

// Sleep Management Functions
void enterDeepSleep() {
    setExpression(19); // shutting down expression
    delay(2000); // Show expression briefly
    
    // Save current state to RTC memory
    Preferences preferences;
    preferences.begin("robot-state", false);
    preferences.putInt("energy", energyLevel);
    preferences.putInt("mood", moodLevel);
    preferences.end();
    
    // Configure deep sleep
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_4, 1); // Wake on touch
    esp_deep_sleep_start();
}

void wakeFromLightSleep() {
    isInLightSleep = false;
    setExpression(13); // waking expression
    energyLevel = min(energyLevel + 20, 100);
    lastInteractionTime = millis();
}

// Interaction Recording
void recordInteraction(int type) {
    lastInteractions[interactionIndex].timestamp = millis();
    lastInteractions[interactionIndex].type = type;
    interactionIndex = (interactionIndex + 1) % 10;
}

// Sound Management
void playSound(const char* filename) {
    if (!SPIFFS.exists(filename)) {
        Serial.printf("File %s does not exist\n", filename);
        return;
    }

    AudioFileSourceSPIFFS *audioFile = new AudioFileSourceSPIFFS(filename);
    AudioGeneratorWAV *wav = new AudioGeneratorWAV();
    wav->begin(audioFile, &audio);

    while (wav->isRunning()) {
        if (!wav->loop()) wav->stop();
    }

    delete wav;
    delete audioFile;
}


void setup() {
    Serial.begin(115200);
    
    // Initialize pins
    pinMode(TOUCH_PIN, INPUT);
    pinMode(SHOCK_PIN, INPUT);
    pinMode(VIBRATION_PIN, OUTPUT);
    pinMode(BATTERY_PIN, INPUT);
    
    // Initialize display
    tft.init();
    tft.setRotation(0);
    tft.fillScreen(TFT_BLACK);
    
    // Initialize audio
    audio.SetPinout(SPEAKER_PIN, 26, 22);
    audio.SetGain(0.5);  // Set the volume to 50%
    
    // Initialize SPIFFS
    if (!SPIFFS.begin(true)) {
        Serial.println("SPIFFS Mount Failed");
        return;
    }
    
    // Restore state if waking from deep sleep
    Preferences preferences;
    preferences.begin("robot-state", true);
    energyLevel = preferences.getInt("energy", 100);
    moodLevel = preferences.getInt("mood", 50);
    preferences.end();
    
    // Set initial expression
    setExpression(0);
    
    // Initialize RTC
    rtc.setTime(0, 0, 0, 1, 1, 2024);  // Set initial time
    
    // Show boot animation
    for (int i = 0; i < 5; i++) {
        tft.fillScreen(TFT_BLACK);
        delay(100);
        displayExpression(0);
        delay(100);
    }
    
    lastInteractionTime = millis();
}

void loop() {
    // Handle core functionalities
    handleBattery();
    handleSleepMode();
    handleMoodChanges();
    
    // Handle inputs
    handleTouch();
    handleShock();
    
    // Update display if needed
    static unsigned long lastUpdate = 0;
    if (millis() - lastUpdate > 50) {  // 20 FPS refresh rate
        updateDisplay();
        lastUpdate = millis();
    }
    
    // Handle expression timing
    if (expressions[currentExpression].duration > 0) {
        if (millis() - expressionStartTime > expressions[currentExpression].duration) {
            setExpression(0);  // Return to normal
        }
    }
    
    // Random idle animations
    if (millis() - lastInteractionTime > 10000) {  // After 10 seconds of no interaction
        if (random(100) < 5) {  // 5% chance each loop
            int randomExpr = random(61);
            if (expressions[randomExpr].canInterrupt) {
                setExpression(randomExpr);
            }
        }
    }
    
    delay(20);  // Small delay to prevent too frequent updates
}

Which board are you compiling for?
Where do we find any non-standard libraries (the Audio... libraries)?

suggest you implement separate programs to test each device and library in turn
when you know they all work start implementing the project
give links to the display and other devices?

You need to show the entire error log in code tags.

Where are these functions defined? Not in the code you posted.