#include <FastLED.h>
// --- Nastavení LED Pásku a Segmentů ---
#define LED_PIN 6 // Datový pin pro LED pásek
#define LEDS_PER_SEGMENT 16
#define NUM_LEDS 64 // Celkový počet LED (4 * 16)
#define SEGMENT_1_START 0
#define SEGMENT_2_START LEDS_PER_SEGMENT
#define SEGMENT_3_START (2 * LEDS_PER_SEGMENT)
#define SEGMENT_4_START (3 * LEDS_PER_SEGMENT)
// --- Nastavení Vstupních Pinů ---
#define MODE_PIN_1 2 // Digitální pin pro Režim 1 (Relé)
#define MODE_PIN_2 3 // Digitální pin pro Režim 2 (Relé)
#define MODE_PIN_3 4 // Digitální pin pro Režim 3 (Relé)
#define POT_PIN A0 // Analogový pin pro Potenciometr (0-5V)
// --- Barevné Konstanty a Jasnost ---
// Pozadí pro segmenty 1-3 (50% jasnosti = 128 z 255)
#define BG_BRIGHTNESS 128
#define BLACK CRGB::Black
#define BACKGROUND_COLOR_1 CRGB(0, 0, BG_BRIGHTNESS) // Modrá (50%)
#define BACKGROUND_COLOR_2 CRGB(0, BG_BRIGHTNESS, 0) // Zelená (50%)
#define BACKGROUND_COLOR_3 CRGB(0, 0, BG_BRIGHTNESS) // Modrá (50%)
#define ACTIVE_COLOR_4 CRGB(255, 255, 255) // Barva segmentu 4 (Plná Bílá)
#define TRAVELING_COLOR_1 CRGB(0, 150, 255) // Tyrkysová (100%)
#define TRAVELING_COLOR_2 CRGB(0, 255, 0) // Jasně zelená (100%)
#define TRAVELING_COLOR_3 CRGB(0, 150, 255) // Tyrkysová (100%)
// --- Proměnné pro Animace a Sledování Stavu ---
CRGB leds[NUM_LEDS];
// Stavy pro FSM (Finite State Machine)
enum SegmentState {
OFF,
FADE_IN,
ANIMATING,
ANALOG_CONTROL
};
// Aktuální stav každého segmentu
SegmentState seg1State = OFF;
SegmentState seg2State = OFF;
SegmentState seg3State = OFF;
SegmentState seg4State = ANALOG_CONTROL;
// Proměnné pro Fade-in proces (Asynchronní)
unsigned long lastFadeUpdate = 0;
const int fadeDelay = 30; // Rychlost postupu (ms)
int fadeLedIndex1 = 0;
int fadeLedIndex2 = LEDS_PER_SEGMENT - 1;
int fadeLedIndex3 = LEDS_PER_SEGMENT - 1;
// Proměnné pro Animace putujícího bodu
unsigned long lastAnimationUpdate = 0;
const int animationDelay = 50; // Rychlost animace bodu (ms)
int currentPos1 = 0;
int currentPos2 = LEDS_PER_SEGMENT - 1;
int currentPos3 = LEDS_PER_SEGMENT - 1;
// --- Funkce pro Správu Digitálního Segmentu 1-3 (FSM) ---
void handleDigitalSegment(int startLed, SegmentState &state, bool isActive, CRGB bgColor, int dir, int &fadeIndex, int &animPos, CRGB animColor) {
bool stateChanged = false;
// 1. DETEKCE ZMĚNY STAVU (ZAP/VYP)
if (isActive) {
if (state == OFF) {
state = FADE_IN;
stateChanged = true;
}
} else { // Segment by měl být VYPNUTÝ
if (state != OFF) {
state = OFF;
stateChanged = true;
}
}
// 2. AKCE PŘI ZMĚNĚ STAVU
if (stateChanged) {
if (state == OFF) {
// Okamžité, vynucené VYPNUTÍ
fill_solid(leds + startLed, LEDS_PER_SEGMENT, BLACK);
FastLED.show();
return;
} else if (state == FADE_IN) {
// Reset indexů při startu
if (dir == 1) { fadeIndex = 0; animPos = 0; }
else { fadeIndex = LEDS_PER_SEGMENT - 1; animPos = LEDS_PER_SEGMENT - 1; }
}
return;
}
// --- Vynucené Vypnutí: Pokud je VYP, zajistíme že je buffer černý ---
if (state == OFF) {
fill_solid(leds + startLed, LEDS_PER_SEGMENT, BLACK);
return;
}
// 3. PROBÍHAJÍCÍ STAVY
if (millis() - lastFadeUpdate >= fadeDelay) {
if (state == FADE_IN) {
// Postupné rozsvěcování
leds[startLed + fadeIndex] = bgColor;
FastLED.show();
if (dir == 1) { // Nahoru
fadeIndex++;
if (fadeIndex >= LEDS_PER_SEGMENT) { state = ANIMATING; }
} else { // Dolů
fadeIndex--;
if (fadeIndex < 0) { state = ANIMATING; }
}
}
}
// 4. ANIMACE PUTUJÍCÍHO BODU
if (state == ANIMATING && millis() - lastAnimationUpdate >= animationDelay) {
// Nejprve nastavit pozadí
fill_solid(leds + startLed, LEDS_PER_SEGMENT, bgColor);
// Nastavit nový bod
leds[startLed + animPos] = animColor;
// Posun pozice bodu
if (dir == 1) {
animPos = (animPos + 1) % LEDS_PER_SEGMENT;
} else {
animPos = (animPos - 1);
if (animPos < 0) animPos = LEDS_PER_SEGMENT - 1;
}
}
}
// --- Funkce pro Správu Segmentu 4 (Analog - Rozsvěcování čtverečků) ---
void handleAnalogSegment(int startLed, CRGB color) {
// 1. Čtení hodnoty z potenciometru (0-1023)
int potValue = analogRead(POT_PIN);
// 2. Mapování hodnoty na POČET LED, které mají svítit (0-16)
int ledsToLight = map(potValue, 0, 1023, 0, LEDS_PER_SEGMENT);
// 3. Vynulování celého segmentu
fill_solid(leds + startLed, LEDS_PER_SEGMENT, BLACK);
// 4. Rozsvícení potřebného počtu LED (lineárně od začátku segmentu)
if (ledsToLight > 0) {
fill_solid(leds + startLed, ledsToLight, color);
}
}
// --- Setup ---
void setup() {
// Piny nastaveny jako INPUT - Vyžaduje externí PULLDOWN rezistory!
pinMode(MODE_PIN_1, INPUT);
pinMode(MODE_PIN_2, INPUT);
pinMode(MODE_PIN_3, INPUT);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(255);
FastLED.clear();
FastLED.show();
}
// --- Main Loop ---
void loop() {
unsigned long now = millis();
// 1. Zjištění AKTUÁLNÍHO stavu digitálních vstupů
bool mode1Active = digitalRead(MODE_PIN_1) == HIGH;
bool mode2Active = digitalRead(MODE_PIN_2) == HIGH;
bool mode3Active = digitalRead(MODE_PIN_3) == HIGH;
// 2. Zpracování digitálně řízených segmentů (1-3)
handleDigitalSegment(
SEGMENT_1_START, seg1State, mode1Active,
BACKGROUND_COLOR_1, 1, fadeLedIndex1, currentPos1, TRAVELING_COLOR_1
);
handleDigitalSegment(
SEGMENT_2_START, seg2State, mode2Active,
BACKGROUND_COLOR_2, -1, fadeLedIndex2, currentPos2, TRAVELING_COLOR_2
);
handleDigitalSegment(
SEGMENT_3_START, seg3State, mode3Active,
BACKGROUND_COLOR_3, -1, fadeLedIndex3, currentPos3, TRAVELING_COLOR_3
);
// 3. Zpracování analogově řízeného segmentu (4)
handleAnalogSegment(SEGMENT_4_START, ACTIVE_COLOR_4);
// 4. Aktualizace časovačů
if (now - lastFadeUpdate >= fadeDelay) {
lastFadeUpdate = now;
}
if (now - lastAnimationUpdate >= animationDelay) {
lastAnimationUpdate = now;
}
// 5. Zobrazení změn
// FastLED.show() je voláno zde pro Animace (krok 4) a Segment 4,
// ale také uvnitř handleDigitalSegment pro plynulé Fade-in.
FastLED.show();
}