#include <Adafruit_NeoPixel.h>
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;
#define LED_PIN 2
#define NUM_LEDS 60
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
int currentEffect = -1;
unsigned long effectTimer = 0;
uint16_t effectStep = 0;
// ================= Utility =================
void showColor(uint32_t color) {
for (int i = 0; i < NUM_LEDS; i++) strip.setPixelColor(i, color);
strip.show();
}
void resetEffect() {
effectStep = 0;
effectTimer = millis();
strip.clear();
strip.show();
}
// ================= Effects =================
void effectRainbow() {
if (millis() - effectTimer > 20) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i,
strip.gamma32(strip.ColorHSV((i * 65536 / NUM_LEDS) + effectStep * 256)));
}
strip.show();
effectStep++;
effectTimer = millis();
}
}
void effectColorWipe(uint32_t color) {
if (millis() - effectTimer > 40) {
if (effectStep < NUM_LEDS) {
strip.setPixelColor(effectStep, color);
strip.show();
effectStep++;
} else {
effectStep = 0;
strip.clear();
}
effectTimer = millis();
}
}
void effectTheater(uint32_t color) {
if (millis() - effectTimer > 60) {
strip.clear();
for (int i = effectStep % 3; i < NUM_LEDS; i += 3) {
strip.setPixelColor(i, color);
}
strip.show();
effectStep++;
effectTimer = millis();
}
}
void meteorEffect(uint32_t color) {
if (millis() - effectTimer > 30) {
for (int i = 0; i < NUM_LEDS; i++) {
uint32_t c = strip.getPixelColor(i);
strip.setPixelColor(i,
(uint8_t)(c >> 16) * 0.7,
(uint8_t)(c >> 8) * 0.7,
(uint8_t)c * 0.7
);
}
strip.setPixelColor(effectStep % NUM_LEDS, color);
strip.show();
effectStep++;
effectTimer = millis();
}
}
void waveEffect(uint32_t color) {
if (millis() - effectTimer > 20) {
for (int i = 0; i < NUM_LEDS; i++) {
int level = (sin((i + effectStep) * 0.2) + 1) * 127;
strip.setPixelColor(i,
((color >> 16) & 255) * level / 255,
((color >> 8) & 255) * level / 255,
(color & 255) * level / 255
);
}
strip.show();
effectStep++;
effectTimer = millis();
}
}
// ================= Effect Selector =================
void runEffect(int e) {
switch (e) {
case 1: showColor(strip.Color(255,0,0)); break;
case 2: showColor(strip.Color(0,255,0)); break;
case 3: showColor(strip.Color(0,0,255)); break;
case 4: effectRainbow(); break;
case 5: effectColorWipe(strip.Color(255,255,0)); break;
case 6: effectColorWipe(strip.Color(0,255,255)); break;
case 7: effectTheater(strip.Color(255,0,0)); break;
case 8: effectTheater(strip.Color(0,255,0)); break;
case 9: effectTheater(strip.Color(0,0,255)); break;
case 10: meteorEffect(strip.Color(255,255,255)); break;
case 11: meteorEffect(strip.Color(255,0,0)); break;
case 12: meteorEffect(strip.Color(0,255,0)); break;
case 13: meteorEffect(strip.Color(0,0,255)); break;
case 14: waveEffect(strip.Color(255,0,0)); break;
case 15: waveEffect(strip.Color(0,255,0)); break;
case 16: waveEffect(strip.Color(0,0,255)); break;
case 17: showColor(strip.Color(255,0,255)); break;
case 18: showColor(strip.Color(255,255,255)); break;
case 19: effectRainbow(); break;
case 20: effectRainbow(); break;
case 21: effectRainbow(); break;
case 22: effectRainbow(); break;
case 23: effectRainbow(); break;
case 24: effectRainbow(); break;
case 25: effectRainbow(); break;
case 26: effectRainbow(); break;
case 27: effectRainbow(); break;
case 28: effectRainbow(); break;
case 29: effectRainbow(); break;
case 30: effectRainbow(); break;
case 31: effectRainbow(); break;
case 32: effectRainbow(); break;
case 33: effectRainbow(); break;
case 34: effectRainbow(); break;
}
}
// ================= Setup =================
void setup() {
strip.begin();
strip.setBrightness(150);
strip.show();
Serial.begin(115200);
SerialBT.begin("ESP32_LED");
}
// ================= Loop =================
void loop() {
if (SerialBT.available()) {
String cmd = SerialBT.readStringUntil('\n');
cmd.trim();
if (cmd == "R") showColor(strip.Color(255,0,0));
else if (cmd == "G") showColor(strip.Color(0,255,0));
else if (cmd == "B") showColor(strip.Color(0,0,255));
else if (cmd == "Y") showColor(strip.Color(255,255,0));
else if (cmd == "P") showColor(strip.Color(255,0,255));
else if (cmd == "U") showColor(strip.Color(128,0,255));
else if (cmd.startsWith("E")) {
int e = cmd.substring(1).toInt();
if (e >= 1 && e <= 34) {
currentEffect = e;
resetEffect();
}
}
}
if (currentEffect > 0) runEffect(currentEffect);
}