Загрузка данных


#include <FastLED.h>

// --- НАСТРОЙКИ ---
#define LED_PIN     25       // Пин управления светодиодами (GPIO 25)
#define BUTTON_PIN  4        // Пин кнопки (замыкается на GND)
#define NUM_LEDS    10       // Всего ровно 10 светодиодов
#define BRIGHTNESS  140      // Комфортная яркость

CRGB leds[NUM_LEDS];
CRGB realLeds[NUM_LEDS]; // Буфер для реального порядка физического подключения

// --- ПАЛИТРА ИЗ 12 ПРИЯТНЫХ СТАТИЧНЫХ ЦВЕТОВ ---
const CRGB pleasantColors[12] = {
  CRGB(255, 120, 50),   // 0. Теплый янтарный
  CRGB(255, 150, 100),  // 1. Пастельный персиковый
  CRGB(255, 100, 150),  // 2. Нежно-розовый
  CRGB(180, 100, 255),  // 3. Мягкий лавандовый
  CRGB(100, 130, 255),  // 4. Спокойный васильковый
  CRGB(50, 180, 255),   // 5. Небесно-голубой
  CRGB(50, 220, 180),   // 6. Бирюзово-мятный
  CRGB(80, 240, 120),   // 7. Светло-салатовый
  CRGB(220, 220, 100),  // 8. Теплый золотистый
  CRGB(255, 180, 50),   // 9. Медовый
  CRGB(200, 150, 220),  // 10. Сиреневая дымка
  CRGB(230, 230, 230)   // 11. Мягкий белый (теплый)
};

// --- СОСТОЯНИЯ ---
int currentHueIndex = 0;   
int currentMode = 0;       
const int totalModes = 6;  

// Переменные кнопки
unsigned long buttonPressStartTime = 0;
bool buttonIsPressed = false;
bool longPressHandled = false;
const unsigned long longPressTime = 500; 

void setup() {
  Serial.begin(115200);
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(realLeds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  handleButton();
  runCurrentMode();
  
  // Маппинг (перенос красивого логического порядка в реальный физический порядок пайким)
  // Распределяем 10 диодов слева направо по платам
  // Допустим, логические индексы 0..3 — левая плата, 4..9 — правая плата
  for (int i = 0; i < NUM_LEDS; i++) {
    realLeds[getPhysicalIndex(i)] = leds[i];
  }
  
  FastLED.show();
  FastLED.delay(20); 
}

// Функция перевода логического порядка в физический (под вашу пайку на фото)
int getPhysicalIndex(int logicalIndex) {
  // Настроено так, чтобы волна шла плавно слева направо по обеим платам:
  const int mapTable[10] = {3, 2, 1, 0, 4, 5, 6, 7, 8, 9}; 
  return mapTable[logicalIndex];
}

// --- ЛОГИКА КНОПКИ ---
void handleButton() {
  bool reading = (digitalRead(BUTTON_PIN) == LOW);

  if (reading && !buttonIsPressed) {
    buttonIsPressed = true;
    buttonPressStartTime = millis();
    longPressHandled = false;
  } 
  else if (reading && buttonIsPressed) {
    if (!longPressHandled && (millis() - buttonPressStartTime >= longPressTime)) {
      currentMode = (currentMode + 1) % totalModes;
      longPressHandled = true;
    }
  } 
  else if (!reading && buttonIsPressed) {
    buttonIsPressed = false;
    if (!longPressHandled) {
      currentHueIndex = (currentHueIndex + 1) % 12;
    }
  }
}

// --- МОДЫ АНИМАЦИИ (РАБОТАЮТ С 10 ВИРТУАЛЬНЫМИ СВЕТОДИОДАМИ) ---
void runCurrentMode() {
  CRGB baseColor = pleasantColors[currentHueIndex];

  switch (currentMode) {
    case 0:
      // 0: Статика выбранным цветом
      fill_solid(leds, NUM_LEDS, baseColor);
      break;

    case 1:
      // 1: Плавное «дыхание»
      {
        float breath = (sin(millis() / 350.0) + 1.0) / 2.0;
        CRGB breathColor = baseColor;
        breathColor.nscale8(breath * 255);
        fill_solid(leds, NUM_LEDS, breathColor);
      }
      break;

    case 2:
      // 2: Красивая бегущая волна слева направо по всем 10 кнопкам
      for (int i = 0; i < NUM_LEDS; i++) {
        float wave = (sin(millis() / 150.0 - i * 0.6) + 1.0) / 2.0;
        CRGB waveColor = baseColor;
        waveColor.nscale8(wave * 255);
        leds[i] = waveColor;
      }
      break;

    case 3:
      // 3: Бегающая искра на приглушенном фоне
      {
        fadeToBlackBy(leds, NUM_LEDS, 50);
        int pos = (millis() / 120) % NUM_LEDS;
        leds[pos] = CRGB::White;
        for(int i = 0; i < NUM_LEDS; i++) {
          if(i != pos) {
            CRGB dimColor = baseColor;
            dimColor.nscale8(80);
            leds[i] = dimColor;
          }
        }
      }
      break;

    case 4:
      // 4: Плавный переливающийся градиент по всей длине
      for (int i = 0; i < NUM_LEDS; i++) {
        leds[i] = blend(baseColor, CHSV(currentHueIndex * 21 + i * 15, 150, 255), 128);
      }
      break;

    case 5:
      // 5: Мягкое мерцание огоньков
      {
        fadeToBlackBy(leds, NUM_LEDS, 30);
        if (random8() < 50) {
          int idx = random8(NUM_LEDS);
          leds[idx] = baseColor;
        }
      }
      break;
  }
}