Perfect! Let's update the project to **TAKEONE Reflex** and add advanced color management for different game scenarios.

## ✅ Updated Code with Advanced Color Features

```cpp
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <Adafruit_NeoPixel.h>
#include <Preferences.h>

// ==========================================
// ⚙️ USER CONFIGURATION (MODULAR)
// ==========================================
#define DEFAULT_DEVICE_NAME "TAKEONE_Reflex"
#define PROJECT_NAME        "TAKEONE Reflex"
#define FIRMWARE_VERSION    "1.0.0"

// --- Feature Toggles (Comment to disable) ---
#define FEATURE_PIEZO
#define FEATURE_BUTTON
#define FEATURE_ACCEL

// --- Pin Assignments (ESP32-C3 Super Mini) ---
#define LED_PIN             3

#ifdef FEATURE_PIEZO
  #define PIEZO_PIN         4
  #define PIEZO_THRESHOLD   1500
#endif

#ifdef FEATURE_BUTTON
  #define BUTTON_PIN        5
  #define BUTTON_THRESHOLD  100
#endif

#ifdef FEATURE_ACCEL
  #define ACCEL_X_PIN       6
  #define ACCEL_Y_PIN       7
  #define ACCEL_Z_PIN       0
  #define ACCEL_THRESHOLD   150
#endif

#define NUM_PIXELS          12
#define BRIGHTNESS          50
#define BREATHE_MAX         40
#define MAX_PRESETS         8        // Number of color presets
#define MAX_SEQUENCE_STEPS  16       // Max colors in sequence
// ==========================================

// --- BLE UUIDs ---
#define SERVICE_UUID             "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID      "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define DEVICE_INFO_SERVICE_UUID "180A"
#define MODEL_NUMBER_CHAR_UUID   "2A24"
#define SERIAL_NUMBER_CHAR_UUID  "2A25"
#define FIRMWARE_REV_CHAR_UUID   "2A26"
#define MANUFACTURER_CHAR_UUID   "2A29"

// --- Pod States ---
enum PodState {
  STATE_BOOT,
  STATE_WAITING,
  STATE_CONNECTED,
  STATE_ACTIVE,
  STATE_SUCCESS,
  STATE_SEQUENCE  // For playing color sequences
};

// --- Color Structure ---
struct LEDColor {
  uint8_t r, g, b;
};

// --- Default Colors ---
LEDColor colorWait      = {0, 0, 255};      // Blue (breathing)
LEDColor colorConn      = {0, 255, 255};    // Cyan
LEDColor colorActive    = {255, 0, 0};      // Red
LEDColor colorSuccess   = {0, 255, 0};      // Green

// --- Color Presets (saved in flash) ---
LEDColor colorPresets[MAX_PRESETS];

// --- Color Sequence ---
LEDColor colorSequence[MAX_SEQUENCE_STEPS];
uint8_t sequenceLength = 0;
uint8_t currentStep = 0;
unsigned long lastStepTime = 0;
unsigned long stepDuration = 500;  // ms per step

// --- Globals ---
Preferences preferences;
char deviceName[16] = DEFAULT_DEVICE_NAME;

Adafruit_NeoPixel strip(NUM_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
BLEServer *pServer = NULL;
BLECharacteristic *pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;

PodState currentState = STATE_BOOT;
unsigned long stateStartTime = 0;
unsigned long lastAnimTime = 0;
int animStep = 0;

unsigned long startTime = 0;
unsigned long reactionTime = 0;
bool gameActive = false;
bool isTapped = false;

int baseX = 0, baseY = 0, baseZ = 0;
bool accelCalibrated = false;

// --- Helper: Create Color ---
uint32_t makeColor(LEDColor c) {
  return strip.Color(c.r, c.g, c.b);
}

// --- Helper: Set All LEDs ---
void fillStrip(uint32_t color) {
  for (int i = 0; i < NUM_PIXELS; i++) {
    strip.setPixelColor(i, color);
  }
  strip.show();
}

// --- Helper: Parse Color from String "R,G,B" ---
LEDColor parseColor(String str) {
  LEDColor c = {0, 0, 0};
  int comma1 = str.indexOf(',');
  int comma2 = str.lastIndexOf(',');
  if (comma1 > 0 && comma2 > comma1) {
    c.r = str.substring(0, comma1).toInt();
    c.g = str.substring(comma1 + 1, comma2).toInt();
    c.b = str.substring(comma2 + 1).toInt();
  }
  return c;
}

// --- Helper: Format Color to String ---
String formatColor(LEDColor c) {
  return String(c.r) + "," + String(c.g) + "," + String(c.b);
}

// --- Save/Load Functions ---
void saveDeviceName(const char* name) {
  preferences.begin("takeone", false);
  preferences.putString("deviceName", name);
  preferences.end();
  strncpy(deviceName, name, 15);
  deviceName[15] = '\0';
}

void loadDeviceName() {
  preferences.begin("takeone", false);
  String savedName = preferences.getString("deviceName", DEFAULT_DEVICE_NAME);
  preferences.end();
  strncpy(deviceName, savedName.c_str(), 15);
  deviceName[15] = '\0';
}

void saveColorPreset(uint8_t index, LEDColor color) {
  preferences.begin("takeone", false);
  String key = "preset" + String(index);
  String value = formatColor(color);
  preferences.putString(key.c_str(), value);
  preferences.end();
  colorPresets[index] = color;
}

void loadColorPresets() {
  preferences.begin("takeone", false);
  for (int i = 0; i < MAX_PRESETS; i++) {
    String key = "preset" + String(i);
    String saved = preferences.getString(key.c_str(), "");
    if (saved.length() > 0) {
      colorPresets[i] = parseColor(saved);
    } else {
      // Default presets
      switch(i) {
        case 0: colorPresets[i] = {255, 0, 0}; break;    // Red
        case 1: colorPresets[i] = {0, 255, 0}; break;    // Green
        case 2: colorPresets[i] = {0, 0, 255}; break;    // Blue
        case 3: colorPresets[i] = {255, 255, 0}; break;  // Yellow
        case 4: colorPresets[i] = {255, 0, 255}; break;  // Magenta
        case 5: colorPresets[i] = {0, 255, 255}; break;  // Cyan
        case 6: colorPresets[i] = {255, 128, 0}; break;  // Orange
        case 7: colorPresets[i] = {128, 0, 255}; break;  // Purple
      }
    }
  }
  preferences.end();
}

void saveSequence() {
  preferences.begin("takeone", false);
  String seqStr = "";
  for (int i = 0; i < sequenceLength; i++) {
    if (i > 0) seqStr += ";";
    seqStr += formatColor(colorSequence[i]);
  }
  preferences.putString("sequence", seqStr);
  preferences.putUInt("seqDuration", stepDuration);
  preferences.end();
}

void loadSequence() {
  preferences.begin("takeone", false);
  String saved = preferences.getString("sequence", "");
  stepDuration = preferences.getUInt("seqDuration", 500);
  
  sequenceLength = 0;
  if (saved.length() > 0) {
    int startIndex = 0;
    while (startIndex < saved.length() && sequenceLength < MAX_SEQUENCE_STEPS) {
      int endIndex = saved.indexOf(';', startIndex);
      if (endIndex == -1) endIndex = saved.length();
      
      String colorStr = saved.substring(startIndex, endIndex);
      colorSequence[sequenceLength++] = parseColor(colorStr);
      startIndex = endIndex + 1;
    }
  }
  preferences.end();
}

// --- Play Next Sequence Step ---
void playNextSequenceStep() {
  if (sequenceLength == 0) return;
  
  fillStrip(makeColor(colorSequence[currentStep]));
  currentStep = (currentStep + 1) % sequenceLength;
  lastStepTime = millis();
}

// --- BLE Callbacks ---
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      currentState = STATE_CONNECTED;
      stateStartTime = millis();
      Serial.println("Device Connected");
    }
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      currentState = STATE_WAITING;
      stateStartTime = millis();
      Serial.println("Device Disconnected");
      BLEDevice::startAdvertising();
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      String value = pCharacteristic->getValue();
      value.trim();
      
      Serial.print("Received: [");
      Serial.print(value);
      Serial.println("]");

      // --- Device Name Commands ---
      if (value.startsWith("SET_DEVICE_NAME:")) {
        String newName = value.substring(16);
        newName.trim();
        
        if (newName.length() > 0 && newName.length() <= 15) {
          saveDeviceName(newName.c_str());
          BLEDevice::deinit(true);
          delay(100);
          BLEDevice::init(deviceName);
          
          BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
          pAdvertising->addServiceUUID(SERVICE_UUID);
          pAdvertising->setScanResponse(true);
          BLEDevice::startAdvertising();
          
          pCharacteristic->setValue("OK:DEVICE_NAME:" + String(deviceName));
          pCharacteristic->notify();
        } else {
          pCharacteristic->setValue("ERROR:NAME_INVALID");
          pCharacteristic->notify();
        }
      }
      else if (value == "GET_DEVICE_NAME") {
        pCharacteristic->setValue("DEVICE_NAME:" + String(deviceName));
        pCharacteristic->notify();
      }
      // --- Color Preset Commands ---
      else if (value.startsWith("SAVE_PRESET:")) {
        // Format: SAVE_PRESET:n:R,G,B
        int firstColon = value.indexOf(':');
        int secondColon = value.indexOf(':', firstColon + 1);
        if (firstColon > 0 && secondColon > firstColon) {
          uint8_t index = value.substring(firstColon + 1, secondColon).toInt();
          if (index < MAX_PRESETS) {
            LEDColor c = parseColor(value.substring(secondColon + 1));
            saveColorPreset(index, c);
            pCharacteristic->setValue("OK:PRESET_SAVED:" + String(index));
            pCharacteristic->notify();
          } else {
            pCharacteristic->setValue("ERROR:PRESET_INDEX");
            pCharacteristic->notify();
          }
        }
      }
      else if (value.startsWith("LOAD_PRESET:")) {
        // Format: LOAD_PRESET:n
        int colon = value.indexOf(':');
        if (colon > 0) {
          uint8_t index = value.substring(colon + 1).toInt();
          if (index < MAX_PRESETS) {
            fillStrip(makeColor(colorPresets[index]));
            pCharacteristic->setValue("OK:PRESET_LOADED:" + String(index));
            pCharacteristic->notify();
          } else {
            pCharacteristic->setValue("ERROR:PRESET_INDEX");
            pCharacteristic->notify();
          }
        }
      }
      else if (value == "GET_PRESETS") {
        String response = "PRESETS|";
        for (int i = 0; i < MAX_PRESETS; i++) {
          if (i > 0) response += "|";
          response += String(i) + ":" + formatColor(colorPresets[i]);
        }
        pCharacteristic->setValue(response);
        pCharacteristic->notify();
      }
      // --- Color Sequence Commands ---
      else if (value.startsWith("SET_SEQUENCE:")) {
        // Format: SET_SEQUENCE:R1,G1,B1;R2,G2,B2;R3,G3,B3
        String seqData = value.substring(13);
        sequenceLength = 0;
        
        int startIndex = 0;
        while (startIndex < seqData.length() && sequenceLength < MAX_SEQUENCE_STEPS) {
          int endIndex = seqData.indexOf(';', startIndex);
          if (endIndex == -1) endIndex = seqData.length();
          
          String colorStr = seqData.substring(startIndex, endIndex);
          colorSequence[sequenceLength++] = parseColor(colorStr);
          startIndex = endIndex + 1;
        }
        
        saveSequence();
        pCharacteristic->setValue("OK:SEQUENCE_SET:" + String(sequenceLength));
        pCharacteristic->notify();
      }
      else if (value.startsWith("SET_STEP_DURATION:")) {
        // Format: SET_STEP_DURATION:500 (milliseconds)
        int colon = value.indexOf(':');
        if (colon > 0) {
          stepDuration = value.substring(colon + 1).toInt();
          saveSequence();
          pCharacteristic->setValue("OK:DURATION:" + String(stepDuration));
          pCharacteristic->notify();
        }
      }
      else if (value == "PLAY_SEQUENCE") {
        if (sequenceLength > 0) {
          currentState = STATE_SEQUENCE;
          currentStep = 0;
          playNextSequenceStep();
          pCharacteristic->setValue("OK:SEQUENCE_PLAYING");
          pCharacteristic->notify();
        } else {
          pCharacteristic->setValue("ERROR:NO_SEQUENCE");
          pCharacteristic->notify();
        }
      }
      else if (value == "STOP_SEQUENCE") {
        currentState = STATE_CONNECTED;
        fillStrip(makeColor(colorConn));
        pCharacteristic->setValue("OK:SEQUENCE_STOPPED");
        pCharacteristic->notify();
      }
      // --- Standard Color Commands ---
      else if (value.startsWith("COLOR_WAIT:")) {
        colorWait = parseColor(value.substring(11));
        pCharacteristic->setValue("OK:COLOR_WAIT:" + formatColor(colorWait));
        pCharacteristic->notify();
      }
      else if (value.startsWith("COLOR_CONN:")) {
        colorConn = parseColor(value.substring(11));
        pCharacteristic->setValue("OK:COLOR_CONN:" + formatColor(colorConn));
        pCharacteristic->notify();
      }
      else if (value.startsWith("COLOR_ACTIVE:")) {
        colorActive = parseColor(value.substring(13));
        pCharacteristic->setValue("OK:COLOR_ACTIVE:" + formatColor(colorActive));
        pCharacteristic->notify();
      }
      else if (value.startsWith("COLOR_SUCCESS:")) {
        colorSuccess = parseColor(value.substring(14));
        pCharacteristic->setValue("OK:COLOR_SUCCESS:" + formatColor(colorSuccess));
        pCharacteristic->notify();
      }
      else if (value == "GET_COLORS") {
        String response = "COLORS|WAIT:" + formatColor(colorWait) + 
                         "|CONN:" + formatColor(colorConn) +
                         "|ACTIVE:" + formatColor(colorActive) +
                         "|SUCCESS:" + formatColor(colorSuccess);
        pCharacteristic->setValue(response);
        pCharacteristic->notify();
      }
      else if (value == "RESET_COLORS") {
        colorWait = {0, 0, 255};
        colorConn = {0, 255, 255};
        colorActive = {255, 0, 0};
        colorSuccess = {0, 255, 0};
        pCharacteristic->setValue("OK:COLORS_RESET");
        pCharacteristic->notify();
      }
      // --- Game Commands ---
      else if (value == "START") {
        currentState = STATE_ACTIVE;
        fillStrip(makeColor(colorActive));
        startTime = micros();
        gameActive = true;
        isTapped = false;
        accelCalibrated = false;
        pCharacteristic->setValue("OK:STARTED");
        pCharacteristic->notify();
        Serial.println("Game Started");
      }
      else if (value == "RESET") {
        currentState = STATE_CONNECTED;
        fillStrip(makeColor(colorConn));
        gameActive = false;
        pCharacteristic->setValue("OK:RESET");
        pCharacteristic->notify();
        Serial.println("Game Reset");
      }
      // --- Device Info ---
      else if (value == "GET_DEVICE_INFO") {
        String response = "INFO|NAME:" + String(deviceName) +
                         "|MODEL:TAKEONE-Reflex" +
                         "|FW:" + String(FIRMWARE_VERSION) +
                         "|MANUFACTURER:DIY" +
                         "|SENSORS:" + 
                         String(defined(FEATURE_PIEZO) ? "P" : "-") +
                         String(defined(FEATURE_BUTTON) ? "B" : "-") +
                         String(defined(FEATURE_ACCEL) ? "A" : "-");
        pCharacteristic->setValue(response);
        pCharacteristic->notify();
      }
      else if (value == "FACTORY_RESET") {
        preferences.begin("takeone", false);
        preferences.clear();
        preferences.end();
        strncpy(deviceName, DEFAULT_DEVICE_NAME, 15);
        loadColorPresets();
        
        BLEDevice::deinit(true);
        delay(100);
        BLEDevice::init(deviceName);
        
        BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
        pAdvertising->addServiceUUID(SERVICE_UUID);
        pAdvertising->setScanResponse(true);
        BLEDevice::startAdvertising();
        
        pCharacteristic->setValue("OK:FACTORY_RESET");
        pCharacteristic->notify();
        Serial.println("Factory reset complete");
      }
      else {
        pCharacteristic->setValue("ERROR:UNKNOWN_COMMAND");
        pCharacteristic->notify();
      }
    }
};

// --- Calibrate Accelerometer ---
void calibrateAccel() {
  #ifdef FEATURE_ACCEL
    if (!accelCalibrated) {
      baseX = analogRead(ACCEL_X_PIN);
      baseY = analogRead(ACCEL_Y_PIN);
      baseZ = analogRead(ACCEL_Z_PIN);
      accelCalibrated = true;
    }
  #endif
}

// --- Check All Enabled Triggers ---
void checkTriggers() {
  if (!gameActive || !deviceConnected || isTapped) return;

  bool triggered = false;

  #ifdef FEATURE_PIEZO
    int piezoValue = analogRead(PIEZO_PIN);
    if (piezoValue > PIEZO_THRESHOLD) {
      triggered = true;
    }
  #endif

  #ifdef FEATURE_BUTTON
    #if !defined(FEATURE_PIEZO) || (BUTTON_PIN != PIEZO_PIN)
      if (digitalRead(BUTTON_PIN) == LOW) {
        triggered = true;
      }
    #endif
  #endif

  #ifdef FEATURE_ACCEL
    if (accelCalibrated && !triggered) {
      int curX = analogRead(ACCEL_X_PIN);
      int curY = analogRead(ACCEL_Y_PIN);
      int curZ = analogRead(ACCEL_Z_PIN);
      
      int diffX = abs(curX - baseX);
      int diffY = abs(curY - baseY);
      int diffZ = abs(curZ - baseZ);
      
      if (diffX > ACCEL_THRESHOLD || diffY > ACCEL_THRESHOLD || diffZ > ACCEL_THRESHOLD) {
        triggered = true;
      }
    }
  #endif

  if (triggered) {
    isTapped = true;
    unsigned long endTime = micros();
    reactionTime = (endTime - startTime) / 1000;
    
    String result = "RESULT:" + String(reactionTime) + "ms";
    pCharacteristic->setValue(result);
    pCharacteristic->notify();
    
    currentState = STATE_SUCCESS;
    stateStartTime = millis();
    fillStrip(makeColor(colorSuccess));
    
    gameActive = false;
  }
}

// --- Reset Trigger After Settle ---
void resetTrigger() {
  if (isTapped) {
    bool settled = false;
    
    #ifdef FEATURE_PIEZO
      int piezoValue = analogRead(PIEZO_PIN);
      if (piezoValue < (PIEZO_THRESHOLD / 2)) settled = true;
    #elif defined(FEATURE_BUTTON)
      if (digitalRead(BUTTON_PIN) == HIGH) settled = true;
    #else
      if (millis() - stateStartTime > 2000) settled = true;
    #endif
    
    if (settled) {
      isTapped = false;
      accelCalibrated = false;
    }
  }
}

// --- Smart Animation Engine ---
void handleAnimations() {
  unsigned long now = millis();

  if (currentState == STATE_BOOT) {
    if (now - stateStartTime < 2000) {
      if (now - lastAnimTime > 50) {
        for (int i = 0; i < NUM_PIXELS; i++) {
          uint32_t color = strip.ColorHSV(i * 255 / NUM_PIXELS + animStep * 10, 255, BRIGHTNESS);
          strip.setPixelColor(i, color);
        }
        strip.show();
        animStep++;
        lastAnimTime = now;
      }
    } else {
      currentState = STATE_WAITING;
      stateStartTime = now;
      fillStrip(0);
    }
  }

  else if (currentState == STATE_WAITING) {
    if (now - lastAnimTime > 10) {
      float breath = sin(now / 800.0);
      float normalized = (breath + 1.0) / 2.0;
      float gammaCorrected = pow(normalized, 2.2);
      int brightness = (int)(gammaCorrected * BREATHE_MAX);
      
      uint32_t color = strip.Color(colorWait.r * brightness / BREATHE_MAX,
                                   colorWait.g * brightness / BREATHE_MAX,
                                   colorWait.b * brightness / BREATHE_MAX);
      fillStrip(color);
      lastAnimTime = now;
    }
  }

  else if (currentState == STATE_CONNECTED) {
    if (now - lastAnimTime > 500) {
      fillStrip(makeColor(colorConn));
      lastAnimTime = now;
    }
  }

  else if (currentState == STATE_ACTIVE) {
    if (now - lastAnimTime > 500) {
      fillStrip(makeColor(colorActive));
      lastAnimTime = now;
    }
  }

  else if (currentState == STATE_SEQUENCE) {
    if (now - lastStepTime >= stepDuration) {
      playNextSequenceStep();
    }
  }

  else if (currentState == STATE_SUCCESS) {
    if (now - stateStartTime > 2000) {
      currentState = STATE_CONNECTED;
      fillStrip(makeColor(colorConn));
    }
  }
}

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

  loadDeviceName();
  loadColorPresets();
  loadSequence();

  Serial.println("================================");
  Serial.println("  " + String(PROJECT_NAME));
  Serial.println("  Firmware v" + String(FIRMWARE_VERSION));
  Serial.println("================================");
  Serial.print("Device Name: ");
  Serial.println(deviceName);
  Serial.print("Piezo:   "); Serial.println(defined(FEATURE_PIEZO) ? "ON" : "OFF");
  Serial.print("Button:  "); Serial.println(defined(FEATURE_BUTTON) ? "ON" : "OFF");
  Serial.print("Accel:   "); Serial.println(defined(FEATURE_ACCEL) ? "ON" : "OFF");
  Serial.println("================================");

  pinMode(LED_PIN, OUTPUT);
  
  #ifdef FEATURE_PIEZO
    pinMode(PIEZO_PIN, INPUT);
  #endif
  
  #ifdef FEATURE_BUTTON
    pinMode(BUTTON_PIN, INPUT_PULLUP);
  #endif
  
  #ifdef FEATURE_ACCEL
    pinMode(ACCEL_X_PIN, INPUT);
    pinMode(ACCEL_Y_PIN, INPUT);
    pinMode(ACCEL_Z_PIN, INPUT);
  #endif

  analogReadResolution(12);

  strip.begin();
  strip.setBrightness(BRIGHTNESS);
  strip.show();
  fillStrip(0);

  currentState = STATE_BOOT;
  stateStartTime = millis();

  BLEDevice::init(deviceName);
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ |
                      BLECharacteristic::PROPERTY_WRITE |
                      BLECharacteristic::PROPERTY_NOTIFY
                    );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->addDescriptor(new BLE2902());
  pService->start();

  BLEService *pDeviceInfoService = pServer->createService(DEVICE_INFO_SERVICE_UUID);
  
  BLECharacteristic *pModelNumberChar = pDeviceInfoService->createCharacteristic(
    MODEL_NUMBER_CHAR_UUID, BLECharacteristic::PROPERTY_READ);
  pModelNumberChar->setValue("TAKEONE-Reflex");
  
  BLECharacteristic *pSerialNumberChar = pDeviceInfoService->createCharacteristic(
    SERIAL_NUMBER_CHAR_UUID, BLECharacteristic::PROPERTY_READ);
  uint8_t baseMac[6];
  esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
           baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
  pSerialNumberChar->setValue(macStr);
  
  BLECharacteristic *pFirmwareRevChar = pDeviceInfoService->createCharacteristic(
    FIRMWARE_REV_CHAR_UUID, BLECharacteristic::PROPERTY_READ);
  pFirmwareRevChar->setValue(FIRMWARE_VERSION);
  
  BLECharacteristic *pManufacturerChar = pDeviceInfoService->createCharacteristic(
    MANUFACTURER_CHAR_UUID, BLECharacteristic::PROPERTY_READ);
  pManufacturerChar->setValue("DIY Reflex Pod");
  
  pDeviceInfoService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->addServiceUUID(DEVICE_INFO_SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  
  Serial.println("System Ready - Waiting for connection...");
  Serial.print("Advertising as: ");
  Serial.println(deviceName);
}

void loop() {
  if (!deviceConnected && oldDeviceConnected) {
    delay(500);
    pServer->startAdvertising();
    oldDeviceConnected = deviceConnected;
  }
  if (deviceConnected && !oldDeviceConnected) {
    oldDeviceConnected = deviceConnected;
  }

  handleAnimations();
  
  if (gameActive && !accelCalibrated) {
    calibrateAccel();
  }
  
  checkTriggers();
  resetTrigger();
  
  delay(10);
}
```

