// OTA Work v0.24
#include <FastLED.h>
#include <WiFi.h>
#include <ArduinoOTA.h>
#define LED_PIN 11
const int LDR_PIN = 16;
#define NUM_LEDS 4
#define BUTTON_A 35
#define BUTTON_B 37
// #define LDR_PIN 16
CRGB leds[NUM_LEDS];
// Define LED modes
enum Mode { SOLID, BLEND, CANDLE };
Mode currentMode = SOLID;
// Color sequence
const CRGB colors[] = {CRGB::White, CRGB::Red, CRGB::Green, CRGB::Blue, CRGB::Yellow, CRGB::Cyan, CRGB::Magenta};
const int numColors = sizeof(colors) / sizeof(colors[0]);
// Function declarations
void setAllLeds(CRGB color);
void flashBlendSpeed(int flashes);
void connectToWiFi();
void handleButtonA();
void handleButtonB();
void enterOTAMode();
void blendColors();
void simulateCandleEffect();
//void detectRoomLight();
// State variables
int currentColorIndex = 0;
int brightnessLevels[] = {255, 160, 100, 60, 30, 10};
int currentBrightnessIndex = 0;
// Button press tracking
bool lastButtonAState = false, lastButtonBState = false;
unsigned long buttonAPressTime = 0, buttonBPressTime = 0;
bool buttonALongPressHandled = false, buttonBLongPressHandled = false;
// LDR threshold and status
int ldrThreshold = 1200; // Adjust for environment
// Timing for effects
unsigned long blendStartTime = 0;
unsigned long lastCandleUpdate = 0;
// Blending speed settings
const unsigned long blendSpeeds[] = {30000, 60000, 120000}; // 30s, 60s, 120s
int currentBlendSpeedIndex = 0;
// Current Blend hue for debugging
uint8_t currentBlendHue = 0;
// Wi-Fi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
void setup() {
Serial.begin(115200);
// Initialize LEDs
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(brightnessLevels[currentBrightnessIndex]);
setAllLeds(CRGB::White);
// Initialize buttons and LDR
pinMode(BUTTON_A, INPUT_PULLUP);
pinMode(BUTTON_B, INPUT_PULLUP);
delay(1000); // Briefly show white
// Connect to Wi-Fi
connectToWiFi();
// Setup OTA
ArduinoOTA.onStart([]() {
String type = (ArduinoOTA.getCommand() == U_FLASH) ? "sketch" : "filesystem";
Serial.println("OTA Start: " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("OTA End");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("OTA Progress: %u%%\r", (progress * 100) / total);
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("OTA Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("OTA Ready");
}
void loop() {
ArduinoOTA.handle(); // Always check OTA
// Detect room light and adjust LED states
//detectRoomLight();
int ldrValue = analogRead(LDR_PIN);
bool isBright = ldrValue > ldrThreshold;
if (isBright) {
// Handle buttons only if room is bright
handleButtonA();
handleButtonB();
// Execute mode-specific behavior
switch (currentMode) {
case SOLID:
break;
case BLEND:
blendColors();
break;
case CANDLE:
simulateCandleEffect();
break;
}
}
delay(10); // Debounce delay
}
void setAllLeds(CRGB color) {
FastLED.clear();
fill_solid(leds, NUM_LEDS, color);
FastLED.show();
}
void flashBlendSpeed(int flashes) {
for (int i = 0; i < flashes; i++) {
// Flash between current blend color and white
fill_solid(leds, NUM_LEDS, CHSV(currentBlendHue, 255, brightnessLevels[currentBrightnessIndex]));
FastLED.show();
delay(250);
setAllLeds(CRGB::White);
delay(250);
}
}
void connectToWiFi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(ssid, password);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (millis() - startTime > 15000) {
Serial.println("\nWi-Fi connection failed.");
return;
}
}
Serial.println("\nWi-Fi connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void handleButtonA() {
bool buttonAState = digitalRead(BUTTON_A) == LOW;
if (buttonAState && !lastButtonAState) {
buttonAPressTime = millis();
buttonALongPressHandled = false;
}
if (buttonAState && millis() - buttonAPressTime >= 1500) {
if (!buttonALongPressHandled) {
buttonALongPressHandled = true;
// Long press: Toggle Blend/Solid Mode
if (currentMode == SOLID) {
currentMode = BLEND;
blendStartTime = millis();
Serial.println("Entered BLEND mode.");
} else {
currentMode = SOLID;
setAllLeds(colors[currentColorIndex]);
Serial.println("Entered SOLID mode.");
}
// printStatus();
}
}
if (!buttonAState && lastButtonAState) {
if (!buttonALongPressHandled) {
// Short press: Change color or Blend speed
if (currentMode == SOLID) {
currentColorIndex = (currentColorIndex + 1) % numColors;
setAllLeds(colors[currentColorIndex]);
Serial.println("Changed SOLID color.");
} else if (currentMode == BLEND) {
currentBlendSpeedIndex = (currentBlendSpeedIndex + 1) % 3;
blendStartTime = millis();
flashBlendSpeed(currentBlendSpeedIndex + 1);
Serial.println("Changed BLEND speed.");
}
// printStatus();
}
buttonALongPressHandled = false;
}
lastButtonAState = buttonAState;
}
void handleButtonB() {
bool buttonBState = digitalRead(BUTTON_B) == LOW;
if (buttonBState && !lastButtonBState) {
buttonBPressTime = millis();
buttonBLongPressHandled = false;
}
if (buttonBState && millis() - buttonBPressTime >= 1500) {
if (!buttonBLongPressHandled) {
buttonBLongPressHandled = true;
// Long press: Toggle Candle Mode
if (currentMode == CANDLE) {
currentMode = SOLID;
setAllLeds(colors[currentColorIndex]);
Serial.println("Exited CANDLE mode.");
} else {
currentMode = CANDLE;
FastLED.setBrightness(255);
Serial.println("Entered CANDLE mode.");
}
// printStatus();
}
}
if (!buttonBState && lastButtonBState) {
if (!buttonBLongPressHandled) {
// Short press: Adjust brightness
currentBrightnessIndex = (currentBrightnessIndex + 1) % (sizeof(brightnessLevels) / sizeof(brightnessLevels[0]));
FastLED.setBrightness(brightnessLevels[currentBrightnessIndex]);
FastLED.show();
Serial.println("Changed brightness level.");
// printStatus();
}
buttonBLongPressHandled = false;
}
lastButtonBState = buttonBState;
}
void blendColors() {
unsigned long now = millis();
unsigned long elapsed = now - blendStartTime;
if (elapsed >= blendSpeeds[currentBlendSpeedIndex]) {
blendStartTime = now;
elapsed = 0;
}
currentBlendHue = map(elapsed, 0, blendSpeeds[currentBlendSpeedIndex], 0, 255);
fill_solid(leds, NUM_LEDS, CHSV(currentBlendHue, 255, brightnessLevels[currentBrightnessIndex]));
FastLED.show();
}
void simulateCandleEffect() {
unsigned long now = millis();
if (now - lastCandleUpdate >= random(50, 150)) {
lastCandleUpdate = now;
int flicker = random(200, 255);
CRGB candleColor = CRGB(flicker, flicker - random(50, 70), flicker - random(100, 120));
setAllLeds(candleColor);
}
}