#include <IRremote.hpp>
#define IR_RECEIVE_PIN 2
const byte ledPins[] = {12, 10, 9, 8, 7, 6, 5, 4, 14, 15};
const bool isPWM[] = {false, true, true, false, false, true, true, false, false, false};
#define TOTAL_LEDS 10
bool isOn = true;
uint8_t brightnessLevels[] = {0, 30, 60, 100, 150, 200, 255};
#define BRIGHTNESS_STEPS 6
uint8_t brightnessIndex = 5;
uint8_t brightness = brightnessLevels[brightnessIndex];
uint8_t animationMode = 0;
unsigned long lastAnimTime = 0;
uint16_t animPos = 0;
void setup() {
for (int i = 0; i < TOTAL_LEDS; i++) {
pinMode(ledPins[i], OUTPUT);
if (isPWM[i]) {
analogWrite(ledPins[i], 0);
} else {
digitalWrite(ledPins[i], LOW);
}
}
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
}
void loop() {
if (IrReceiver.decode()) {
uint32_t command = IrReceiver.decodedIRData.decodedRawData;
handleIRCommand(command);
IrReceiver.resume();
}
if (isOn) {
unsigned long now = millis();
unsigned long delayTime = getAnimDelay();
if (now - lastAnimTime > delayTime) {
lastAnimTime = now;
executeAnimation();
animPos++;
}
} else {
allLEDsOff();
}
}
unsigned long getAnimDelay() {
switch (animationMode) {
case 0: return 300;
case 1: return 120;
case 2: return 130;
case 3: return 400;
case 4: return 90;
case 5: return 300;
case 6: return 200;
default: return 200;
}
}
void handleIRCommand(uint32_t cmd) {
switch (cmd) {
case 0xF708FB04: isOn = !isOn; break;
case 0xFD02FB04:
if (brightnessIndex < BRIGHTNESS_STEPS - 1) {
brightnessIndex++;
brightness = brightnessLevels[brightnessIndex];
}
break;
case 0xFC03FB04:
if (brightnessIndex > 0) {
brightnessIndex--;
brightness = brightnessLevels[brightnessIndex];
}
break;
case 0xEF10FB04: animationMode = 0; break;
case 0xEE11FB04: animationMode = 1; break;
case 0xED12FB04: animationMode = 2; break;
case 0xEC13FB04: animationMode = 3; break;
case 0xEB14FB04: animationMode = 4; break;
case 0xEA15FB04: animationMode = 5; break;
case 0xE916FB04: animationMode = 6; break;
}
}
void executeAnimation() {
switch (animationMode) {
case 0: animAllOn(); break;
case 1: animSequence(); break;
case 2: animRunningPair(); break;
case 3: animBlinkAll(); break;
case 4: animWave(); break;
case 5: animAlternate(); break;
case 6: animRandom(); break;
}
}
void animAllOn() {
for (int i = 0; i < TOTAL_LEDS; i++) {
if (isPWM[i]) {
analogWrite(ledPins[i], brightness);
} else {
digitalWrite(ledPins[i], HIGH);
}
}
}
void animSequence() {
allLEDsOff();
int current = animPos % TOTAL_LEDS;
if (isPWM[current]) {
analogWrite(ledPins[current], brightness);
} else {
digitalWrite(ledPins[current], HIGH);
}
}
void animRunningPair() {
allLEDsOff();
int first = animPos % TOTAL_LEDS;
int second = (first + 1) % TOTAL_LEDS;
if (isPWM[first]) {
analogWrite(ledPins[first], brightness);
} else {
digitalWrite(ledPins[first], HIGH);
}
if (isPWM[second]) {
analogWrite(ledPins[second], brightness);
} else {
digitalWrite(ledPins[second], HIGH);
}
}
void animBlinkAll() {
bool state = (animPos / 2) % 2;
for (int i = 0; i < TOTAL_LEDS; i++) {
if (isPWM[i]) {
analogWrite(ledPins[i], state ? brightness : 0);
} else {
digitalWrite(ledPins[i], state ? HIGH : LOW);
}
}
}
void animWave() {
allLEDsOff();
int waveSize = 3;
for (int i = 0; i < waveSize; i++) {
int idx = (animPos + i) % TOTAL_LEDS;
if (isPWM[idx]) {
analogWrite(ledPins[idx], brightness);
} else {
digitalWrite(ledPins[idx], HIGH);
}
}
}
void animAlternate() {
bool state = animPos % 2;
for (int i = 0; i < TOTAL_LEDS; i++) {
if (i % 2 == state) {
if (isPWM[i]) {
analogWrite(ledPins[i], brightness);
} else {
digitalWrite(ledPins[i], HIGH);
}
} else {
if (isPWM[i]) {
analogWrite(ledPins[i], 0);
} else {
digitalWrite(ledPins[i], LOW);
}
}
}
}
void animRandom() {
allLEDsOff();
for (int i = 0; i < 3; i++) {
int idx = random(TOTAL_LEDS);
if (isPWM[idx]) {
analogWrite(ledPins[idx], brightness);
} else {
digitalWrite(ledPins[idx], HIGH);
}
}
}
void allLEDsOff() {
for (int i = 0; i < TOTAL_LEDS; i++) {
if (isPWM[i]) {
analogWrite(ledPins[i], 0);
} else {
digitalWrite(ledPins[i], LOW);
}
}
}