---

## 📱 Complete BLE Command Reference

### **Device Management**
| Command | Description | Response |
| :--- | :--- | :--- |
| `SET_DEVICE_NAME:NewName` | Change device name (max 15 chars) | `OK:DEVICE_NAME:NewName` |
| `GET_DEVICE_NAME` | Get current name | `DEVICE_NAME:TAKEONE_Reflex` |
| `GET_DEVICE_INFO` | Get full device info | `INFO\|NAME:...\|MODEL:...\|...` |
| `FACTORY_RESET` | Reset all settings | `OK:FACTORY_RESET` |

### **Standard Colors**
| Command | Description | Example |
| :--- | :--- | :--- |
| `COLOR_WAIT:R,G,B` | Waiting/breathing color | `COLOR_WAIT:0,0,255` |
| `COLOR_CONN:R,G,B` | Connected state color | `COLOR_CONN:0,255,255` |
| `COLOR_ACTIVE:R,G,B` | Game active color | `COLOR_ACTIVE:255,0,0` |
| `COLOR_SUCCESS:R,G,B` | Success/triggered color | `COLOR_SUCCESS:0,255,0` |
| `GET_COLORS` | Get all colors | `COLORS\|WAIT:...\|CONN:...\|...` |
| `RESET_COLORS` | Reset to defaults | `OK:COLORS_RESET` |

### **Color Presets (NEW!)**
Save and recall up to **8 color presets** for different game scenarios:

| Command | Description | Example |
| :--- | :--- | :--- |
| `SAVE_PRESET:n:R,G,B` | Save color to preset slot n (0-7) | `SAVE_PRESET:3:255,128,0` |
| `LOAD_PRESET:n` | Load and apply preset n | `LOAD_PRESET:3` |
| `GET_PRESETS` | Get all saved presets | `PRESETS\|0:255,0,0\|1:0,255,0\|...` |

**Use Case**: 
- Preset 0: Red (stop/slap)
- Preset 1: Green (go/jump)
- Preset 2: Blue (squat)
- Preset 3: Yellow (push-up)
- etc.

### **Color Sequences (NEW!)**
Create automatic color patterns for reaction drills:

| Command | Description | Example |
| :--- | :--- | :--- |
| `SET_SEQUENCE:R1,G1,B1;R2,G2,B2;...` | Set sequence (up to 16 colors) | `SET_SEQUENCE:255,0,0;0,255,0;0,0,255` |
| `SET_STEP_DURATION:ms` | Set duration per step | `SET_STEP_DURATION:1000` |
| `PLAY_SEQUENCE` | Start playing sequence | `OK:SEQUENCE_PLAYING` |
| `STOP_SEQUENCE` | Stop sequence | `OK:SEQUENCE_STOPPED` |

**Use Case**: 
- Red → Green → Blue cycle for "follow the light" drills
- Random color patterns for cognitive training
- Timed sequences for interval training

### **Game Control**
| Command | Description | Response |
| :--- | :--- | :--- |
| `START` | Start reaction test | `OK:STARTED` |
| `RESET` | Stop game | `OK:RESET` |

---

## 🎮 Example Training Scenarios

### **Scenario 1: Color-Coded Actions**
```
# Setup different colors for different actions
SAVE_PRESET:0:255,0,0      # Red = Slap
SAVE_PRESET:1:0,255,0      # Green = Jump
SAVE_PRESET:2:0,0,255      # Blue = Squat
SAVE_PRESET:3:255,255,0    # Yellow = Push-up

# During training, coach sends:
LOAD_PRESET:0              # Athlete sees RED → Slaps pod
LOAD_PRESET:1              # Athlete sees GREEN → Jumps
LOAD_PRESET:2              # Athlete sees BLUE → Squats
```

### **Scenario 2: Pattern Recognition**
```
# Create a sequence
SET_SEQUENCE:255,0,0;0,255,0;0,0,255;255,255,0
SET_STEP_DURATION:800
PLAY_SEQUENCE

# Pod cycles: Red → Green → Blue → Yellow → Red...
# Athlete must perform action matching each color
```

### **Scenario 3: Reaction Drill**
```
# Set custom active color (purple)
COLOR_ACTIVE:255,0,255

# Start game
START
# Pod turns PURPLE
# Athlete reacts
# Result: RESULT:245ms
```

---

## 📊 Default Color Presets

| Slot | Color | RGB Value | Use Case |
| :--- | :--- | :--- | :--- |
| 0 | Red | 255,0,0 | Stop/Slap |
| 1 | Green | 0,255,0 | Go/Jump |
| 2 | Blue | 0,0,255 | Squat/Hold |
| 3 | Yellow | 255,255,0 | Push-up |
| 4 | Magenta | 255,0,255 | Burpee |
| 5 | Cyan | 0,255,255 | Rest |
| 6 | Orange | 255,128,0 | Lunge |
| 7 | Purple | 128,0,255 | Plank |

---

## 🎯 Quick Start Guide

1. **Connect** to `TAKEONE_Reflex`
2. **Enable notifications** on characteristic
3. **Test basic function**:
   ```
   START
   [Press button]
   → RESULT:XXXms
   ```
4. **Set custom colors**:
   ```
   SAVE_PRESET:0:255,0,0
   SAVE_PRESET:1:0,255,0
   LOAD_PRESET:0  → Red lights up
   LOAD_PRESET:1  → Green lights up
   ```
5. **Create sequence**:
   ```
   SET_SEQUENCE:255,0,0;0,255,0;0,0,255
   SET_STEP_DURATION:1000
   PLAY_SEQUENCE
   ```

---

This makes **TAKEONE Reflex** a professional-grade training tool with unlimited color combinations for different exercises! 🎨💪